25
1
# teapo v0.5a
2
​
3
Self-editing filesystem embedded in a single HTML file.
4
​
5
The idea, all of the painstaking implementation and the vision by [Oleg Mihailik](mihailik@gmail.com).
6
See the credits section for the used libraries and respective licences. 
7
​
8
### Outstanding tasks:
9
 * Better internal API for doc handler and for the app itself
10
 * Highlight of the changed files (comparing local storage and the original DOM)
11
 * Styles and colours (planning for pale seaside 'Whitstable' blue).
12
 * Scrollbar to use syntax-highlighted document lines.
13
 * TypeScript extra features: current signature/symbol in the status, navigate to, search integration, tooltips.
14
 * More local storage adapters.
15
 * Delete folder.
16
 * Rename file/folder.
17
 * Upload to GitHub, GDrive, Dropbox etc.
18
 * Stronger browser support (the target is ALL).
19
 * FS integration in Chrome app, node-webkit, HTMLA-ie7.
20
 * node emulation over teapo-Drive.
21
 * Toast popup/fadeout messages for key events: opening, building, import-export completion.
22
 * Sub-domains for doc handlers (separate contexts in TS/JS for selected subdirectories)
23
 * Demos in the repository: itself, TypeScript whole, PE.js, dummy sample
24
​
25
The next big version cut is planned for Christmas.
  • app
    • appRoot
      • importExport
        • exportAllHTML.ts
          module teapo.app.appRoot.importExport {
            
            export function exportAllHTML() { 
              var filename = saveFileName();
              exportBlob(filename, ['<!doctype html>\n', document.documentElement.outerHTML]);
            }
            
          }
        • exportAllZIP.ts
          module teapo.app.appRoot.importExport {
          
            export function exportAllZIP(drive: persistence.Drive) {
              zip.useWebWorkers = false;
              var filename = saveFileName();
              if (filename.length > '.html'.length && filename.slice(filename.length - '.html'.length).toLowerCase() === '.html')
                filename = filename.slice(0, filename.length - '.html'.length);
              else if (filename.length > '.htm'.length && filename.slice(filename.length - '.htm'.length).toLowerCase() === '.htm')
                filename = filename.slice(0, filename.length - '.htm'.length);
              filename += '.zip';
          
              var blobWriter = new zip.BlobWriter();
              zip.createWriter(blobWriter, (zipWriter) => {
          
                var files = drive.files();
                var completedCount = 0;
          
                var zipwritingCompleted = () => {
                  zipWriter.close((blob) => {
                    var url = URL.createObjectURL(blob);
                    var a = document.createElement('a');
                    a.href = url;
                    a.setAttribute('download', filename);
                    a.click();
                  });
                };
          
                var continueWriter = () => {
                  if (completedCount === files.length) {
                    zipwritingCompleted();
                    return;
                  }
          
                  var content = drive.read(files[completedCount]);
          
                  var zipRelativePath = files[completedCount].slice(1);
          
                  zipWriter.add(zipRelativePath, new zip.TextReader(content), () => {
                    completedCount++;
          
                    setTimeout(continueWriter, 1);
                  });
                };
          
                continueWriter();
              });
            }
            
          }
        • exportBlob.ts
          module teapo.app.appRoot.importExport { 
          
          
            export function exportBlob(filename: string, textChunks: string[]) { 
              var blob: Blob = new (<any>Blob)(textChunks, { type: 'application/octet-stream' });
              var url = URL.createObjectURL(blob);
              var a = document.createElement('a');
              a.href = url;
              a.setAttribute('download', filename);
              try {
                // safer save method, supposed to work with FireFox
                var evt = document.createEvent("MouseEvents");
                (<any>evt).initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                a.dispatchEvent(evt);
              }
              catch (e) {
                a.click();
              }
            }
          
          }
        • importSingleFileWithConfirmation.ts
          module teapo.app.appRoot.importExport { 
          
            export function importSingleFileWithConfirmation(
              requestLoad: (fileReader: FileReader, file: File) => void,
              read: (file: string) => string,
              write: (file: string, text: string) => void,
              convertText: (raw: string) => string) {
          
                importExport.loadFile(
                  requestLoad,
                  (data, file) => {
                    var saveNamePromptMessage;
                    var existingRaw = read(files.normalizePath(file.name));
                    var existing = convertText ? convertText(existingRaw) : existingRaw;
                    if (existing) {
                      if (existing === data) {
                        saveNamePromptMessage =
                          file.name + ' already exists ' +
                          'with that same content ' +
                          '(' + data.length + ' character' + (data.length === 1 ? '' : 's') + ')' +
                          '\n' +
                          'Provide path or cancel:';
                      }
                      else {
                        saveNamePromptMessage =
                          file.name + ' already exists ' +
                          'with that different content ' +
                          '(' + data.length + ' character' + (data.length === 1 ? '' : 's') + 
                          ' comparing to ' + existing.length+' in the existing)' +
                          '\n' +
                          'Provide path or cancel:';
                      }
                    }
                    else {
                      saveNamePromptMessage =
                       file.name+' loaded '+data.length+' character' + (data.length === 1 ? '' : 's')+
                        '\n' +
                        'Provide path or cancel:';
                    }
                    
                    var saveName = prompt(saveNamePromptMessage, file.name);
                    if (!saveName)
                      return;
          
                    saveName = files.normalizePath(saveName);
          
                    write(saveName, convertText ? convertText(data) : data);
          
                  });
          
            }
          }
        • importZIPWithConfirmation.ts
          module teapo.app.appRoot.importExport { 
          
            export function importZIPWithConfirmation(drive: persistence.Drive) {
          
                importExport.loadFile(
                  (fileReader, file) => fileReader.readAsArrayBuffer(file),
                  (data, file) => { 
          
          					zip.useWebWorkers = false;
                    zip.createReader(
                      new zip.BlobReader (file),
                      reader => {
                        reader.getEntries(entries => {
          
                          var folder = prompt(
                            'Add ' + entries.length + ' files from zip to a virtual folder:',
                          '/');
          
                          if (!folder)
                            return;
          
                          if (folder.charAt(0) !== '/')
                            folder = '/' + folder;
                          if (folder.charAt(folder.length - 1) !== '/')
                            folder = folder + '/';
          
                          var completeCount = 0;
                          var overwriteCount = 0;
                          
                          var processEntry = () => {
          
                            if (completeCount === entries.length) {
                              alert(
                                completeCount + ' imported into ' + folder +
                                (overwriteCount ? ', ' + overwriteCount + ' existing files overwritten' : ''));
                              return;
                            }
          
                            var entry = entries[completeCount];
          
                            if (entry.directory) {
                            	completeCount++;
                              processEntry();
                              return;
                            }
          
                            var writer = new zip.TextWriter();
          
                            entry.getData(writer, (text) => {
                              var virtFilename = folder + entry.filename;
                              var normFileName = files.normalizePath(virtFilename);
          
                              var isOverwrite = false;
          
                              var fileEntry = drive.read(normFileName);
                              if (fileEntry)
                                isOverwrite = true;
          
                              drive.write(normFileName, text);
          
                              if (isOverwrite)
                                overwriteCount++;
          
                              completeCount++;
                              setTimeout(() => processEntry(), 1);
          
                            }); 
                          };
                          
                          processEntry();
          
                        });
                      },
                      error => {
                        alert('Zip file error: ' + error);
                      });
                    
                  });
          
            }
          }
        • loadFile.ts
          module teapo.app.appRoot.importExport { 
          
            export function loadFile(
              requestLoad: (fileReader: FileReader, file: File) => void,
              processData: (data: any, file: File) => void) {
              var input = document.createElement('input');
              input.type = 'file';
          
              input.onchange = () => {
                if (!input.files || !input.files.length) return;
          
                var fileReader = new FileReader();
                fileReader.onerror = (error) => {
                  alert('read ' + error.message);
                };
                fileReader.onloadend = () => {
                  if (fileReader.readyState !== 2) {
                    alert('read ' + fileReader.readyState + fileReader.error);
                    return;
                  }
          
                  processData(fileReader.result, input.files[0]);
                };
          
                requestLoad(fileReader, input.files[0]);
              };
          
              input.click();
            }
          }
        • saveFileName.ts
          module teapo.app.appRoot.importExport {
            
            export function saveFileName() {
          
              if (window.location.protocol.toLowerCase() === 'blob:')
                return 'nteapo.html';
          
              var urlParts = window.location.pathname.split('/');
              var currentFileName = decodeURI(urlParts[urlParts.length - 1]);
              var lastDot = currentFileName.indexOf('.');
              if (lastDot > 0) {
                currentFileName = currentFileName.slice(0, lastDot) + '.html';
              }
              else {
                currentFileName += '.html';
              }
              return currentFileName;
            }
          
          }
      • PageModel.ts
        module teapo.app.appRoot {
          
          export class PageModel {
        
            private _drive: persistence.Drive = null;
            private _fileTree: teapo.files.FileTree = null;
            private _docHost: docs.DocHost = null;
        
            docHostRegions: docs.types.DocHostRegions = <any>{};
            fileTreeHost: HTMLElement = null;
            flyoutScroller: HTMLElement = null;
            brandingArea: HTMLElement = null;
          
            constructor() {
            }
        
            loadFromDOM(completed: () => void) {
              var fileTree = new teapo.files.FileTree(this.fileTreeHost);
        
              app.loading('Retrieving cached files...');
        
              var uniqueKey = this._getUniqueKey();
              var domTimestamp = fileTree.timestamp;
        
              var mountedDriveCallback: persistence.mountDrive.Callback = mountedDrive => {
        
                  app.loading('Initialising document host...');
                  var docHost = new docs.DocHost(
                      this.docHostRegions,
                      mountedDrive);
        
                  // everything loaded, now assign to state
                  this._fileTree = fileTree;
                  this._docHost = docHost;
                  this._drive = mountedDrive;
        
                  this._fileTree.selectedFile.subscribe(newSelectedFile => this._docHost.show(newSelectedFile));
        
                  if (this._fileTree.selectedFile()) {
                    app.loading('Opening...');
                    this._docHost.show(this._fileTree.selectedFile());
                  }
        
                  var readmeMD = this._drive.read('/readme.md');
                	if (readmeMD) {
                    if (!this._fileTree.selectedFile()) {
                      app.loading('Opening readme...');
                      this._fileTree.selectedFile('/readme.md');
                    }
        
                    var readmeHTML = marked(readmeMD);
                    if (this.brandingArea && 'innerHTML' in this.brandingArea)
                      this.brandingArea.innerHTML = readmeHTML;
                  }
        
                  build.processTemplate.mainDrive = mountedDrive;
        
                  completed();
        
              };
        
              mountedDriveCallback.progress = (current, total) => {
                app.loading('Retrieving cached files: ' + current + ' of ' + total + '...');
              };
              
        
              persistence.mountDrive(
                fileTree,
                uniqueKey,
                domTimestamp,
                <any>teapo.persistence,
                mountedDriveCallback);
            }
        
            keydown(unused, e: KeyboardEvent) {
              if (e.keyCode === 220 || e.which === 220
                || e.keyCode === 79 || e.which === 79) {
                if (e.ctrlKey || e.altKey || e.metaKey) {
                  this.moreClick();
                  return;
                }
              }
        
              if (e.keyCode === 66 || e.which === 66) {
                if (e.ctrlKey || e.altKey || e.metaKey) {
                  this.buildClick();
                  return;
                }
              }
        
              return true;
            }
          
            thickbarMouseDown(unused, e: MouseEvent) {
              dragScrollMouseDown(e, this.flyoutScroller);
            }
        
            moreClick() {
              
              if (!this._fileTree)
                return;
              
              var currentSelectedText = '';
              var moreDlg = new moreDialog.Model(
                this._fileTree.selectedFile(),
                currentSelectedText,
                this._drive.files(),
                typedFilename => { 
                  document.body.removeChild(div);
                  if (!typedFilename)
                    return;
        
                  var newFile = files.normalizePath(typedFilename);
        
                  if (this._drive.read(newFile) === null) {
                    this._drive.write(newFile, '');
                    this._docHost.add(newFile);
                  }
        
                  this._fileTree.selectedFile(newFile);
                });
        
              var div = document.createElement('div');
              document.body.appendChild(div);
              ko.applyBindingsToNode(div, { template: { name: 'MoreDialogView' } }, moreDlg);
              moreDlg.loadFromDOM();
            }
          
            deleteClick() {
              
              var removeFile = this._fileTree.selectedFile();
              if (!removeFile)
                return;
              
              if (!confirm('Remove file\n  ' + removeFile + '  ?'))
                return;
              
              this._drive.write(removeFile, null);
              this._docHost.remove(removeFile);
            }
          
            private _getUniqueKey() {
              var key = window.location.pathname;
        
              key = key.split('?')[0];
              key = key.split('#')[0];
        
              key = key.toLowerCase();
        
              var ignoreSuffix = '/index.html';
        
              if (key.length > ignoreSuffix.length && key.slice(key.length - ignoreSuffix.length) === ignoreSuffix)
                key = key.slice(0, key.length - ignoreSuffix.length);
        
              return key;
            }
        
            buildClick() { 
              var template: string;
              var file = this._fileTree.selectedFile();
              if (file && (file.slice(file.length - '.html'.length) === '.html' || file.slice(file.length - '.html'.length) === '.htm')) {
                template = this._drive.read(file);
              }
              else {
                template = this._drive.read('/index.html');
              }
        
              if (template) {
                build.functions.appPageModel = this;
                var processed = build.processTemplate(template, [build.functions]);
                var blob = new Blob([processed], { type: 'text/html' });
                var url = URL.createObjectURL(blob);
                window.open(url, '_blank' + Date.now());
              }
            }
        
            exportAllHTML() {
              importExport.exportAllHTML();
            }
          
            exportAllZIP() {
              importExport.exportAllZIP(this._drive);
            }
          
            exportCurrentFile() {
              var selectedFile = this._fileTree.selectedFile();
              if (selectedFile)
                return;
              
              var simpleFileParts = selectedFile.split('/');
              var simpleFile = simpleFileParts[simpleFileParts.length - 1];
              
              importExport.exportBlob(simpleFile, [this._drive.read(selectedFile)]);
            }
        
            importText() {
              this._importSingeFile(
                (fileReader, file) => fileReader.readAsText(file),
                null);
            }
        
            importBase64() {
              this._importSingeFile(
                (fileReader, file) => fileReader.readAsArrayBuffer(file),
                text => {
                  alert('Base64 encoding is not implemented.');
                  return text;
                });
            }
        
            private _importSingeFile(requestLoad: (fileReader: FileReader, file: File) => void, convertText: (raw: string) => string) {
              importExport.importSingleFileWithConfirmation(
                requestLoad,
                file => this._drive.read(file),
                (saveName, data) => {
                  if (this._drive.read(saveName)) {
                    this._docHost.remove(saveName);
                  }
        
                  this._drive.write(saveName, data);
                  
                  this._drive.read(saveName);
                  this._docHost.add(saveName);
                  
                  this._fileTree.selectedFile(saveName);
                },
                convertText);
            }
        
            importZIP() {
              importExport.importZIPWithConfirmation(this._drive);
            }
        
        
          }
          
        }
      • dragScroll.ts
        module teapo.app.appRoot {
          
          export function dragScrollMouseDown(e: MouseEvent, scroller: HTMLElement) {
            var start = e.clientX;
            var startScroll = scroller.scrollLeft;
            var move = (e: MouseEvent) => {
              var offset = e.clientX - start;
              scroller.scrollLeft = startScroll - offset;
            };
            var up = (e: MouseEvent) => {
              removeEventListener(window, 'mousemove', move);
              removeEventListener(window, 'mouseup', up);
              if (scroller.releaseCapture) {
                scroller.releaseCapture();
                removeEventListener(scroller, 'mousemove', move);
                removeEventListener(scroller, 'mouseup', up);
              }
            };
            if (scroller.setCapture) {
              scroller.setCapture(true);
              addEventListener(scroller, 'mousemove', move);
              addEventListener(scroller, 'mouseup', up);
            }
            addEventListener(window, 'mousemove', move);
            addEventListener(window, 'mouseup', up);
          }
          
        }
    • importDialog
      • Model.ts
        module teapo.app.importDialog {
          
          export class Model {
        
            constructor() {
            }
        
          }
          
          
        }
      • layout.html
        <div class=teapo-import-dialog-background
           data-bind="click: dismiss, event: { keydown: keydown }">
          
          <div class=teapo-import-dialog
             data-bind="click: function() { }, clickBubble: false">
        
            <!-- 
        
        			# as file  [filename]      [x] base64
        			# unpack ZIP    [directory]    <list-of-files-with clashes highlighted>
        			# unpack another teapo  [directory]   <list-of-files-with clashes highlighted>
        
        		-->
            
          </div>
          
        </div>
    • koBindingHandlers
      • load.ts
        module teapo.app.koBindingHandlers.load {
        
          export function init(elem, valueAccessor, allBindings, viewModel, bindingContext) {
            valueAccessor();
          }
        
        }
      • loadRaw.ts
        module teapo.app.koBindingHandlers.loadRaw {
        
          export function init(elem, valueAccessor, allBindings, viewModel, bindingContext) {
            valueAccessor();
            return { controlsDescendantBindings: true };
          }
        
        }
      • register.ts
        module teapo.app.koBindingHandlers {
        
          export function register(ko) {
        
            for (var k in teapo.app.koBindingHandlers) if (teapo.app.koBindingHandlers.hasOwnProperty(k)) {
              var bindingHandler = teapo.app.koBindingHandlers[k];
              if (bindingHandler && typeof bindingHandler === 'object')
                ko.bindingHandlers[k] = bindingHandler;
            }
        
          }
          
        }
    • moreDialog
      • Model.ts
        module teapo.app.moreDialog {
          
          export class Model {
        
            text = ko.observable<string>(null);
            matchItems = ko.observableArray<Model.MatchItem>([]);
            textInput: HTMLInputElement = null;
          
            private _selectedItem = -1;
            private _allMatchItems: Model.MatchItem[] = [];
        
            constructor(
              currentFile: string,
              currentSelection: string,
              private _files: string[],
              private _completed: (selected: string) => void) {
        
              for (var i = 0; i < this._files.length; i++) {
                var m = new Model.MatchItem(
                  this._files[i],
                  'file',
                  this._completed);
                this._allMatchItems.push(m);
              }
        
              this._allMatchItems.sort((m1, m2) => {
                if (m1.text > m2.text) return 1;
                else if (m1.text < m2.text) return -1;
                else return 0;
              })
        
              this.text(currentSelection || (currentFile ? currentFile.slice(1) : ''));
              
              this._updateList();
              
              var updateTimeout = 0;
              this.text.subscribe(() => {
                if (updateTimeout)
                  clearTimeout(updateTimeout);
                updateTimeout = setTimeout(() => this._updateList(), 300);
              });
            }
          
            loadFromDOM() {
              if (this.textInput)
                this.textInput.select();
              else
                alert('textInput is not there!');
            }
        
            keydown(unused, e: KeyboardEvent) {
              if (e.keyCode === 13 || e.which === 13 || e.key === 'Enter') {
                this._keyEnter();
              }
              else if (e.keyCode === 27 || e.which === 27 || e.key === 'Escape') {
                this._keyEnter();
              }
              else if (e.keyCode === 38 || e.which === 38) {
                this._keyUp();
              }
              else if (e.keyCode === 40 || e.which === 40) {
                this._keyDown();
              }
              else {
                return true;
              }
            }
        
            acceptClick() {
              var sel = this._selectedItem >= 0 ? this.matchItems()[this._selectedItem] : null;
              if (sel)
                this._completed(sel.text);
              else
                this._completed(this.text());
            }
        
            dismiss() {
              this._completed(null);
            }
          
            private _keyEnter() {
              this.acceptClick();
            }
          
            private _keyUp() {
              this._moveSelection(-1);
            }
        
            private _keyDown() {
              this._moveSelection(+1);
            }
          
            private _moveSelection(delta: number) {
              if (this._selectedItem >= 0) {
                var old = this.matchItems()[this._selectedItem];
                if (old)
                  old.selected(false);
              }
        
              var newSelection = this._selectedItem + delta;
              if (newSelection < 0)
                newSelection = this.matchItems().length-1;
              if (newSelection >= this.matchItems().length)
                newSelection = 0;
        
              this._selectedItem = newSelection;
        
              var sel = this.matchItems()[newSelection];
              if (sel)
                sel.selected(true);
            }
          
            private _updateList() {
              var list: Model.MatchItem[] = [];
              var fullMatch = -1;
              var text = this.text();
              var textLower = (text || '').toLowerCase();
              for (var i = 0; i < this._allMatchItems.length; i++) {
                var m = this._allMatchItems[i];
                if (text) { 
                  if (m.text === text) {
                    if (fullMatch === -1) {
                      m.selected(true);
                      fullMatch = i;
                    }
                    else {
                      m.selected(false);
                      list.push(m);
                    }
                  }
                  else if (m.text.toLowerCase().indexOf(textLower) >= 0) {
                    m.selected(false);
                    list.push(m);
                  }
                  else {
                    m.selected(false);
                  }
                }
                else {
                  m.selected(false);
                  list.push(m);
                }
              }
              if (!list.length) {
                var m = new Model.MatchItem(text, 'create', this._completed);
                m.display = 'Create new file: ' + text;
                m.selected(true);
                fullMatch = 0;
                list.push(m);
              }
              this.matchItems(list);
              this._selectedItem = fullMatch;
            }
            
          }
        
          export module Model {
            
            export class MatchItem {
              
              selected = ko.observable(false);
              display: string;
              
              constructor(
                public text: string,
                public type: string,
                private _completed: (file: string) => void) {
                this.display = text;
              }
        
              clickSelect() {
                this._completed(this.text);
              }
              
            }
            
          }
          
        }
      • layout.html
        <div class=teapo-more-dialog-background
           data-bind="click: dismiss, event: { keydown: keydown }">
          
          <div class=teapo-more-dialog
             data-bind="click: function() { }, clickBubble: false">
            
            <input data-bind="hasFocus: true, textInput: text, load: textInput=$element">
            <div class=teapo-more-dialog-list data-bind="foreach: matchItems">
              <div class=teapo-more-dialog-item
                 data-bind="text: display, css: { selected: selected }, click: clickSelect "></div>
              </div>
            </div>
            
          </div>
          
        </div>
      • style.css
        .teapo-more-dialog-background {
          
          position: fixed !important;
          position: absolute;
          left: 0px; top: 0px;
          width: 100%; height: 100%;
          background: rgba(1,1,1,0.6);
          z-index: 200;
          
        }
        
        .teapo-more-dialog {
          
          position: fixed !important;
          position: absolute;
          left: 15%;
          width: 70%;
          top: 20%;
          height: 70%;
        
          background: gold;
        
        }
        
        .teapo-more-dialog-list {
          height: 80%;
          overflow: auto;
        }
        
        .teapo-more-dialog input {
          
          width: 100%;
          font-size: 200%;
          
        }
        
        .teapo-more-dialog .teapo-more-dialog-item {
          font-size: 140%;
          padding: 0.25em;
        }
        
        .teapo-more-dialog .teapo-more-dialog-item.selected {
          background: cornflowerblue;
          color: white;
        }
    • System.ts
      module teapo.app {
      
        export interface System {
      
          drive: persistence.Drive;
      
          tree: FileTree;
          
        }
      
        export interface FileTree {
          
          
          
        }
      
      }
    • body.css
      html {
        box-sizing: border-box;
      }
      
      *, *:before, *:after {
        box-sizing: inherit;
      }
      
      html {
        height: 100%;
        margin: 0px;
        padding: 0px;
        border: none;
        overflow: hidden;
      }
      
      body {
        height: 100%;
        margin: 0px;
        padding: 0px;
        border: none;
        overflow: hidden;
      }
      
    • flyout-branding.css
      .teapo-extra-content {
        float: left;
        width: 75%;
        height: 100%;
        margin-right: -1em;
      }
      
      .teapo-extra-content .teapo-branding-area {
        height: 60%;
        padding: 1em;
        overflow: auto;
      }
      
      .teapo-extra-content .teapo-scrollable-bottom {
        height: 36%;
        overflow: auto;
      }
      
      .teapo-extra-content .teapo-links {
        float: left;
        font-size: 90%;
        width: 50%;
      }
      
      .teapo-extra-content .teapo-credits {
        float: left;
        height: 36%;
        width: 50%;
      }
      
    • flyout.css
      .teapo-main-content {
        position: fixed !important;
        position: absolute;
        left: 0px; top: 0px;
        height: 100%;
        width: 80%;
        padding-bottom: 2em;
      }
      
      
      .teapo-flyout-scroller {
        position: fixed !important;
        position: absolute;
        left: 0px; top: 0px; width: 100%; height: 100%;
        overflow-y: hidden;
        overflow-x: scroll;
      }
      
      .teapo-flyout-scroller-bg {
        height: 100%;
        width: 150%;
        padding-left: 80%;
      }
      
      .teapo-flyout {
        border-top: solid 1px silver;
        position: relative;
        height: 100%;
        background: #A6D785;
        z-index: 100;
        overflow: hidden;
        padding-bottom: 2em;
      }
      
      
    • loading.css
      #teapo-loading-host {
      
        position: absolute;
        left: 12%;
        top: 25%;
        z-index: 5000;
        
      }
      
      #teapo-loading-title {
        
        font-size: 200%;
        font-weight: 100;
        opacity: 0.6;
        
      }
    • loading.ts
      module teapo.app {
        
        var loadingHostDIV: HTMLElement;
        var loadingTitleDIV: HTMLElement;
        var loadingProgressDIV: HTMLElement;
      
        var loadingTimeout: number = 0;
      
        // baseUI, domFilesystem, flyoutUI, libraries
        var currentDescription;
      
        export function loading(description) {
      
          if (!loadingHostDIV) {
            loadingHostDIV = document.getElementById('teapo-loading-host');
            loadingTitleDIV = document.getElementById('teapo-loading-title');
            loadingProgressDIV = document.getElementById('teapo-loading-progress');
          }
      
          if (description) {
            loadingHostDIV.style.display = 'block';
          }
          else {
            loadingHostDIV.style.display = 'none';
            return;
          }
      
          currentDescription = description;
          if ('textContent' in loadingTitleDIV)
            loadingTitleDIV.textContent = currentDescription;
          else
            loadingTitleDIV.innerText = currentDescription;
        }
        
        
      }
    • start.ts
      module teapo.app {
      
        export function start() {
      
          loading('Initialising the application...');
      
      
          koBindingHandlers.register(ko);
      
          addEventListener(window, 'load', () =>
          {
            removeSpyScripts();
            removeTrailElements();
      
            loading('Restoring the setup...');
      
            try { 
              var layout = new teapo.app.appRoot.PageModel();
      
              loading('Rendering...');
      
              ko.applyBindings(layout, document.body);
      
              loading('Processing...');
              layout.loadFromDOM(() => {
      
                setTimeout(() => {
                  runStartScripts(() => {
                    loading(null);
                  });
                }, 1);
      
              });
            }
            catch (error) { 
              alert('teapo.start ' + error + ' ' + error.stack); 
            }
      
          });
      
        }
          
        var startScripts: { (completed: () => void): void; }[] = [];
      
        export module start {
          
          export function addStartScript(script: (completed: () => void) => void ) {
            startScripts.push(script);
          }
          
        }
        
        function runStartScripts(completed: () => void) {
          var completionInvoked = false;
          invokeNextStartupScript();
      
          function invokeNextStartupScript() {
            if (!startScripts.length) {
              if (!completionInvoked) {
                completionInvoked = true;
                setTimeout(() => {
                  completed();
                }, 1);
              }
              return;
            }
      
            var nextScript = startScripts.shift();
            nextScript(() => { 
              invokeNextStartupScript();
            });
      
            setTimeout(invokeNextStartupScript, 1);
          }
        }
          
        function removeSpyScripts() {
          var spyScripts: Element[] = [];
          for (var i = 0; i < document.scripts.length; i++) {
            if (document.scripts[i].getAttribute('data-legit') !== 'teapo')
              spyScripts.push(document.scripts[i]);
          }
          
          for (var i = 0; i < spyScripts.length; i++) {
            spyScripts[i].parentNode.removeChild(spyScripts[i]);
          }
        }
        
        function removeTrailElements() {
          var lastDIV = document.getElementById('teapo-last-element');
          while (lastDIV.nextSibling) {
            lastDIV.nextSibling.parentNode.removeChild(lastDIV.nextSibling);
          }
        }
      
      }
    • status.css
      .teapo-status-bar {
        position: fixed !important;
        position: absolute;
        left: 0px;
        bottom: 0px;
        height: 2em;
        width: 100%;
        background: goldenrod;
        z-index: 100;
      }
    • tree-and-bar.css
      .teapo-file-tree {
        float: left;
        width: 20%;
        height: 100%;
        overflow: auto;
      }
      
      .teapo-thick-bar-host {
        float: left;
        width: 2em;
        height: 100%;
        overflow: hidden;
      }
      
      .teapo-thick-bar-host .teapo-more-button {
        width: 2em;
        height: 2em;
        font-size: inherit;
        font-family: inherit;
        position: absolute;
        opacity: 0.8;
      }
      
      .teapo-thick-bar-host .teapo-thick-bar-bg {
        height: 100%;
        margin-top: 2em;
        padding-bottom: 2em;
      }
      
      .teapo-thick-bar-host .teapo-thick-bar-bg .teapo-thick-bar {
        height: 100%;
        background: #F0FFF0;
        cursor: move;
      }
      
  • build
    • functions
      • appPageModel.ts
        module teapo.build.functions {
          
          export var appPageModel: app.appRoot.PageModel;
          
        }
      • embedFile.ts
        module teapo.build.functions {
        
          export function embedFile(file: string) {
            var text = processTemplate.mainDrive.read(files.normalizePath(file));
            return text;
          }
          
        }
      • embedTree.ts
        module teapo.build.functions {
          
          export function embedTree() {
        
              var docNames = processTemplate.mainDrive.files();
              docNames.sort();
        
              var rootDir = {};
              for (var i = 0; i < docNames.length; i++) {
                var fullPath = docNames[i];
                var file = fullPath;
                if (file.charAt(0) === '/') file = file.slice(1);
                var parts = file.split('/');
                var dir = rootDir;
                for (var j = 0; j < parts.length - 1; j++) {
                  dir = dir[parts[j]] || (dir[parts[j]] = {});
                }
                var docState = processTemplate.mainDrive.read(fullPath);
                dir[parts[parts.length - 1]] = docState;
              }
        
              var tmp = document.createElement('pre');
        
              var addDir = (dir) => {
                for (var k in dir) if (dir.hasOwnProperty(k)) {
                  var child = dir[k];
                  if (typeof child === 'string') {
                    output.push('<li class=teapo-file><div class=teapo-file-name>' + k + '</div>');
                    tmp.textContent = child;
                    output.push('<pre class=teapo-file-content>' + tmp.innerHTML + '</pre></li>');
                  }
                  else {
                    output.push('<li class="teapo-dir teapo-dir-collapsed"><div class=teapo-dir-name>' + k + '</div><ul>');
                    addDir(child);
                    output.push('</ul></li>');
                  }
                }
              }
        
              var output: string[] = [];
        
              addDir(rootDir);
        
              return output.join('');
        
          }
          
        }
      • typescriptBuild.ts
        module teapo.build.functions {
        
          export function typescriptBuild() {
            
            typescriptBuild.mainTS.compilerOptions.out = 'index.js';
        
            var files = typescriptBuild.mainTS.host.getScriptFileNames();
            var nonDeclFile = null;
            for (var i = 0; i < files.length; i++) {
              var f = files[i];
              if (f.slice(f.length - '.d.ts'.length) === '.d.ts')
                continue;
              nonDeclFile = f;
              break;
            }
            
            var emitOutput = typescriptBuild.mainTS.service().getEmitOutput(nonDeclFile);
            if (emitOutput.emitOutputStatus !== ts.EmitReturnStatus.Succeeded) {
        
              var errors: string[] = [];
              var errorFiles = 0;
        
              for (var i = 0; i < files.length; i++) {
                var syntactic = typescriptBuild.mainTS.service().getSyntacticDiagnostics(files[i]);
                var semantic = typescriptBuild.mainTS.service().getSemanticDiagnostics(files[i]);
                
                var both = syntactic ?
                  (semantic ? syntactic.concat(semantic) : syntactic) :
                  (semantic ? semantic : null);
        
                if (!both || !both.length)
                  continue;
        
                errorFiles++;
                var fileSnapshot = typescriptBuild.mainTS.host.getScriptSnapshot(files[i]);
                var linestarts = fileSnapshot.getLineStartPositions();
                for (var j = 0; j < both.length; j++) {
                  var err = both[j];
        
                  var pos = err.file ? err.file.getLineAndCharacterFromPosition(err.start) : null;
                  errors.push(
                    err.file.filename +
                    ' ' +(ts.DiagnosticCategory[err.category]) +
                    (pos ? ' @'+pos.line + ':' + pos.character : ' @@' + err.start) + ' ' + err.messageText);
                }
              }
              alert(
                ts.EmitReturnStatus[emitOutput.emitOutputStatus] + ' building ' + nonDeclFile + ', ' + errors.length + ' errors in ' + errorFiles+' files:\n'+
                errors.join('\n'));
            }
        
            if (emitOutput.outputFiles)
              return emitOutput.outputFiles[0].text;
            
            
          }
            
          export module typescriptBuild {
         
            export var mainTS: typescript.TypeScriptService;
        
          }
          
        }
    • processTemplate.ts
      module teapo.build {
        
        export function processTemplate(template: string, scopes: any[]): string {
          // <%= expr %>
          // <% statement %>
          // <%-- comment --%>
      
          var generated: string[] = [];
          for (var i = 0; i < scopes.length; i++) {
            generated.push('with(scopes[' + i + ']) {');
          }
          
          generated.push('var output =[];');
      
          var index = 0;
          while (index < template.length) {
            
            var nextOpenASP = template.indexOf('<%', index);
            if (nextOpenASP < 0) {
              generateWrite(generated, template.slice(index));
              break;
            }
      
            var ch = template.charAt(nextOpenASP + 2);
            if (ch === '=') {
              var closeASP = template.indexOf('%>', nextOpenASP);
              if (closeASP < 0) {
                generateWrite(generated, template.slice(index));
                break;
              }
      
              generateWrite(generated, template.slice(index, nextOpenASP));
              generateRedirect(generated, template.slice(nextOpenASP + 3, closeASP));
              index = closeASP + 2;
            }
            else if (ch === '-') {
              var closeCommentMatch = template.charAt(nextOpenASP + 3) === '-' ? '--%>' : '-%>';
              var closeComment = template.indexOf(closeCommentMatch, nextOpenASP);
              if (closeComment < 0) {
                generateWrite(generated, template.slice(index));
                break;
              }
      
              generateWrite(generated, template.slice(index, nextOpenASP));
              index = closeComment + closeCommentMatch.length;
            }
            else {
              var closeASP = template.indexOf('%>', nextOpenASP);
              if (closeASP < 0) {
                generateWrite(generated, template.slice(index));
                break;
              }
      
              generateWrite(generated, template.slice(index, nextOpenASP));
              generateStatement(generated, template.slice(nextOpenASP + 2, closeASP));
              index = closeASP + 2;
            }
            
          }
      
          for (var i = 0; i < scopes.length; i++) {
            generated.push('}');
          }
      
          generated.push('return output.join(\'\');');
      
          var fnText = generated.join('\n');
          
          var fn = Function('scopes', fnText);
          
          return fn(scopes);
        }
      
        export module processTemplate {
      
          export var mainDrive: persistence.Drive;
      
        }
        
        function generateWrite(generated: string[], chunk: string) {
          if (chunk)
            generated.push('output.push(\'' + stringLiteral(chunk) + '\');');
        }
        
        function generateRedirect(generated: string[], redirect: string) {
          generated.push('output.push(' + redirect + ');');
        }
      
        function generateStatement(generated: string[], statement: string) {
          generated.push(statement);
        }
      
        function stringLiteral(text: string) {
          return text.
            replace(/\n/g, '\\n').
            replace(/\r/g, '\\r').
            replace(/\t/g, '\\t').
            replace(/\'/g, '\\\'').
            replace(/\"/g, '\\"');
        }
        
      }
  • docs
    • types
      • text
        • base
          • SimpleCodeMirrorDocHandler.ts
            module teapo.docs.types.text.base {
            
              export class SimpleCodeMirrorDocHandler implements CodeMirrorTextDoc {
            
                path = null;
                editor: CodeMirror = null;
                doc: CodeMirror.Doc = null;
                text: () => string = null;
                scroller: HTMLElement = null;
                status: HTMLElement = null;
                keyMap: any = {
                  "Ctrl-Enter": () => this._triggerCompletion(true),
                  "Alt-Enter": () => this._triggerCompletion(true),
                  "Ctrl-J": () => this._triggerCompletion(true),
                  "Alt-J": () => this._triggerCompletion(true)
                };
                removed = false;
            
                state: any = null;
            
                private _completionTimer: Timer = null;
                private _completionLastChangeText = null;
                private _isCompleting = false;
            
                constructor() {
                }
            
                open() {
                }
            
                close() {
                  if (this._completionTimer)
            	      this._completionTimer.stop();
                }
            
                remove() { 
                }
            
            
                asyncCompletion = false;
                
                shouldTriggerCompletion(textBeforeCursor: string): boolean {
                  return false;
                }
            
                getCompletions(callback?: Function): any {
                  return null;
                }
            
                onChanges(docChanges: CodeMirror.EditorChange[], summary: { lead: number; mid: number; trail: number; }) {
            
                  if (this.getCompletions) {
                    if (!this._isCompleting) {
                      var cur = this.doc.getCursor();
                      var line = this.doc.getLine(cur.line);
                      this._completionLastChangeText = line.slice(0, cur.ch);
            
                      if (!this._completionTimer)
                        this._createCompletionTimer();
                      this._completionTimer.reset();
                    }
                  }
                }
            
                private _createCompletionTimer() {
                  this._completionTimer = new Timer();
                  this._completionTimer.interval = 200;
                  this._completionTimer.ontick = () => {
                    if (this._isCompleting) return;
                    if (!this.editor)
                      return;
            
                    if (!this.shouldTriggerCompletion || this.shouldTriggerCompletion(this._completionLastChangeText)) {
                      this._triggerCompletion(/*implicitly*/ true);
                    }
                  };
                }
            
                onSave() {
                  
                }
            
                private _triggerCompletion(implicitly: boolean) {
            
                  this._completionTimer.stop();
            
                  var lastResult;
                  
                  var close = () => {
                    CodeMirror.off(lastResult, 'close', close);
                    this._isCompleting = false;
                  };
                  
                  var hintFn = (cm,callback,options) => {
                    
                    var processResults = (results: CodeMirror.showHint.CompletionResult) => { 
                      if (result && result.list && implicitly) {
                        var chunk = this.doc.getRange(result.from, result.to);
                        for (var i = 0; i < result.list.length; i++) {
                          if (result.list[i] == <any>chunk) {
                            result = null;
                            break;
                          }
                        }
                      }
            
                      if (result) { 
                        this._isCompleting = true;
            
                        lastResult = result;
                        CodeMirror.on(lastResult, 'close', close);
                      }
                      else {
                        this._isCompleting = false;
                        if (lastResult)
                          CodeMirror.off(lastResult, 'close', close);
                      }
            
                      return result;
                    };
                    
                    if (this.asyncCompletion) {
                      (<any>this.getCompletions)(result => {
                        var res = processResults(result);
                        callback(res);
                      });
                    }
                    else {
                    
                      var result: CodeMirror.showHint.CompletionResult = this.getCompletions();
                      
                      var res = processResults(result);
                      return res;
                    }
                  };
                  
                  if (this.asyncCompletion) {
                    (<any>hintFn).async = true;
                  }
                  
                  var hintData: CodeMirror.showHint.Options = {
                    hint: hintFn,
                    completeSingle: implicitly ? false : true
                  };
            
                  // console.log('hintData ', hintData);
                  this.editor.showHint(hintData);
            
                }
                
                onCompletion(callback: (result: CodeMirror.showHint.CompletionResult) => void) {
                  var completions = <CodeMirror.showHint.CompletionResult>(<any>CodeMirror).hint.css(this.editor);
                  callback(completions);
                }
                
              }
              
            }
        • css
          • CssDocHandler.ts
            module teapo.docs.types.text.css {
              
              export var expectsFile = /.*\.css/g;
              export var acceptsFile = /.*\.css/g;
            
              export function loadText(path: string, storage: DocState): CodeMirrorTextDoc {
                return new CssDocHandler();
              }
            
              export class CssDocHandler extends base.SimpleCodeMirrorDocHandler {
            
                constructor() {
                  super();
                }
            
            
            
                shouldTriggerCompletion(textBeforeCursor: string) {
            
                  if (textBeforeCursor.slice(textBeforeCursor.length - 2) === ': ')
                    return true;
                  var lastChar = textBeforeCursor.charAt(textBeforeCursor.length - 1);
                  if (lastChar === '-')
                    return true;
                  if (lastChar.toLowerCase() !== lastChar.toUpperCase())
                    return true;
                  
                }
                
                getCompletions() {
                  return (<any>CodeMirror).hint.css(this.editor);
                }
                
              }
            
              export function createCodeMirrorDoc(text: string): CodeMirror.Doc {
                return new CodeMirror.Doc(text || '', 'css');
              }
            
              
            }
        • html
          • HtmlDocHandler.ts
            module teapo.docs.types.text.html {
            
              export var expectsFile = /.*\.(html|htm)/g;
              export var acceptsFile = /.*\.(html|htm)/g;
            
              export function loadText(path: string, storage: DocState): CodeMirrorTextDoc {
                return new HtmlDocHandler();
              }
            
              export class HtmlDocHandler extends base.SimpleCodeMirrorDocHandler {
            
                constructor() {
                  super();
                }
            
            
            
                shouldTriggerCompletion(textBeforeCursor: string) {
            
                  var cursorPos = this.doc.getCursor();
                  var token = this.editor.getTokenAt(cursorPos);
                  var lastChar = textBeforeCursor.charAt(textBeforeCursor.length - 1);
                  if (lastChar === '<')
                    return true;
            
                  if (lastChar === '=' && token.type) // ignore equals sign not inside element tag
                    return true;
            
                  if (lastChar.toLowerCase() !== lastChar.toUpperCase()) {
            
                    if (token.type) // token.type == null -> means simple text, don't complete
                      return true;
                  }
                  
                }
                
                getCompletions() {
                  return (<any>CodeMirror).hint.html(this.editor);
                }
                
              }
              
              export function createCodeMirrorDoc(text: string): CodeMirror.Doc {
                return new CodeMirror.Doc(text || '', 'text/html');
              }
            
              
            }
        • js
          • JavaScriptDocHandler.ts
            module teapo.docs.types.text.js {
              
              export var expectsFile = /.*\.js/g;
              export var acceptsFile = /.*\.js/g;
            
              export function loadText(path: string, storage: DocState): CodeMirrorTextDoc {
                return new JavaScriptDocHandler();
              }
            
              export class JavaScriptDocHandler extends base.SimpleCodeMirrorDocHandler {
            
                constructor() {
                  super();
                }
            
                load(text: string) {
                  ternServer().server.addFile(this.path, text);
                }
            
                open() {
                  ternServer().server.delFile(this.path);
                  ternServer().addDoc(this.path, this.doc);
            
                }
            
                shouldTriggerCompletion(textBeforeCursor: string) {
            
                  var lastChar = textBeforeCursor.charAt(textBeforeCursor.length - 1);
                  if (lastChar === '.')
                    return true;
                  if (lastChar.toLowerCase() !== lastChar.toUpperCase())
                    return true;
                  
                }
                
                getCompletions(callback): any {
            
                  if (_completionSuccess === false) {
                    return (<any>CodeMirror).hint.javascript(this.editor);
                  }
            
                  try {
                    ternServer().getHint(this.editor, callback);
                    _completionSuccess = true;
                  }
                  finally {
                    if (!_completionSuccess)
                      _completionSuccess = false;
                  }
                  
            
                }
                
              }
            
              
              export function createCodeMirrorDoc(text: string): CodeMirror.Doc {
                return new CodeMirror.Doc(text || '', 'javascript');
              }
            
              var _completionSuccess;
              var _ternServer;
              function ternServer() {
                
                if (_ternServer) return _ternServer;
                
                if (!(<any>CodeMirror).TernServer) return null;
                _ternServer = new (<any>CodeMirror).TernServer();
                return _ternServer;
                
              }
            }
        • json
          • JsonDocHandler.ts
            module teapo.docs.types.text.json {
              
              export var expectsFile = /.*\.json/g;
              export var acceptsFile = /.*\.json/g;
            
              export function loadText(path: string, storage: DocState): CodeMirrorTextDoc {
                return new js.JavaScriptDocHandler();
              }
              
              export function createCodeMirrorDoc(text: string): CodeMirror.Doc {
                return new CodeMirror.Doc(text || '', 'json');
              }
            
              
            }
        • less
          • LessDocHandler.ts
            module teapo.docs.types.text.less {
              
              export var expectsFile = /.*\.less/g;
              export var acceptsFile = /.*\.less/g;
            
              export function loadText(path: string, storage: DocState): CodeMirrorTextDoc {
                return new css.CssDocHandler();
              }
              
              export function createCodeMirrorDoc(text: string): CodeMirror.Doc {
                return new CodeMirror.Doc(text || '', 'text/x-less');
              }
            
              
            }
        • md
          • MarkdownDocHandler.ts
            module teapo.docs.types.text.md {
              
              export var expectsFile = /.*\.md/g;
              export var acceptsFile = /.*\.md/g;
            
              export function loadText(path: string, storage: DocState): CodeMirrorTextDoc {
                return new MarkdownDocHandler();
              }
            
              export class MarkdownDocHandler extends base.SimpleCodeMirrorDocHandler {
            
                constructor() {
                  super();
                }
                
              }
            
              export function createCodeMirrorDoc(text: string): CodeMirror.Doc {
                return new CodeMirror.Doc(text || '', 'text/x-markdown');
              }
            
              
            }
        • sass
          • SassDocHandler.ts
            module teapo.docs.types.text.sass {
            
              export var expectsFile = /.*\.sass/g;
              export var acceptsFile = /.*\.sass/g;
            
              export function loadText(path: string, storage: DocState): CodeMirrorTextDoc {
                return new css.CssDocHandler();
              }
              
              export function createCodeMirrorDoc(text: string): CodeMirror.Doc {
                return new CodeMirror.Doc(text || '', 'text/x-sass');
              }
            
              
            }
        • scrollerView
          • ScrollerModel.ts
            module teapo.docs.types.text.scrollerView {
              
              export class ScrollerModel {
            
                lines = ko.observableArray<ScrollerModel.LineModel>([]);
                lineHeight: string;
                private _lineHeightNum: number;
            
                viewportFrom = ko.observable('0');
                viewportHeight = ko.observable('0');
                _debug = null;
            
                private _recreateTimeout = 0;
              
                constructor(
                  private _doc: CodeMirror.Doc,
                  private _viewLineNumber: number) {
            
                  this._lineHeightNum = ((10000 / this._viewLineNumber) | 0) / 100; // exact number of percents
                  this.lineHeight = this._lineHeightNum + '%';
            
                  this._recreateLines();
                }
            
                docChanges(docChanges: CodeMirror.EditorChange[]) {
                  
                  if (this._recreateTimeout)
                    clearTimeout(this._recreateTimeout);
                  this._recreateTimeout = setTimeout(() => this._recreateLines(), 200);
                  
                }
            
                scroll(scrollInfo: CodeMirror.ScrollInfo) {
                  var height = scrollInfo.height;
                  var lineCount = this._doc.lineCount();
                  if (lineCount < this._viewLineNumber)
                    height = Math.max(height, this._doc.getEditor().defaultTextHeight() * this._viewLineNumber);
                  
                  this.viewportFrom((scrollInfo.top * 100 / height) + '%');
                  this.viewportHeight((scrollInfo.clientHeight * 100 / height) + '%');
                  (<any>scrollInfo).maxHeight = height;
                  this._debug = {
                    lineCount: lineCount,
                    heightAtLine: this._doc.getEditor().heightAtLine(lineCount - 2),
                    defaultLineHeight: this._doc.getEditor().defaultTextHeight(),
                    height: height,
                    scrollInfo: scrollInfo
                  };
                }
            
                bindHandlers(dragElement: HTMLElement) {
                  addEventListener(dragElement, 'touchstart', (e: any) => { 
                    if (!e.touches || !e.touches.length) return;
                    var editor = this._doc.getEditor();
                    if (!editor) return;
            
                    var dbg = null;
            
                    var scrollInfo = editor.getScrollInfo();
                    if (scrollInfo.clientHeight === scrollInfo.height) return;
                    var startTop = scrollInfo.top;
                    var startCoord = e.touches[0].clientY;
                    var factor = scrollInfo.clientHeight / scrollInfo.height;
                    var move = e => {
                      if (!e.touches || !e.touches.length) return;
                      var editor = this._doc.getEditor();
                      if (!editor) return;
            
                      var scrollInfo = editor.getScrollInfo();
            
                      var deltaY = e.touches[0].clientY - startCoord;
                      var offset = deltaY * factor;
                      editor.scrollTo(null, scrollInfo.top + deltaY);
                      dbg = 'scrollY->'+ (scrollInfo.top + deltaY)+' factor:'+factor+' deltaY:'+deltaY;
                    };
            
                    var close = e => {
                      alert(dbg);
                      removeEventListener(window, 'touchend', close);
                      removeEventListener(window, 'touchmove', move);
                    };
            
                    addEventListener(window, 'touchmove', move);
                    addEventListener(window, 'touchend', close);
                  });
            
                  addEventListener(dragElement, 'mousedown', (e: MouseEvent) => {
                    var editor = this._doc.getEditor();
                    if (!editor) return;
            
                    var dbg = null;
            
                    var scrollInfo = editor.getScrollInfo();
                    if (scrollInfo.clientHeight === scrollInfo.height) return;
                    var startTop = scrollInfo.top;
                    var startCoord = e.clientY;
                    var factor = scrollInfo.clientHeight / scrollInfo.height;
                    var move = (e: MouseEvent) => {
                      var editor = this._doc.getEditor();
                      if (!editor) return;
            
                      var scrollInfo = editor.getScrollInfo();
            
                      var deltaY = e.clientY - startCoord;
                      var offset = deltaY * factor;
                      editor.scrollTo(null, scrollInfo.top + deltaY);
                    };
            
                    var close = e => {
                      removeEventListener(window, 'mouseup', close);
                      removeEventListener(window, 'mousemove', move);
                    };
            
                    addEventListener(window, 'mousemove', move);
                    addEventListener(window, 'mouseup', close);
                  });
                }
            
                private _recreateLines() {
                  var newLines: ScrollerModel.LineModel[] = [];
                  
                  var docLineCount = this._doc.lineCount();
                  
                  var run: string[] = [];
                  
                  var maxLength = 50;
                  
                  for (var i = 0; i < docLineCount; i++) {
                    run.push(this._doc.getLine(i));
                    if (i > docLineCount * (this._lineHeightNum/100) * (newLines.length+1) 
                        || i === docLineCount - 1) { 
                      var newLine = this._createLine(run);
                      maxLength = Math.max(maxLength, newLine.leadLength + newLine.textLength);
                      newLines.push(newLine);
                      run = [];
                    }
                  }
            
                  for (var i = 0; i < newLines.length; i++) {
                    newLines[i].lineWidth = ((100 * newLines[i].textLength / maxLength) | 0) + '%';
                    newLines[i].lineLead = ((100 * newLines[i].leadLength / maxLength) | 0) + '%';
                  }
            
                  this.lines(newLines);
                  
                  var editor = this._doc.getEditor();
                  if (editor)
                    this.scroll(editor.getScrollInfo());
                }
              
                private _createLine(run: string[]): ScrollerModel.LineModel {
                  return new ScrollerModel.LineModel(run);
                }
            
              }
            
              export module ScrollerModel {
                
                export class LineModel {
            
                  leadLength = 0;
                  textLength = 0;
                  lineWidth: string = null;
               		lineLead: string = null;
            
                  constructor(run: string[]) {
                    this.textLength = 0;
                    for (var i = 0; i < run.length; i++) {
                      var ln = run[i];
            
                      var lead = 0;
                      for (var j = 0; j < ln.length; j++) {
                        if (ln.charAt(j)===' ')
                          lead++;
                        else if (ln.charAt(j)==='\t')
                          lead+=2;
                        else
                          break;
                      }
            
                      this.leadLength += lead;
                      this.textLength += ln.length - j;
                    }
                    this.textLength = (this.textLength / i) | 0;
                  }
                }
                
              }
            }
          • ScrollerView.html
            <div class=teapo-scroller-outer
                 data-bind="load: bindHandlers($element)">
              <div class=teapo-scroller-thumb
                 data-bind="style: { top: viewportFrom, height: viewportHeight }">
              </div>
            </div>
            
            <!-- ko foreach: lines -->
            <div class=teapo-scroller-line
               data-bind="style: { marginLeft: lineLead, width: lineWidth, height: $parent.lineHeight }">
            </div>
            
            <!-- /ko -->
            
          • style.css
            .teapo-scroller-outer {
              float: left;
              width: 0px;
              height: 100%;
            }
            
            .teapo-scroller-thumb {
              position: relative;
              border: solid 3px red;
              width: 2.2em;
              margin: -0.1em;
              opacity: 0.5;
            }
            
            .teapo-scroller-line-host {
              width: 2em;
            }
            
            .teapo-scroller-line {
              background: gray;
              font-size: 3pt;
            }
        • scss
          • ScssDocHandler.ts
            module teapo.docs.types.text.scss {
            
              export var expectsFile = /.*\.scss/g;
              export var acceptsFile = /.*\.scss/g;
            
              export function loadText(path: string, storage: DocState): CodeMirrorTextDoc {
                return new css.CssDocHandler();
              }
            
              export function createCodeMirrorDoc(text: string): CodeMirror.Doc {
                return new CodeMirror.Doc(text || '', 'text/x-scss');
              }
            
              
            }
        • ts
          • CodeMirrorCompletion.ts
            module teapo.docs.types.text.ts_ {
              
              export class CodeMirrorCompletion implements CodeMirror.showHint.Completion {
            
                text: string;
                from: CodeMirror.Pos;
                to: CodeMirror.Pos;
            
                constructor(
                  private lead: string,
                  private prefix: string,
                  private suffix: string,
                  private trail: string,
                  private lineNum: number,
                  private _entry: ts.CompletionEntry,
                  private _details: ts.CompletionEntryDetails) {
                  this.text = this._entry.name;
                  this.from = CodeMirror.Pos(lineNum, lead.length);
                  this.to = CodeMirror.Pos(lineNum, lead.length + prefix.length + suffix.length);
                }
            
                render(element: HTMLElement, self, data) {
                  var skipVerbose = 0;
                  if (this._details.displayParts.length > 3
                    && this._details.displayParts[0].text === '('
                    && this._details.displayParts[2].text === ')')
                    skipVerbose = 3;
            
                  element.appendChild(createSpan(
                    this._entry.kind.charAt(0),
                    'teapo-completion-icon teapo-completion-icon-' + this._entry.kind));
            
                  renderSyntaxPart(this._details.displayParts, element, this.text);
            
                  if (this._details.documentation && this._details.documentation.length) {
                    var docSpan = document.createElement('span');
                    docSpan.className = 'teapo-syntax-docs';
                    setTextContent(docSpan, ' // ');
                    renderSyntaxPart(this._details.documentation, docSpan);
                    element.appendChild(docSpan);
                  }
                }
                
              }
            
              var _useTextContent = -1;
              function createSpan(text: string, className: string) {
                var span = document.createElement('span');
                if (_useTextContent === -1)
                  _useTextContent = 'textContent' in span ? 1:0;
                if (_useTextContent)
                  span.textContent = text;
                else
                  span.innerText = text;
                span.className = className;
                return span;
              }
              
            }
          • TypeScriptDocHandler.ts
            module teapo.docs.types.text.ts_ {
            
              export var expectsFile = /.*\.ts/g;
              export var acceptsFile = /.*\.ts/g;
              
              var _typescriptService: typescript.TypeScriptService;
            
              function typescriptService() {
                if (!_typescriptService) {
                  _typescriptService = new typescript.TypeScriptService();
                  build.functions.typescriptBuild.mainTS = _typescriptService;
                }
            
                return _typescriptService;
              }
            
              export function loadText(path: string, storage: DocState): CodeMirrorTextDoc {
                return new TypeScriptDocHandler();
              }
            
              export class TypeScriptDocHandler
                extends base.SimpleCodeMirrorDocHandler
                implements typescript.ExternalDocument {
            
                private _changes: ts.TextChangeRange[] = [];
            
                private _diagMarkers: CodeMirror.TextMarker[] = null;
                private _diagsTimer = new Timer();
            
                private _matchHighlightTimer = new Timer();
                private _matchMarkers: { marker: CodeMirror.TextMarker; offset: number; isCurrent: boolean; }[] = null;
                private _matchMarkersInvalidated = true;
            
                private _statusUpdateTimer = new Timer();
            
                private _autoformatInProgress = false;
            
                constructor() {
                  super();
            
                  this.keyMap['Ctrl-,'] = () => this._matchGo(-1);
                  this.keyMap['Ctrl-<'] = () => this._matchGo(-1);
                  this.keyMap['Alt-,'] = () => this._matchGo(-1);
                  this.keyMap['Alt-<'] = () => this._matchGo(-1);
                  this.keyMap['Ctrl-.'] = () => this._matchGo(+1);
                  this.keyMap['Ctrl->'] = () => this._matchGo(+1);
                  this.keyMap['Alt-.'] = () => this._matchGo(+1);
                  this.keyMap['Alt->'] = () => this._matchGo(+1);
            
            
                  this._matchHighlightTimer.interval = 400;
                  this._matchHighlightTimer.ontick = () => this._updateMatchHighlight();
            
                  this._diagsTimer.interval = 600;
                  this._diagsTimer.ontick = () => this._updateDiags();
            
                  this._statusUpdateTimer.interval = 200;
                  this._statusUpdateTimer.ontick = () => this._updateStatus();
                }
            
                load(text: string) {
                  typescriptService().addFile(this.path, this);
                }
            
                open() {
                  this._diagsTimer.reset();
                  this._matchHighlightTimer.reset();
                  this._statusUpdateTimer.reset();
                }
            
                close() {
                  this._diagsTimer.stop();
                  this._matchHighlightTimer.stop();
                  this._statusUpdateTimer.stop();
                }
            
                shouldTriggerCompletion(textBeforeCursor: string) {
                  var lastChar = textBeforeCursor.charAt(textBeforeCursor.length - 1);
                  if (lastChar === '.')
                    return true;
                  if (lastChar.toLowerCase() !== lastChar.toUpperCase())
                    return true;
                }
                
                getCompletions(): any {
                  var cur = this.doc.getCursor();
                  var curOffset = this.doc.indexFromPos(cur);
                  
                  var completions = typescriptService().service().getCompletionsAtPosition(
                    this.path,
                    curOffset,
                    false);
                  
                  if (!completions || !completions.entries.length)
                    return;
            
                  var lineText = this.doc.getLine(cur.line);
                  var prefixLength = 0;
                  while (prefixLength < cur.ch) {
                    var ch = lineText.charAt(cur.ch - prefixLength-1);
                    if (!isalphanumeric(ch))
                      break;
                    prefixLength++;
                  }
                  var suffixLength = 0;
                  while (cur.ch + suffixLength < lineText.length) {
                    var ch = lineText.charAt(cur.ch + suffixLength);
                    if (!isalphanumeric(ch))
                      break;
                    suffixLength++;
                  }
                  var lead = lineText.slice(0, cur.ch - prefixLength);
                  var prefix = lineText.slice (cur.ch - prefixLength, cur.ch);
                  var suffix = lineText.slice(cur.ch, cur.ch + suffixLength);
                  var trail = lineText.slice(cur.ch + suffixLength);
                  var matchTextLower = prefix.toLowerCase();
                  
                  var completionEntries: CodeMirrorCompletion[] = [];
                  for (var i = 0; i < completions.entries.length; i++) {
                    if (completionEntries.length > 16) break;
                    var co = completions.entries[i];
                    
                    if (prefixLength && co.name.toLowerCase().indexOf(matchTextLower) < 0)
                      continue;
                    
                    var det = typescriptService().service().getCompletionEntryDetails(this.path, curOffset, co.name);
            
                    completionEntries.push(new CodeMirrorCompletion(
                      lead, prefix, suffix, trail, cur.line,
                      co, det));
                  }
            
                  if (!completionEntries.length
                   || (completionEntries.length === 1 && completionEntries[completionEntries.length - 1].text === prefix))
                    return;
            
                  var result: CodeMirror.showHint.CompletionResult = {
                    list: completionEntries,
                    from: CodeMirror.Pos(cur.line, cur.ch - prefixLength),
                    to: cur
                  };
            
                  return result;
                }
            
                onChanges(docChanges: CodeMirror.EditorChange[], summary: ChangeSummary) {
            
                  this._changes.push(new ts.TextChangeRange(
                    new ts.TextSpan(summary.lead, summary.mid),
                    summary.mid));
            
                  this._diagsTimer.reset();
                  this._matchHighlightTimer.reset();
                  this._matchMarkersInvalidated = true;
            
                  this._statusUpdateTimer.reset();
            
                  super.onChanges(docChanges, summary);
            
                  this._autoformatAsNeeded(docChanges);
                }
            
                onCursorMoved(cursorPos: CodeMirror.Pos) {
                  this._matchHighlightTimer.reset();
                  this._statusUpdateTimer.reset();
                }
            
                changes(): ts.TextChangeRange[] {
                  return this._changes;
                }
            
                private _autoformatAsNeeded(docChanges: CodeMirror.EditorChange[]) {
            
                  if (this._autoformatInProgress)
                    return;
            
                  var ch = docChanges[docChanges.length-1];
                  var chText = ch.text.length ? ch.text[ch.text.length-1] : null;
                  if (!chText && ch.text.length > 1)
                    chText = '\n';
                  
                  var lastch = chText.charAt(chText.length-1);
                  switch (lastch) {
                    case '}':
                    case ';':
                    case '\n':
                      break;
            
                    default:
                      return;
                  }
            
                  var cursor = this.doc.getCursor();
                  var cursorOffset = this.doc.indexFromPos(cursor);
            
                  var fmtOps: ts.FormatCodeOptions = {
                    IndentSize: 2,
                    TabSize: 2,
                    NewLineCharacter: '\n',
                    ConvertTabsToSpaces: true,
            
                    InsertSpaceAfterCommaDelimiter: true,
                    InsertSpaceAfterSemicolonInForStatements: true,
                    InsertSpaceBeforeAndAfterBinaryOperators: true,
                    InsertSpaceAfterKeywordsInControlFlowStatements: true,
                    InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
                    InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
                    PlaceOpenBraceOnNewLineForFunctions: false,
                    PlaceOpenBraceOnNewLineForControlBlocks: false,
                  };
            
                  var fmtEdits = typescriptService().service().getFormattingEditsAfterKeystroke(
                    this.path,
                    cursorOffset,
                    lastch,
                    fmtOps);
                  console.log('..'+JSON.stringify(lastch));
            
                  if (fmtEdits && fmtEdits.length) {
                    this._autoformatInProgress = true;
                    this.editor.operation(() => {
                      for (var i = 0; i < fmtEdits.length; i++) {
                        var ed = fmtEdits[i];
                        var from = this.doc.posFromIndex(ed.span.start());
                        var to = this.doc.posFromIndex(ed.span.end());
                        this.doc.replaceRange(ed.newText, from, to);
                        console.log('change '+i+':: '+from.line+':'+from.ch+'['+ed.span.length()+']='+JSON.stringify(ed.newText));
                      }
                    });
                    this._autoformatInProgress = false;
                  }
                    
                }
            
                private _updateDiags() {
                  if (this.removed) return;
            
                  this.editor.operation(() => {
            
                    if (this._diagMarkers) {
                      for (var i = 0; i <this._diagMarkers.length; i++) {
                        var m = this._diagMarkers[i];
                        m.clear();
                      }
                    }
                    this._diagMarkers = [];
            
                    var syntacticDiags = typescriptService().service().getSyntacticDiagnostics(this.path);
                    var semanticDiags = typescriptService().service().getSemanticDiagnostics(this.path);
            
                    if (syntacticDiags) {
                      for (var i = 0; i < syntacticDiags.length; i++) {
                        this._addDiag(syntacticDiags[i], 'syntactic');
                      }
                    }
            
                    if (semanticDiags) {
                      for (var i = 0; i < semanticDiags.length; i++) {
                        this._addDiag(semanticDiags[i], 'semantic');
                      }
                    }
            
                    this._updateStatus();
                  });
            
                }
                  
                private _addDiag(d: ts.Diagnostic, kind: string) {
                  var tsFrom = d.file.getLineAndCharacterFromPosition(d.start);
                  var tsTo = d.file.getLineAndCharacterFromPosition(d.start + d.length);
                  var marker = this.doc.markText(
                    CodeMirror.Pos(tsFrom.line-1, tsFrom.character-1),
                    CodeMirror.Pos(tsTo.line-1, tsTo.character-1),
                    {
                      className: 'teapo-diag teapo-diag-'+kind+' teapo-diag-'+ts.DiagnosticCategory[d.category]
                    });
                  marker['__error'] = d;
                  this._diagMarkers.push(marker);
                  // TODO: update rendering
                }
            
                private _updateMatchHighlight() {
                  if (!this.doc && !this.editor)
                    return;
            
                  var cursor = this.doc.getCursor();
                  var cursorOffset = this.doc.indexFromPos(cursor);
                  if (!this._matchMarkersInvalidated && this._matchMarkers) {
                    for (var i = 0; i < this._matchMarkers.length; i++) {
                      var m = this._matchMarkers[i];
                      var pos = m.marker.find();
                      if (compareSign(pos.from, cursor)<=0 && compareSign(cursor, pos.to)<=0) {
                        if (m.isCurrent) {
                          // all is well
                          return;
                        }
                      }
                    }
                  }
            
                  this.editor.operation(() => {
            
                    if (this._matchMarkers) {
                      for (var i = 0; i < this._matchMarkers.length; i++) {
                        this._matchMarkers[i].marker.clear();
                      }
                    }
                    this._matchMarkers = [];
            
                    var newMatches = typescriptService().service().getOccurrencesAtPosition(this.path, cursorOffset);
                    if (!newMatches)
                      return;
            
                    for (var i = 0; i < newMatches.length; i++) {
                      var m = newMatches[i];
                      if (m.fileName !== this.path)
                        continue;
            
                      var from = this.doc.posFromIndex(m.textSpan.start());
                      var to = this.doc.posFromIndex(m.textSpan.end());
            
                      var isCurrent = m.textSpan.containsPosition(cursorOffset);
            
                      var marker = this.doc.markText(
                        from,
                        to,
                        {
                          className: isCurrent ? 'teapo-match teapo-match-current' : 'teapo-match'
                        });
                      this._matchMarkers.push({ marker: marker, offset: m.textSpan.start(), isCurrent: isCurrent });
            
                    }
            
                    this._matchMarkers.sort((m1, m2) => m1.offset - m2.offset);
            
                  });
            
                  this._matchMarkersInvalidated = false;
                  
                }
                  
                private _matchGo(dir: number) {
                  if (!this.doc && !this.editor)
                    return;
            
                  if (this._matchHighlightTimer.isWaiting())
                    this._matchHighlightTimer.endWaiting();
                  if (!this._matchMarkers)
                    this._updateMatchHighlight();
            
                  var cursor = this.doc.getCursor();
                  var cursorOffset = this.doc.indexFromPos(cursor);
            
                  for (var matchIndex = 0; matchIndex < this._matchMarkers.length; matchIndex++) {
                    var m = this._matchMarkers[matchIndex];
                    if (m.isCurrent)
                      break;
                  }
            
                  if (matchIndex >= this._matchMarkers.length)
                    return;
            
                  var newMatchIndex = matchIndex + dir;
                  if (newMatchIndex < 0)
                    newMatchIndex = this._matchMarkers.length - 1;
                  else if (newMatchIndex >= this._matchMarkers.length)
                    newMatchIndex = 0;
            
                  var innerOffset = cursorOffset - this._matchMarkers[matchIndex].offset;
                  var newCursorOffset = this._matchMarkers[newMatchIndex].offset + innerOffset;
                  var newCursor = this.doc.posFromIndex(newCursorOffset);
            
                  this.doc.setCursor(newCursor);
                  this._updateMatchHighlight();
                    
                }
            
                private _updateStatus() {
                  if (!this.editor)
                    return;
            
                  var cursor = this.doc.getCursor();
                  var cursorOffset = this.doc.indexFromPos(cursor);
            
                  if (this._diagMarkers) {
                    var anyErrors = false;
                    for (var i = 0; i < this._diagMarkers.length; i++) {
                      var dm = this._diagMarkers[i];
                      var dmPos = dm.find();
                      if (dmPos
                          && compareSign(dmPos.from, cursor)<=0 
                          && compareSign(cursor, dmPos.to)<=0) {
                        var d: ts.Diagnostic = dm['__error'];
            
                        var errSpan = document.createElement('span');
                        if ('textContent' in errSpan)
                          errSpan.textContent = '? '+d.messageText+' ';
                        else
                          errSpan.innerText = '? '+d.messageText + ' ';
                        
                        errSpan.className = 'teapo-diag-'+ts.DiagnosticCategory[d.category];
            
                        setTextContent(this.status, '');
            
                        this.status.appendChild(errSpan);
                        anyErrors = true;
                      }
                    }
            
                    if (anyErrors)
                      return;
                  }
            
                  var signature = typescriptService().service().getSignatureHelpItems(this.path, cursorOffset);
                  if (signature && signature.items.length) {
                    setTextContent(this.status, '');
            
                    var si = signature.items[signature.selectedItemIndex || 0];
                    if (si.prefixDisplayParts)
                      renderSyntaxPart(si.prefixDisplayParts, this.status);
                    if (si.parameters) {
                      for (var i = 0; i < si.parameters.length; i++) {
                        if (i > 0)
                          renderSyntaxPart(si.separatorDisplayParts, this.status);
                        if (i === signature.argumentIndex) {
                          var paramHighlight = document.createElement('span');
                          paramHighlight.className = 'teapo-syntax-current';
                        	renderSyntaxPart(si.parameters[i].displayParts, paramHighlight);
                          this.status.appendChild(paramHighlight);
                        }
                        else {
                          renderSyntaxPart(si.parameters[i].displayParts, this.status);
                        }
                      }
                    }
                    if (si.suffixDisplayParts)
                      renderSyntaxPart(si.suffixDisplayParts, this.status);
            
                    if (si.documentation && si.documentation.length) {
                      var docSpan = document.createElement('span');
                      docSpan.className = 'teapo-syntax-docs';
                      setTextContent(docSpan, ' // ');
                      renderSyntaxPart(si.documentation, docSpan);
                      this.status.appendChild(docSpan);
                    }
                    
                  }
                  else {
                    var qi = typescriptService().service().getQuickInfoAtPosition(this.path, cursorOffset);
                    if (qi && qi.displayParts) {
                      setTextContent(this.status, '');
            
                      var skipUntilCloseBracket = true;
                      for (var i = 0; i < qi.displayParts.length; i++) {
                        var dip = qi.displayParts[i];
                        if (skipUntilCloseBracket) {
                          if (dip.text === ')')
                            skipUntilCloseBracket = false;
                          continue;
                        }
                        if (!dip.text)
                          continue; // TS really does inject empty tokens
            
                        var sp = document.createElement('span');
                        if ('textContent' in sp)
                          sp.textContent = dip.text;
                        else
                          sp.innerText = dip.text;
                        sp.className = 'teapo-syntax-'+dip.kind;
                        
                        this.status.appendChild(sp);
                      }
            
                      if (qi.documentation && qi.documentation.length) {
                        var sp = document.createElement('span');
                        var sp = document.createElement('span');
                        if ('textContent' in sp)
                          sp.textContent = ' // ';
                        else
                          sp.innerText = ' // ';
                        sp.className = 'teapo-syntax-comment';
                        this.status.appendChild(sp);
            
                        for (var i = 0; i < qi.documentation.length; i++) {
                          var dip = qi.documentation[i];
            
                          if (!dip.text)
                            continue; // TS really does inject empty tokens
            
                          var sp = document.createElement('span');
                          if ('textContent' in sp)
                            sp.textContent = dip.text;
                          else
                            sp.innerText = dip.text;
                          sp.className = 'teapo-syntax-'+dip.kind;
            
                          this.status.appendChild(sp);
                        }
                      }
                    }
                    else {
                      if ('textContent' in this.status)
                        this.status.textContent = this.path;
                      else
                        this.status.innerText = this.path;
                    }
                  }
                }
            
              }
            
              export function createCodeMirrorDoc(text: string): CodeMirror.Doc {
                return new CodeMirror.Doc(text || '', 'text/typescript');
              }
            
              function compareSign(p1: CodeMirror.Pos, p2: CodeMirror.Pos) {
                if (p1.line > p2.line)
                  return 1;
                else if (p1.line < p2.line)
                  return -1;
                else if (p1.ch > p2.ch)
                  return 1;
                else if (p1.ch < p2.ch)
                  return -1;
                else
                  return 0;      
              }
            
              function isalphanumeric(ch: string) {
                if (ch >= '0' && ch <= '9') return true;
                if (ch >= 'A' && ch <= 'Z') return true;
                if (ch >= 'a' && ch <= 'z') return true;
                if (ch === '_' || ch ==='$') return true;
                if (ch.charCodeAt(0) < 128) return false;
                // slow Unicode path
                return ch.toLowerCase() !== ch.toUpperCase();
              }
            
            }
          • renderSyntaxPart.ts
            module teapo.docs.types.text.ts_ {
            
              export function renderSyntaxPart(syntax: ts.SymbolDisplayPart[], element: HTMLElement, skipUntil?: string): void {
                var skipping = skipUntil ? true : false;
            
                for (var i = 0; i < syntax.length; i++) {
                  var p = syntax[i];
                  if (!p.text) continue;
            
                  if (skipping) {
                    if (p.text === skipUntil)
                      skipping = false;
                    else
                    	continue;
                  }
            
                  var sp = document.createElement('span');
                  setTextContent(sp, p.text);
                  sp.className = 'teapo-syntax-'+p.kind;
            
                  element.appendChild(sp);
                }
              }
            
              
            }
          • style.css
            .teapo-completion-icon {
              border: solid 1px black;
              font-size: 0.8;
              display: inline-block;
              width: 1.5em;
              margin: 2px;
              margin-right: 0.3em;
              text-align: center;
              border-radius: 3px;
            }
            
            .teapo-completion-icon-local {
              border-color: fuchsia;
              color: fuchsia;
              background: lavenderblush;
            }
            
            .teapo-completion-icon-function {
              border-color: green;
              color: green;
              background: honeydew;
            }
            
            .teapo-syntax-moduleName {
              opacity: 0.3;
            }
            
            .teapo-syntax-className {
              opacity: 0.5;
            }
            
            .teapo-syntax-propertyName {
              font-weight: bold;
            }
            
            .teapo-syntax-methodName {
              font-weight: bold;
            }
            
            .teapo-syntax-keyword {
              opacity: 0.7;
            }
            
            .teapo-syntax-current {
              font-weight: bold;
            }
            
            .teapo-syntax-docs {
              opacity: 0.8;
            }
            
            
            .teapo-match {
              background: silver;
              background: rgba(20, 120, 0, 0.08);
              background: linear-gradient(rgba(20,120,0,0), rgba(20,120,0,0.02), rgba(20,120,0,0.2));
              border-bottom: solid 2px rgba(20,120,0,0.3);
            }
            
            .teapo-match-current {
              background: silver;
              background: rgba(20, 120, 0, 0.08);
              background: linear-gradient(rgba(20,120,0,0), rgba(20,120,0,0.01), rgba(20,120,0,0.2));
              border-bottom: solid 3px rgba(20,120,0,0.3);
            }
            
            
            .teapo-diag-syntactic {
              background: solid coral 3px;
              background: rgba(255, 127, 80, 0.4);
              border-bottom: solid 4px tomato;
            }
            
            .teapo-diag-semantic {
              background: gold;
              background: rgba(255, 215, 0, 0.4);
              border-bottom: solid 4px orange;
            }
            
        • CodeMirror-ext.css
          .CodeMirror {
            height: 100%;
            font-family: inherit;
            font-size: inherit;
          }
          
          .CodeMirror-hints {
            font-family: inherit;
          }
          .CodeMirror-hint {
            max-width: 52em;
            max-height: 4.5em;
            overflow-x: inherit;
            overflow-y: hidden;
            white-space: normal;
          }
          
          
        • CodeMirrorDocHandler.ts
          module teapo.docs.types.text {
          
            export class CodeMirrorDocHandler implements DocHandler {
          
              static codeMirrorEditorPools: { [moduleName: string]: CodeMirror[]; } = { };
              
              private _closures = {
                cm_changes: (cm, docChanges) => this._docChanges(docChanges),
                cm_cursorActivity: (cm) => this._cursorActivity(),
                cm_scroll: (cm) => this._scroll()
              };
          
              private _saveTimer = new Timer();
          
              private _appliedKeyMap = null;
              
              private _scrollerModel: scrollerView.ScrollerModel = null;
          
              private _retrievedText: string = null;
              private _validLead: number = -1;
              private _validTrail: number = 0;
              private _totalLength: number = 0;
          
              constructor(
                public path: string,
                public storage: DocState,
                public textDoc: CodeMirrorTextDoc,
                public moduleName: string,
                public moduleObj: TextHandlerModule) {
                
                this._saveTimer.ontick = () => this._save();
                
                this.textDoc.path = path;
          
                this.textDoc.text = () => this.text();
                
                if (this.textDoc.load) {
                  var text = this.storage.read();
                  this.textDoc.load(text);
                }
                
              }
          
              showEditor(regions: DocHostRegions): void {
          
                var cmPool =
                  CodeMirrorDocHandler.codeMirrorEditorPools[this.moduleName || ''] ||
                  (CodeMirrorDocHandler.codeMirrorEditorPools[this.moduleName || ''] = []);
          
                if (cmPool.length) {
                  this.textDoc.editor = cmPool.pop();
                	// avoid zoom on focus
                	this.textDoc.editor.getInputField().style.fontSize = '16px';
          
                  regions.content.appendChild(this.textDoc.editor.getWrapperElement());
                }
                else {
                  this.textDoc.editor = (this.moduleObj && this.moduleObj.createCodeMirrorEditor) ?
                    this.moduleObj.createCodeMirrorEditor(regions.content) :
                    createCodeMirrorEditor(regions.content);
          
                  this._appliedKeyMap = this.textDoc.keyMap;
                  if (this._appliedKeyMap) {
                    this.textDoc.editor.addKeyMap(this._appliedKeyMap);
                  }
                }
          
                if (!this.textDoc.doc) {
                  if (!this._retrievedText && typeof this._retrievedText !== 'string') {
                    this._retrievedText = this.storage.read();
                    this._validLead = -1;
                    this._validTrail = 0;
                    this._totalLength = this._retrievedText.length;
                  }
          
                  this.textDoc.doc = (this.moduleObj && this.moduleObj.createCodeMirrorDoc) ?
                    this.moduleObj.createCodeMirrorDoc(this.storage.read()) :
                    createCodeMirrorDoc(this._retrievedText);
                }
          
                if (!this._scrollerModel) {
                  this._scrollerModel = new scrollerView.ScrollerModel(this.textDoc.doc, 300);
                }
                
                this.textDoc.editor.swapDoc(this.textDoc.doc);
          
                this.textDoc.editor.on('changes', this._closures.cm_changes);
                this.textDoc.editor.on('cursorActivity', this._closures.cm_cursorActivity);
                this.textDoc.editor.on('scroll', this._closures.cm_scroll);
          
                if (!this.textDoc.scroller) {
                  this.textDoc.scroller = document.createElement('div');
                  this.textDoc.scroller.style.width = '100%';
                  this.textDoc.scroller.style.height = '100%';
                  ko.renderTemplate('ScrollerView', this._scrollerModel, null, this.textDoc.scroller);
                }
          
                regions.scroller.appendChild(this.textDoc.scroller);
                
                if (!this.textDoc.status) {
                  this.textDoc.status = document.createElement('div');
                  this.textDoc.status.style.width = '100%';
                  this.textDoc.status.style.height = '100%';
                  this.textDoc.status.textContent = this.path;
                }
          
                regions.status.appendChild(this.textDoc.status);
          
                if (this.textDoc.open)
                  this.textDoc.open();
                
                setTimeout(() => {
                  if (this.textDoc.editor && this.textDoc.editor.getDoc() === this.textDoc.doc) {
                    this.textDoc.editor.refresh();
                    this.textDoc.editor.focus();
                    this._scroll();
                  }
                }, 2);
          
              }
          
              hideEditor(): void {
          
                this._saveTimer.endWaiting();
                
                this.textDoc.editor.off('changes', this._closures.cm_changes);
                this.textDoc.editor.off('cursorActivity', this._closures.cm_cursorActivity);
                this.textDoc.editor.off('scroll', this._closures.cm_scroll);
          
                if (this._appliedKeyMap) {
                  this.textDoc.editor.removeKeyMap(this._appliedKeyMap);
                  this._appliedKeyMap = null;
                }
          
                if (this.textDoc.close)
                  this.textDoc.close();
                
                var editor = this.textDoc.editor;
                this.textDoc.editor = null;
                
                var cmPool =
                  CodeMirrorDocHandler.codeMirrorEditorPools[this.moduleName || ''];
                
                cmPool.push(editor);
              }
              
              remove() {
                this._saveTimer.stop();
                if (this.textDoc.remove)
                  this.textDoc.remove();
          
                this.textDoc.doc = null;
              }
          
              text(): string {
          
                var doc = this.textDoc.doc;
                if (!this._retrievedText && typeof this._retrievedText !== 'string') {
                  this._retrievedText = doc ? doc.getValue() : this.storage.read();
                  this._totalLength = this._retrievedText.length;
                  this._validLead = -1;
                  return this._retrievedText;
                }
          
                if (this._validLead < 0)
                  return this._retrievedText;
          
                var lineCount = doc.lineCount();
                var totalLength = doc.indexFromPos({
                  line: lineCount - 1,
                  ch: doc.getLine(lineCount - 1).length
                });
          
                if (this._validLead + this._validTrail === this._retrievedText.length
                   && this._retrievedText.length === totalLength)
                  return this._retrievedText;
          
                if (this._validLead + this._validTrail < totalLength / 4) { // if more than 0.75 of the document is modified
                  this._retrievedText = doc.getValue();
                  this._validLead = -1;
                  return this._retrievedText;
                }
          
                var mid = doc.getRange(
                  doc.posFromIndex(this._validLead),
                  doc.posFromIndex(totalLength - this._validTrail));
                
                this._retrievedText =
                  this._retrievedText.slice(0, this._validLead) +
                  mid +
                  this._retrievedText.slice(this._retrievedText.length - this._validTrail);
                this._validLead = -1;
          
                
                return this._retrievedText;
              }
          
              private _docChanges(docChanges: CodeMirror.EditorChange[]) {
          
                var doc = this.textDoc.doc;
          
                var lineCount = doc.lineCount();
                var newTotalLength = doc.indexFromPos({
                  line: lineCount - 1,
                  ch: doc.getLine(lineCount - 1).length
                });
          
                var changeLead = -1;
                var changeTrail = -1;
                var deltaLength = 0;
                for (var i = 0; i < docChanges.length; i++) {
                  var ch = docChanges[i];
                  var removedLength = totalLength(ch.removed);
                  var addedLength = totalLength(ch.text);
                  var fromIndex = doc.indexFromPos(ch.from);
                  var trail = newTotalLength - fromIndex - addedLength;
                  
                  deltaLength += addedLength - removedLength;
                  
                  if (changeLead < 0) {
                    changeLead = fromIndex;
                    changeTrail = trail;
                  }
                  else {
                    changeLead = Math.min(changeLead, fromIndex);
                    changeTrail = Math.min(changeTrail, trail);
                  }
                }
                
                if (this._validLead < 0) {
                  this._validLead = changeLead;
                  this._validTrail = changeTrail;
                }
                else {
                  this._validLead = Math.min(this._validLead, changeLead);
                  this._validTrail = Math.min(this._validTrail, changeTrail);
                }
          
                var changeSummary = {
                  lead: changeLead,
                  mid: this._totalLength - changeLead - changeTrail,
                  newmid: 0,
                  trail: changeTrail
                };
                changeSummary.newmid = changeSummary.mid + deltaLength;
          
                this._totalLength = newTotalLength;
          
                if (this.textDoc.onChanges) {
                  this.textDoc.onChanges(docChanges, changeSummary);
                }
          
                if (this._scrollerModel)
                  this._scrollerModel.docChanges(docChanges);
          
                this._saveTimer.interval = (this.moduleObj && this.moduleObj.saveDelay) || saveDelay;
                this._saveTimer.reset();
          
              }
          
              private _cursorActivity() {
                if (this.textDoc.onCursorMoved) {
                  var cursorPos = this.textDoc.doc.getCursor();
                  //this.textDoc.status.textContent = 'token '+this.textDoc.editor.getTokenAt(cursorPos).type;
                  this.textDoc.onCursorMoved(cursorPos);
                }
          
                // TODO: scroller/thickBar cursor activity
          
              }
              
              private _scroll() {
                var scr = this.textDoc.editor.getScrollInfo();
                if (this.textDoc.onScroll)
                  this.textDoc.onScroll(scr);
          
                if (this._scrollerModel)
                  this._scrollerModel.scroll(scr);
                
              }
          
              private _save() {
                this.storage.write(this.text());
              }
          
            }
          
            function totalLength(lines: string[]): number {
              var length = 0;
              for (var i = 0 ; i < lines.length; i++) {
                length += lines[i].length;
              }
              if (lines.length > 1)
                length += lines.length - 1;
              return length;
            }
          }
        • api.ts
          module teapo.docs.types.text {
            
            export interface TextHandlerModule {
          
              loadText(path: string, storage: DocState): CodeMirrorTextDoc;
              
              expectsFile: RegExp;
              acceptsFile?: RegExp;
          
              createCodeMirrorEditor?: (host: HTMLElement) => CodeMirror;
              createCodeMirrorDoc?: (text: string) => CodeMirror.Doc;
              
              saveDelay?: number;
          
            }
            
            export function loadText(path: string, storage: DocState): CodeMirrorTextDoc {
              return {
                path: null,
                editor: null,
                doc: null,
                text: null,
                scroller: null,
                status: null,
                state: null,
                open: null,
                close: null,
                remove: null
              };
            }
          
            export interface CodeMirrorTextDoc {
          
              path: string;
              editor: CodeMirror;
              doc: CodeMirror.Doc;
              text: () => string;
              scroller: HTMLElement;
              status: HTMLElement;
              removed?: boolean;
          
              state: any;
          
              load?: (text: string) => void;
          
              open();
              close();
              remove();
          
              onCursorMoved?: (cursorPos: CodeMirror.Pos) => void;
              onScroll?: (scrollInfo: CodeMirror.ScrollInfo) => void;
          
              onChanges?: (
                docChanges: CodeMirror.EditorChange[],
                summary: ChangeSummary) => void;
          
              onSave?: () => void;
          
              keyMap?: any;
            }
          
            export interface ChangeSummary {
              lead: number;
              mid: number;
              newmid: number;
              trail: number;
            }
          
            export function createCodeMirrorEditor(host: HTMLElement): CodeMirror {
              return new CodeMirror(host, {
                  lineNumbers: true,
                  matchBrackets: true,
                  autoCloseBrackets: true,
                  matchTags: true,
                  showTrailingSpace: true,
                  autoCloseTags: true,
                  //highlightSelectionMatches: {showToken: /\w/},
                  styleActiveLine: true,
                  tabSize: 2
                });
            }
            
            export function createCodeMirrorDoc(text: string): CodeMirror.Doc {
              return new CodeMirror.Doc(text || '');
            }
          
          }
        • load.ts
          module teapo.docs.types.text {
          
            export var expectsFile = /.*\.txt/g;
            export var acceptsFile = /.*/g;
            
            export var saveDelay = 700;
          
            export function load(path: string, storage: DocState): DocHandler {
          
              var submodules = listSubmodules<TextHandlerModule>(teapo.docs.types.text, 'loadText');
              for (var i = 0; i < submodules.length; i++) {
          
                var match = path.match(submodules[i].moduleObj.expectsFile);
                if (match && match.length && match[0] === path) {
                  var textDoc = submodules[i].moduleObj.loadText(path, storage);
                  if (textDoc)
                    return new CodeMirrorDocHandler(path, storage, textDoc, submodules[i].moduleName, submodules[i].moduleObj);
                }
          
              }
              
              for (var i = 0; i < submodules.length; i++) {
          
                if (submodules[i].moduleObj.acceptsFile) { 
                  var match = path.match(submodules[i].moduleObj.acceptsFile);
                  if (!match || !match.length || match[0] !== path) continue;
                }
          
                var textDoc = submodules[i].moduleObj.loadText(path, storage);
                if (textDoc)
                  return new CodeMirrorDocHandler(path, storage, textDoc, submodules[i].moduleName, submodules[i].moduleObj);
              }
          
              var textDoc = teapo.docs.types.text.loadText(path, storage);
              return new CodeMirrorDocHandler(
                path, storage, textDoc,
                null, null);
              
            }
            
            
            
          
            
          }
      • api.ts
        /**
         * Add your generic document type handlers to nested modules
         * inside 'types' module.
         * Define load function in the same way load function is defined here below.
         */
        module teapo.docs.types {
        
          export interface DocHandlerModule {
            
            load(path: string, storage: DocState): DocHandler;
            
            expectsFile: RegExp;
            acceptsFile?: RegExp;
        
          }
          
          /**
           * Default type loading.
           * Other handlers should conform to the same signature, and be on the child modules, like so:
           * module teapo.docs.types.text { function load(...); }
           */
          declare function load(path: string, storage: DocState): DocHandler;
        
          export interface DocHandler {
        
            showEditor(regions: DocHostRegions): void;
            hideEditor(): void;
        
            remove();
        
          }
        
          export interface DocHostRegions {
            content: HTMLElement;
            scroller: HTMLElement;
            status: HTMLElement;
          }
        
          
          export interface DocState {
            read(): string;
            write(content: string);
            
            readState(): any;
            writeState(state: any);
          }
        
        
        }
      • listSubmodules.ts
        module teapo.docs.types {
          
          export function listSubmodules<T>(
            parentModule: any,
            loadFunctionName: string) {
            
            var result: { moduleName: string; moduleObj: T; }[] = parentModule.__cachedSubmoduleList;
        
            if (!result) {
              result = parentModule.__cachedSubmoduleList = [];
        
              for (var moduleName in parentModule) if (parentModule.hasOwnProperty(moduleName)) {
                var moduleObj = parentModule[moduleName];
                if (moduleObj && typeof moduleObj === 'object'
                  && moduleName.charAt(0).toUpperCase() !== moduleName.charAt(0)
                  && moduleObj[loadFunctionName] && typeof moduleObj[loadFunctionName] === 'function'
                  && moduleObj.expectsFile) {
                  result.push({ moduleName: moduleName, moduleObj: moduleObj });
                }
              }
              
              parentModule.__cachedSubmoduleList = result;
            }
        
            return result;
          }
          
        }
      • load.ts
        module teapo.docs.types {
          
          export function load(path: string, storage: DocState): DocHandler {
           
            var submodules = listSubmodules<DocHandlerModule>(teapo.docs.types, 'load');
            for (var i = 0; i < submodules.length; i++) {
        
              var match = path.match(submodules[i].moduleObj.expectsFile);
              if (match && match.length && match[0] === path) {
                var docHandler = submodules[i].moduleObj.load(path, storage);
                if (docHandler)
                  return docHandler;
              }
        
            }
            
            for (var i = 0; i < submodules.length; i++) {
        
              if (submodules[i].moduleObj.acceptsFile) { 
                var match = path.match(submodules[i].moduleObj.acceptsFile);
                if (!match || !match.length || match[0] !== path) continue;
              }
        
              var docHandler = submodules[i].moduleObj.load(path, storage);
              if (docHandler)
                return docHandler;
            }
        
            return null;
          }
          
        }
    • DocHost.ts
      module teapo.docs {
        
        export class DocHost {
      
          private _docs: { [file: string]: docs.types.DocHandler; } = {};
      
          private _activeHandler: docs.types.DocHandler = null;
      
          constructor(
            private _regions: docs.types.DocHostRegions,
            private _drive: persistence.Drive) {
      
            var files = this._drive.files();
            for (var i = 0; i < files.length; i++) {
              this.add(files[i]);
            }
      
          }
        
          show(file: string) {
      
            var oldHandler = this._activeHandler;
            var oldElements: Element[] = [];
      
            if (this._regions.content) {
              for (var i = 0; i < this._regions.content.children.length; i++) {
                oldElements.push(this._regions.content.children[i]);
              }
            }
      
            if (this._regions.scroller) {
              for (var i = 0; i < this._regions.scroller.children.length; i++) {
                oldElements.push(this._regions.scroller.children[i]);
              }
            }
      
             if (this._regions.status) {
              for (var i = 0; i < this._regions.status.children.length; i++) {
                oldElements.push(this._regions.status.children[i]);
              }
            }
      
            try {
              this._activeHandler = this._docs[file];
              if (!this._activeHandler) {
      
                if (file === null)
                  return; // one of expected values here
      
                // TODO: handle unopenable file
                return;
              }
      
              this._activeHandler.showEditor(this._regions);
            }
            finally {
      
              if (oldHandler && oldHandler.hideEditor) {
                oldHandler.hideEditor();
              }
      
              for (var i = 0; i < oldElements.length; i++) {
                oldElements[i].parentNode.removeChild(oldElements[i]);
              }
      
            }
          }
      
          add(file: string) {
            var docState = new DocState(file, this._drive);
            var docHandler = docs.types.load(file, docState);
            this._docs[file] = docHandler;
          }
      
          remove(file: string) {
      
            var openAnotherFile = false;
            
            var docHandler = this._docs[file];
            if (docHandler) {
      
              openAnotherFile = true;
      
              if (this._activeHandler === docHandler) {
                this.show(null);
              }
      
              docHandler.remove();
      
              delete this._docs[file];
            }
            
            if (openAnotherFile) {
              // TODO: show another file
            }
          }
          
        }
      
        class DocState implements docs.types.DocState {
          
          constructor(private _file: string, private _drive: persistence.Drive) {
          }
      
          read(): string {
            return this._drive.read(this._file);
          }
      
          write(content: string) {
            this._drive.timestamp = Date.now ? Date.now() : +new Date();
            this._drive.write(this._file, content);
          }
          
          readState(): any {
            // TODO...
          }
      
          writeState(state: any) {
            // TODO...
          }
          
        }
        
      }
  • files
    • FileTree.css
      .teapo-file-tree {
        padding-left: 1.5em;
      }
      
      .teapo-file-tree ul {
        margin: 1px;
        margin-left: 0px;
        padding-left: 0.4em;
      }
      
      .teapo-file-tree ul li {
        margin: 0px;
        padding: 0px;
      }
      
      .teapo-file-tree li .teapo-file-name {
        padding: 2px;
      }
      
      .teapo-file-tree li .teapo-dir-name {
        padding: 2px;
        font-weight: bold;
      }
      
      .teapo-file-tree ul li .teapo-file-name:hover {
        padding: 1px;
        border: solid 1px gold;
      }
      
      .teapo-file-tree ul li .teapo-dir-name:hover {
        padding: 1px;
        border: solid 1px gold;
      }
      
      
      .teapo-file-tree li.teapo-dir {
        list-style: circle;
        cursor: default;
      }
      
      .teapo-file-tree .teapo-dir-collapsed ul {
        display: none;
      }
      
      
      .teapo-file-tree li.teapo-file {
        list-style: square;
      }
      
      .teapo-file-tree .teapo-file-selected {
        background: cornflowerblue;
      }
      
      
      .teapo-file-content {
        display: none;
      }
      
    • FileTree.ts
      module teapo.files {
        
        export class FileTree implements persistence.Drive {
      
          private _virtualRoot: Node;
          private _allFiles: { [file: string]: Node; } = {};
          private _selectedFileNode = ko.observable<Node>(null);
      
          selectedFile = ko.computed<string>({
            read: () => {
              var n = this._selectedFileNode();
              return n ? n.fullPath : null;
            },
            write: (value) => {
              var node = this._allFiles[value] || null;
              if (node || value === null || value === undefined)
                this._selectFileNode(node);
            }
          });
          
          timestamp: number = 0;
      
          constructor(private _host: HTMLElement) {
      
            var domSelection = { selectedFile: null };
            this._virtualRoot = new Node(null, <any>this._host, this._allFiles, domSelection);
            
            if (domSelection.selectedFile)
              this.selectedFile(domSelection.selectedFile);
            
            try {
              var timestamStr = this._virtualRoot.readAttr('timestamp');
              this.timestamp = timestamStr ? parseInt(timestamStr) : 0;
            }
            catch (parseError) {
              this.timestamp = 0;
            }
      
            addEventListener(this._host, 'click', e => this._onClick(<any>e));
          }
      
          files(): string[] {
            return objectKeys(this._allFiles);
          }
      
          read(file: string): string {
            var n = this._allFiles[file];
            if (n)
              return n.read();
            else
              return null;
          }
      
          write(file: string, content: string) {
            var n = this._allFiles[file];
            if (!n) {
              file = normalizePath(file);
              n = this._allFiles[file];
            }
      
            if (n) {
              if (content || typeof content === 'string') {
                n.write(content);
              }
              else {
                n.parent.remove(n);
                delete this._allFiles[file];
              }
            }
            else {
              if (!content && typeof content !== 'string')
                return;
      
              var newFile = this._createFile(file);
              newFile.write(content);
            }
            
            this._virtualRoot.writeAttr('timestamp', this.timestamp + '');
          }
          
          private _createFile(file: string): Node {
            var lastSlashPos = file.lastIndexOf('/');
            if (lastSlashPos) { // slash in position other than lead
              var parentDir = file.slice(1, lastSlashPos);
              var fileName = file = file.slice(lastSlashPos + 1);
              var parent = this._virtualRoot.findOrCreateDir(parentDir);
              var node = parent.createFile(fileName);
              this._allFiles[node.fullPath] = node;
              return node;
            }
            else { 
              var node = this._virtualRoot.createFile(file.slice(1));
              this._allFiles[node.fullPath] = node;
              return node;
            }
          }
          
          private _onClick(e: MouseEvent) {
            var node = this._getNode(<any>e.target || <any>e.srcElement);
            if (!node) return;
            if (node === this._virtualRoot) return;
            
            if (node.isDir) {
              node.toggleCollapse();
            }
            else {
              this._selectFileNode(node);
            }
            
          }
          
          private _selectFileNode(node: Node) {
            var oldSelected = this._selectedFileNode();
            if (oldSelected) {
              oldSelected.setSelectClass(false);
            }
            
            if (node)
              node.setSelectClass(true);
            
            this._selectedFileNode(node);
          }
          
          private _getNode(elem: HTMLElement): Node {
            while (elem) {
              var node = (<any>elem)._teapo_node;
              if (node) return node;
              elem = elem.parentElement;
              if (!elem)
                return null;
            }
          }
      
        }
      
        class Node {
      
          isDir: boolean = false;
          name: string = null;
          fullPath: string = null;
      
          private _contentPRE: HTMLPreElement = null;
          private _subDirs: Node[] = [];
          private _files: Node[] = [];
          private _ul: HTMLUListElement = null;
          
          constructor(
            public parent: Node,
            public li: HTMLElement,
            allFiles: { [file: string]: Node; },
            selection: { selectedFile: string; }) {
              
            (<any>li)._teapo_node = this;
            
            var childLIs: HTMLLIElement[] = [];
            for (var i = 0; i < this.li.children.length; i++) {
      
              var child = this.li.children[i];
              if ((<HTMLLIElement>child).tagName === 'LI') childLIs.push(<HTMLLIElement>child);
              if ((<HTMLUListElement>child).tagName === 'UL') {
                this._ul = <HTMLUListElement>child;
                for (var j = 0; j < this._ul.children.length; j++) {
                  var ulLI = <HTMLLIElement>this._ul.children[j];
                  if (ulLI.tagName === 'LI') childLIs.push(ulLI);
                }
              }
              
      
              if ((<HTMLDivElement>child).tagName === 'DIV' && (<HTMLDivElement>child).className) {
                if ((<HTMLDivElement>child).className.indexOf('teapo-file-name') >= 0) {
                  this.isDir = false;
                  this.name = child.textContent || (<HTMLDivElement>child).innerText;
                }
                else if ((<HTMLDivElement>child).className.indexOf('teapo-dir-name') >= 0) {
                  this.isDir = true;
                  this.name = child.textContent || (<HTMLDivElement>child).innerText;
                }
              }
      
              if ((<HTMLPreElement>child).tagName === 'PRE' && (<HTMLPreElement>child).className 
                && (<HTMLPreElement>child).className.indexOf('teapo-file-content') >= 0) {
                
                if (this._contentPRE) {
                  // double content?
                }
                else {
                  this._contentPRE = <HTMLPreElement>child;
                }
                
              }
      
            }
            
            if (this.parent) {
              this.fullPath = this.parent.fullPath + '/' + this.name;
            }
            else { 
              this.name = '';
              this.fullPath = '';
            }
            
            if (selection) {
              if (li.className.indexOf('teapo-file-selected') >= 0) {
                if (selection.selectedFile)
                  li.className = li.className.replace(/teapo\-file\-selected/g, '');
                else
                  selection.selectedFile = this.fullPath;
              }
            }
            else { 
              if (li.className.indexOf('teapo-file-selected') >= 0)
                li.className = li.className.replace(/teapo\-file\-selected/g, '');
            }
      
            if (allFiles)
              this._createChildNodesAndSort(childLIs, allFiles, selection);
      
          }
      
          read(): string {
            if (this.isDir)
              return null; // DEBUG
      
            return this._contentPRE ? this._contentPRE.textContent || this._contentPRE.innerText : '';
          }
      
          write(content: string) {
            if (this.isDir)
              return; // DEBUG
      
            if (!this._contentPRE) {
              this._contentPRE = document.createElement('pre');
              this._contentPRE.className = 'teapo-file-content';
              this.li.appendChild(this._contentPRE);
            }
            
            if (this._contentPRE.textContent || 'textContent' in this._contentPRE)
              this._contentPRE.textContent = content || '';
            else
              this._contentPRE.innerText = content || '';
          }
        
          readAttr(prop: string) {
            if (this.li)
              return this.li.getAttribute(getSafeAttributeName(prop));
            else
              return this._ul.getAttribute(getSafeAttributeName(prop));      
          }
        
          writeAttr(prop: string, value: string) {
            if (value === null || value === undefined) {
              if (this.li)
                this.li.removeAttribute(getSafeAttributeName(prop));
              else
                this._ul.removeAttribute(getSafeAttributeName(prop));      
            }
            else {
              if (this.li)
                this.li.setAttribute(getSafeAttributeName(prop), value);
              else
                this._ul.setAttribute(getSafeAttributeName(prop), value);
            }
          }
        
          remove(childNode: Node) {
            var nodeList = childNode.isDir ? this._subDirs : this._files;
            var index = nodeList.indexOf(childNode);
            nodeList.splice(index, 1);
            this._ul.removeChild(childNode.li);
            
            if (!this.parent || this._files.length + this._subDirs.length)
              return;
      
            this.parent.remove(this);
          }
      
          findOrCreateDir(relativePath: string): Node {
            
            var slashPos = relativePath.indexOf('/');
            var subdirName = slashPos > 0 ? relativePath.slice(0, slashPos) : relativePath;
            var restPath = slashPos > 0 ? relativePath.slice(slashPos + 1) : null;
            
            var matchIndex = this._binarySearchNode(subdirName, this._subDirs);
            var subdir: Node;
            if (matchIndex >= 0) {
              subdir = this._subDirs[matchIndex];
            }
            else {
              //return this._subDirs[matchIndex];
              var insertIndex = -matchIndex - 100;
      
              var newLI = document.createElement('li');
              var fnameDIV = document.createElement('div');
              fnameDIV.className = 'teapo-dir-name';
              if ('textContent' in fnameDIV)
                fnameDIV.textContent = subdirName;
              else
                fnameDIV.innerText = subdirName;
              newLI.appendChild(fnameDIV);
              var ul = document.createElement('ul');
              newLI.appendChild(ul);
              subdir = new Node(this, newLI, /*allFiles*/ null, /*selection*/ null);
              
              var insertSibling =
                insertIndex < this._subDirs.length ? this._subDirs[insertIndex].li    :
                this._files.length ? this._files[0].li :
                null;
              
              this._subDirs.splice(insertIndex, 0, subdir);
              if (!this._ul) {
                this._ul = document.createElement('ul');
                this.li.appendChild(this._ul);
              }
      
              this._ul.insertBefore(subdir.li, insertSibling);
            }
            
            if (restPath)
              return subdir.findOrCreateDir(restPath);
            else
              return subdir;
          }
        
          createFile(fileName: string): Node {
            var newLI = document.createElement('li');
            var fnameDIV = document.createElement('div');
            fnameDIV.className = 'teapo-file-name';
            if ('textContent' in fnameDIV)
              fnameDIV.textContent = fileName;
            else
              fnameDIV.innerText = fileName;
              
            newLI.appendChild(fnameDIV);
            var newNode = new Node(this, newLI, /*allFiles*/ null, /*selection*/ null);
            this._insertChildNode(
              this._files,
              newNode,
                /*forceRerootingEvenIfOrdered*/ true,
                /*insertBeforeElement*/null);
            return newNode;
          }
        
          toggleCollapse() {
            if (this.li.className && this.li.className.indexOf('teapo-dir-collapsed') >= 0) {
              this.li.className = this.li.className.replace(/teapo\-dir\-collapsed/g, '');
            }
            else { 
              this.li.className = (this.li.className || '') + ' teapo-dir-collapsed';
            }
          }
        
          setSelectClass(selected: boolean) {
            if (selected) {
              this.li.className = (this.li.className || '') + ' teapo-file-selected';
            }
            else { 
              this.li.className = this.li.className ? this.li.className.replace(/teapo\-file\-selected/g, '') : null;
            }
          }
      
          private _createChildNodesAndSort(
            childLIs: HTMLLIElement[],
            allFiles: { [file: string]: Node; },
            selection: { selectedFile: string; }) {
            
            for (var i = 0; i < childLIs.length; i++) {
              var node = new Node(this, childLIs[i], allFiles, selection);
              
              if (node.isDir) {
                this._insertChildNode(
                  this._subDirs, node,
                  /*forceRerootingEvenIfOrdered*/ <any>this._files.length,
                  this._files.length ? this._files[0].li : node.li);
              }
              else {
                allFiles[node.fullPath] = node;
                this._insertChildNode(
                  this._files, node,
                  /*forceRerootingEvenIfOrdered*/ false,
                  node.li);
              }
            }
            
          }
      
          private _insertChildNode(
            nodeList: Node[],
            node: Node,
            forceRerootingEvenIfOrdered: boolean,
            insertBeforeElement: HTMLElement) {
            
            var insertIndex = this._binarySearchNode(node.name, nodeList);
            if (insertIndex >= 0)
              alert('Node should not exist: we are inserting it.');
      
            insertIndex = -insertIndex - 100;
            
            if (insertIndex >= nodeList.length) {      
              nodeList.push(node);
              if (forceRerootingEvenIfOrdered)
                this._ul.insertBefore(node.li, insertBeforeElement);
              return;
            }
      
            this._ul.insertBefore(node.li, nodeList[insertIndex].li);
            nodeList.splice(insertIndex, 0, node);
            
          }
        
          /** returns match index, or (-100 - insertionIndex) */
          private _binarySearchNode(name: string, list: Node[]): number {
            if (!list.length)
              return -100;
            
            if (name > list[list.length - 1].name)
              return -100 - list.length;
            if (name == list[list.length - 1].name)
              return list.length - 1;
            
            if (name < list[0].name)
              return -100;
            if (name === list[0].name)
              return 0;
            
            var rangeStart = 1;
            var rangeLength = list.length - 2;
            while (true) {
              if (!rangeLength)
                return -100 - rangeStart;
              
              var mid = rangeStart + (rangeLength >> 1);
              if (name === list[mid].name)
                return mid;
      
              if (name < list[mid].name) {
                rangeLength = mid - rangeStart;
              }
              else {
                rangeLength -= mid - rangeStart + 1;
                rangeStart = mid + 1;
              }
            }
          }
          
        }
      
        export function normalizePath(path: string) : string {
          
          if (!path) return '/'; // empty paths converted to root
          
          while (' \n\t\r'.indexOf(path.charAt(0))>=0) // removing leading whitespace
            path = path.slice(1);
      
          while ('\n\t\r\\'.indexOf(path.charAt(path.length - 1))>=0) // removing trailing whitespace and trailing slashes
            path = path.slice(0, path.length - 1);
      
          if (path.charAt(0) !== '/') // ensuring leading slash
            path = '/' + path;
      
          path = path.replace(/\/\/*/g, '/'); // replacing duplicate slashes with single
      
          return path;
        }
      
        export function getSafeAttributeName(caseSensitiveName: string): string {
          if (caseSensitiveName.toLowerCase() === caseSensitiveName
             && caseSensitiveName.indexOf('^')<0)
            return caseSensitiveName;
          var result: string[] = [];
          for (var i = 0; i < caseSensitiveName.length; i++) {
            var c = caseSensitiveName.charAt(i);
            if (c === '^' || c.toLowerCase() !== c)
              result.push('^');
      
            result.push(c);
          }
          return result.join('');
        }
      
      }
  • imports
    • acorn
      • acorn.js
        // Acorn is a tiny, fast JavaScript parser written in JavaScript.
        //
        // Acorn was written by Marijn Haverbeke and various contributors and
        // released under an MIT license. The Unicode regexps (for identifiers
        // and whitespace) were taken from [Esprima](http://esprima.org) by
        // Ariya Hidayat.
        //
        // Git repositories for Acorn are available at
        //
        //     http://marijnhaverbeke.nl/git/acorn
        //     https://github.com/marijnh/acorn.git
        //
        // Please use the [github bug tracker][ghbt] to report issues.
        //
        // [ghbt]: https://github.com/marijnh/acorn/issues
        //
        // This file defines the main parser interface. The library also comes
        // with a [error-tolerant parser][dammit] and an
        // [abstract syntax tree walker][walk], defined in other files.
        //
        // [dammit]: acorn_loose.js
        // [walk]: util/walk.js
        
        (function(root, mod) {
          if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS
          if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD
          mod(root.acorn || (root.acorn = {})); // Plain browser env
        })(this, function(exports) {
          "use strict";
        
          exports.version = "0.9.1";
        
          // The main exported interface (under `self.acorn` when in the
          // browser) is a `parse` function that takes a code string and
          // returns an abstract syntax tree as specified by [Mozilla parser
          // API][api], with the caveat that inline XML is not recognized.
          //
          // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
        
          var options, input, inputLen, sourceFile;
        
          exports.parse = function(inpt, opts) {
            input = String(inpt); inputLen = input.length;
            setOptions(opts);
            initTokenState();
            initParserState();
            return parseTopLevel(options.program);
          };
        
          // A second optional argument can be given to further configure
          // the parser process. These options are recognized:
        
          var defaultOptions = exports.defaultOptions = {
            // `ecmaVersion` indicates the ECMAScript version to parse. Must
            // be either 3, or 5, or 6. This influences support for strict
            // mode, the set of reserved words, support for getters and
            // setters and other features.
            ecmaVersion: 5,
            // Turn on `strictSemicolons` to prevent the parser from doing
            // automatic semicolon insertion.
            strictSemicolons: false,
            // When `allowTrailingCommas` is false, the parser will not allow
            // trailing commas in array and object literals.
            allowTrailingCommas: true,
            // By default, reserved words are not enforced. Enable
            // `forbidReserved` to enforce them. When this option has the
            // value "everywhere", reserved words and keywords can also not be
            // used as property names.
            forbidReserved: false,
            // When enabled, a return at the top level is not considered an
            // error.
            allowReturnOutsideFunction: false,
            // When `locations` is on, `loc` properties holding objects with
            // `start` and `end` properties in `{line, column}` form (with
            // line being 1-based and column 0-based) will be attached to the
            // nodes.
            locations: false,
            // A function can be passed as `onToken` option, which will
            // cause Acorn to call that function with object in the same
            // format as tokenize() returns. Note that you are not
            // allowed to call the parser from the callback—that will
            // corrupt its internal state.
            onToken: null,
            // A function can be passed as `onComment` option, which will
            // cause Acorn to call that function with `(block, text, start,
            // end)` parameters whenever a comment is skipped. `block` is a
            // boolean indicating whether this is a block (`/* */`) comment,
            // `text` is the content of the comment, and `start` and `end` are
            // character offsets that denote the start and end of the comment.
            // When the `locations` option is on, two more parameters are
            // passed, the full `{line, column}` locations of the start and
            // end of the comments. Note that you are not allowed to call the
            // parser from the callback—that will corrupt its internal state.
            onComment: null,
            // Nodes have their start and end characters offsets recorded in
            // `start` and `end` properties (directly on the node, rather than
            // the `loc` object, which holds line/column data. To also add a
            // [semi-standardized][range] `range` property holding a `[start,
            // end]` array with the same numbers, set the `ranges` option to
            // `true`.
            //
            // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
            ranges: false,
            // It is possible to parse multiple files into a single AST by
            // passing the tree produced by parsing the first file as
            // `program` option in subsequent parses. This will add the
            // toplevel forms of the parsed file to the `Program` (top) node
            // of an existing parse tree.
            program: null,
            // When `locations` is on, you can pass this to record the source
            // file in every node's `loc` object.
            sourceFile: null,
            // This value, if given, is stored in every node, whether
            // `locations` is on or off.
            directSourceFile: null,
            // When enabled, parenthesized expressions are represented by
            // (non-standard) ParenthesizedExpression nodes
            preserveParens: false
          };
        
          // This function tries to parse a single expression at a given
          // offset in a string. Useful for parsing mixed-language formats
          // that embed JavaScript expressions.
        
          exports.parseExpressionAt = function(inpt, pos, opts) {
            input = String(inpt); inputLen = input.length;
            setOptions(opts);
            initTokenState(pos);
            initParserState();
            return parseExpression();
          };
        
          var isArray = function (obj) {
            return Object.prototype.toString.call(obj) === "[object Array]";
          };
        
          function setOptions(opts) {
            options = opts || {};
            for (var opt in defaultOptions) if (!has(options, opt))
              options[opt] = defaultOptions[opt];
            sourceFile = options.sourceFile || null;
            if (isArray(options.onToken)) {
              var tokens = options.onToken;
              options.onToken = function (token) {
                tokens.push(token);
              };
            }
            if (isArray(options.onComment)) {
              var comments = options.onComment;
              options.onComment = function (block, text, start, end, startLoc, endLoc) {
                var comment = {
                  type: block ? 'Block' : 'Line',
                  value: text,
                  start: start,
                  end: end
                };
                if (options.locations) {
                  comment.loc = new SourceLocation();
                  comment.loc.start = startLoc;
                  comment.loc.end = endLoc;
                }
                if (options.ranges)
                  comment.range = [start, end];
                comments.push(comment);
              };
            }
            isKeyword = options.ecmaVersion >= 6 ? isEcma6Keyword : isEcma5AndLessKeyword;
          }
        
          // The `getLineInfo` function is mostly useful when the
          // `locations` option is off (for performance reasons) and you
          // want to find the line/column position for a given character
          // offset. `input` should be the code string that the offset refers
          // into.
        
          var getLineInfo = exports.getLineInfo = function(input, offset) {
            for (var line = 1, cur = 0;;) {
              lineBreak.lastIndex = cur;
              var match = lineBreak.exec(input);
              if (match && match.index < offset) {
                ++line;
                cur = match.index + match[0].length;
              } else break;
            }
            return {line: line, column: offset - cur};
          };
        
          function Token() {
            this.type = tokType;
            this.value = tokVal;
            this.start = tokStart;
            this.end = tokEnd;
            if (options.locations) {
              this.loc = new SourceLocation();
              this.loc.end = tokEndLoc;
              // TODO: remove in next major release
              this.startLoc = tokStartLoc;
              this.endLoc = tokEndLoc;
            }
            if (options.ranges)
              this.range = [tokStart, tokEnd];
          }
        
          exports.Token = Token;
        
          // Acorn is organized as a tokenizer and a recursive-descent parser.
          // The `tokenize` export provides an interface to the tokenizer.
          // Because the tokenizer is optimized for being efficiently used by
          // the Acorn parser itself, this interface is somewhat crude and not
          // very modular. Performing another parse or call to `tokenize` will
          // reset the internal state, and invalidate existing tokenizers.
        
          exports.tokenize = function(inpt, opts) {
            input = String(inpt); inputLen = input.length;
            setOptions(opts);
            initTokenState();
        
            function getToken(forceRegexp) {
              lastEnd = tokEnd;
              readToken(forceRegexp);
              return new Token();
            }
            getToken.jumpTo = function(pos, reAllowed) {
              tokPos = pos;
              if (options.locations) {
                tokCurLine = 1;
                tokLineStart = lineBreak.lastIndex = 0;
                var match;
                while ((match = lineBreak.exec(input)) && match.index < pos) {
                  ++tokCurLine;
                  tokLineStart = match.index + match[0].length;
                }
              }
              tokRegexpAllowed = reAllowed;
              skipSpace();
            };
            return getToken;
          };
        
          // State is kept in (closure-)global variables. We already saw the
          // `options`, `input`, and `inputLen` variables above.
        
          // The current position of the tokenizer in the input.
        
          var tokPos;
        
          // The start and end offsets of the current token.
        
          var tokStart, tokEnd;
        
          // When `options.locations` is true, these hold objects
          // containing the tokens start and end line/column pairs.
        
          var tokStartLoc, tokEndLoc;
        
          // The type and value of the current token. Token types are objects,
          // named by variables against which they can be compared, and
          // holding properties that describe them (indicating, for example,
          // the precedence of an infix operator, and the original name of a
          // keyword token). The kind of value that's held in `tokVal` depends
          // on the type of the token. For literals, it is the literal value,
          // for operators, the operator name, and so on.
        
          var tokType, tokVal;
        
          // Internal state for the tokenizer. To distinguish between division
          // operators and regular expressions, it remembers whether the last
          // token was one that is allowed to be followed by an expression.
          // (If it is, a slash is probably a regexp, if it isn't it's a
          // division operator. See the `parseStatement` function for a
          // caveat.)
        
          var tokRegexpAllowed;
        
          // When `options.locations` is true, these are used to keep
          // track of the current line, and know when a new line has been
          // entered.
        
          var tokCurLine, tokLineStart;
        
          // These store the position of the previous token, which is useful
          // when finishing a node and assigning its `end` position.
        
          var lastStart, lastEnd, lastEndLoc;
        
          // This is the parser's state. `inFunction` is used to reject
          // `return` statements outside of functions, `inGenerator` to
          // reject `yield`s outside of generators, `labels` to verify
          // that `break` and `continue` have somewhere to jump to, and
          // `strict` indicates whether strict mode is on.
        
          var inFunction, inGenerator, labels, strict;
        
          // This counter is used for checking that arrow expressions did
          // not contain nested parentheses in argument list.
        
          var metParenL;
        
          // This is used by parser for detecting if it's inside ES6
          // Template String. If it is, it should treat '$' as prefix before
          // '{expression}' and everything else as string literals.
        
          var inTemplate;
        
          function initParserState() {
            lastStart = lastEnd = tokPos;
            if (options.locations) lastEndLoc = new Position;
            inFunction = inGenerator = strict = false;
            labels = [];
            readToken();
          }
        
          // This function is used to raise exceptions on parse errors. It
          // takes an offset integer (into the current `input`) to indicate
          // the location of the error, attaches the position to the end
          // of the error message, and then raises a `SyntaxError` with that
          // message.
        
          function raise(pos, message) {
            var loc = getLineInfo(input, pos);
            message += " (" + loc.line + ":" + loc.column + ")";
            var err = new SyntaxError(message);
            err.pos = pos; err.loc = loc; err.raisedAt = tokPos;
            throw err;
          }
        
          // Reused empty array added for node fields that are always empty.
        
          var empty = [];
        
          // ## Token types
        
          // The assignment of fine-grained, information-carrying type objects
          // allows the tokenizer to store the information it has about a
          // token in a way that is very cheap for the parser to look up.
        
          // All token type variables start with an underscore, to make them
          // easy to recognize.
        
          // These are the general types. The `type` property is only used to
          // make them recognizeable when debugging.
        
          var _num = {type: "num"}, _regexp = {type: "regexp"}, _string = {type: "string"};
          var _name = {type: "name"}, _eof = {type: "eof"};
        
          // Keyword tokens. The `keyword` property (also used in keyword-like
          // operators) indicates that the token originated from an
          // identifier-like word, which is used when parsing property names.
          //
          // The `beforeExpr` property is used to disambiguate between regular
          // expressions and divisions. It is set on all token types that can
          // be followed by an expression (thus, a slash after them would be a
          // regular expression).
          //
          // `isLoop` marks a keyword as starting a loop, which is important
          // to know when parsing a label, in order to allow or disallow
          // continue jumps to that label.
        
          var _break = {keyword: "break"}, _case = {keyword: "case", beforeExpr: true}, _catch = {keyword: "catch"};
          var _continue = {keyword: "continue"}, _debugger = {keyword: "debugger"}, _default = {keyword: "default"};
          var _do = {keyword: "do", isLoop: true}, _else = {keyword: "else", beforeExpr: true};
          var _finally = {keyword: "finally"}, _for = {keyword: "for", isLoop: true}, _function = {keyword: "function"};
          var _if = {keyword: "if"}, _return = {keyword: "return", beforeExpr: true}, _switch = {keyword: "switch"};
          var _throw = {keyword: "throw", beforeExpr: true}, _try = {keyword: "try"}, _var = {keyword: "var"};
          var _let = {keyword: "let"}, _const = {keyword: "const"};
          var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true};
          var _this = {keyword: "this"};
          var _class = {keyword: "class"}, _extends = {keyword: "extends", beforeExpr: true};
          var _export = {keyword: "export"}, _import = {keyword: "import"};
          var _yield = {keyword: "yield", beforeExpr: true};
        
          // The keywords that denote values.
        
          var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true};
          var _false = {keyword: "false", atomValue: false};
        
          // Some keywords are treated as regular operators. `in` sometimes
          // (when parsing `for`) needs to be tested against specifically, so
          // we assign a variable name to it for quick comparing.
        
          var _in = {keyword: "in", binop: 7, beforeExpr: true};
        
          // Map keyword names to token types.
        
          var keywordTypes = {"break": _break, "case": _case, "catch": _catch,
                              "continue": _continue, "debugger": _debugger, "default": _default,
                              "do": _do, "else": _else, "finally": _finally, "for": _for,
                              "function": _function, "if": _if, "return": _return, "switch": _switch,
                              "throw": _throw, "try": _try, "var": _var, "let": _let, "const": _const,
                              "while": _while, "with": _with,
                              "null": _null, "true": _true, "false": _false, "new": _new, "in": _in,
                              "instanceof": {keyword: "instanceof", binop: 7, beforeExpr: true}, "this": _this,
                              "typeof": {keyword: "typeof", prefix: true, beforeExpr: true},
                              "void": {keyword: "void", prefix: true, beforeExpr: true},
                              "delete": {keyword: "delete", prefix: true, beforeExpr: true},
                              "class": _class, "extends": _extends,
                              "export": _export, "import": _import, "yield": _yield};
        
          // Punctuation token types. Again, the `type` property is purely for debugging.
        
          var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true};
          var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
          var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
          var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _ellipsis = {type: "..."}, _question = {type: "?", beforeExpr: true};
          var _arrow = {type: "=>", beforeExpr: true}, _bquote = {type: "`"}, _dollarBraceL = {type: "${", beforeExpr: true};
        
          // Operators. These carry several kinds of properties to help the
          // parser use them properly (the presence of these properties is
          // what categorizes them as operators).
          //
          // `binop`, when present, specifies that this operator is a binary
          // operator, and will refer to its precedence.
          //
          // `prefix` and `postfix` mark the operator as a prefix or postfix
          // unary operator. `isUpdate` specifies that the node produced by
          // the operator should be of type UpdateExpression rather than
          // simply UnaryExpression (`++` and `--`).
          //
          // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
          // binary operators with a very low precedence, that should result
          // in AssignmentExpression nodes.
        
          var _slash = {binop: 10, beforeExpr: true}, _eq = {isAssign: true, beforeExpr: true};
          var _assign = {isAssign: true, beforeExpr: true};
          var _incDec = {postfix: true, prefix: true, isUpdate: true}, _prefix = {prefix: true, beforeExpr: true};
          var _logicalOR = {binop: 1, beforeExpr: true};
          var _logicalAND = {binop: 2, beforeExpr: true};
          var _bitwiseOR = {binop: 3, beforeExpr: true};
          var _bitwiseXOR = {binop: 4, beforeExpr: true};
          var _bitwiseAND = {binop: 5, beforeExpr: true};
          var _equality = {binop: 6, beforeExpr: true};
          var _relational = {binop: 7, beforeExpr: true};
          var _bitShift = {binop: 8, beforeExpr: true};
          var _plusMin = {binop: 9, prefix: true, beforeExpr: true};
          var _modulo = {binop: 10, beforeExpr: true};
        
          // '*' may be multiply or have special meaning in ES6
          var _star = {binop: 10, beforeExpr: true};
        
          // Provide access to the token types for external users of the
          // tokenizer.
        
          exports.tokTypes = {bracketL: _bracketL, bracketR: _bracketR, braceL: _braceL, braceR: _braceR,
                              parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon,
                              dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq,
                              name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string,
                              arrow: _arrow, bquote: _bquote, dollarBraceL: _dollarBraceL};
          for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];
        
          // This is a trick taken from Esprima. It turns out that, on
          // non-Chrome browsers, to check whether a string is in a set, a
          // predicate containing a big ugly `switch` statement is faster than
          // a regular expression, and on Chrome the two are about on par.
          // This function uses `eval` (non-lexical) to produce such a
          // predicate from a space-separated string of words.
          //
          // It starts by sorting the words by length.
        
          function makePredicate(words) {
            words = words.split(" ");
            var f = "", cats = [];
            out: for (var i = 0; i < words.length; ++i) {
              for (var j = 0; j < cats.length; ++j)
                if (cats[j][0].length == words[i].length) {
                  cats[j].push(words[i]);
                  continue out;
                }
              cats.push([words[i]]);
            }
            function compareTo(arr) {
              if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";";
              f += "switch(str){";
              for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":";
              f += "return true}return false;";
            }
        
            // When there are more than three length categories, an outer
            // switch first dispatches on the lengths, to save on comparisons.
        
            if (cats.length > 3) {
              cats.sort(function(a, b) {return b.length - a.length;});
              f += "switch(str.length){";
              for (var i = 0; i < cats.length; ++i) {
                var cat = cats[i];
                f += "case " + cat[0].length + ":";
                compareTo(cat);
              }
              f += "}";
        
            // Otherwise, simply generate a flat `switch` statement.
        
            } else {
              compareTo(words);
            }
            return new Function("str", f);
          }
        
          // The ECMAScript 3 reserved word list.
        
          var isReservedWord3 = makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile");
        
          // ECMAScript 5 reserved words.
        
          var isReservedWord5 = makePredicate("class enum extends super const export import");
        
          // The additional reserved words in strict mode.
        
          var isStrictReservedWord = makePredicate("implements interface let package private protected public static yield");
        
          // The forbidden variable names in strict mode.
        
          var isStrictBadIdWord = makePredicate("eval arguments");
        
          // And the keywords.
        
          var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
        
          var isEcma5AndLessKeyword = makePredicate(ecma5AndLessKeywords);
        
          var isEcma6Keyword = makePredicate(ecma5AndLessKeywords + " let const class extends export import yield");
        
          var isKeyword = isEcma5AndLessKeyword;
        
          // ## Character categories
        
          // Big ugly regular expressions that match characters in the
          // whitespace, identifier, and identifier-start categories. These
          // are only applied when a character is found to actually have a
          // code point above 128.
          // Generated by `tools/generate-identifier-regex.js`.
        
          var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
          var nonASCIIidentifierStartChars = "\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC";
          var nonASCIIidentifierChars = "\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19B0-\u19C0\u19C8\u19C9\u19D0-\u19D9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u200C\u200D\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA620-\uA629\uA66F\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F1\uA900-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F";
          var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
          var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
        
          // Whether a single character denotes a newline.
        
          var newline = /[\n\r\u2028\u2029]/;
        
          // Matches a whole line break (where CRLF is considered a single
          // line break). Used to count lines.
        
          var lineBreak = /\r\n|[\n\r\u2028\u2029]/g;
        
          // Test whether a given character code starts an identifier.
        
          var isIdentifierStart = exports.isIdentifierStart = function(code) {
            if (code < 65) return code === 36;
            if (code < 91) return true;
            if (code < 97) return code === 95;
            if (code < 123)return true;
            return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
          };
        
          // Test whether a given character is part of an identifier.
        
          var isIdentifierChar = exports.isIdentifierChar = function(code) {
            if (code < 48) return code === 36;
            if (code < 58) return true;
            if (code < 65) return false;
            if (code < 91) return true;
            if (code < 97) return code === 95;
            if (code < 123)return true;
            return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
          };
        
          // ## Tokenizer
        
          // These are used when `options.locations` is on, for the
          // `tokStartLoc` and `tokEndLoc` properties.
        
          function Position() {
            this.line = tokCurLine;
            this.column = tokPos - tokLineStart;
          }
        
          // Reset the token state. Used at the start of a parse.
        
          function initTokenState(pos) {
            if (pos) {
              tokPos = pos;
              tokLineStart = Math.max(0, input.lastIndexOf("\n", pos));
              tokCurLine = input.slice(0, tokLineStart).split(newline).length;
            } else {
              tokCurLine = 1;
              tokPos = tokLineStart = 0;
            }
            tokRegexpAllowed = true;
            metParenL = 0;
            inTemplate = false;
            skipSpace();
          }
        
          // Called at the end of every token. Sets `tokEnd`, `tokVal`, and
          // `tokRegexpAllowed`, and skips the space after the token, so that
          // the next one's `tokStart` will point at the right position.
        
          function finishToken(type, val, shouldSkipSpace) {
            tokEnd = tokPos;
            if (options.locations) tokEndLoc = new Position;
            tokType = type;
            if (shouldSkipSpace !== false) skipSpace();
            tokVal = val;
            tokRegexpAllowed = type.beforeExpr;
            if (options.onToken) {
              options.onToken(new Token());
            }
          }
        
          function skipBlockComment() {
            var startLoc = options.onComment && options.locations && new Position;
            var start = tokPos, end = input.indexOf("*/", tokPos += 2);
            if (end === -1) raise(tokPos - 2, "Unterminated comment");
            tokPos = end + 2;
            if (options.locations) {
              lineBreak.lastIndex = start;
              var match;
              while ((match = lineBreak.exec(input)) && match.index < tokPos) {
                ++tokCurLine;
                tokLineStart = match.index + match[0].length;
              }
            }
            if (options.onComment)
              options.onComment(true, input.slice(start + 2, end), start, tokPos,
                                startLoc, options.locations && new Position);
          }
        
          function skipLineComment(startSkip) {
            var start = tokPos;
            var startLoc = options.onComment && options.locations && new Position;
            var ch = input.charCodeAt(tokPos+=startSkip);
            while (tokPos < inputLen && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
              ++tokPos;
              ch = input.charCodeAt(tokPos);
            }
            if (options.onComment)
              options.onComment(false, input.slice(start + startSkip, tokPos), start, tokPos,
                                startLoc, options.locations && new Position);
          }
        
          // Called at the start of the parse and after every token. Skips
          // whitespace and comments, and.
        
          function skipSpace() {
            while (tokPos < inputLen) {
              var ch = input.charCodeAt(tokPos);
              if (ch === 32) { // ' '
                ++tokPos;
              } else if (ch === 13) {
                ++tokPos;
                var next = input.charCodeAt(tokPos);
                if (next === 10) {
                  ++tokPos;
                }
                if (options.locations) {
                  ++tokCurLine;
                  tokLineStart = tokPos;
                }
              } else if (ch === 10 || ch === 8232 || ch === 8233) {
                ++tokPos;
                if (options.locations) {
                  ++tokCurLine;
                  tokLineStart = tokPos;
                }
              } else if (ch > 8 && ch < 14) {
                ++tokPos;
              } else if (ch === 47) { // '/'
                var next = input.charCodeAt(tokPos + 1);
                if (next === 42) { // '*'
                  skipBlockComment();
                } else if (next === 47) { // '/'
                  skipLineComment(2);
                } else break;
              } else if (ch === 160) { // '\xa0'
                ++tokPos;
              } else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
                ++tokPos;
              } else {
                break;
              }
            }
          }
        
          // ### Token reading
        
          // This is the function that is called to fetch the next token. It
          // is somewhat obscure, because it works in character codes rather
          // than characters, and because operator parsing has been inlined
          // into it.
          //
          // All in the name of speed.
          //
          // The `forceRegexp` parameter is used in the one case where the
          // `tokRegexpAllowed` trick does not work. See `parseStatement`.
        
          function readToken_dot() {
            var next = input.charCodeAt(tokPos + 1);
            if (next >= 48 && next <= 57) return readNumber(true);
            var next2 = input.charCodeAt(tokPos + 2);
            if (options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
              tokPos += 3;
              return finishToken(_ellipsis);
            } else {
              ++tokPos;
              return finishToken(_dot);
            }
          }
        
          function readToken_slash() { // '/'
            var next = input.charCodeAt(tokPos + 1);
            if (tokRegexpAllowed) {++tokPos; return readRegexp();}
            if (next === 61) return finishOp(_assign, 2);
            return finishOp(_slash, 1);
          }
        
          function readToken_mult_modulo(code) { // '%*'
            var next = input.charCodeAt(tokPos + 1);
            if (next === 61) return finishOp(_assign, 2);
            return finishOp(code === 42 ? _star : _modulo, 1);
          }
        
          function readToken_pipe_amp(code) { // '|&'
            var next = input.charCodeAt(tokPos + 1);
            if (next === code) return finishOp(code === 124 ? _logicalOR : _logicalAND, 2);
            if (next === 61) return finishOp(_assign, 2);
            return finishOp(code === 124 ? _bitwiseOR : _bitwiseAND, 1);
          }
        
          function readToken_caret() { // '^'
            var next = input.charCodeAt(tokPos + 1);
            if (next === 61) return finishOp(_assign, 2);
            return finishOp(_bitwiseXOR, 1);
          }
        
          function readToken_plus_min(code) { // '+-'
            var next = input.charCodeAt(tokPos + 1);
            if (next === code) {
              if (next == 45 && input.charCodeAt(tokPos + 2) == 62 &&
                  newline.test(input.slice(lastEnd, tokPos))) {
                // A `-->` line comment
                skipLineComment(3);
                skipSpace();
                return readToken();
              }
              return finishOp(_incDec, 2);
            }
            if (next === 61) return finishOp(_assign, 2);
            return finishOp(_plusMin, 1);
          }
        
          function readToken_lt_gt(code) { // '<>'
            var next = input.charCodeAt(tokPos + 1);
            var size = 1;
            if (next === code) {
              size = code === 62 && input.charCodeAt(tokPos + 2) === 62 ? 3 : 2;
              if (input.charCodeAt(tokPos + size) === 61) return finishOp(_assign, size + 1);
              return finishOp(_bitShift, size);
            }
            if (next == 33 && code == 60 && input.charCodeAt(tokPos + 2) == 45 &&
                input.charCodeAt(tokPos + 3) == 45) {
              // `<!--`, an XML-style comment that should be interpreted as a line comment
              skipLineComment(4);
              skipSpace();
              return readToken();
            }
            if (next === 61)
              size = input.charCodeAt(tokPos + 2) === 61 ? 3 : 2;
            return finishOp(_relational, size);
          }
        
          function readToken_eq_excl(code) { // '=!', '=>'
            var next = input.charCodeAt(tokPos + 1);
            if (next === 61) return finishOp(_equality, input.charCodeAt(tokPos + 2) === 61 ? 3 : 2);
            if (code === 61 && next === 62 && options.ecmaVersion >= 6) { // '=>'
              tokPos += 2;
              return finishToken(_arrow);
            }
            return finishOp(code === 61 ? _eq : _prefix, 1);
          }
        
          // Get token inside ES6 template (special rules work there).
        
          function getTemplateToken(code) {
            // '`' and '${' have special meanings, but they should follow
            // string (can be empty)
            if (tokType === _string) {
              if (code === 96) { // '`'
                ++tokPos;
                return finishToken(_bquote);
              } else
              if (code === 36 && input.charCodeAt(tokPos + 1) === 123) { // '${'
                tokPos += 2;
                return finishToken(_dollarBraceL);
              }
            }
        
            if (code === 125) { // '}'
              ++tokPos;
              return finishToken(_braceR, undefined, false);
            }
        
            // anything else is considered string literal
            return readTmplString();
          }
        
          function getTokenFromCode(code) {
            switch (code) {
            // The interpretation of a dot depends on whether it is followed
            // by a digit or another two dots.
            case 46: // '.'
              return readToken_dot();
        
            // Punctuation tokens.
            case 40: ++tokPos; return finishToken(_parenL);
            case 41: ++tokPos; return finishToken(_parenR);
            case 59: ++tokPos; return finishToken(_semi);
            case 44: ++tokPos; return finishToken(_comma);
            case 91: ++tokPos; return finishToken(_bracketL);
            case 93: ++tokPos; return finishToken(_bracketR);
            case 123: ++tokPos; return finishToken(_braceL);
            case 125: ++tokPos; return finishToken(_braceR);
            case 58: ++tokPos; return finishToken(_colon);
            case 63: ++tokPos; return finishToken(_question);
        
            case 96: // '`'
              if (options.ecmaVersion >= 6) {
                ++tokPos;
                return finishToken(_bquote, undefined, false);
              }
        
            case 48: // '0'
              var next = input.charCodeAt(tokPos + 1);
              if (next === 120 || next === 88) return readRadixNumber(16); // '0x', '0X' - hex number
              if (options.ecmaVersion >= 6) {
                if (next === 111 || next === 79) return readRadixNumber(8); // '0o', '0O' - octal number
                if (next === 98 || next === 66) return readRadixNumber(2); // '0b', '0B' - binary number
              }
            // Anything else beginning with a digit is an integer, octal
            // number, or float.
            case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
              return readNumber(false);
        
            // Quotes produce strings.
            case 34: case 39: // '"', "'"
              return readString(code);
        
            // Operators are parsed inline in tiny state machines. '=' (61) is
            // often referred to. `finishOp` simply skips the amount of
            // characters it is given as second argument, and returns a token
            // of the type given by its first argument.
        
            case 47: // '/'
              return readToken_slash();
        
            case 37: case 42: // '%*'
              return readToken_mult_modulo(code);
        
            case 124: case 38: // '|&'
              return readToken_pipe_amp(code);
        
            case 94: // '^'
              return readToken_caret();
        
            case 43: case 45: // '+-'
              return readToken_plus_min(code);
        
            case 60: case 62: // '<>'
              return readToken_lt_gt(code);
        
            case 61: case 33: // '=!'
              return readToken_eq_excl(code);
        
            case 126: // '~'
              return finishOp(_prefix, 1);
            }
        
            return false;
          }
        
          function readToken(forceRegexp) {
            if (!forceRegexp) tokStart = tokPos;
            else tokPos = tokStart + 1;
            if (options.locations) tokStartLoc = new Position;
            if (forceRegexp) return readRegexp();
            if (tokPos >= inputLen) return finishToken(_eof);
        
            var code = input.charCodeAt(tokPos);
        
            if (inTemplate) return getTemplateToken(code);
        
            // Identifier or keyword. '\uXXXX' sequences are allowed in
            // identifiers, so '\' also dispatches to that.
            if (isIdentifierStart(code) || code === 92 /* '\' */) return readWord();
        
            var tok = getTokenFromCode(code);
        
            if (tok === false) {
              // If we are here, we either found a non-ASCII identifier
              // character, or something that's entirely disallowed.
              var ch = String.fromCharCode(code);
              if (ch === "\\" || nonASCIIidentifierStart.test(ch)) return readWord();
              raise(tokPos, "Unexpected character '" + ch + "'");
            }
            return tok;
          }
        
          function finishOp(type, size) {
            var str = input.slice(tokPos, tokPos + size);
            tokPos += size;
            finishToken(type, str);
          }
        
          var regexpUnicodeSupport = false;
          try { new RegExp("\uffff", "u"); regexpUnicodeSupport = true; }
          catch(e) {}
        
          // Parse a regular expression. Some context-awareness is necessary,
          // since a '/' inside a '[]' set does not end the expression.
        
          function readRegexp() {
            var content = "", escaped, inClass, start = tokPos;
            for (;;) {
              if (tokPos >= inputLen) raise(start, "Unterminated regular expression");
              var ch = input.charAt(tokPos);
              if (newline.test(ch)) raise(start, "Unterminated regular expression");
              if (!escaped) {
                if (ch === "[") inClass = true;
                else if (ch === "]" && inClass) inClass = false;
                else if (ch === "/" && !inClass) break;
                escaped = ch === "\\";
              } else escaped = false;
              ++tokPos;
            }
            var content = input.slice(start, tokPos);
            ++tokPos;
            // Need to use `readWord1` because '\uXXXX' sequences are allowed
            // here (don't ask).
            var mods = readWord1();
            var tmp = content;
            if (mods) {
              var validFlags = /^[gmsiy]*$/;
              if (options.ecmaVersion >= 6) validFlags = /^[gmsiyu]*$/;
              if (!validFlags.test(mods)) raise(start, "Invalid regular expression flag");
              if (mods.indexOf('u') >= 0 && !regexpUnicodeSupport) {
                // Replace each astral symbol and every Unicode code point
                // escape sequence that represents such a symbol with a single
                // ASCII symbol to avoid throwing on regular expressions that
                // are only valid in combination with the `/u` flag.
                tmp = tmp
                  .replace(/\\u\{([0-9a-fA-F]{5,6})\}/g, "x")
                  .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
              }
            }
            // Detect invalid regular expressions.
            try {
              new RegExp(tmp);
            } catch (e) {
              if (e instanceof SyntaxError) raise(start, "Error parsing regular expression: " + e.message);
              raise(e);
            }
            // Get a regular expression object for this pattern-flag pair, or `null` in
            // case the current environment doesn't support the flags it uses.
            try {
              var value = new RegExp(content, mods);
            } catch (err) {
              value = null;
            }
            return finishToken(_regexp, {pattern: content, flags: mods, value: value});
          }
        
          // Read an integer in the given radix. Return null if zero digits
          // were read, the integer value otherwise. When `len` is given, this
          // will return `null` unless the integer has exactly `len` digits.
        
          function readInt(radix, len) {
            var start = tokPos, total = 0;
            for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
              var code = input.charCodeAt(tokPos), val;
              if (code >= 97) val = code - 97 + 10; // a
              else if (code >= 65) val = code - 65 + 10; // A
              else if (code >= 48 && code <= 57) val = code - 48; // 0-9
              else val = Infinity;
              if (val >= radix) break;
              ++tokPos;
              total = total * radix + val;
            }
            if (tokPos === start || len != null && tokPos - start !== len) return null;
        
            return total;
          }
        
          function readRadixNumber(radix) {
            tokPos += 2; // 0x
            var val = readInt(radix);
            if (val == null) raise(tokStart + 2, "Expected number in radix " + radix);
            if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");
            return finishToken(_num, val);
          }
        
          // Read an integer, octal integer, or floating-point number.
        
          function readNumber(startsWithDot) {
            var start = tokPos, isFloat = false, octal = input.charCodeAt(tokPos) === 48;
            if (!startsWithDot && readInt(10) === null) raise(start, "Invalid number");
            if (input.charCodeAt(tokPos) === 46) {
              ++tokPos;
              readInt(10);
              isFloat = true;
            }
            var next = input.charCodeAt(tokPos);
            if (next === 69 || next === 101) { // 'eE'
              next = input.charCodeAt(++tokPos);
              if (next === 43 || next === 45) ++tokPos; // '+-'
              if (readInt(10) === null) raise(start, "Invalid number");
              isFloat = true;
            }
            if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");
        
            var str = input.slice(start, tokPos), val;
            if (isFloat) val = parseFloat(str);
            else if (!octal || str.length === 1) val = parseInt(str, 10);
            else if (/[89]/.test(str) || strict) raise(start, "Invalid number");
            else val = parseInt(str, 8);
            return finishToken(_num, val);
          }
        
          // Read a string value, interpreting backslash-escapes.
        
          function readCodePoint() {
            var ch = input.charCodeAt(tokPos), code;
        
            if (ch === 123) {
              if (options.ecmaVersion < 6) unexpected();
              ++tokPos;
              code = readHexChar(input.indexOf('}', tokPos) - tokPos);
              ++tokPos;
              if (code > 0x10FFFF) unexpected();
            } else {
              code = readHexChar(4);
            }
        
            // UTF-16 Encoding
            if (code <= 0xFFFF) {
              return String.fromCharCode(code);
            }
            var cu1 = ((code - 0x10000) >> 10) + 0xD800;
            var cu2 = ((code - 0x10000) & 1023) + 0xDC00;
            return String.fromCharCode(cu1, cu2);
          }
        
          function readString(quote) {
            ++tokPos;
            var out = "";
            for (;;) {
              if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
              var ch = input.charCodeAt(tokPos);
              if (ch === quote) {
                ++tokPos;
                return finishToken(_string, out);
              }
              if (ch === 92) { // '\'
                out += readEscapedChar();
              } else {
                ++tokPos;
                if (newline.test(String.fromCharCode(ch))) {
                  raise(tokStart, "Unterminated string constant");
                }
                out += String.fromCharCode(ch); // '\'
              }
            }
          }
        
          function readTmplString() {
            var out = "";
            for (;;) {
              if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
              var ch = input.charCodeAt(tokPos);
              if (ch === 96 || ch === 36 && input.charCodeAt(tokPos + 1) === 123) // '`', '${'
                return finishToken(_string, out);
              if (ch === 92) { // '\'
                out += readEscapedChar();
              } else {
                ++tokPos;
                if (newline.test(String.fromCharCode(ch))) {
                  if (ch === 13 && input.charCodeAt(tokPos) === 10) {
                    ++tokPos;
                    ch = 10;
                  }
                  if (options.locations) {
                    ++tokCurLine;
                    tokLineStart = tokPos;
                  }
                }
                out += String.fromCharCode(ch); // '\'
              }
            }
          }
        
          // Used to read escaped characters
        
          function readEscapedChar() {
            var ch = input.charCodeAt(++tokPos);
            var octal = /^[0-7]+/.exec(input.slice(tokPos, tokPos + 3));
            if (octal) octal = octal[0];
            while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1);
            if (octal === "0") octal = null;
            ++tokPos;
            if (octal) {
              if (strict) raise(tokPos - 2, "Octal literal in strict mode");
              tokPos += octal.length - 1;
              return String.fromCharCode(parseInt(octal, 8));
            } else {
              switch (ch) {
                case 110: return "\n"; // 'n' -> '\n'
                case 114: return "\r"; // 'r' -> '\r'
                case 120: return String.fromCharCode(readHexChar(2)); // 'x'
                case 117: return readCodePoint(); // 'u'
                case 116: return "\t"; // 't' -> '\t'
                case 98: return "\b"; // 'b' -> '\b'
                case 118: return "\u000b"; // 'v' -> '\u000b'
                case 102: return "\f"; // 'f' -> '\f'
                case 48: return "\0"; // 0 -> '\0'
                case 13: if (input.charCodeAt(tokPos) === 10) ++tokPos; // '\r\n'
                case 10: // ' \n'
                  if (options.locations) { tokLineStart = tokPos; ++tokCurLine; }
                  return "";
                default: return String.fromCharCode(ch);
              }
            }
          }
        
          // Used to read character escape sequences ('\x', '\u', '\U').
        
          function readHexChar(len) {
            var n = readInt(16, len);
            if (n === null) raise(tokStart, "Bad character escape sequence");
            return n;
          }
        
          // Used to signal to callers of `readWord1` whether the word
          // contained any escape sequences. This is needed because words with
          // escape sequences must not be interpreted as keywords.
        
          var containsEsc;
        
          // Read an identifier, and return it as a string. Sets `containsEsc`
          // to whether the word contained a '\u' escape.
          //
          // Only builds up the word character-by-character when it actually
          // containeds an escape, as a micro-optimization.
        
          function readWord1() {
            containsEsc = false;
            var word, first = true, start = tokPos;
            for (;;) {
              var ch = input.charCodeAt(tokPos);
              if (isIdentifierChar(ch)) {
                if (containsEsc) word += input.charAt(tokPos);
                ++tokPos;
              } else if (ch === 92) { // "\"
                if (!containsEsc) word = input.slice(start, tokPos);
                containsEsc = true;
                if (input.charCodeAt(++tokPos) != 117) // "u"
                  raise(tokPos, "Expecting Unicode escape sequence \\uXXXX");
                ++tokPos;
                var esc = readHexChar(4);
                var escStr = String.fromCharCode(esc);
                if (!escStr) raise(tokPos - 1, "Invalid Unicode escape");
                if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc)))
                  raise(tokPos - 4, "Invalid Unicode escape");
                word += escStr;
              } else {
                break;
              }
              first = false;
            }
            return containsEsc ? word : input.slice(start, tokPos);
          }
        
          // Read an identifier or keyword token. Will check for reserved
          // words when necessary.
        
          function readWord() {
            var word = readWord1();
            var type = _name;
            if (!containsEsc && isKeyword(word))
              type = keywordTypes[word];
            return finishToken(type, word);
          }
        
          // ## Parser
        
          // A recursive descent parser operates by defining functions for all
          // syntactic elements, and recursively calling those, each function
          // advancing the input stream and returning an AST node. Precedence
          // of constructs (for example, the fact that `!x[1]` means `!(x[1])`
          // instead of `(!x)[1]` is handled by the fact that the parser
          // function that parses unary prefix operators is called first, and
          // in turn calls the function that parses `[]` subscripts — that
          // way, it'll receive the node for `x[1]` already parsed, and wraps
          // *that* in the unary operator node.
          //
          // Acorn uses an [operator precedence parser][opp] to handle binary
          // operator precedence, because it is much more compact than using
          // the technique outlined above, which uses different, nesting
          // functions to specify precedence, for all of the ten binary
          // precedence levels that JavaScript defines.
          //
          // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
        
          // ### Parser utilities
        
          // Continue to the next token.
        
          function next() {
            lastStart = tokStart;
            lastEnd = tokEnd;
            lastEndLoc = tokEndLoc;
            readToken();
          }
        
          // Enter strict mode. Re-reads the next token to please pedantic
          // tests ("use strict"; 010; -- should fail).
        
          function setStrict(strct) {
            strict = strct;
            tokPos = tokStart;
            if (options.locations) {
              while (tokPos < tokLineStart) {
                tokLineStart = input.lastIndexOf("\n", tokLineStart - 2) + 1;
                --tokCurLine;
              }
            }
            skipSpace();
            readToken();
          }
        
          // Start an AST node, attaching a start offset.
        
          function Node() {
            this.type = null;
            this.start = tokStart;
            this.end = null;
          }
        
          exports.Node = Node;
        
          function SourceLocation() {
            this.start = tokStartLoc;
            this.end = null;
            if (sourceFile !== null) this.source = sourceFile;
          }
        
          function startNode() {
            var node = new Node();
            if (options.locations)
              node.loc = new SourceLocation();
            if (options.directSourceFile)
              node.sourceFile = options.directSourceFile;
            if (options.ranges)
              node.range = [tokStart, 0];
            return node;
          }
        
          // Sometimes, a node is only started *after* the token stream passed
          // its start position. The functions below help storing a position
          // and creating a node from a previous position.
        
          function storeCurrentPos() {
            return options.locations ? [tokStart, tokStartLoc] : tokStart;
          }
        
          function startNodeAt(pos) {
            var node = new Node(), start = pos;
            if (options.locations) {
              node.loc = new SourceLocation();
              node.loc.start = start[1];
              start = pos[0];
            }
            node.start = start;
            if (options.directSourceFile)
              node.sourceFile = options.directSourceFile;
            if (options.ranges)
              node.range = [start, 0];
        
            return node;
          }
        
          // Finish an AST node, adding `type` and `end` properties.
        
          function finishNode(node, type) {
            node.type = type;
            node.end = lastEnd;
            if (options.locations)
              node.loc.end = lastEndLoc;
            if (options.ranges)
              node.range[1] = lastEnd;
            return node;
          }
        
          // Test whether a statement node is the string literal `"use strict"`.
        
          function isUseStrict(stmt) {
            return options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" &&
              stmt.expression.type === "Literal" && stmt.expression.value === "use strict";
          }
        
          // Predicate that tests whether the next token is of the given
          // type, and if yes, consumes it as a side effect.
        
          function eat(type) {
            if (tokType === type) {
              next();
              return true;
            } else {
              return false;
            }
          }
        
          // Test whether a semicolon can be inserted at the current position.
        
          function canInsertSemicolon() {
            return !options.strictSemicolons &&
              (tokType === _eof || tokType === _braceR || newline.test(input.slice(lastEnd, tokStart)));
          }
        
          // Consume a semicolon, or, failing that, see if we are allowed to
          // pretend that there is a semicolon at this position.
        
          function semicolon() {
            if (!eat(_semi) && !canInsertSemicolon()) unexpected();
          }
        
          // Expect a token of a given type. If found, consume it, otherwise,
          // raise an unexpected token error.
        
          function expect(type) {
            eat(type) || unexpected();
          }
        
          // Raise an unexpected token error.
        
          function unexpected(pos) {
            raise(pos != null ? pos : tokStart, "Unexpected token");
          }
        
          // Checks if hash object has a property.
        
          function has(obj, propName) {
            return Object.prototype.hasOwnProperty.call(obj, propName);
          }
          // Convert existing expression atom to assignable pattern
          // if possible.
        
          function toAssignable(node, allowSpread, checkType) {
            if (options.ecmaVersion >= 6 && node) {
              switch (node.type) {
                case "Identifier":
                case "MemberExpression":
                  break;
        
                case "ObjectExpression":
                  node.type = "ObjectPattern";
                  for (var i = 0; i < node.properties.length; i++) {
                    var prop = node.properties[i];
                    if (prop.kind !== "init") unexpected(prop.key.start);
                    toAssignable(prop.value, false, checkType);
                  }
                  break;
        
                case "ArrayExpression":
                  node.type = "ArrayPattern";
                  for (var i = 0, lastI = node.elements.length - 1; i <= lastI; i++) {
                    toAssignable(node.elements[i], i === lastI, checkType);
                  }
                  break;
        
                case "SpreadElement":
                  if (allowSpread) {
                    toAssignable(node.argument, false, checkType);
                    checkSpreadAssign(node.argument);
                  } else {
                    unexpected(node.start);
                  }
                  break;
        
                default:
                  if (checkType) unexpected(node.start);
              }
            }
            return node;
          }
        
          // Checks if node can be assignable spread argument.
        
          function checkSpreadAssign(node) {
            if (node.type !== "Identifier" && node.type !== "ArrayPattern")
              unexpected(node.start);
          }
        
          // Verify that argument names are not repeated, and it does not
          // try to bind the words `eval` or `arguments`.
        
          function checkFunctionParam(param, nameHash) {
            switch (param.type) {
              case "Identifier":
                if (isStrictReservedWord(param.name) || isStrictBadIdWord(param.name))
                  raise(param.start, "Defining '" + param.name + "' in strict mode");
                if (has(nameHash, param.name))
                  raise(param.start, "Argument name clash in strict mode");
                nameHash[param.name] = true;
                break;
        
              case "ObjectPattern":
                for (var i = 0; i < param.properties.length; i++)
                  checkFunctionParam(param.properties[i].value, nameHash);
                break;
        
              case "ArrayPattern":
                for (var i = 0; i < param.elements.length; i++) {
                  var elem = param.elements[i];
                  if (elem) checkFunctionParam(elem, nameHash);
                }
                break;
            }
          }
        
          // Check if property name clashes with already added.
          // Object/class getters and setters are not allowed to clash —
          // either with each other or with an init property — and in
          // strict mode, init properties are also not allowed to be repeated.
        
          function checkPropClash(prop, propHash) {
            if (options.ecmaVersion >= 6) return;
            var key = prop.key, name;
            switch (key.type) {
              case "Identifier": name = key.name; break;
              case "Literal": name = String(key.value); break;
              default: return;
            }
            var kind = prop.kind || "init", other;
            if (has(propHash, name)) {
              other = propHash[name];
              var isGetSet = kind !== "init";
              if ((strict || isGetSet) && other[kind] || !(isGetSet ^ other.init))
                raise(key.start, "Redefinition of property");
            } else {
              other = propHash[name] = {
                init: false,
                get: false,
                set: false
              };
            }
            other[kind] = true;
          }
        
          // Verify that a node is an lval — something that can be assigned
          // to.
        
          function checkLVal(expr, isBinding) {
            switch (expr.type) {
              case "Identifier":
                if (strict && (isStrictBadIdWord(expr.name) || isStrictReservedWord(expr.name)))
                  raise(expr.start, isBinding
                    ? "Binding " + expr.name + " in strict mode"
                    : "Assigning to " + expr.name + " in strict mode"
                  );
                break;
        
              case "MemberExpression":
                if (!isBinding) break;
        
              case "ObjectPattern":
                for (var i = 0; i < expr.properties.length; i++)
                  checkLVal(expr.properties[i].value, isBinding);
                break;
        
              case "ArrayPattern":
                for (var i = 0; i < expr.elements.length; i++) {
                  var elem = expr.elements[i];
                  if (elem) checkLVal(elem, isBinding);
                }
                break;
        
              case "SpreadElement":
                break;
        
              case "ParenthesizedExpression":
                checkLVal(expr.expression);
                break;
        
              default:
                raise(expr.start, "Assigning to rvalue");
            }
          }
        
          // ### Statement parsing
        
          // Parse a program. Initializes the parser, reads any number of
          // statements, and wraps them in a Program node.  Optionally takes a
          // `program` argument.  If present, the statements will be appended
          // to its body instead of creating a new node.
        
          function parseTopLevel(program) {
            var node = program || startNode(), first = true;
            if (!program) node.body = [];
            while (tokType !== _eof) {
              var stmt = parseStatement();
              node.body.push(stmt);
              if (first && isUseStrict(stmt)) setStrict(true);
              first = false;
            }
            return finishNode(node, "Program");
          }
        
          var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
        
          // Parse a single statement.
          //
          // If expecting a statement and finding a slash operator, parse a
          // regular expression literal. This is to handle cases like
          // `if (foo) /blah/.exec(foo);`, where looking at the previous token
          // does not help.
        
          function parseStatement() {
            if (tokType === _slash || tokType === _assign && tokVal == "/=")
              readToken(true);
        
            var starttype = tokType, node = startNode();
        
            // Most types of statements are recognized by the keyword they
            // start with. Many are trivial to parse, some require a bit of
            // complexity.
        
            switch (starttype) {
            case _break: case _continue: return parseBreakContinueStatement(node, starttype.keyword);
            case _debugger: return parseDebuggerStatement(node);
            case _do: return parseDoStatement(node);
            case _for: return parseForStatement(node);
            case _function: return parseFunctionStatement(node);
            case _class: return parseClass(node, true);
            case _if: return parseIfStatement(node);
            case _return: return parseReturnStatement(node);
            case _switch: return parseSwitchStatement(node);
            case _throw: return parseThrowStatement(node);
            case _try: return parseTryStatement(node);
            case _var: case _let: case _const: return parseVarStatement(node, starttype.keyword);
            case _while: return parseWhileStatement(node);
            case _with: return parseWithStatement(node);
            case _braceL: return parseBlock(); // no point creating a function for this
            case _semi: return parseEmptyStatement(node);
            case _export: return parseExport(node);
            case _import: return parseImport(node);
        
              // If the statement does not start with a statement keyword or a
              // brace, it's an ExpressionStatement or LabeledStatement. We
              // simply start parsing an expression, and afterwards, if the
              // next token is a colon and the expression was a simple
              // Identifier node, we switch to interpreting it as a label.
            default:
              var maybeName = tokVal, expr = parseExpression();
              if (starttype === _name && expr.type === "Identifier" && eat(_colon))
                return parseLabeledStatement(node, maybeName, expr);
              else return parseExpressionStatement(node, expr);
            }
          }
        
          function parseBreakContinueStatement(node, keyword) {
            var isBreak = keyword == "break";
            next();
            if (eat(_semi) || canInsertSemicolon()) node.label = null;
            else if (tokType !== _name) unexpected();
            else {
              node.label = parseIdent();
              semicolon();
            }
        
            // Verify that there is an actual destination to break or
            // continue to.
            for (var i = 0; i < labels.length; ++i) {
              var lab = labels[i];
              if (node.label == null || lab.name === node.label.name) {
                if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
                if (node.label && isBreak) break;
              }
            }
            if (i === labels.length) raise(node.start, "Unsyntactic " + keyword);
            return finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
          }
        
          function parseDebuggerStatement(node) {
            next();
            semicolon();
            return finishNode(node, "DebuggerStatement");
          }
        
          function parseDoStatement(node) {
            next();
            labels.push(loopLabel);
            node.body = parseStatement();
            labels.pop();
            expect(_while);
            node.test = parseParenExpression();
            semicolon();
            return finishNode(node, "DoWhileStatement");
          }
        
          // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
          // loop is non-trivial. Basically, we have to parse the init `var`
          // statement or expression, disallowing the `in` operator (see
          // the second parameter to `parseExpression`), and then check
          // whether the next token is `in` or `of`. When there is no init
          // part (semicolon immediately after the opening parenthesis), it
          // is a regular `for` loop.
        
          function parseForStatement(node) {
            next();
            labels.push(loopLabel);
            expect(_parenL);
            if (tokType === _semi) return parseFor(node, null);
            if (tokType === _var || tokType === _let) {
              var init = startNode(), varKind = tokType.keyword, isLet = tokType === _let;
              next();
              parseVar(init, true, varKind);
              finishNode(init, "VariableDeclaration");
              if ((tokType === _in || (options.ecmaVersion >= 6 && tokType === _name && tokVal === "of")) && init.declarations.length === 1 &&
                  !(isLet && init.declarations[0].init))
                return parseForIn(node, init);
              return parseFor(node, init);
            }
            var init = parseExpression(false, true);
            if (tokType === _in || (options.ecmaVersion >= 6 && tokType === _name && tokVal === "of")) {
              checkLVal(init);
              return parseForIn(node, init);
            }
            return parseFor(node, init);
          }
        
          function parseFunctionStatement(node) {
            next();
            return parseFunction(node, true);
          }
        
          function parseIfStatement(node) {
            next();
            node.test = parseParenExpression();
            node.consequent = parseStatement();
            node.alternate = eat(_else) ? parseStatement() : null;
            return finishNode(node, "IfStatement");
          }
        
          function parseReturnStatement(node) {
            if (!inFunction && !options.allowReturnOutsideFunction)
              raise(tokStart, "'return' outside of function");
            next();
        
            // In `return` (and `break`/`continue`), the keywords with
            // optional arguments, we eagerly look for a semicolon or the
            // possibility to insert one.
        
            if (eat(_semi) || canInsertSemicolon()) node.argument = null;
            else { node.argument = parseExpression(); semicolon(); }
            return finishNode(node, "ReturnStatement");
          }
        
          function parseSwitchStatement(node) {
            next();
            node.discriminant = parseParenExpression();
            node.cases = [];
            expect(_braceL);
            labels.push(switchLabel);
        
            // Statements under must be grouped (by label) in SwitchCase
            // nodes. `cur` is used to keep the node that we are currently
            // adding statements to.
        
            for (var cur, sawDefault; tokType != _braceR;) {
              if (tokType === _case || tokType === _default) {
                var isCase = tokType === _case;
                if (cur) finishNode(cur, "SwitchCase");
                node.cases.push(cur = startNode());
                cur.consequent = [];
                next();
                if (isCase) cur.test = parseExpression();
                else {
                  if (sawDefault) raise(lastStart, "Multiple default clauses"); sawDefault = true;
                  cur.test = null;
                }
                expect(_colon);
              } else {
                if (!cur) unexpected();
                cur.consequent.push(parseStatement());
              }
            }
            if (cur) finishNode(cur, "SwitchCase");
            next(); // Closing brace
            labels.pop();
            return finishNode(node, "SwitchStatement");
          }
        
          function parseThrowStatement(node) {
            next();
            if (newline.test(input.slice(lastEnd, tokStart)))
              raise(lastEnd, "Illegal newline after throw");
            node.argument = parseExpression();
            semicolon();
            return finishNode(node, "ThrowStatement");
          }
        
          function parseTryStatement(node) {
            next();
            node.block = parseBlock();
            node.handler = null;
            if (tokType === _catch) {
              var clause = startNode();
              next();
              expect(_parenL);
              clause.param = parseIdent();
              if (strict && isStrictBadIdWord(clause.param.name))
                raise(clause.param.start, "Binding " + clause.param.name + " in strict mode");
              expect(_parenR);
              clause.guard = null;
              clause.body = parseBlock();
              node.handler = finishNode(clause, "CatchClause");
            }
            node.guardedHandlers = empty;
            node.finalizer = eat(_finally) ? parseBlock() : null;
            if (!node.handler && !node.finalizer)
              raise(node.start, "Missing catch or finally clause");
            return finishNode(node, "TryStatement");
          }
        
          function parseVarStatement(node, kind) {
            next();
            parseVar(node, false, kind);
            semicolon();
            return finishNode(node, "VariableDeclaration");
          }
        
          function parseWhileStatement(node) {
            next();
            node.test = parseParenExpression();
            labels.push(loopLabel);
            node.body = parseStatement();
            labels.pop();
            return finishNode(node, "WhileStatement");
          }
        
          function parseWithStatement(node) {
            if (strict) raise(tokStart, "'with' in strict mode");
            next();
            node.object = parseParenExpression();
            node.body = parseStatement();
            return finishNode(node, "WithStatement");
          }
        
          function parseEmptyStatement(node) {
            next();
            return finishNode(node, "EmptyStatement");
          }
        
          function parseLabeledStatement(node, maybeName, expr) {
            for (var i = 0; i < labels.length; ++i)
              if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared");
            var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null;
            labels.push({name: maybeName, kind: kind});
            node.body = parseStatement();
            labels.pop();
            node.label = expr;
            return finishNode(node, "LabeledStatement");
          }
        
          function parseExpressionStatement(node, expr) {
            node.expression = expr;
            semicolon();
            return finishNode(node, "ExpressionStatement");
          }
        
          // Used for constructs like `switch` and `if` that insist on
          // parentheses around their expression.
        
          function parseParenExpression() {
            expect(_parenL);
            var val = parseExpression();
            expect(_parenR);
            return val;
          }
        
          // Parse a semicolon-enclosed block of statements, handling `"use
          // strict"` declarations when `allowStrict` is true (used for
          // function bodies).
        
          function parseBlock(allowStrict) {
            var node = startNode(), first = true, oldStrict;
            node.body = [];
            expect(_braceL);
            while (!eat(_braceR)) {
              var stmt = parseStatement();
              node.body.push(stmt);
              if (first && allowStrict && isUseStrict(stmt)) {
                oldStrict = strict;
                setStrict(strict = true);
              }
              first = false;
            }
            if (oldStrict === false) setStrict(false);
            return finishNode(node, "BlockStatement");
          }
        
          // Parse a regular `for` loop. The disambiguation code in
          // `parseStatement` will already have parsed the init statement or
          // expression.
        
          function parseFor(node, init) {
            node.init = init;
            expect(_semi);
            node.test = tokType === _semi ? null : parseExpression();
            expect(_semi);
            node.update = tokType === _parenR ? null : parseExpression();
            expect(_parenR);
            node.body = parseStatement();
            labels.pop();
            return finishNode(node, "ForStatement");
          }
        
          // Parse a `for`/`in` and `for`/`of` loop, which are almost
          // same from parser's perspective.
        
          function parseForIn(node, init) {
            var type = tokType === _in ? "ForInStatement" : "ForOfStatement";
            next();
            node.left = init;
            node.right = parseExpression();
            expect(_parenR);
            node.body = parseStatement();
            labels.pop();
            return finishNode(node, type);
          }
        
          // Parse a list of variable declarations.
        
          function parseVar(node, noIn, kind) {
            node.declarations = [];
            node.kind = kind;
            for (;;) {
              var decl = startNode();
              decl.id = options.ecmaVersion >= 6 ? toAssignable(parseExprAtom()) : parseIdent();
              checkLVal(decl.id, true);
              decl.init = eat(_eq) ? parseExpression(true, noIn) : (kind === _const.keyword ? unexpected() : null);
              node.declarations.push(finishNode(decl, "VariableDeclarator"));
              if (!eat(_comma)) break;
            }
            return node;
          }
        
          // ### Expression parsing
        
          // These nest, from the most general expression type at the top to
          // 'atomic', nondivisible expression types at the bottom. Most of
          // the functions will simply let the function(s) below them parse,
          // and, *if* the syntactic construct they handle is present, wrap
          // the AST node that the inner parser gave them in another node.
        
          // Parse a full expression. The arguments are used to forbid comma
          // sequences (in argument lists, array literals, or object literals)
          // or the `in` operator (in for loops initalization expressions).
        
          function parseExpression(noComma, noIn) {
            var start = storeCurrentPos();
            var expr = parseMaybeAssign(noIn);
            if (!noComma && tokType === _comma) {
              var node = startNodeAt(start);
              node.expressions = [expr];
              while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn));
              return finishNode(node, "SequenceExpression");
            }
            return expr;
          }
        
          // Parse an assignment expression. This includes applications of
          // operators like `+=`.
        
          function parseMaybeAssign(noIn) {
            var start = storeCurrentPos();
            var left = parseMaybeConditional(noIn);
            if (tokType.isAssign) {
              var node = startNodeAt(start);
              node.operator = tokVal;
              node.left = tokType === _eq ? toAssignable(left) : left;
              checkLVal(left);
              next();
              node.right = parseMaybeAssign(noIn);
              return finishNode(node, "AssignmentExpression");
            }
            return left;
          }
        
          // Parse a ternary conditional (`?:`) operator.
        
          function parseMaybeConditional(noIn) {
            var start = storeCurrentPos();
            var expr = parseExprOps(noIn);
            if (eat(_question)) {
              var node = startNodeAt(start);
              node.test = expr;
              node.consequent = parseExpression(true);
              expect(_colon);
              node.alternate = parseExpression(true, noIn);
              return finishNode(node, "ConditionalExpression");
            }
            return expr;
          }
        
          // Start the precedence parser.
        
          function parseExprOps(noIn) {
            var start = storeCurrentPos();
            return parseExprOp(parseMaybeUnary(), start, -1, noIn);
          }
        
          // Parse binary operators with the operator precedence parsing
          // algorithm. `left` is the left-hand side of the operator.
          // `minPrec` provides context that allows the function to stop and
          // defer further parser to one of its callers when it encounters an
          // operator that has a lower precedence than the set it is parsing.
        
          function parseExprOp(left, leftStart, minPrec, noIn) {
            var prec = tokType.binop;
            if (prec != null && (!noIn || tokType !== _in)) {
              if (prec > minPrec) {
                var node = startNodeAt(leftStart);
                node.left = left;
                node.operator = tokVal;
                var op = tokType;
                next();
                var start = storeCurrentPos();
                node.right = parseExprOp(parseMaybeUnary(), start, prec, noIn);
                finishNode(node, (op === _logicalOR || op === _logicalAND) ? "LogicalExpression" : "BinaryExpression");
                return parseExprOp(node, leftStart, minPrec, noIn);
              }
            }
            return left;
          }
        
          // Parse unary operators, both prefix and postfix.
        
          function parseMaybeUnary() {
            if (tokType.prefix) {
              var node = startNode(), update = tokType.isUpdate;
              node.operator = tokVal;
              node.prefix = true;
              tokRegexpAllowed = true;
              next();
              node.argument = parseMaybeUnary();
              if (update) checkLVal(node.argument);
              else if (strict && node.operator === "delete" &&
                       node.argument.type === "Identifier")
                raise(node.start, "Deleting local variable in strict mode");
              return finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
            }
            var start = storeCurrentPos();
            var expr = parseExprSubscripts();
            while (tokType.postfix && !canInsertSemicolon()) {
              var node = startNodeAt(start);
              node.operator = tokVal;
              node.prefix = false;
              node.argument = expr;
              checkLVal(expr);
              next();
              expr = finishNode(node, "UpdateExpression");
            }
            return expr;
          }
        
          // Parse call, dot, and `[]`-subscript expressions.
        
          function parseExprSubscripts() {
            var start = storeCurrentPos();
            return parseSubscripts(parseExprAtom(), start);
          }
        
          function parseSubscripts(base, start, noCalls) {
            if (eat(_dot)) {
              var node = startNodeAt(start);
              node.object = base;
              node.property = parseIdent(true);
              node.computed = false;
              return parseSubscripts(finishNode(node, "MemberExpression"), start, noCalls);
            } else if (eat(_bracketL)) {
              var node = startNodeAt(start);
              node.object = base;
              node.property = parseExpression();
              node.computed = true;
              expect(_bracketR);
              return parseSubscripts(finishNode(node, "MemberExpression"), start, noCalls);
            } else if (!noCalls && eat(_parenL)) {
              var node = startNodeAt(start);
              node.callee = base;
              node.arguments = parseExprList(_parenR, false);
              return parseSubscripts(finishNode(node, "CallExpression"), start, noCalls);
            } else if (tokType === _bquote) {
              var node = startNodeAt(start);
              node.tag = base;
              node.quasi = parseTemplate();
              return parseSubscripts(finishNode(node, "TaggedTemplateExpression"), start, noCalls);
            } return base;
          }
        
          // Parse an atomic expression — either a single token that is an
          // expression, an expression started by a keyword like `function` or
          // `new`, or an expression wrapped in punctuation like `()`, `[]`,
          // or `{}`.
        
          function parseExprAtom() {
            switch (tokType) {
            case _this:
              var node = startNode();
              next();
              return finishNode(node, "ThisExpression");
        
            case _yield:
              if (inGenerator) return parseYield();
        
            case _name:
              var start = storeCurrentPos();
              var id = parseIdent(tokType !== _name);
              if (eat(_arrow)) {
                return parseArrowExpression(startNodeAt(start), [id]);
              }
              return id;
        
            case _regexp:
              var node = startNode();
              node.regex = {pattern: tokVal.pattern, flags: tokVal.flags};
              node.value = tokVal.value;
              node.raw = input.slice(tokStart, tokEnd);
              next();
              return finishNode(node, "Literal");
        
            case _num: case _string:
              var node = startNode();
              node.value = tokVal;
              node.raw = input.slice(tokStart, tokEnd);
              next();
              return finishNode(node, "Literal");
        
            case _null: case _true: case _false:
              var node = startNode();
              node.value = tokType.atomValue;
              node.raw = tokType.keyword;
              next();
              return finishNode(node, "Literal");
        
            case _parenL:
              var start = storeCurrentPos();
              var tokStartLoc1 = tokStartLoc, tokStart1 = tokStart, val, exprList;
              next();
              // check whether this is generator comprehension or regular expression
              if (options.ecmaVersion >= 7 && tokType === _for) {
                val = parseComprehension(startNodeAt(start), true);
              } else {
                var oldParenL = ++metParenL;
                if (tokType !== _parenR) {
                  val = parseExpression();
                  exprList = val.type === "SequenceExpression" ? val.expressions : [val];
                } else {
                  exprList = [];
                }
                expect(_parenR);
                // if '=>' follows '(...)', convert contents to arguments
                if (metParenL === oldParenL && eat(_arrow)) {
                  val = parseArrowExpression(startNodeAt(start), exprList);
                } else {
                  // forbid '()' before everything but '=>'
                  if (!val) unexpected(lastStart);
                  // forbid '...' in sequence expressions
                  if (options.ecmaVersion >= 6) {
                    for (var i = 0; i < exprList.length; i++) {
                      if (exprList[i].type === "SpreadElement") unexpected();
                    }
                  }
        
                  if (options.preserveParens) {
                    var par = startNodeAt(start);
                    par.expression = val;
                    val = finishNode(par, "ParenthesizedExpression");
                  }
                }
              }
              return val;
        
            case _bracketL:
              var node = startNode();
              next();
              // check whether this is array comprehension or regular array
              if (options.ecmaVersion >= 7 && tokType === _for) {
                return parseComprehension(node, false);
              }
              node.elements = parseExprList(_bracketR, true, true);
              return finishNode(node, "ArrayExpression");
        
            case _braceL:
              return parseObj();
        
            case _function:
              var node = startNode();
              next();
              return parseFunction(node, false);
        
            case _class:
              return parseClass(startNode(), false);
        
            case _new:
              return parseNew();
        
            case _ellipsis:
              return parseSpread();
        
            case _bquote:
              return parseTemplate();
        
            default:
              unexpected();
            }
          }
        
          // New's precedence is slightly tricky. It must allow its argument
          // to be a `[]` or dot subscript expression, but not a call — at
          // least, not without wrapping it in parentheses. Thus, it uses the
        
          function parseNew() {
            var node = startNode();
            next();
            var start = storeCurrentPos();
            node.callee = parseSubscripts(parseExprAtom(), start, true);
            if (eat(_parenL)) node.arguments = parseExprList(_parenR, false);
            else node.arguments = empty;
            return finishNode(node, "NewExpression");
          }
        
          // Parse spread element '...expr'
        
          function parseSpread() {
            var node = startNode();
            next();
            node.argument = parseExpression(true);
            return finishNode(node, "SpreadElement");
          }
        
          // Parse template expression.
        
          function parseTemplate() {
            var node = startNode();
            node.expressions = [];
            node.quasis = [];
            inTemplate = true;
            next();
            for (;;) {
              var elem = startNode();
              elem.value = {cooked: tokVal, raw: input.slice(tokStart, tokEnd)};
              elem.tail = false;
              next();
              node.quasis.push(finishNode(elem, "TemplateElement"));
              if (tokType === _bquote) { // '`', end of template
                elem.tail = true;
                break;
              }
              inTemplate = false;
              expect(_dollarBraceL);
              node.expressions.push(parseExpression());
              inTemplate = true;
              // hack to include previously skipped space
              tokPos = tokEnd;
              expect(_braceR);
            }
            inTemplate = false;
            next();
            return finishNode(node, "TemplateLiteral");
          }
        
          // Parse an object literal.
        
          function parseObj() {
            var node = startNode(), first = true, propHash = {};
            node.properties = [];
            next();
            while (!eat(_braceR)) {
              if (!first) {
                expect(_comma);
                if (options.allowTrailingCommas && eat(_braceR)) break;
              } else first = false;
        
              var prop = startNode(), isGenerator;
              if (options.ecmaVersion >= 6) {
                prop.method = false;
                prop.shorthand = false;
                isGenerator = eat(_star);
              }
              parsePropertyName(prop);
              if (eat(_colon)) {
                prop.value = parseExpression(true);
                prop.kind = "init";
              } else if (options.ecmaVersion >= 6 && tokType === _parenL) {
                prop.kind = "init";
                prop.method = true;
                prop.value = parseMethod(isGenerator);
              } else if (options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
                         (prop.key.name === "get" || prop.key.name === "set")) {
                if (isGenerator) unexpected();
                prop.kind = prop.key.name;
                parsePropertyName(prop);
                prop.value = parseMethod(false);
              } else if (options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
                prop.kind = "init";
                prop.value = prop.key;
                prop.shorthand = true;
              } else unexpected();
        
              checkPropClash(prop, propHash);
              node.properties.push(finishNode(prop, "Property"));
            }
            return finishNode(node, "ObjectExpression");
          }
        
          function parsePropertyName(prop) {
            if (options.ecmaVersion >= 6) {
              if (eat(_bracketL)) {
                prop.computed = true;
                prop.key = parseExpression();
                expect(_bracketR);
                return;
              } else {
                prop.computed = false;
              }
            }
            prop.key = (tokType === _num || tokType === _string) ? parseExprAtom() : parseIdent(true);
          }
        
          // Initialize empty function node.
        
          function initFunction(node) {
            node.id = null;
            node.params = [];
            if (options.ecmaVersion >= 6) {
              node.defaults = [];
              node.rest = null;
              node.generator = false;
            }
          }
        
          // Parse a function declaration or literal (depending on the
          // `isStatement` parameter).
        
          function parseFunction(node, isStatement, allowExpressionBody) {
            initFunction(node);
            if (options.ecmaVersion >= 6) {
              node.generator = eat(_star);
            }
            if (isStatement || tokType === _name) {
              node.id = parseIdent();
            }
            parseFunctionParams(node);
            parseFunctionBody(node, allowExpressionBody);
            return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
          }
        
          // Parse object or class method.
        
          function parseMethod(isGenerator) {
            var node = startNode();
            initFunction(node);
            parseFunctionParams(node);
            var allowExpressionBody;
            if (options.ecmaVersion >= 6) {
              node.generator = isGenerator;
              allowExpressionBody = true;
            } else {
              allowExpressionBody = false;
            }
            parseFunctionBody(node, allowExpressionBody);
            return finishNode(node, "FunctionExpression");
          }
        
          // Parse arrow function expression with given parameters.
        
          function parseArrowExpression(node, params) {
            initFunction(node);
        
            var defaults = node.defaults, hasDefaults = false;
        
            for (var i = 0, lastI = params.length - 1; i <= lastI; i++) {
              var param = params[i];
        
              if (param.type === "AssignmentExpression" && param.operator === "=") {
                hasDefaults = true;
                params[i] = param.left;
                defaults.push(param.right);
              } else {
                toAssignable(param, i === lastI, true);
                defaults.push(null);
                if (param.type === "SpreadElement") {
                  params.length--;
                  node.rest = param.argument;
                  break;
                }
              }
            }
        
            node.params = params;
            if (!hasDefaults) node.defaults = [];
        
            parseFunctionBody(node, true);
            return finishNode(node, "ArrowFunctionExpression");
          }
        
          // Parse function parameters.
        
          function parseFunctionParams(node) {
            var defaults = [], hasDefaults = false;
        
            expect(_parenL);
            for (;;) {
              if (eat(_parenR)) {
                break;
              } else if (options.ecmaVersion >= 6 && eat(_ellipsis)) {
                node.rest = toAssignable(parseExprAtom(), false, true);
                checkSpreadAssign(node.rest);
                expect(_parenR);
                defaults.push(null);
                break;
              } else {
                node.params.push(options.ecmaVersion >= 6 ? toAssignable(parseExprAtom(), false, true) : parseIdent());
                if (options.ecmaVersion >= 6) {
                  if (eat(_eq)) {
                    hasDefaults = true;
                    defaults.push(parseExpression(true));
                  } else {
                    defaults.push(null);
                  }
                }
                if (!eat(_comma)) {
                  expect(_parenR);
                  break;
                }
              }
            }
        
            if (hasDefaults) node.defaults = defaults;
          }
        
          // Parse function body and check parameters.
        
          function parseFunctionBody(node, allowExpression) {
            var isExpression = allowExpression && tokType !== _braceL;
        
            if (isExpression) {
              node.body = parseExpression(true);
              node.expression = true;
            } else {
              // Start a new scope with regard to labels and the `inFunction`
              // flag (restore them to their old value afterwards).
              var oldInFunc = inFunction, oldInGen = inGenerator, oldLabels = labels;
              inFunction = true; inGenerator = node.generator; labels = [];
              node.body = parseBlock(true);
              node.expression = false;
              inFunction = oldInFunc; inGenerator = oldInGen; labels = oldLabels;
            }
        
            // If this is a strict mode function, verify that argument names
            // are not repeated, and it does not try to bind the words `eval`
            // or `arguments`.
            if (strict || !isExpression && node.body.body.length && isUseStrict(node.body.body[0])) {
              var nameHash = {};
              if (node.id)
                checkFunctionParam(node.id, {});
              for (var i = 0; i < node.params.length; i++)
                checkFunctionParam(node.params[i], nameHash);
              if (node.rest)
                checkFunctionParam(node.rest, nameHash);
            }
          }
        
          // Parse a class declaration or literal (depending on the
          // `isStatement` parameter).
        
          function parseClass(node, isStatement) {
            next();
            node.id = tokType === _name ? parseIdent() : isStatement ? unexpected() : null;
            node.superClass = eat(_extends) ? parseExpression() : null;
            var classBody = startNode();
            classBody.body = [];
            expect(_braceL);
            while (!eat(_braceR)) {
              var method = startNode();
              if (tokType === _name && tokVal === "static") {
                next();
                method['static'] = true;
              } else {
                method['static'] = false;
              }
              var isGenerator = eat(_star);
              parsePropertyName(method);
              if (tokType !== _parenL && !method.computed && method.key.type === "Identifier" &&
                  (method.key.name === "get" || method.key.name === "set")) {
                if (isGenerator) unexpected();
                method.kind = method.key.name;
                parsePropertyName(method);
              } else {
                method.kind = "";
              }
              method.value = parseMethod(isGenerator);
              classBody.body.push(finishNode(method, "MethodDefinition"));
              eat(_semi);
            }
            node.body = finishNode(classBody, "ClassBody");
            return finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
          }
        
          // Parses a comma-separated list of expressions, and returns them as
          // an array. `close` is the token type that ends the list, and
          // `allowEmpty` can be turned on to allow subsequent commas with
          // nothing in between them to be parsed as `null` (which is needed
          // for array literals).
        
          function parseExprList(close, allowTrailingComma, allowEmpty) {
            var elts = [], first = true;
            while (!eat(close)) {
              if (!first) {
                expect(_comma);
                if (allowTrailingComma && options.allowTrailingCommas && eat(close)) break;
              } else first = false;
        
              if (allowEmpty && tokType === _comma) elts.push(null);
              else elts.push(parseExpression(true));
            }
            return elts;
          }
        
          // Parse the next token as an identifier. If `liberal` is true (used
          // when parsing properties), it will also convert keywords into
          // identifiers.
        
          function parseIdent(liberal) {
            var node = startNode();
            if (liberal && options.forbidReserved == "everywhere") liberal = false;
            if (tokType === _name) {
              if (!liberal &&
                  (options.forbidReserved &&
                   (options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(tokVal) ||
                   strict && isStrictReservedWord(tokVal)) &&
                  input.slice(tokStart, tokEnd).indexOf("\\") == -1)
                raise(tokStart, "The keyword '" + tokVal + "' is reserved");
              node.name = tokVal;
            } else if (liberal && tokType.keyword) {
              node.name = tokType.keyword;
            } else {
              unexpected();
            }
            tokRegexpAllowed = false;
            next();
            return finishNode(node, "Identifier");
          }
        
          // Parses module export declaration.
        
          function parseExport(node) {
            next();
            // export var|const|let|function|class ...;
            if (tokType === _var || tokType === _const || tokType === _let || tokType === _function || tokType === _class) {
              node.declaration = parseStatement();
              node['default'] = false;
              node.specifiers = null;
              node.source = null;
            } else
            // export default ...;
            if (eat(_default)) {
              node.declaration = parseExpression(true);
              node['default'] = true;
              node.specifiers = null;
              node.source = null;
              semicolon();
            } else {
              // export * from '...';
              // export { x, y as z } [from '...'];
              var isBatch = tokType === _star;
              node.declaration = null;
              node['default'] = false;
              node.specifiers = parseExportSpecifiers();
              if (tokType === _name && tokVal === "from") {
                next();
                node.source = tokType === _string ? parseExprAtom() : unexpected();
              } else {
                if (isBatch) unexpected();
                node.source = null;
              }
              semicolon();
            }
            return finishNode(node, "ExportDeclaration");
          }
        
          // Parses a comma-separated list of module exports.
        
          function parseExportSpecifiers() {
            var nodes = [], first = true;
            if (tokType === _star) {
              // export * from '...'
              var node = startNode();
              next();
              nodes.push(finishNode(node, "ExportBatchSpecifier"));
            } else {
              // export { x, y as z } [from '...']
              expect(_braceL);
              while (!eat(_braceR)) {
                if (!first) {
                  expect(_comma);
                  if (options.allowTrailingCommas && eat(_braceR)) break;
                } else first = false;
        
                var node = startNode();
                node.id = parseIdent();
                if (tokType === _name && tokVal === "as") {
                  next();
                  node.name = parseIdent(true);
                } else {
                  node.name = null;
                }
                nodes.push(finishNode(node, "ExportSpecifier"));
              }
            }
            return nodes;
          }
        
          // Parses import declaration.
        
          function parseImport(node) {
            next();
            // import '...';
            if (tokType === _string) {
              node.specifiers = [];
              node.source = parseExprAtom();
              node.kind = "";
            } else {
              node.specifiers = parseImportSpecifiers();
              if (tokType !== _name || tokVal !== "from") unexpected();
              next();
              node.source = tokType === _string ? parseExprAtom() : unexpected();
              // only for backward compatibility with Esprima's AST
              // (it doesn't support mixed default + named yet)
              node.kind = node.specifiers[0]['default'] ? "default" : "named";
            }
            semicolon();
            return finishNode(node, "ImportDeclaration");
          }
        
          // Parses a comma-separated list of module imports.
        
          function parseImportSpecifiers() {
            var nodes = [], first = true;
            if (tokType === _star) {
              var node = startNode();
              next();
              if (tokType !== _name || tokVal !== "as") unexpected();
              next();
              node.name = parseIdent();
              checkLVal(node.name, true);
              nodes.push(finishNode(node, "ImportBatchSpecifier"));
              return nodes;
            }
            if (tokType === _name) {
              // import defaultObj, { x, y as z } from '...'
              var node = startNode();
              node.id = parseIdent();
              checkLVal(node.id, true);
              node.name = null;
              node['default'] = true;
              nodes.push(finishNode(node, "ImportSpecifier"));
              if (!eat(_comma)) return nodes;
            }
            expect(_braceL);
            while (!eat(_braceR)) {
              if (!first) {
                expect(_comma);
                if (options.allowTrailingCommas && eat(_braceR)) break;
              } else first = false;
        
              var node = startNode();
              node.id = parseIdent(true);
              if (tokType === _name && tokVal === "as") {
                next();
                node.name = parseIdent();
              } else {
                node.name = null;
              }
              checkLVal(node.name || node.id, true);
              node['default'] = false;
              nodes.push(finishNode(node, "ImportSpecifier"));
            }
            return nodes;
          }
        
          // Parses yield expression inside generator.
        
          function parseYield() {
            var node = startNode();
            next();
            if (eat(_semi) || canInsertSemicolon()) {
              node.delegate = false;
              node.argument = null;
            } else {
              node.delegate = eat(_star);
              node.argument = parseExpression(true);
            }
            return finishNode(node, "YieldExpression");
          }
        
          // Parses array and generator comprehensions.
        
          function parseComprehension(node, isGenerator) {
            node.blocks = [];
            while (tokType === _for) {
              var block = startNode();
              next();
              expect(_parenL);
              block.left = toAssignable(parseExprAtom());
              checkLVal(block.left, true);
              if (tokType !== _name || tokVal !== "of") unexpected();
              next();
              // `of` property is here for compatibility with Esprima's AST
              // which also supports deprecated [for (... in ...) expr]
              block.of = true;
              block.right = parseExpression();
              expect(_parenR);
              node.blocks.push(finishNode(block, "ComprehensionBlock"));
            }
            node.filter = eat(_if) ? parseParenExpression() : null;
            node.body = parseExpression();
            expect(isGenerator ? _parenR : _bracketR);
            node.generator = isGenerator;
            return finishNode(node, "ComprehensionExpression");
          }
        
        });
        
      • acorn_loose.js
        // Acorn: Loose parser
        //
        // This module provides an alternative parser (`parse_dammit`) that
        // exposes that same interface as `parse`, but will try to parse
        // anything as JavaScript, repairing syntax error the best it can.
        // There are circumstances in which it will raise an error and give
        // up, but they are very rare. The resulting AST will be a mostly
        // valid JavaScript AST (as per the [Mozilla parser API][api], except
        // that:
        //
        // - Return outside functions is allowed
        //
        // - Label consistency (no conflicts, break only to existing labels)
        //   is not enforced.
        //
        // - Bogus Identifier nodes with a name of `"✖"` are inserted whenever
        //   the parser got too confused to return anything meaningful.
        //
        // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
        //
        // The expected use for this is to *first* try `acorn.parse`, and only
        // if that fails switch to `parse_dammit`. The loose parser might
        // parse badly indented code incorrectly, so **don't** use it as
        // your default parser.
        //
        // Quite a lot of acorn.js is duplicated here. The alternative was to
        // add a *lot* of extra cruft to that file, making it less readable
        // and slower. Copying and editing the code allowed me to make
        // invasive changes and simplifications without creating a complicated
        // tangle.
        
        (function(root, mod) {
          if (typeof exports == "object" && typeof module == "object") return mod(exports, require("./acorn")); // CommonJS
          if (typeof define == "function" && define.amd) return define(["exports", "./acorn"], mod); // AMD
          mod(root.acorn || (root.acorn = {}), root.acorn); // Plain browser env
        })(this, function(exports, acorn) {
          "use strict";
        
          var tt = acorn.tokTypes;
        
          var options, input, fetchToken, context;
        
          exports.parse_dammit = function(inpt, opts) {
            if (!opts) opts = {};
            input = String(inpt);
            if (/^#!.*/.test(input)) input = "//" + input.slice(2);
        
            options = opts;
            if (!opts.tabSize) opts.tabSize = 4;
            fetchToken = acorn.tokenize(input, opts);
            sourceFile = options.sourceFile || null;
            context = [];
            nextLineStart = 0;
            ahead.length = 0;
            next();
            return parseTopLevel();
          };
        
          var lastEnd, token = {start: 0, end: 0}, ahead = [];
          var curLineStart, nextLineStart, curIndent, lastEndLoc, sourceFile;
        
          function next() {
            lastEnd = token.end;
            if (options.locations)
              lastEndLoc = token.endLoc;
        
            if (ahead.length)
              token = ahead.shift();
            else
              token = readToken();
        
            if (token.start >= nextLineStart) {
              while (token.start >= nextLineStart) {
                curLineStart = nextLineStart;
                nextLineStart = lineEnd(curLineStart) + 1;
              }
              curIndent = indentationAfter(curLineStart);
            }
          }
        
          function readToken() {
            for (;;) {
              try {
                return fetchToken();
              } catch(e) {
                if (!(e instanceof SyntaxError)) throw e;
        
                // Try to skip some text, based on the error message, and then continue
                var msg = e.message, pos = e.raisedAt, replace = true;
                if (/unterminated/i.test(msg)) {
                  pos = lineEnd(e.pos + 1);
                  if (/string/.test(msg)) {
                    replace = {start: e.pos, end: pos, type: tt.string, value: input.slice(e.pos + 1, pos)};
                  } else if (/regular expr/i.test(msg)) {
                    var re = input.slice(e.pos, pos);
                    try { re = new RegExp(re); } catch(e) {}
                    replace = {start: e.pos, end: pos, type: tt.regexp, value: re};
                  } else {
                    replace = false;
                  }
                } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number/i.test(msg)) {
                  while (pos < input.length && !isSpace(input.charCodeAt(pos))) ++pos;
                } else if (/character escape|expected hexadecimal/i.test(msg)) {
                  while (pos < input.length) {
                    var ch = input.charCodeAt(pos++);
                    if (ch === 34 || ch === 39 || isNewline(ch)) break;
                  }
                } else if (/unexpected character/i.test(msg)) {
                  pos++;
                  replace = false;
                } else if (/regular expression/i.test(msg)) {
                  replace = true;
                } else {
                  throw e;
                }
                resetTo(pos);
                if (replace === true) replace = {start: pos, end: pos, type: tt.name, value: "✖"};
                if (replace) {
                  if (options.locations) {
                    replace.startLoc = acorn.getLineInfo(input, replace.start);
                    replace.endLoc = acorn.getLineInfo(input, replace.end);
                  }
                  return replace;
                }
              }
            }
          }
        
          function resetTo(pos) {
            for (;;) {
              try {
                var ch = input.charAt(pos - 1);
                var reAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) ||
                  /[enwfd]/.test(ch) && /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(input.slice(pos - 10, pos));
                return fetchToken.jumpTo(pos, reAllowed);
              } catch(e) {
                if (!(e instanceof SyntaxError && /unterminated comment/i.test(e.message))) throw e;
                pos = lineEnd(e.pos + 1);
                if (pos >= input.length) return;
              }
            }
          }
        
          function lookAhead(n) {
            while (n > ahead.length)
              ahead.push(readToken());
            return ahead[n-1];
          }
        
          var newline = /[\n\r\u2028\u2029]/;
        
          function isNewline(ch) {
            return ch === 10 || ch === 13 || ch === 8232 || ch === 8329;
          }
          function isSpace(ch) {
            return (ch < 14 && ch > 8) || ch === 32 || ch === 160 || isNewline(ch);
          }
        
          function pushCx() {
            context.push(curIndent);
          }
          function popCx() {
            curIndent = context.pop();
          }
        
          function lineEnd(pos) {
            while (pos < input.length && !isNewline(input.charCodeAt(pos))) ++pos;
            return pos;
          }
          function indentationAfter(pos) {
            for (var count = 0;; ++pos) {
              var ch = input.charCodeAt(pos);
              if (ch === 32) ++count;
              else if (ch === 9) count += options.tabSize;
              else return count;
            }
          }
        
          function closes(closeTok, indent, line, blockHeuristic) {
            if (token.type === closeTok || token.type === tt.eof) return true;
            if (line != curLineStart && curIndent < indent && tokenStartsLine() &&
                (!blockHeuristic || nextLineStart >= input.length ||
                 indentationAfter(nextLineStart) < indent)) return true;
            return false;
          }
        
          function tokenStartsLine() {
            for (var p = token.start - 1; p >= curLineStart; --p) {
              var ch = input.charCodeAt(p);
              if (ch !== 9 && ch !== 32) return false;
            }
            return true;
          }
        
          function Node(start) {
            this.type = null;
            this.start = start;
            this.end = null;
          }
          Node.prototype = acorn.Node.prototype;
        
          function SourceLocation(start) {
            this.start = start || token.startLoc || {line: 1, column: 0};
            this.end = null;
            if (sourceFile !== null) this.source = sourceFile;
          }
        
          function startNode() {
            var node = new Node(token.start);
            if (options.locations)
              node.loc = new SourceLocation();
            if (options.directSourceFile)
              node.sourceFile = options.directSourceFile;
            if (options.ranges)
              node.range = [token.start, 0];
            return node;
          }
        
          function storeCurrentPos() {
            return options.locations ? [token.start, token.startLoc] : token.start;
          }
        
          function startNodeAt(pos) {
            var node;
            if (options.locations) {
              node = new Node(pos[0]);
              node.loc = new SourceLocation(pos[1]);
            } else {
              node = new Node(pos);
            }
            if (options.directSourceFile)
              node.sourceFile = options.directSourceFile;
            if (options.ranges)
              node.range = [pos[0], 0];
            return node;
          }
        
          function finishNode(node, type) {
            node.type = type;
            node.end = lastEnd;
            if (options.locations)
              node.loc.end = lastEndLoc;
            if (options.ranges)
              node.range[1] = lastEnd;
            return node;
          }
        
          function dummyIdent() {
            var dummy = startNode();
            dummy.name = "✖";
            return finishNode(dummy, "Identifier");
          }
          function isDummy(node) { return node.name == "✖"; }
        
          function eat(type) {
            if (token.type === type) {
              next();
              return true;
            }
          }
        
          function canInsertSemicolon() {
            return (token.type === tt.eof || token.type === tt.braceR || newline.test(input.slice(lastEnd, token.start)));
          }
          function semicolon() {
            eat(tt.semi);
          }
        
          function expect(type) {
            if (eat(type)) return true;
            if (lookAhead(1).type == type) {
              next(); next();
              return true;
            }
            if (lookAhead(2).type == type) {
              next(); next(); next();
              return true;
            }
          }
        
          function checkLVal(expr) {
            if (expr.type === "Identifier" || expr.type === "MemberExpression") return expr;
            return dummyIdent();
          }
        
          function parseTopLevel() {
            var node = startNode();
            node.body = [];
            while (token.type !== tt.eof) node.body.push(parseStatement());
            return finishNode(node, "Program");
          }
        
          function parseStatement() {
            var starttype = token.type, node = startNode();
        
            switch (starttype) {
            case tt._break: case tt._continue:
              next();
              var isBreak = starttype === tt._break;
              node.label = token.type === tt.name ? parseIdent() : null;
              semicolon();
              return finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
        
            case tt._debugger:
              next();
              semicolon();
              return finishNode(node, "DebuggerStatement");
        
            case tt._do:
              next();
              node.body = parseStatement();
              node.test = eat(tt._while) ? parseParenExpression() : dummyIdent();
              semicolon();
              return finishNode(node, "DoWhileStatement");
        
            case tt._for:
              next();
              pushCx();
              expect(tt.parenL);
              if (token.type === tt.semi) return parseFor(node, null);
              if (token.type === tt._var) {
                var init = startNode();
                next();
                parseVar(init, true);
                if (init.declarations.length === 1 && eat(tt._in))
                  return parseForIn(node, init);
                return parseFor(node, init);
              }
              var init = parseExpression(false, true);
              if (eat(tt._in)) {return parseForIn(node, checkLVal(init));}
              return parseFor(node, init);
        
            case tt._function:
              next();
              return parseFunction(node, true);
        
            case tt._if:
              next();
              node.test = parseParenExpression();
              node.consequent = parseStatement();
              node.alternate = eat(tt._else) ? parseStatement() : null;
              return finishNode(node, "IfStatement");
        
            case tt._return:
              next();
              if (eat(tt.semi) || canInsertSemicolon()) node.argument = null;
              else { node.argument = parseExpression(); semicolon(); }
              return finishNode(node, "ReturnStatement");
        
            case tt._switch:
              var blockIndent = curIndent, line = curLineStart;
              next();
              node.discriminant = parseParenExpression();
              node.cases = [];
              pushCx();
              expect(tt.braceL);
        
              for (var cur; !closes(tt.braceR, blockIndent, line, true);) {
                if (token.type === tt._case || token.type === tt._default) {
                  var isCase = token.type === tt._case;
                  if (cur) finishNode(cur, "SwitchCase");
                  node.cases.push(cur = startNode());
                  cur.consequent = [];
                  next();
                  if (isCase) cur.test = parseExpression();
                  else cur.test = null;
                  expect(tt.colon);
                } else {
                  if (!cur) {
                    node.cases.push(cur = startNode());
                    cur.consequent = [];
                    cur.test = null;
                  }
                  cur.consequent.push(parseStatement());
                }
              }
              if (cur) finishNode(cur, "SwitchCase");
              popCx();
              eat(tt.braceR);
              return finishNode(node, "SwitchStatement");
        
            case tt._throw:
              next();
              node.argument = parseExpression();
              semicolon();
              return finishNode(node, "ThrowStatement");
        
            case tt._try:
              next();
              node.block = parseBlock();
              node.handler = null;
              if (token.type === tt._catch) {
                var clause = startNode();
                next();
                expect(tt.parenL);
                clause.param = parseIdent();
                expect(tt.parenR);
                clause.guard = null;
                clause.body = parseBlock();
                node.handler = finishNode(clause, "CatchClause");
              }
              node.finalizer = eat(tt._finally) ? parseBlock() : null;
              if (!node.handler && !node.finalizer) return node.block;
              return finishNode(node, "TryStatement");
        
            case tt._var:
              next();
              node = parseVar(node);
              return node;
        
            case tt._while:
              next();
              node.test = parseParenExpression();
              node.body = parseStatement();
              return finishNode(node, "WhileStatement");
        
            case tt._with:
              next();
              node.object = parseParenExpression();
              node.body = parseStatement();
              return finishNode(node, "WithStatement");
        
            case tt.braceL:
              return parseBlock();
        
            case tt.semi:
              next();
              return finishNode(node, "EmptyStatement");
        
            default:
              var expr = parseExpression();
              if (isDummy(expr)) {
                next();
                if (token.type === tt.eof) return finishNode(node, "EmptyStatement");
                return parseStatement();
              } else if (starttype === tt.name && expr.type === "Identifier" && eat(tt.colon)) {
                node.body = parseStatement();
                node.label = expr;
                return finishNode(node, "LabeledStatement");
              } else {
                node.expression = expr;
                semicolon();
                return finishNode(node, "ExpressionStatement");
              }
            }
          }
        
          function parseBlock() {
            var node = startNode();
            pushCx();
            expect(tt.braceL);
            var blockIndent = curIndent, line = curLineStart;
            node.body = [];
            while (!closes(tt.braceR, blockIndent, line, true))
              node.body.push(parseStatement());
            popCx();
            eat(tt.braceR);
            return finishNode(node, "BlockStatement");
          }
        
          function parseFor(node, init) {
            node.init = init;
            node.test = node.update = null;
            if (eat(tt.semi) && token.type !== tt.semi) node.test = parseExpression();
            if (eat(tt.semi) && token.type !== tt.parenR) node.update = parseExpression();
            popCx();
            expect(tt.parenR);
            node.body = parseStatement();
            return finishNode(node, "ForStatement");
          }
        
          function parseForIn(node, init) {
            node.left = init;
            node.right = parseExpression();
            popCx();
            expect(tt.parenR);
            node.body = parseStatement();
            return finishNode(node, "ForInStatement");
          }
        
          function parseVar(node, noIn) {
            node.declarations = [];
            node.kind = "var";
            while (token.type === tt.name) {
              var decl = startNode();
              decl.id = parseIdent();
              decl.init = eat(tt.eq) ? parseExpression(true, noIn) : null;
              node.declarations.push(finishNode(decl, "VariableDeclarator"));
              if (!eat(tt.comma)) break;
            }
            if (!node.declarations.length) {
              var decl = startNode();
              decl.id = dummyIdent();
              node.declarations.push(finishNode(decl, "VariableDeclarator"));
            }
            if (!noIn) semicolon();
            return finishNode(node, "VariableDeclaration");
          }
        
          function parseExpression(noComma, noIn) {
            var start = storeCurrentPos();
            var expr = parseMaybeAssign(noIn);
            if (!noComma && token.type === tt.comma) {
              var node = startNodeAt(start);
              node.expressions = [expr];
              while (eat(tt.comma)) node.expressions.push(parseMaybeAssign(noIn));
              return finishNode(node, "SequenceExpression");
            }
            return expr;
          }
        
          function parseParenExpression() {
            pushCx();
            expect(tt.parenL);
            var val = parseExpression();
            popCx();
            expect(tt.parenR);
            return val;
          }
        
          function parseMaybeAssign(noIn) {
            var start = storeCurrentPos();
            var left = parseMaybeConditional(noIn);
            if (token.type.isAssign) {
              var node = startNodeAt(start);
              node.operator = token.value;
              node.left = checkLVal(left);
              next();
              node.right = parseMaybeAssign(noIn);
              return finishNode(node, "AssignmentExpression");
            }
            return left;
          }
        
          function parseMaybeConditional(noIn) {
            var start = storeCurrentPos();
            var expr = parseExprOps(noIn);
            if (eat(tt.question)) {
              var node = startNodeAt(start);
              node.test = expr;
              node.consequent = parseExpression(true);
              node.alternate = expect(tt.colon) ? parseExpression(true, noIn) : dummyIdent();
              return finishNode(node, "ConditionalExpression");
            }
            return expr;
          }
        
          function parseExprOps(noIn) {
            var start = storeCurrentPos();
            var indent = curIndent, line = curLineStart;
            return parseExprOp(parseMaybeUnary(noIn), start, -1, noIn, indent, line);
          }
        
          function parseExprOp(left, start, minPrec, noIn, indent, line) {
            if (curLineStart != line && curIndent < indent && tokenStartsLine()) return left;
            var prec = token.type.binop;
            if (prec != null && (!noIn || token.type !== tt._in)) {
              if (prec > minPrec) {
                var node = startNodeAt(start);
                node.left = left;
                node.operator = token.value;
                next();
                if (curLineStart != line && curIndent < indent && tokenStartsLine()) {
                  node.right = dummyIdent();
                } else {
                  var rightStart = storeCurrentPos();
                  node.right = parseExprOp(parseMaybeUnary(noIn), rightStart, prec, noIn, indent, line);
                }
                finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression");
                return parseExprOp(node, start, minPrec, noIn, indent, line);
              }
            }
            return left;
          }
        
          function parseMaybeUnary(noIn) {
            if (token.type.prefix) {
              var node = startNode(), update = token.type.isUpdate;
              node.operator = token.value;
              node.prefix = true;
              next();
              node.argument = parseMaybeUnary(noIn);
              if (update) node.argument = checkLVal(node.argument);
              return finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
            }
            var start = storeCurrentPos();
            var expr = parseExprSubscripts();
            while (token.type.postfix && !canInsertSemicolon()) {
              var node = startNodeAt(start);
              node.operator = token.value;
              node.prefix = false;
              node.argument = checkLVal(expr);
              next();
              expr = finishNode(node, "UpdateExpression");
            }
            return expr;
          }
        
          function parseExprSubscripts() {
            var start = storeCurrentPos();
            return parseSubscripts(parseExprAtom(), start, false, curIndent, curLineStart);
          }
        
          function parseSubscripts(base, start, noCalls, startIndent, line) {
            for (;;) {
              if (curLineStart != line && curIndent <= startIndent && tokenStartsLine()) {
                if (token.type == tt.dot && curIndent == startIndent)
                  --startIndent;
                else
                  return base;
              }
        
              if (eat(tt.dot)) {
                var node = startNodeAt(start);
                node.object = base;
                if (curLineStart != line && curIndent <= startIndent && tokenStartsLine())
                  node.property = dummyIdent();
                else
                  node.property = parsePropertyAccessor() || dummyIdent();
                node.computed = false;
                base = finishNode(node, "MemberExpression");
              } else if (token.type == tt.bracketL) {
                pushCx();
                next();
                var node = startNodeAt(start);
                node.object = base;
                node.property = parseExpression();
                node.computed = true;
                popCx();
                expect(tt.bracketR);
                base = finishNode(node, "MemberExpression");
              } else if (!noCalls && token.type == tt.parenL) {
                pushCx();
                var node = startNodeAt(start);
                node.callee = base;
                node.arguments = parseExprList(tt.parenR);
                base = finishNode(node, "CallExpression");
              } else {
                return base;
              }
            }
          }
        
          function parseExprAtom() {
            switch (token.type) {
            case tt._this:
              var node = startNode();
              next();
              return finishNode(node, "ThisExpression");
            case tt.name:
              return parseIdent();
            case tt.num: case tt.string: case tt.regexp:
              var node = startNode();
              node.value = token.value;
              node.raw = input.slice(token.start, token.end);
              next();
              return finishNode(node, "Literal");
        
            case tt._null: case tt._true: case tt._false:
              var node = startNode();
              node.value = token.type.atomValue;
              node.raw = token.type.keyword;
              next();
              return finishNode(node, "Literal");
        
            case tt.parenL:
              next();
              var val = parseExpression();
              expect(tt.parenR);
              return val;
        
            case tt.bracketL:
              var node = startNode();
              pushCx();
              node.elements = parseExprList(tt.bracketR);
              return finishNode(node, "ArrayExpression");
        
            case tt.braceL:
              return parseObj();
        
            case tt._function:
              var node = startNode();
              next();
              return parseFunction(node, false);
        
            case tt._new:
              return parseNew();
        
            default:
              return dummyIdent();
            }
          }
        
          function parseNew() {
            var node = startNode(), startIndent = curIndent, line = curLineStart;
            next();
            var start = storeCurrentPos();
            node.callee = parseSubscripts(parseExprAtom(), start, true, startIndent, line);
            if (token.type == tt.parenL) {
              pushCx();
              node.arguments = parseExprList(tt.parenR);
            } else {
              node.arguments = [];
            }
            return finishNode(node, "NewExpression");
          }
        
          function parseObj() {
            var node = startNode();
            node.properties = [];
            pushCx();
            var indent = curIndent + 1, line = curLineStart;
            next();
            if (curIndent + 1 < indent) { indent = curIndent; line = curLineStart; }
            while (!closes(tt.braceR, indent, line)) {
              var name = parsePropertyName();
              if (!name) { if (isDummy(parseExpression(true))) next(); eat(tt.comma); continue; }
              var prop = startNode();
              prop.key = name;
              if (eat(tt.colon)) {
                prop.value = parseExpression(true);
                prop.kind = "init";
              } else if (options.ecmaVersion >= 5 && prop.key.type === "Identifier" &&
                         (prop.key.name === "get" || prop.key.name === "set")) {
                prop.kind = prop.key.name;
                prop.key = parsePropertyName() || dummyIdent();
                prop.value = parseFunction(startNode(), false);
              } else {
                prop.value = dummyIdent();
              }
        
              node.properties.push(finishNode(prop, "Property"));
              eat(tt.comma);
            }
            popCx();
            eat(tt.braceR);
            return finishNode(node, "ObjectExpression");
          }
        
          function parsePropertyName() {
            if (token.type === tt.num || token.type === tt.string) return parseExprAtom();
            if (token.type === tt.name || token.type.keyword) return parseIdent();
          }
        
          function parsePropertyAccessor() {
            if (token.type === tt.name || token.type.keyword) return parseIdent();
          }
        
          function parseIdent() {
            var node = startNode();
            node.name = token.type === tt.name ? token.value : token.type.keyword;
            next();
            return finishNode(node, "Identifier");
          }
        
          function parseFunction(node, isStatement) {
            if (token.type === tt.name) node.id = parseIdent();
            else if (isStatement) node.id = dummyIdent();
            else node.id = null;
            node.params = [];
            pushCx();
            expect(tt.parenL);
            while (token.type == tt.name) {
              node.params.push(parseIdent());
              eat(tt.comma);
            }
            popCx();
            eat(tt.parenR);
            node.body = parseBlock();
            return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
          }
        
          function parseExprList(close) {
            var indent = curIndent, line = curLineStart, elts = [], continuedLine = nextLineStart;
            next(); // Opening bracket
            if (curLineStart > continuedLine) continuedLine = curLineStart;
            while (!closes(close, indent + (curLineStart <= continuedLine ? 1 : 0), line)) {
              var elt = parseExpression(true);
              if (isDummy(elt)) {
                if (closes(close, indent, line)) break;
                next();
              } else {
                elts.push(elt);
              }
              while (eat(tt.comma)) {}
            }
            popCx();
            eat(close);
            return elts;
          }
        });
        
      • walk.js
        // AST walker module for Mozilla Parser API compatible trees
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS
          if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD
          mod((this.acorn || (this.acorn = {})).walk = {}); // Plain browser env
        })(function(exports) {
          "use strict";
        
          // A simple walk is one where you simply specify callbacks to be
          // called on specific nodes. The last two arguments are optional. A
          // simple use would be
          //
          //     walk.simple(myTree, {
          //         Expression: function(node) { ... }
          //     });
          //
          // to do something with all expressions. All Parser API node types
          // can be used to identify node types, as well as Expression,
          // Statement, and ScopeBody, which denote categories of nodes.
          //
          // The base argument can be used to pass a custom (recursive)
          // walker, and state can be used to give this walked an initial
          // state.
          exports.simple = function(node, visitors, base, state) {
            if (!base) base = exports.base;
            function c(node, st, override) {
              var type = override || node.type, found = visitors[type];
              base[type](node, st, c);
              if (found) found(node, st);
            }
            c(node, state);
          };
        
          // An ancestor walk builds up an array of ancestor nodes (including
          // the current node) and passes them to the callback as the state parameter.
          exports.ancestor = function(node, visitors, base, state) {
            if (!base) base = exports.base;
            if (!state) state = [];
            function c(node, st, override) {
              var type = override || node.type, found = visitors[type];
              if (node != st[st.length - 1]) {
                st = st.slice();
                st.push(node);
              }
              base[type](node, st, c);
              if (found) found(node, st);
            }
            c(node, state);
          };
        
          // A recursive walk is one where your functions override the default
          // walkers. They can modify and replace the state parameter that's
          // threaded through the walk, and can opt how and whether to walk
          // their child nodes (by calling their third argument on these
          // nodes).
          exports.recursive = function(node, state, funcs, base) {
            var visitor = funcs ? exports.make(funcs, base) : base;
            function c(node, st, override) {
              visitor[override || node.type](node, st, c);
            }
            c(node, state);
          };
        
          function makeTest(test) {
            if (typeof test == "string")
              return function(type) { return type == test; };
            else if (!test)
              return function() { return true; };
            else
              return test;
          }
        
          function Found(node, state) { this.node = node; this.state = state; }
        
          // Find a node with a given start, end, and type (all are optional,
          // null can be used as wildcard). Returns a {node, state} object, or
          // undefined when it doesn't find a matching node.
          exports.findNodeAt = function(node, start, end, test, base, state) {
            test = makeTest(test);
            try {
              if (!base) base = exports.base;
              var c = function(node, st, override) {
                var type = override || node.type;
                if ((start == null || node.start <= start) &&
                    (end == null || node.end >= end))
                  base[type](node, st, c);
                if (test(type, node) &&
                    (start == null || node.start == start) &&
                    (end == null || node.end == end))
                  throw new Found(node, st);
              };
              c(node, state);
            } catch (e) {
              if (e instanceof Found) return e;
              throw e;
            }
          };
        
          // Find the innermost node of a given type that contains the given
          // position. Interface similar to findNodeAt.
          exports.findNodeAround = function(node, pos, test, base, state) {
            test = makeTest(test);
            try {
              if (!base) base = exports.base;
              var c = function(node, st, override) {
                var type = override || node.type;
                if (node.start > pos || node.end < pos) return;
                base[type](node, st, c);
                if (test(type, node)) throw new Found(node, st);
              };
              c(node, state);
            } catch (e) {
              if (e instanceof Found) return e;
              throw e;
            }
          };
        
          // Find the outermost matching node after a given position.
          exports.findNodeAfter = function(node, pos, test, base, state) {
            test = makeTest(test);
            try {
              if (!base) base = exports.base;
              var c = function(node, st, override) {
                if (node.end < pos) return;
                var type = override || node.type;
                if (node.start >= pos && test(type, node)) throw new Found(node, st);
                base[type](node, st, c);
              };
              c(node, state);
            } catch (e) {
              if (e instanceof Found) return e;
              throw e;
            }
          };
        
          // Find the outermost matching node before a given position.
          exports.findNodeBefore = function(node, pos, test, base, state) {
            test = makeTest(test);
            if (!base) base = exports.base;
            var max;
            var c = function(node, st, override) {
              if (node.start > pos) return;
              var type = override || node.type;
              if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node))
                max = new Found(node, st);
              base[type](node, st, c);
            };
            c(node, state);
            return max;
          };
        
          // Used to create a custom walker. Will fill in all missing node
          // type properties with the defaults.
          exports.make = function(funcs, base) {
            if (!base) base = exports.base;
            var visitor = {};
            for (var type in base) visitor[type] = base[type];
            for (var type in funcs) visitor[type] = funcs[type];
            return visitor;
          };
        
          function skipThrough(node, st, c) { c(node, st); }
          function ignore(_node, _st, _c) {}
        
          // Node walkers.
        
          var base = exports.base = {};
          base.Program = base.BlockStatement = function(node, st, c) {
            for (var i = 0; i < node.body.length; ++i)
              c(node.body[i], st, "Statement");
          };
          base.Statement = skipThrough;
          base.EmptyStatement = ignore;
          base.ExpressionStatement = function(node, st, c) {
            c(node.expression, st, "Expression");
          };
          base.IfStatement = function(node, st, c) {
            c(node.test, st, "Expression");
            c(node.consequent, st, "Statement");
            if (node.alternate) c(node.alternate, st, "Statement");
          };
          base.LabeledStatement = function(node, st, c) {
            c(node.body, st, "Statement");
          };
          base.BreakStatement = base.ContinueStatement = ignore;
          base.WithStatement = function(node, st, c) {
            c(node.object, st, "Expression");
            c(node.body, st, "Statement");
          };
          base.SwitchStatement = function(node, st, c) {
            c(node.discriminant, st, "Expression");
            for (var i = 0; i < node.cases.length; ++i) {
              var cs = node.cases[i];
              if (cs.test) c(cs.test, st, "Expression");
              for (var j = 0; j < cs.consequent.length; ++j)
                c(cs.consequent[j], st, "Statement");
            }
          };
          base.ReturnStatement = base.YieldExpression = function(node, st, c) {
            if (node.argument) c(node.argument, st, "Expression");
          };
          base.ThrowStatement = base.SpreadElement = function(node, st, c) {
            c(node.argument, st, "Expression");
          };
          base.TryStatement = function(node, st, c) {
            c(node.block, st, "Statement");
            if (node.handler) c(node.handler.body, st, "ScopeBody");
            if (node.finalizer) c(node.finalizer, st, "Statement");
          };
          base.WhileStatement = function(node, st, c) {
            c(node.test, st, "Expression");
            c(node.body, st, "Statement");
          };
          base.DoWhileStatement = base.WhileStatement;
          base.ForStatement = function(node, st, c) {
            if (node.init) c(node.init, st, "ForInit");
            if (node.test) c(node.test, st, "Expression");
            if (node.update) c(node.update, st, "Expression");
            c(node.body, st, "Statement");
          };
          base.ForInStatement = base.ForOfStatement = function(node, st, c) {
            c(node.left, st, "ForInit");
            c(node.right, st, "Expression");
            c(node.body, st, "Statement");
          };
          base.ForInit = function(node, st, c) {
            if (node.type == "VariableDeclaration") c(node, st);
            else c(node, st, "Expression");
          };
          base.DebuggerStatement = ignore;
        
          base.FunctionDeclaration = function(node, st, c) {
            c(node, st, "Function");
          };
          base.VariableDeclaration = function(node, st, c) {
            for (var i = 0; i < node.declarations.length; ++i) {
              var decl = node.declarations[i];
              if (decl.init) c(decl.init, st, "Expression");
            }
          };
        
          base.Function = function(node, st, c) {
            c(node.body, st, "ScopeBody");
          };
          base.ScopeBody = function(node, st, c) {
            c(node, st, "Statement");
          };
        
          base.Expression = skipThrough;
          base.ThisExpression = ignore;
          base.ArrayExpression = function(node, st, c) {
            for (var i = 0; i < node.elements.length; ++i) {
              var elt = node.elements[i];
              if (elt) c(elt, st, "Expression");
            }
          };
          base.ObjectExpression = function(node, st, c) {
            for (var i = 0; i < node.properties.length; ++i)
              c(node.properties[i], st);
          };
          base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration;
          base.SequenceExpression = base.TemplateLiteral = function(node, st, c) {
            for (var i = 0; i < node.expressions.length; ++i)
              c(node.expressions[i], st, "Expression");
          };
          base.UnaryExpression = base.UpdateExpression = function(node, st, c) {
            c(node.argument, st, "Expression");
          };
          base.BinaryExpression = base.AssignmentExpression = base.LogicalExpression = function(node, st, c) {
            c(node.left, st, "Expression");
            c(node.right, st, "Expression");
          };
          base.ConditionalExpression = function(node, st, c) {
            c(node.test, st, "Expression");
            c(node.consequent, st, "Expression");
            c(node.alternate, st, "Expression");
          };
          base.NewExpression = base.CallExpression = function(node, st, c) {
            c(node.callee, st, "Expression");
            if (node.arguments) for (var i = 0; i < node.arguments.length; ++i)
              c(node.arguments[i], st, "Expression");
          };
          base.MemberExpression = function(node, st, c) {
            c(node.object, st, "Expression");
            if (node.computed) c(node.property, st, "Expression");
          };
          base.Identifier = base.Literal = base.ExportDeclaration = base.ImportDeclaration = ignore;
        
          base.TaggedTemplateExpression = function(node, st, c) {
            c(node.tag, st, "Expression");
            c(node.quasi, st);
          };
          base.ClassDeclaration = base.ClassExpression = function(node, st, c) {
            if (node.superClass) c(node.superClass, st, "Expression");
            for (var i = 0; i < node.body.body.length; i++)
              c(node.body.body[i], st);
          };
          base.MethodDefinition = base.Property = function(node, st, c) {
            if (node.computed) c(node.key, st, "Expression");
            c(node.value, st, "Expression");
          };
          base.ComprehensionExpression = function(node, st, c) {
            for (var i = 0; i < node.blocks.length; i++)
              c(node.blocks[i].right, st, "Expression");
            c(node.body, st, "Expression");
          };
        
          // NOTE: the stuff below is deprecated, and will be removed when 1.0 is released
        
          // A custom walker that keeps track of the scope chain and the
          // variables defined in it.
          function makeScope(prev, isCatch) {
            return {vars: Object.create(null), prev: prev, isCatch: isCatch};
          }
          function normalScope(scope) {
            while (scope.isCatch) scope = scope.prev;
            return scope;
          }
          exports.scopeVisitor = exports.make({
            Function: function(node, scope, c) {
              var inner = makeScope(scope);
              for (var i = 0; i < node.params.length; ++i)
                inner.vars[node.params[i].name] = {type: "argument", node: node.params[i]};
              if (node.id) {
                var decl = node.type == "FunctionDeclaration";
                (decl ? normalScope(scope) : inner).vars[node.id.name] =
                  {type: decl ? "function" : "function name", node: node.id};
              }
              c(node.body, inner, "ScopeBody");
            },
            TryStatement: function(node, scope, c) {
              c(node.block, scope, "Statement");
              if (node.handler) {
                var inner = makeScope(scope, true);
                inner.vars[node.handler.param.name] = {type: "catch clause", node: node.handler.param};
                c(node.handler.body, inner, "ScopeBody");
              }
              if (node.finalizer) c(node.finalizer, scope, "Statement");
            },
            VariableDeclaration: function(node, scope, c) {
              var target = normalScope(scope);
              for (var i = 0; i < node.declarations.length; ++i) {
                var decl = node.declarations[i];
                target.vars[decl.id.name] = {type: "var", node: decl.id};
                if (decl.init) c(decl.init, scope, "Expression");
              }
            }
          });
        
        });
        
    • codemirror
      • active-line.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        // Because sometimes you need to style the cursor's line.
        //
        // Adds an option 'styleActiveLine' which, when enabled, gives the
        // active line's wrapping <div> the CSS class "CodeMirror-activeline",
        // and gives its background <div> the class "CodeMirror-activeline-background".
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          "use strict";
          var WRAP_CLASS = "CodeMirror-activeline";
          var BACK_CLASS = "CodeMirror-activeline-background";
        
          CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
            var prev = old && old != CodeMirror.Init;
            if (val && !prev) {
              cm.state.activeLines = [];
              updateActiveLines(cm, cm.listSelections());
              cm.on("beforeSelectionChange", selectionChange);
            } else if (!val && prev) {
              cm.off("beforeSelectionChange", selectionChange);
              clearActiveLines(cm);
              delete cm.state.activeLines;
            }
          });
        
          function clearActiveLines(cm) {
            for (var i = 0; i < cm.state.activeLines.length; i++) {
              cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
              cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
            }
          }
        
          function sameArray(a, b) {
            if (a.length != b.length) return false;
            for (var i = 0; i < a.length; i++)
              if (a[i] != b[i]) return false;
            return true;
          }
        
          function updateActiveLines(cm, ranges) {
            var active = [];
            for (var i = 0; i < ranges.length; i++) {
              var range = ranges[i];
              if (!range.empty()) continue;
              var line = cm.getLineHandleVisualStart(range.head.line);
              if (active[active.length - 1] != line) active.push(line);
            }
            if (sameArray(cm.state.activeLines, active)) return;
            cm.operation(function() {
              clearActiveLines(cm);
              for (var i = 0; i < active.length; i++) {
                cm.addLineClass(active[i], "wrap", WRAP_CLASS);
                cm.addLineClass(active[i], "background", BACK_CLASS);
              }
              cm.state.activeLines = active;
            });
          }
        
          function selectionChange(cm, sel) {
            updateActiveLines(cm, sel.ranges);
          }
        });
        
      • codemirror.css
        /* BASICS */
        
        .CodeMirror {
          /* Set height, width, borders, and global font properties here */
          font-family: monospace;
          height: 300px;
        }
        .CodeMirror-scroll {
          /* Set scrolling behaviour here */
          overflow: auto;
        }
        
        /* PADDING */
        
        .CodeMirror-lines {
          padding: 4px 0; /* Vertical padding around content */
        }
        .CodeMirror pre {
          padding: 0 4px; /* Horizontal padding of content */
        }
        
        .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
          background-color: white; /* The little square between H and V scrollbars */
        }
        
        /* GUTTER */
        
        .CodeMirror-gutters {
          border-right: 1px solid #ddd;
          background-color: #f7f7f7;
          white-space: nowrap;
        }
        .CodeMirror-linenumbers {}
        .CodeMirror-linenumber {
          padding: 0 3px 0 5px;
          min-width: 20px;
          text-align: right;
          color: #999;
          -moz-box-sizing: content-box;
          box-sizing: content-box;
        }
        
        .CodeMirror-guttermarker { color: black; }
        .CodeMirror-guttermarker-subtle { color: #999; }
        
        /* CURSOR */
        
        .CodeMirror div.CodeMirror-cursor {
          border-left: 1px solid black;
        }
        /* Shown when moving in bi-directional text */
        .CodeMirror div.CodeMirror-secondarycursor {
          border-left: 1px solid silver;
        }
        .CodeMirror.cm-fat-cursor div.CodeMirror-cursor {
          width: auto;
          border: 0;
          background: #7e7;
        }
        .CodeMirror.cm-fat-cursor div.CodeMirror-cursors {
          z-index: 1;
        }
        
        .cm-animate-fat-cursor {
          width: auto;
          border: 0;
          -webkit-animation: blink 1.06s steps(1) infinite;
          -moz-animation: blink 1.06s steps(1) infinite;
          animation: blink 1.06s steps(1) infinite;
        }
        @-moz-keyframes blink {
          0% { background: #7e7; }
          50% { background: none; }
          100% { background: #7e7; }
        }
        @-webkit-keyframes blink {
          0% { background: #7e7; }
          50% { background: none; }
          100% { background: #7e7; }
        }
        @keyframes blink {
          0% { background: #7e7; }
          50% { background: none; }
          100% { background: #7e7; }
        }
        
        /* Can style cursor different in overwrite (non-insert) mode */
        div.CodeMirror-overwrite div.CodeMirror-cursor {}
        
        .cm-tab { display: inline-block; text-decoration: inherit; }
        
        .CodeMirror-ruler {
          border-left: 1px solid #ccc;
          position: absolute;
        }
        
        /* DEFAULT THEME */
        
        .cm-s-default .cm-keyword {color: #708;}
        .cm-s-default .cm-atom {color: #219;}
        .cm-s-default .cm-number {color: #164;}
        .cm-s-default .cm-def {color: #00f;}
        .cm-s-default .cm-variable,
        .cm-s-default .cm-punctuation,
        .cm-s-default .cm-property,
        .cm-s-default .cm-operator {}
        .cm-s-default .cm-variable-2 {color: #05a;}
        .cm-s-default .cm-variable-3 {color: #085;}
        .cm-s-default .cm-comment {color: #a50;}
        .cm-s-default .cm-string {color: #a11;}
        .cm-s-default .cm-string-2 {color: #f50;}
        .cm-s-default .cm-meta {color: #555;}
        .cm-s-default .cm-qualifier {color: #555;}
        .cm-s-default .cm-builtin {color: #30a;}
        .cm-s-default .cm-bracket {color: #997;}
        .cm-s-default .cm-tag {color: #170;}
        .cm-s-default .cm-attribute {color: #00c;}
        .cm-s-default .cm-header {color: blue;}
        .cm-s-default .cm-quote {color: #090;}
        .cm-s-default .cm-hr {color: #999;}
        .cm-s-default .cm-link {color: #00c;}
        
        .cm-negative {color: #d44;}
        .cm-positive {color: #292;}
        .cm-header, .cm-strong {font-weight: bold;}
        .cm-em {font-style: italic;}
        .cm-link {text-decoration: underline;}
        .cm-strikethrough {text-decoration: line-through;}
        
        .cm-s-default .cm-error {color: #f00;}
        .cm-invalidchar {color: #f00;}
        
        /* Default styles for common addons */
        
        div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
        div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
        .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
        .CodeMirror-activeline-background {background: #e8f2ff;}
        
        /* STOP */
        
        /* The rest of this file contains styles related to the mechanics of
           the editor. You probably shouldn't touch them. */
        
        .CodeMirror {
          line-height: 1;
          position: relative;
          overflow: hidden;
          background: white;
          color: black;
        }
        
        .CodeMirror-scroll {
          /* 30px is the magic margin used to hide the element's real scrollbars */
          /* See overflow: hidden in .CodeMirror */
          margin-bottom: -30px; margin-right: -30px;
          padding-bottom: 30px;
          height: 100%;
          outline: none; /* Prevent dragging from highlighting the element */
          position: relative;
          -moz-box-sizing: content-box;
          box-sizing: content-box;
        }
        .CodeMirror-sizer {
          position: relative;
          border-right: 30px solid transparent;
          -moz-box-sizing: content-box;
          box-sizing: content-box;
        }
        
        /* The fake, visible scrollbars. Used to force redraw during scrolling
           before actuall scrolling happens, thus preventing shaking and
           flickering artifacts. */
        .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
          position: absolute;
          z-index: 6;
          display: none;
        }
        .CodeMirror-vscrollbar {
          right: 0; top: 0;
          overflow-x: hidden;
          overflow-y: scroll;
        }
        .CodeMirror-hscrollbar {
          bottom: 0; left: 0;
          overflow-y: hidden;
          overflow-x: scroll;
        }
        .CodeMirror-scrollbar-filler {
          right: 0; bottom: 0;
        }
        .CodeMirror-gutter-filler {
          left: 0; bottom: 0;
        }
        
        .CodeMirror-gutters {
          position: absolute; left: 0; top: 0;
          padding-bottom: 30px;
          z-index: 3;
        }
        .CodeMirror-gutter {
          white-space: normal;
          height: 100%;
          -moz-box-sizing: content-box;
          box-sizing: content-box;
          padding-bottom: 30px;
          margin-bottom: -32px;
          display: inline-block;
          /* Hack to make IE7 behave */
          *zoom:1;
          *display:inline;
        }
        .CodeMirror-gutter-wrapper {
          position: absolute;
          z-index: 4;
          height: 100%;
        }
        .CodeMirror-gutter-elt {
          position: absolute;
          cursor: default;
          z-index: 4;
        }
        
        .CodeMirror-lines {
          cursor: text;
          min-height: 1px; /* prevents collapsing before first draw */
        }
        .CodeMirror pre {
          /* Reset some styles that the rest of the page might have set */
          -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
          border-width: 0;
          background: transparent;
          font-family: inherit;
          font-size: inherit;
          margin: 0;
          white-space: pre;
          word-wrap: normal;
          line-height: inherit;
          color: inherit;
          z-index: 2;
          position: relative;
          overflow: visible;
        }
        .CodeMirror-wrap pre {
          word-wrap: break-word;
          white-space: pre-wrap;
          word-break: normal;
        }
        
        .CodeMirror-linebackground {
          position: absolute;
          left: 0; right: 0; top: 0; bottom: 0;
          z-index: 0;
        }
        
        .CodeMirror-linewidget {
          position: relative;
          z-index: 2;
          overflow: auto;
        }
        
        .CodeMirror-widget {}
        
        .CodeMirror-wrap .CodeMirror-scroll {
          overflow-x: hidden;
        }
        
        .CodeMirror-measure {
          position: absolute;
          width: 100%;
          height: 0;
          overflow: hidden;
          visibility: hidden;
        }
        .CodeMirror-measure pre { position: static; }
        
        .CodeMirror div.CodeMirror-cursor {
          position: absolute;
          border-right: none;
          width: 0;
        }
        
        div.CodeMirror-cursors {
          visibility: hidden;
          position: relative;
          z-index: 3;
        }
        .CodeMirror-focused div.CodeMirror-cursors {
          visibility: visible;
        }
        
        .CodeMirror-selected { background: #d9d9d9; }
        .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
        .CodeMirror-crosshair { cursor: crosshair; }
        
        .cm-searching {
          background: #ffa;
          background: rgba(255, 255, 0, .4);
        }
        
        /* IE7 hack to prevent it from returning funny offsetTops on the spans */
        .CodeMirror span { *vertical-align: text-bottom; }
        
        /* Used to force a border model for a node */
        .cm-force-border { padding-right: .1px; }
        
        @media print {
          /* Hide the cursor when printing */
          .CodeMirror div.CodeMirror-cursors {
            visibility: hidden;
          }
        }
        
        /* See issue #2901 */
        .cm-tab-wrap-hack:after { content: ''; }
        
        /* Help users use markselection to safely style text background */
        span.CodeMirror-selectedtext { background: none; }
        
      • codemirror.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        // This is CodeMirror (http://codemirror.net), a code editor
        // implemented in JavaScript on top of the browser's DOM.
        //
        // You can find some technical background for some of the code below
        // at http://marijnhaverbeke.nl/blog/#cm-internals .
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            module.exports = mod();
          else if (typeof define == "function" && define.amd) // AMD
            return define([], mod);
          else // Plain browser env
            this.CodeMirror = mod();
        })(function() {
          "use strict";
        
          // BROWSER SNIFFING
        
          // Kludges for bugs and behavior differences that can't be feature
          // detected are enabled based on userAgent etc sniffing.
        
          var gecko = /gecko\/\d/i.test(navigator.userAgent);
          // ie_uptoN means Internet Explorer version N or lower
          var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
          var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
          var ie = ie_upto10 || ie_11up;
          var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
          var webkit = /WebKit\//.test(navigator.userAgent);
          var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
          var chrome = /Chrome\//.test(navigator.userAgent);
          var presto = /Opera\//.test(navigator.userAgent);
          var safari = /Apple Computer/.test(navigator.vendor);
          var khtml = /KHTML\//.test(navigator.userAgent);
          var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
          var phantom = /PhantomJS/.test(navigator.userAgent);
        
          var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
          // This is woefully incomplete. Suggestions for alternative methods welcome.
          var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
          var mac = ios || /Mac/.test(navigator.platform);
          var windows = /win/i.test(navigator.platform);
        
          var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
          if (presto_version) presto_version = Number(presto_version[1]);
          if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
          // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
          var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
          var captureRightClick = gecko || (ie && ie_version >= 9);
        
          // Optimize some code when these features are not used.
          var sawReadOnlySpans = false, sawCollapsedSpans = false;
        
          // EDITOR CONSTRUCTOR
        
          // A CodeMirror instance represents an editor. This is the object
          // that user code is usually dealing with.
        
          function CodeMirror(place, options) {
            if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
        
            this.options = options = options ? copyObj(options) : {};
            // Determine effective options based on given values and defaults.
            copyObj(defaults, options, false);
            setGuttersForLineNumbers(options);
        
            var doc = options.value;
            if (typeof doc == "string") doc = new Doc(doc, options.mode);
            this.doc = doc;
        
            var display = this.display = new Display(place, doc);
            display.wrapper.CodeMirror = this;
            updateGutters(this);
            themeChanged(this);
            if (options.lineWrapping)
              this.display.wrapper.className += " CodeMirror-wrap";
            if (options.autofocus && !mobile) focusInput(this);
        
            this.state = {
              keyMaps: [],  // stores maps added by addKeyMap
              overlays: [], // highlighting overlays, as added by addOverlay
              modeGen: 0,   // bumped when mode/overlay changes, used to invalidate highlighting info
              overwrite: false, focused: false,
              suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
              pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput
              draggingText: false,
              highlight: new Delayed(), // stores highlight worker timeout
              keySeq: null  // Unfinished key sequence
            };
        
            // Override magic textarea content restore that IE sometimes does
            // on our hidden textarea on reload
            if (ie && ie_version < 11) setTimeout(bind(resetInput, this, true), 20);
        
            registerEventHandlers(this);
            ensureGlobalHandlers();
        
            startOperation(this);
            this.curOp.forceUpdate = true;
            attachDoc(this, doc);
        
            if ((options.autofocus && !mobile) || activeElt() == display.input)
              setTimeout(bind(onFocus, this), 20);
            else
              onBlur(this);
        
            for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
              optionHandlers[opt](this, options[opt], Init);
            maybeUpdateLineNumberWidth(this);
            for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
            endOperation(this);
          }
        
          // DISPLAY CONSTRUCTOR
        
          // The display handles the DOM integration, both for input reading
          // and content drawing. It holds references to DOM nodes and
          // display-related state.
        
          function Display(place, doc) {
            var d = this;
        
            // The semihidden textarea that is focused when the editor is
            // focused, and receives input.
            var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
            // The textarea is kept positioned near the cursor to prevent the
            // fact that it'll be scrolled into view on input from scrolling
            // our fake cursor out of view. On webkit, when wrap=off, paste is
            // very slow. So make the area wide instead.
            if (webkit) input.style.width = "1000px";
            else input.setAttribute("wrap", "off");
            // If border: 0; -- iOS fails to open keyboard (issue #1287)
            if (ios) input.style.border = "1px solid black";
            input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
        
            // Wraps and hides input textarea
            d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
            // The fake scrollbar elements.
            d.scrollbarH = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
            d.scrollbarV = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
            // Covers bottom-right square when both scrollbars are present.
            d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
            // Covers bottom of gutter when coverGutterNextToScrollbar is on
            // and h scrollbar is present.
            d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
            // Will contain the actual code, positioned to cover the viewport.
            d.lineDiv = elt("div", null, "CodeMirror-code");
            // Elements are added to these to represent selection and cursors.
            d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
            d.cursorDiv = elt("div", null, "CodeMirror-cursors");
            // A visibility: hidden element used to find the size of things.
            d.measure = elt("div", null, "CodeMirror-measure");
            // When lines outside of the viewport are measured, they are drawn in this.
            d.lineMeasure = elt("div", null, "CodeMirror-measure");
            // Wraps everything that needs to exist inside the vertically-padded coordinate system
            d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
                              null, "position: relative; outline: none");
            // Moved around its parent to cover visible view.
            d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
            // Set to the height of the document, allowing scrolling.
            d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
            // Behavior of elts with overflow: auto and padding is
            // inconsistent across browsers. This is used to ensure the
            // scrollable area is big enough.
            d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
            // Will contain the gutters, if any.
            d.gutters = elt("div", null, "CodeMirror-gutters");
            d.lineGutter = null;
            // Actual scrollable element.
            d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
            d.scroller.setAttribute("tabIndex", "-1");
            // The element in which the editor lives.
            d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
                                    d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
        
            // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
            if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
            // Needed to hide big blue blinking cursor on Mobile Safari
            if (ios) input.style.width = "0px";
            if (!webkit) d.scroller.draggable = true;
            // Needed to handle Tab key in KHTML
            if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
            // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
            if (ie && ie_version < 8) d.scrollbarH.style.minHeight = d.scrollbarV.style.minWidth = "18px";
        
            if (place) {
              if (place.appendChild) place.appendChild(d.wrapper);
              else place(d.wrapper);
            }
        
            // Current rendered range (may be bigger than the view window).
            d.viewFrom = d.viewTo = doc.first;
            // Information about the rendered lines.
            d.view = [];
            // Holds info about a single rendered line when it was rendered
            // for measurement, while not in view.
            d.externalMeasured = null;
            // Empty space (in pixels) above the view
            d.viewOffset = 0;
            d.lastWrapHeight = d.lastWrapWidth = 0;
            d.updateLineNumbers = null;
        
            // Used to only resize the line number gutter when necessary (when
            // the amount of lines crosses a boundary that makes its width change)
            d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
            // See readInput and resetInput
            d.prevInput = "";
            // Set to true when a non-horizontal-scrolling line widget is
            // added. As an optimization, line widget aligning is skipped when
            // this is false.
            d.alignWidgets = false;
            // Flag that indicates whether we expect input to appear real soon
            // now (after some event like 'keypress' or 'input') and are
            // polling intensively.
            d.pollingFast = false;
            // Self-resetting timeout for the poller
            d.poll = new Delayed();
        
            d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
        
            // Tracks when resetInput has punted to just putting a short
            // string into the textarea instead of the full selection.
            d.inaccurateSelection = false;
        
            // Tracks the maximum line length so that the horizontal scrollbar
            // can be kept static when scrolling.
            d.maxLine = null;
            d.maxLineLength = 0;
            d.maxLineChanged = false;
        
            // Used for measuring wheel scrolling granularity
            d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
        
            // True when shift is held down.
            d.shift = false;
        
            // Used to track whether anything happened since the context menu
            // was opened.
            d.selForContextMenu = null;
          }
        
          // STATE UPDATES
        
          // Used to get the editor into a consistent state again when options change.
        
          function loadMode(cm) {
            cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
            resetModeState(cm);
          }
        
          function resetModeState(cm) {
            cm.doc.iter(function(line) {
              if (line.stateAfter) line.stateAfter = null;
              if (line.styles) line.styles = null;
            });
            cm.doc.frontier = cm.doc.first;
            startWorker(cm, 100);
            cm.state.modeGen++;
            if (cm.curOp) regChange(cm);
          }
        
          function wrappingChanged(cm) {
            if (cm.options.lineWrapping) {
              addClass(cm.display.wrapper, "CodeMirror-wrap");
              cm.display.sizer.style.minWidth = "";
            } else {
              rmClass(cm.display.wrapper, "CodeMirror-wrap");
              findMaxLine(cm);
            }
            estimateLineHeights(cm);
            regChange(cm);
            clearCaches(cm);
            setTimeout(function(){updateScrollbars(cm);}, 100);
          }
        
          // Returns a function that estimates the height of a line, to use as
          // first approximation until the line becomes visible (and is thus
          // properly measurable).
          function estimateHeight(cm) {
            var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
            var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
            return function(line) {
              if (lineIsHidden(cm.doc, line)) return 0;
        
              var widgetsHeight = 0;
              if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
                if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
              }
        
              if (wrapping)
                return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
              else
                return widgetsHeight + th;
            };
          }
        
          function estimateLineHeights(cm) {
            var doc = cm.doc, est = estimateHeight(cm);
            doc.iter(function(line) {
              var estHeight = est(line);
              if (estHeight != line.height) updateLineHeight(line, estHeight);
            });
          }
        
          function themeChanged(cm) {
            cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
              cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
            clearCaches(cm);
          }
        
          function guttersChanged(cm) {
            updateGutters(cm);
            regChange(cm);
            setTimeout(function(){alignHorizontally(cm);}, 20);
          }
        
          // Rebuild the gutter elements, ensure the margin to the left of the
          // code matches their width.
          function updateGutters(cm) {
            var gutters = cm.display.gutters, specs = cm.options.gutters;
            removeChildren(gutters);
            for (var i = 0; i < specs.length; ++i) {
              var gutterClass = specs[i];
              var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
              if (gutterClass == "CodeMirror-linenumbers") {
                cm.display.lineGutter = gElt;
                gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
              }
            }
            gutters.style.display = i ? "" : "none";
            updateGutterSpace(cm);
          }
        
          function updateGutterSpace(cm) {
            var width = cm.display.gutters.offsetWidth;
            cm.display.sizer.style.marginLeft = width + "px";
            cm.display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0;
          }
        
          // Compute the character length of a line, taking into account
          // collapsed ranges (see markText) that might hide parts, and join
          // other lines onto it.
          function lineLength(line) {
            if (line.height == 0) return 0;
            var len = line.text.length, merged, cur = line;
            while (merged = collapsedSpanAtStart(cur)) {
              var found = merged.find(0, true);
              cur = found.from.line;
              len += found.from.ch - found.to.ch;
            }
            cur = line;
            while (merged = collapsedSpanAtEnd(cur)) {
              var found = merged.find(0, true);
              len -= cur.text.length - found.from.ch;
              cur = found.to.line;
              len += cur.text.length - found.to.ch;
            }
            return len;
          }
        
          // Find the longest line in the document.
          function findMaxLine(cm) {
            var d = cm.display, doc = cm.doc;
            d.maxLine = getLine(doc, doc.first);
            d.maxLineLength = lineLength(d.maxLine);
            d.maxLineChanged = true;
            doc.iter(function(line) {
              var len = lineLength(line);
              if (len > d.maxLineLength) {
                d.maxLineLength = len;
                d.maxLine = line;
              }
            });
          }
        
          // Make sure the gutters options contains the element
          // "CodeMirror-linenumbers" when the lineNumbers option is true.
          function setGuttersForLineNumbers(options) {
            var found = indexOf(options.gutters, "CodeMirror-linenumbers");
            if (found == -1 && options.lineNumbers) {
              options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
            } else if (found > -1 && !options.lineNumbers) {
              options.gutters = options.gutters.slice(0);
              options.gutters.splice(found, 1);
            }
          }
        
          // SCROLLBARS
        
          function hScrollbarTakesSpace(cm) {
            return cm.display.scroller.clientHeight - cm.display.wrapper.clientHeight < scrollerCutOff - 3;
          }
        
          // Prepare DOM reads needed to update the scrollbars. Done in one
          // shot to minimize update/measure roundtrips.
          function measureForScrollbars(cm) {
            var scroll = cm.display.scroller;
            return {
              clientHeight: scroll.clientHeight,
              barHeight: cm.display.scrollbarV.clientHeight,
              scrollWidth: scroll.scrollWidth, clientWidth: scroll.clientWidth,
              hScrollbarTakesSpace: hScrollbarTakesSpace(cm),
              barWidth: cm.display.scrollbarH.clientWidth,
              docHeight: Math.round(cm.doc.height + paddingVert(cm.display))
            };
          }
        
          // Re-synchronize the fake scrollbars with the actual size of the
          // content.
          function updateScrollbars(cm, measure) {
            if (!measure) measure = measureForScrollbars(cm);
            var d = cm.display, sWidth = scrollbarWidth(d.measure);
            var scrollHeight = measure.docHeight + scrollerCutOff;
            var needsH = measure.scrollWidth > measure.clientWidth;
            if (needsH && measure.scrollWidth <= measure.clientWidth + 1 &&
                sWidth > 0 && !measure.hScrollbarTakesSpace)
              needsH = false; // (Issue #2562)
            var needsV = scrollHeight > measure.clientHeight;
        
            if (needsV) {
              d.scrollbarV.style.display = "block";
              d.scrollbarV.style.bottom = needsH ? sWidth + "px" : "0";
              // A bug in IE8 can cause this value to be negative, so guard it.
              d.scrollbarV.firstChild.style.height =
                Math.max(0, scrollHeight - measure.clientHeight + (measure.barHeight || d.scrollbarV.clientHeight)) + "px";
            } else {
              d.scrollbarV.style.display = "";
              d.scrollbarV.firstChild.style.height = "0";
            }
            if (needsH) {
              d.scrollbarH.style.display = "block";
              d.scrollbarH.style.right = needsV ? sWidth + "px" : "0";
              d.scrollbarH.firstChild.style.width =
                (measure.scrollWidth - measure.clientWidth + (measure.barWidth || d.scrollbarH.clientWidth)) + "px";
            } else {
              d.scrollbarH.style.display = "";
              d.scrollbarH.firstChild.style.width = "0";
            }
            if (needsH && needsV) {
              d.scrollbarFiller.style.display = "block";
              d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = sWidth + "px";
            } else d.scrollbarFiller.style.display = "";
            if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
              d.gutterFiller.style.display = "block";
              d.gutterFiller.style.height = sWidth + "px";
              d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
            } else d.gutterFiller.style.display = "";
        
            if (!cm.state.checkedOverlayScrollbar && measure.clientHeight > 0) {
              if (sWidth === 0) {
                var w = mac && !mac_geMountainLion ? "12px" : "18px";
                d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = w;
                var barMouseDown = function(e) {
                  if (e_target(e) != d.scrollbarV && e_target(e) != d.scrollbarH)
                    operation(cm, onMouseDown)(e);
                };
                on(d.scrollbarV, "mousedown", barMouseDown);
                on(d.scrollbarH, "mousedown", barMouseDown);
              }
              cm.state.checkedOverlayScrollbar = true;
            }
          }
        
          // Compute the lines that are visible in a given viewport (defaults
          // the the current scroll position). viewport may contain top,
          // height, and ensure (see op.scrollToPos) properties.
          function visibleLines(display, doc, viewport) {
            var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
            top = Math.floor(top - paddingTop(display));
            var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
        
            var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
            // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
            // forces those lines into the viewport (if possible).
            if (viewport && viewport.ensure) {
              var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
              if (ensureFrom < from)
                return {from: ensureFrom,
                        to: lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)};
              if (Math.min(ensureTo, doc.lastLine()) >= to)
                return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight),
                        to: ensureTo};
            }
            return {from: from, to: Math.max(to, from + 1)};
          }
        
          // LINE NUMBERS
        
          // Re-align line numbers and gutter marks to compensate for
          // horizontal scrolling.
          function alignHorizontally(cm) {
            var display = cm.display, view = display.view;
            if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
            var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
            var gutterW = display.gutters.offsetWidth, left = comp + "px";
            for (var i = 0; i < view.length; i++) if (!view[i].hidden) {
              if (cm.options.fixedGutter && view[i].gutter)
                view[i].gutter.style.left = left;
              var align = view[i].alignable;
              if (align) for (var j = 0; j < align.length; j++)
                align[j].style.left = left;
            }
            if (cm.options.fixedGutter)
              display.gutters.style.left = (comp + gutterW) + "px";
          }
        
          // Used to ensure that the line number gutter is still the right
          // size for the current document size. Returns true when an update
          // is needed.
          function maybeUpdateLineNumberWidth(cm) {
            if (!cm.options.lineNumbers) return false;
            var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
            if (last.length != display.lineNumChars) {
              var test = display.measure.appendChild(elt("div", [elt("div", last)],
                                                         "CodeMirror-linenumber CodeMirror-gutter-elt"));
              var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
              display.lineGutter.style.width = "";
              display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
              display.lineNumWidth = display.lineNumInnerWidth + padding;
              display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
              display.lineGutter.style.width = display.lineNumWidth + "px";
              updateGutterSpace(cm);
              return true;
            }
            return false;
          }
        
          function lineNumberFor(options, i) {
            return String(options.lineNumberFormatter(i + options.firstLineNumber));
          }
        
          // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
          // but using getBoundingClientRect to get a sub-pixel-accurate
          // result.
          function compensateForHScroll(display) {
            return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;
          }
        
          // DISPLAY DRAWING
        
          function DisplayUpdate(cm, viewport, force) {
            var display = cm.display;
        
            this.viewport = viewport;
            // Store some values that we'll need later (but don't want to force a relayout for)
            this.visible = visibleLines(display, cm.doc, viewport);
            this.editorIsHidden = !display.wrapper.offsetWidth;
            this.wrapperHeight = display.wrapper.clientHeight;
            this.wrapperWidth = display.wrapper.clientWidth;
            this.oldViewFrom = display.viewFrom; this.oldViewTo = display.viewTo;
            this.oldScrollerWidth = display.scroller.clientWidth;
            this.force = force;
            this.dims = getDimensions(cm);
          }
        
          // Does the actual updating of the line display. Bails out
          // (returning false) when there is nothing to be done and forced is
          // false.
          function updateDisplayIfNeeded(cm, update) {
            var display = cm.display, doc = cm.doc;
            if (update.editorIsHidden) {
              resetView(cm);
              return false;
            }
        
            // Bail out if the visible area is already rendered and nothing changed.
            if (!update.force &&
                update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
                (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
                countDirtyView(cm) == 0)
              return false;
        
            if (maybeUpdateLineNumberWidth(cm)) {
              resetView(cm);
              update.dims = getDimensions(cm);
            }
        
            // Compute a suitable new viewport (from & to)
            var end = doc.first + doc.size;
            var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
            var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
            if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
            if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
            if (sawCollapsedSpans) {
              from = visualLineNo(cm.doc, from);
              to = visualLineEndNo(cm.doc, to);
            }
        
            var different = from != display.viewFrom || to != display.viewTo ||
              display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
            adjustView(cm, from, to);
        
            display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
            // Position the mover div to align with the current scroll position
            cm.display.mover.style.top = display.viewOffset + "px";
        
            var toUpdate = countDirtyView(cm);
            if (!different && toUpdate == 0 && !update.force &&
                (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
              return false;
        
            // For big changes, we hide the enclosing element during the
            // update, since that speeds up the operations on most browsers.
            var focused = activeElt();
            if (toUpdate > 4) display.lineDiv.style.display = "none";
            patchDisplay(cm, display.updateLineNumbers, update.dims);
            if (toUpdate > 4) display.lineDiv.style.display = "";
            // There might have been a widget with a focused element that got
            // hidden or updated, if so re-focus it.
            if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
        
            // Prevent selection and cursors from interfering with the scroll
            // width.
            removeChildren(display.cursorDiv);
            removeChildren(display.selectionDiv);
        
            if (different) {
              display.lastWrapHeight = update.wrapperHeight;
              display.lastWrapWidth = update.wrapperWidth;
              startWorker(cm, 400);
            }
        
            display.updateLineNumbers = null;
        
            return true;
          }
        
          function postUpdateDisplay(cm, update) {
            var force = update.force, viewport = update.viewport;
            for (var first = true;; first = false) {
              if (first && cm.options.lineWrapping && update.oldScrollerWidth != cm.display.scroller.clientWidth) {
                force = true;
              } else {
                force = false;
                // Clip forced viewport to actual scrollable area.
                if (viewport && viewport.top != null)
                  viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - scrollerCutOff -
                                            cm.display.scroller.clientHeight, viewport.top)};
                // Updated line heights might result in the drawn area not
                // actually covering the viewport. Keep looping until it does.
                update.visible = visibleLines(cm.display, cm.doc, viewport);
                if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
                  break;
              }
              if (!updateDisplayIfNeeded(cm, update)) break;
              updateHeightsInViewport(cm);
              var barMeasure = measureForScrollbars(cm);
              updateSelection(cm);
              setDocumentHeight(cm, barMeasure);
              updateScrollbars(cm, barMeasure);
            }
        
            signalLater(cm, "update", cm);
            if (cm.display.viewFrom != update.oldViewFrom || cm.display.viewTo != update.oldViewTo)
              signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
          }
        
          function updateDisplaySimple(cm, viewport) {
            var update = new DisplayUpdate(cm, viewport);
            if (updateDisplayIfNeeded(cm, update)) {
              updateHeightsInViewport(cm);
              postUpdateDisplay(cm, update);
              var barMeasure = measureForScrollbars(cm);
              updateSelection(cm);
              setDocumentHeight(cm, barMeasure);
              updateScrollbars(cm, barMeasure);
            }
          }
        
          function setDocumentHeight(cm, measure) {
            cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = measure.docHeight + "px";
            cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px";
          }
        
          function checkForWebkitWidthBug(cm, measure) {
            // Work around Webkit bug where it sometimes reserves space for a
            // non-existing phantom scrollbar in the scroller (Issue #2420)
            if (cm.display.sizer.offsetWidth + cm.display.gutters.offsetWidth < cm.display.scroller.clientWidth - 1) {
              cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = "0px";
              cm.display.gutters.style.height = measure.docHeight + "px";
            }
          }
        
          // Read the actual heights of the rendered lines, and update their
          // stored heights to match.
          function updateHeightsInViewport(cm) {
            var display = cm.display;
            var prevBottom = display.lineDiv.offsetTop;
            for (var i = 0; i < display.view.length; i++) {
              var cur = display.view[i], height;
              if (cur.hidden) continue;
              if (ie && ie_version < 8) {
                var bot = cur.node.offsetTop + cur.node.offsetHeight;
                height = bot - prevBottom;
                prevBottom = bot;
              } else {
                var box = cur.node.getBoundingClientRect();
                height = box.bottom - box.top;
              }
              var diff = cur.line.height - height;
              if (height < 2) height = textHeight(display);
              if (diff > .001 || diff < -.001) {
                updateLineHeight(cur.line, height);
                updateWidgetHeight(cur.line);
                if (cur.rest) for (var j = 0; j < cur.rest.length; j++)
                  updateWidgetHeight(cur.rest[j]);
              }
            }
          }
        
          // Read and store the height of line widgets associated with the
          // given line.
          function updateWidgetHeight(line) {
            if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
              line.widgets[i].height = line.widgets[i].node.offsetHeight;
          }
        
          // Do a bulk-read of the DOM positions and sizes needed to draw the
          // view, so that we don't interleave reading and writing to the DOM.
          function getDimensions(cm) {
            var d = cm.display, left = {}, width = {};
            var gutterLeft = d.gutters.clientLeft;
            for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
              left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
              width[cm.options.gutters[i]] = n.clientWidth;
            }
            return {fixedPos: compensateForHScroll(d),
                    gutterTotalWidth: d.gutters.offsetWidth,
                    gutterLeft: left,
                    gutterWidth: width,
                    wrapperWidth: d.wrapper.clientWidth};
          }
        
          // Sync the actual display DOM structure with display.view, removing
          // nodes for lines that are no longer in view, and creating the ones
          // that are not there yet, and updating the ones that are out of
          // date.
          function patchDisplay(cm, updateNumbersFrom, dims) {
            var display = cm.display, lineNumbers = cm.options.lineNumbers;
            var container = display.lineDiv, cur = container.firstChild;
        
            function rm(node) {
              var next = node.nextSibling;
              // Works around a throw-scroll bug in OS X Webkit
              if (webkit && mac && cm.display.currentWheelTarget == node)
                node.style.display = "none";
              else
                node.parentNode.removeChild(node);
              return next;
            }
        
            var view = display.view, lineN = display.viewFrom;
            // Loop over the elements in the view, syncing cur (the DOM nodes
            // in display.lineDiv) with the view as we go.
            for (var i = 0; i < view.length; i++) {
              var lineView = view[i];
              if (lineView.hidden) {
              } else if (!lineView.node) { // Not drawn yet
                var node = buildLineElement(cm, lineView, lineN, dims);
                container.insertBefore(node, cur);
              } else { // Already drawn
                while (cur != lineView.node) cur = rm(cur);
                var updateNumber = lineNumbers && updateNumbersFrom != null &&
                  updateNumbersFrom <= lineN && lineView.lineNumber;
                if (lineView.changes) {
                  if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false;
                  updateLineForChanges(cm, lineView, lineN, dims);
                }
                if (updateNumber) {
                  removeChildren(lineView.lineNumber);
                  lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
                }
                cur = lineView.node.nextSibling;
              }
              lineN += lineView.size;
            }
            while (cur) cur = rm(cur);
          }
        
          // When an aspect of a line changes, a string is added to
          // lineView.changes. This updates the relevant part of the line's
          // DOM structure.
          function updateLineForChanges(cm, lineView, lineN, dims) {
            for (var j = 0; j < lineView.changes.length; j++) {
              var type = lineView.changes[j];
              if (type == "text") updateLineText(cm, lineView);
              else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims);
              else if (type == "class") updateLineClasses(lineView);
              else if (type == "widget") updateLineWidgets(lineView, dims);
            }
            lineView.changes = null;
          }
        
          // Lines with gutter elements, widgets or a background class need to
          // be wrapped, and have the extra elements added to the wrapper div
          function ensureLineWrapped(lineView) {
            if (lineView.node == lineView.text) {
              lineView.node = elt("div", null, null, "position: relative");
              if (lineView.text.parentNode)
                lineView.text.parentNode.replaceChild(lineView.node, lineView.text);
              lineView.node.appendChild(lineView.text);
              if (ie && ie_version < 8) lineView.node.style.zIndex = 2;
            }
            return lineView.node;
          }
        
          function updateLineBackground(lineView) {
            var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
            if (cls) cls += " CodeMirror-linebackground";
            if (lineView.background) {
              if (cls) lineView.background.className = cls;
              else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
            } else if (cls) {
              var wrap = ensureLineWrapped(lineView);
              lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
            }
          }
        
          // Wrapper around buildLineContent which will reuse the structure
          // in display.externalMeasured when possible.
          function getLineContent(cm, lineView) {
            var ext = cm.display.externalMeasured;
            if (ext && ext.line == lineView.line) {
              cm.display.externalMeasured = null;
              lineView.measure = ext.measure;
              return ext.built;
            }
            return buildLineContent(cm, lineView);
          }
        
          // Redraw the line's text. Interacts with the background and text
          // classes because the mode may output tokens that influence these
          // classes.
          function updateLineText(cm, lineView) {
            var cls = lineView.text.className;
            var built = getLineContent(cm, lineView);
            if (lineView.text == lineView.node) lineView.node = built.pre;
            lineView.text.parentNode.replaceChild(built.pre, lineView.text);
            lineView.text = built.pre;
            if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
              lineView.bgClass = built.bgClass;
              lineView.textClass = built.textClass;
              updateLineClasses(lineView);
            } else if (cls) {
              lineView.text.className = cls;
            }
          }
        
          function updateLineClasses(lineView) {
            updateLineBackground(lineView);
            if (lineView.line.wrapClass)
              ensureLineWrapped(lineView).className = lineView.line.wrapClass;
            else if (lineView.node != lineView.text)
              lineView.node.className = "";
            var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
            lineView.text.className = textClass || "";
          }
        
          function updateLineGutter(cm, lineView, lineN, dims) {
            if (lineView.gutter) {
              lineView.node.removeChild(lineView.gutter);
              lineView.gutter = null;
            }
            var markers = lineView.line.gutterMarkers;
            if (cm.options.lineNumbers || markers) {
              var wrap = ensureLineWrapped(lineView);
              var gutterWrap = lineView.gutter =
                wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "left: " +
                                      (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
                                      "px; width: " + dims.gutterTotalWidth + "px"),
                                  lineView.text);
              if (lineView.line.gutterClass)
                gutterWrap.className += " " + lineView.line.gutterClass;
              if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
                lineView.lineNumber = gutterWrap.appendChild(
                  elt("div", lineNumberFor(cm.options, lineN),
                      "CodeMirror-linenumber CodeMirror-gutter-elt",
                      "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
                      + cm.display.lineNumInnerWidth + "px"));
              if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {
                var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
                if (found)
                  gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
                                             dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
              }
            }
          }
        
          function updateLineWidgets(lineView, dims) {
            if (lineView.alignable) lineView.alignable = null;
            for (var node = lineView.node.firstChild, next; node; node = next) {
              var next = node.nextSibling;
              if (node.className == "CodeMirror-linewidget")
                lineView.node.removeChild(node);
            }
            insertLineWidgets(lineView, dims);
          }
        
          // Build a line's DOM representation from scratch
          function buildLineElement(cm, lineView, lineN, dims) {
            var built = getLineContent(cm, lineView);
            lineView.text = lineView.node = built.pre;
            if (built.bgClass) lineView.bgClass = built.bgClass;
            if (built.textClass) lineView.textClass = built.textClass;
        
            updateLineClasses(lineView);
            updateLineGutter(cm, lineView, lineN, dims);
            insertLineWidgets(lineView, dims);
            return lineView.node;
          }
        
          // A lineView may contain multiple logical lines (when merged by
          // collapsed spans). The widgets for all of them need to be drawn.
          function insertLineWidgets(lineView, dims) {
            insertLineWidgetsFor(lineView.line, lineView, dims, true);
            if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
              insertLineWidgetsFor(lineView.rest[i], lineView, dims, false);
          }
        
          function insertLineWidgetsFor(line, lineView, dims, allowAbove) {
            if (!line.widgets) return;
            var wrap = ensureLineWrapped(lineView);
            for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
              var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
              if (!widget.handleMouseEvents) node.ignoreEvents = true;
              positionLineWidget(widget, node, lineView, dims);
              if (allowAbove && widget.above)
                wrap.insertBefore(node, lineView.gutter || lineView.text);
              else
                wrap.appendChild(node);
              signalLater(widget, "redraw");
            }
          }
        
          function positionLineWidget(widget, node, lineView, dims) {
            if (widget.noHScroll) {
              (lineView.alignable || (lineView.alignable = [])).push(node);
              var width = dims.wrapperWidth;
              node.style.left = dims.fixedPos + "px";
              if (!widget.coverGutter) {
                width -= dims.gutterTotalWidth;
                node.style.paddingLeft = dims.gutterTotalWidth + "px";
              }
              node.style.width = width + "px";
            }
            if (widget.coverGutter) {
              node.style.zIndex = 5;
              node.style.position = "relative";
              if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
            }
          }
        
          // POSITION OBJECT
        
          // A Pos instance represents a position within the text.
          var Pos = CodeMirror.Pos = function(line, ch) {
            if (!(this instanceof Pos)) return new Pos(line, ch);
            this.line = line; this.ch = ch;
          };
        
          // Compare two positions, return 0 if they are the same, a negative
          // number when a is less, and a positive number otherwise.
          var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };
        
          function copyPos(x) {return Pos(x.line, x.ch);}
          function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }
          function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }
        
          // SELECTION / CURSOR
        
          // Selection objects are immutable. A new one is created every time
          // the selection changes. A selection is one or more non-overlapping
          // (and non-touching) ranges, sorted, and an integer that indicates
          // which one is the primary selection (the one that's scrolled into
          // view, that getCursor returns, etc).
          function Selection(ranges, primIndex) {
            this.ranges = ranges;
            this.primIndex = primIndex;
          }
        
          Selection.prototype = {
            primary: function() { return this.ranges[this.primIndex]; },
            equals: function(other) {
              if (other == this) return true;
              if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;
              for (var i = 0; i < this.ranges.length; i++) {
                var here = this.ranges[i], there = other.ranges[i];
                if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;
              }
              return true;
            },
            deepCopy: function() {
              for (var out = [], i = 0; i < this.ranges.length; i++)
                out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));
              return new Selection(out, this.primIndex);
            },
            somethingSelected: function() {
              for (var i = 0; i < this.ranges.length; i++)
                if (!this.ranges[i].empty()) return true;
              return false;
            },
            contains: function(pos, end) {
              if (!end) end = pos;
              for (var i = 0; i < this.ranges.length; i++) {
                var range = this.ranges[i];
                if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
                  return i;
              }
              return -1;
            }
          };
        
          function Range(anchor, head) {
            this.anchor = anchor; this.head = head;
          }
        
          Range.prototype = {
            from: function() { return minPos(this.anchor, this.head); },
            to: function() { return maxPos(this.anchor, this.head); },
            empty: function() {
              return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;
            }
          };
        
          // Take an unsorted, potentially overlapping set of ranges, and
          // build a selection out of it. 'Consumes' ranges array (modifying
          // it).
          function normalizeSelection(ranges, primIndex) {
            var prim = ranges[primIndex];
            ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });
            primIndex = indexOf(ranges, prim);
            for (var i = 1; i < ranges.length; i++) {
              var cur = ranges[i], prev = ranges[i - 1];
              if (cmp(prev.to(), cur.from()) >= 0) {
                var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
                var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
                if (i <= primIndex) --primIndex;
                ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
              }
            }
            return new Selection(ranges, primIndex);
          }
        
          function simpleSelection(anchor, head) {
            return new Selection([new Range(anchor, head || anchor)], 0);
          }
        
          // Most of the external API clips given positions to make sure they
          // actually exist within the document.
          function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
          function clipPos(doc, pos) {
            if (pos.line < doc.first) return Pos(doc.first, 0);
            var last = doc.first + doc.size - 1;
            if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
            return clipToLen(pos, getLine(doc, pos.line).text.length);
          }
          function clipToLen(pos, linelen) {
            var ch = pos.ch;
            if (ch == null || ch > linelen) return Pos(pos.line, linelen);
            else if (ch < 0) return Pos(pos.line, 0);
            else return pos;
          }
          function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
          function clipPosArray(doc, array) {
            for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);
            return out;
          }
        
          // SELECTION UPDATES
        
          // The 'scroll' parameter given to many of these indicated whether
          // the new cursor position should be scrolled into view after
          // modifying the selection.
        
          // If shift is held or the extend flag is set, extends a range to
          // include a given position (and optionally a second position).
          // Otherwise, simply returns the range between the given positions.
          // Used for cursor motion and such.
          function extendRange(doc, range, head, other) {
            if (doc.cm && doc.cm.display.shift || doc.extend) {
              var anchor = range.anchor;
              if (other) {
                var posBefore = cmp(head, anchor) < 0;
                if (posBefore != (cmp(other, anchor) < 0)) {
                  anchor = head;
                  head = other;
                } else if (posBefore != (cmp(head, other) < 0)) {
                  head = other;
                }
              }
              return new Range(anchor, head);
            } else {
              return new Range(other || head, head);
            }
          }
        
          // Extend the primary selection range, discard the rest.
          function extendSelection(doc, head, other, options) {
            setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);
          }
        
          // Extend all selections (pos is an array of selections with length
          // equal the number of selections)
          function extendSelections(doc, heads, options) {
            for (var out = [], i = 0; i < doc.sel.ranges.length; i++)
              out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);
            var newSel = normalizeSelection(out, doc.sel.primIndex);
            setSelection(doc, newSel, options);
          }
        
          // Updates a single range in the selection.
          function replaceOneSelection(doc, i, range, options) {
            var ranges = doc.sel.ranges.slice(0);
            ranges[i] = range;
            setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
          }
        
          // Reset the selection to a single range.
          function setSimpleSelection(doc, anchor, head, options) {
            setSelection(doc, simpleSelection(anchor, head), options);
          }
        
          // Give beforeSelectionChange handlers a change to influence a
          // selection update.
          function filterSelectionChange(doc, sel) {
            var obj = {
              ranges: sel.ranges,
              update: function(ranges) {
                this.ranges = [];
                for (var i = 0; i < ranges.length; i++)
                  this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
                                             clipPos(doc, ranges[i].head));
              }
            };
            signal(doc, "beforeSelectionChange", doc, obj);
            if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
            if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);
            else return sel;
          }
        
          function setSelectionReplaceHistory(doc, sel, options) {
            var done = doc.history.done, last = lst(done);
            if (last && last.ranges) {
              done[done.length - 1] = sel;
              setSelectionNoUndo(doc, sel, options);
            } else {
              setSelection(doc, sel, options);
            }
          }
        
          // Set a new selection.
          function setSelection(doc, sel, options) {
            setSelectionNoUndo(doc, sel, options);
            addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
          }
        
          function setSelectionNoUndo(doc, sel, options) {
            if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
              sel = filterSelectionChange(doc, sel);
        
            var bias = options && options.bias ||
              (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
            setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
        
            if (!(options && options.scroll === false) && doc.cm)
              ensureCursorVisible(doc.cm);
          }
        
          function setSelectionInner(doc, sel) {
            if (sel.equals(doc.sel)) return;
        
            doc.sel = sel;
        
            if (doc.cm) {
              doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
              signalCursorActivity(doc.cm);
            }
            signalLater(doc, "cursorActivity", doc);
          }
        
          // Verify that the selection does not partially select any atomic
          // marked ranges.
          function reCheckSelection(doc) {
            setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);
          }
        
          // Return a selection that does not partially select any atomic
          // ranges.
          function skipAtomicInSelection(doc, sel, bias, mayClear) {
            var out;
            for (var i = 0; i < sel.ranges.length; i++) {
              var range = sel.ranges[i];
              var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);
              var newHead = skipAtomic(doc, range.head, bias, mayClear);
              if (out || newAnchor != range.anchor || newHead != range.head) {
                if (!out) out = sel.ranges.slice(0, i);
                out[i] = new Range(newAnchor, newHead);
              }
            }
            return out ? normalizeSelection(out, sel.primIndex) : sel;
          }
        
          // Ensure a given position is not inside an atomic range.
          function skipAtomic(doc, pos, bias, mayClear) {
            var flipped = false, curPos = pos;
            var dir = bias || 1;
            doc.cantEdit = false;
            search: for (;;) {
              var line = getLine(doc, curPos.line);
              if (line.markedSpans) {
                for (var i = 0; i < line.markedSpans.length; ++i) {
                  var sp = line.markedSpans[i], m = sp.marker;
                  if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
                      (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
                    if (mayClear) {
                      signal(m, "beforeCursorEnter");
                      if (m.explicitlyCleared) {
                        if (!line.markedSpans) break;
                        else {--i; continue;}
                      }
                    }
                    if (!m.atomic) continue;
                    var newPos = m.find(dir < 0 ? -1 : 1);
                    if (cmp(newPos, curPos) == 0) {
                      newPos.ch += dir;
                      if (newPos.ch < 0) {
                        if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
                        else newPos = null;
                      } else if (newPos.ch > line.text.length) {
                        if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
                        else newPos = null;
                      }
                      if (!newPos) {
                        if (flipped) {
                          // Driven in a corner -- no valid cursor position found at all
                          // -- try again *with* clearing, if we didn't already
                          if (!mayClear) return skipAtomic(doc, pos, bias, true);
                          // Otherwise, turn off editing until further notice, and return the start of the doc
                          doc.cantEdit = true;
                          return Pos(doc.first, 0);
                        }
                        flipped = true; newPos = pos; dir = -dir;
                      }
                    }
                    curPos = newPos;
                    continue search;
                  }
                }
              }
              return curPos;
            }
          }
        
          // SELECTION DRAWING
        
          // Redraw the selection and/or cursor
          function drawSelection(cm) {
            var display = cm.display, doc = cm.doc, result = {};
            var curFragment = result.cursors = document.createDocumentFragment();
            var selFragment = result.selection = document.createDocumentFragment();
        
            for (var i = 0; i < doc.sel.ranges.length; i++) {
              var range = doc.sel.ranges[i];
              var collapsed = range.empty();
              if (collapsed || cm.options.showCursorWhenSelecting)
                drawSelectionCursor(cm, range, curFragment);
              if (!collapsed)
                drawSelectionRange(cm, range, selFragment);
            }
        
            // Move the hidden textarea near the cursor to prevent scrolling artifacts
            if (cm.options.moveInputWithCursor) {
              var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
              var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
              result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
                                                  headPos.top + lineOff.top - wrapOff.top));
              result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
                                                   headPos.left + lineOff.left - wrapOff.left));
            }
        
            return result;
          }
        
          function showSelection(cm, drawn) {
            removeChildrenAndAdd(cm.display.cursorDiv, drawn.cursors);
            removeChildrenAndAdd(cm.display.selectionDiv, drawn.selection);
            if (drawn.teTop != null) {
              cm.display.inputDiv.style.top = drawn.teTop + "px";
              cm.display.inputDiv.style.left = drawn.teLeft + "px";
            }
          }
        
          function updateSelection(cm) {
            showSelection(cm, drawSelection(cm));
          }
        
          // Draws a cursor for the given range
          function drawSelectionCursor(cm, range, output) {
            var pos = cursorCoords(cm, range.head, "div", null, null, !cm.options.singleCursorHeightPerLine);
        
            var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
            cursor.style.left = pos.left + "px";
            cursor.style.top = pos.top + "px";
            cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
        
            if (pos.other) {
              // Secondary cursor, shown when on a 'jump' in bi-directional text
              var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
              otherCursor.style.display = "";
              otherCursor.style.left = pos.other.left + "px";
              otherCursor.style.top = pos.other.top + "px";
              otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
            }
          }
        
          // Draws the given range as a highlighted selection
          function drawSelectionRange(cm, range, output) {
            var display = cm.display, doc = cm.doc;
            var fragment = document.createDocumentFragment();
            var padding = paddingH(cm.display), leftSide = padding.left, rightSide = display.lineSpace.offsetWidth - padding.right;
        
            function add(left, top, width, bottom) {
              if (top < 0) top = 0;
              top = Math.round(top);
              bottom = Math.round(bottom);
              fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
                                       "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) +
                                       "px; height: " + (bottom - top) + "px"));
            }
        
            function drawForLine(line, fromArg, toArg) {
              var lineObj = getLine(doc, line);
              var lineLen = lineObj.text.length;
              var start, end;
              function coords(ch, bias) {
                return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
              }
        
              iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
                var leftPos = coords(from, "left"), rightPos, left, right;
                if (from == to) {
                  rightPos = leftPos;
                  left = right = leftPos.left;
                } else {
                  rightPos = coords(to - 1, "right");
                  if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
                  left = leftPos.left;
                  right = rightPos.right;
                }
                if (fromArg == null && from == 0) left = leftSide;
                if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
                  add(left, leftPos.top, null, leftPos.bottom);
                  left = leftSide;
                  if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
                }
                if (toArg == null && to == lineLen) right = rightSide;
                if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
                  start = leftPos;
                if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
                  end = rightPos;
                if (left < leftSide + 1) left = leftSide;
                add(left, rightPos.top, right - left, rightPos.bottom);
              });
              return {start: start, end: end};
            }
        
            var sFrom = range.from(), sTo = range.to();
            if (sFrom.line == sTo.line) {
              drawForLine(sFrom.line, sFrom.ch, sTo.ch);
            } else {
              var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
              var singleVLine = visualLine(fromLine) == visualLine(toLine);
              var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
              var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
              if (singleVLine) {
                if (leftEnd.top < rightStart.top - 2) {
                  add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
                  add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
                } else {
                  add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
                }
              }
              if (leftEnd.bottom < rightStart.top)
                add(leftSide, leftEnd.bottom, null, rightStart.top);
            }
        
            output.appendChild(fragment);
          }
        
          // Cursor-blinking
          function restartBlink(cm) {
            if (!cm.state.focused) return;
            var display = cm.display;
            clearInterval(display.blinker);
            var on = true;
            display.cursorDiv.style.visibility = "";
            if (cm.options.cursorBlinkRate > 0)
              display.blinker = setInterval(function() {
                display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden";
              }, cm.options.cursorBlinkRate);
            else if (cm.options.cursorBlinkRate < 0)
              display.cursorDiv.style.visibility = "hidden";
          }
        
          // HIGHLIGHT WORKER
        
          function startWorker(cm, time) {
            if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)
              cm.state.highlight.set(time, bind(highlightWorker, cm));
          }
        
          function highlightWorker(cm) {
            var doc = cm.doc;
            if (doc.frontier < doc.first) doc.frontier = doc.first;
            if (doc.frontier >= cm.display.viewTo) return;
            var end = +new Date + cm.options.workTime;
            var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
            var changedLines = [];
        
            doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
              if (doc.frontier >= cm.display.viewFrom) { // Visible
                var oldStyles = line.styles;
                var highlighted = highlightLine(cm, line, state, true);
                line.styles = highlighted.styles;
                var oldCls = line.styleClasses, newCls = highlighted.classes;
                if (newCls) line.styleClasses = newCls;
                else if (oldCls) line.styleClasses = null;
                var ischange = !oldStyles || oldStyles.length != line.styles.length ||
                  oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
                for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
                if (ischange) changedLines.push(doc.frontier);
                line.stateAfter = copyState(doc.mode, state);
              } else {
                processLine(cm, line.text, state);
                line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
              }
              ++doc.frontier;
              if (+new Date > end) {
                startWorker(cm, cm.options.workDelay);
                return true;
              }
            });
            if (changedLines.length) runInOp(cm, function() {
              for (var i = 0; i < changedLines.length; i++)
                regLineChange(cm, changedLines[i], "text");
            });
          }
        
          // Finds the line to start with when starting a parse. Tries to
          // find a line with a stateAfter, so that it can start with a
          // valid state. If that fails, it returns the line with the
          // smallest indentation, which tends to need the least context to
          // parse correctly.
          function findStartLine(cm, n, precise) {
            var minindent, minline, doc = cm.doc;
            var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
            for (var search = n; search > lim; --search) {
              if (search <= doc.first) return doc.first;
              var line = getLine(doc, search - 1);
              if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
              var indented = countColumn(line.text, null, cm.options.tabSize);
              if (minline == null || minindent > indented) {
                minline = search - 1;
                minindent = indented;
              }
            }
            return minline;
          }
        
          function getStateBefore(cm, n, precise) {
            var doc = cm.doc, display = cm.display;
            if (!doc.mode.startState) return true;
            var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
            if (!state) state = startState(doc.mode);
            else state = copyState(doc.mode, state);
            doc.iter(pos, n, function(line) {
              processLine(cm, line.text, state);
              var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo;
              line.stateAfter = save ? copyState(doc.mode, state) : null;
              ++pos;
            });
            if (precise) doc.frontier = pos;
            return state;
          }
        
          // POSITION MEASUREMENT
        
          function paddingTop(display) {return display.lineSpace.offsetTop;}
          function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
          function paddingH(display) {
            if (display.cachedPaddingH) return display.cachedPaddingH;
            var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
            var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
            var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
            if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data;
            return data;
          }
        
          // Ensure the lineView.wrapping.heights array is populated. This is
          // an array of bottom offsets for the lines that make up a drawn
          // line. When lineWrapping is on, there might be more than one
          // height.
          function ensureLineHeights(cm, lineView, rect) {
            var wrapping = cm.options.lineWrapping;
            var curWidth = wrapping && cm.display.scroller.clientWidth;
            if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
              var heights = lineView.measure.heights = [];
              if (wrapping) {
                lineView.measure.width = curWidth;
                var rects = lineView.text.firstChild.getClientRects();
                for (var i = 0; i < rects.length - 1; i++) {
                  var cur = rects[i], next = rects[i + 1];
                  if (Math.abs(cur.bottom - next.bottom) > 2)
                    heights.push((cur.bottom + next.top) / 2 - rect.top);
                }
              }
              heights.push(rect.bottom - rect.top);
            }
          }
        
          // Find a line map (mapping character offsets to text nodes) and a
          // measurement cache for the given line number. (A line view might
          // contain multiple lines when collapsed ranges are present.)
          function mapFromLineView(lineView, line, lineN) {
            if (lineView.line == line)
              return {map: lineView.measure.map, cache: lineView.measure.cache};
            for (var i = 0; i < lineView.rest.length; i++)
              if (lineView.rest[i] == line)
                return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]};
            for (var i = 0; i < lineView.rest.length; i++)
              if (lineNo(lineView.rest[i]) > lineN)
                return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true};
          }
        
          // Render a line into the hidden node display.externalMeasured. Used
          // when measurement is needed for a line that's not in the viewport.
          function updateExternalMeasurement(cm, line) {
            line = visualLine(line);
            var lineN = lineNo(line);
            var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
            view.lineN = lineN;
            var built = view.built = buildLineContent(cm, view);
            view.text = built.pre;
            removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
            return view;
          }
        
          // Get a {top, bottom, left, right} box (in line-local coordinates)
          // for a given character.
          function measureChar(cm, line, ch, bias) {
            return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias);
          }
        
          // Find a line view that corresponds to the given line number.
          function findViewForLine(cm, lineN) {
            if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
              return cm.display.view[findViewIndex(cm, lineN)];
            var ext = cm.display.externalMeasured;
            if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
              return ext;
          }
        
          // Measurement can be split in two steps, the set-up work that
          // applies to the whole line, and the measurement of the actual
          // character. Functions like coordsChar, that need to do a lot of
          // measurements in a row, can thus ensure that the set-up work is
          // only done once.
          function prepareMeasureForLine(cm, line) {
            var lineN = lineNo(line);
            var view = findViewForLine(cm, lineN);
            if (view && !view.text)
              view = null;
            else if (view && view.changes)
              updateLineForChanges(cm, view, lineN, getDimensions(cm));
            if (!view)
              view = updateExternalMeasurement(cm, line);
        
            var info = mapFromLineView(view, line, lineN);
            return {
              line: line, view: view, rect: null,
              map: info.map, cache: info.cache, before: info.before,
              hasHeights: false
            };
          }
        
          // Given a prepared measurement object, measures the position of an
          // actual character (or fetches it from the cache).
          function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
            if (prepared.before) ch = -1;
            var key = ch + (bias || ""), found;
            if (prepared.cache.hasOwnProperty(key)) {
              found = prepared.cache[key];
            } else {
              if (!prepared.rect)
                prepared.rect = prepared.view.text.getBoundingClientRect();
              if (!prepared.hasHeights) {
                ensureLineHeights(cm, prepared.view, prepared.rect);
                prepared.hasHeights = true;
              }
              found = measureCharInner(cm, prepared, ch, bias);
              if (!found.bogus) prepared.cache[key] = found;
            }
            return {left: found.left, right: found.right,
                    top: varHeight ? found.rtop : found.top,
                    bottom: varHeight ? found.rbottom : found.bottom};
          }
        
          var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
        
          function measureCharInner(cm, prepared, ch, bias) {
            var map = prepared.map;
        
            var node, start, end, collapse;
            // First, search the line map for the text node corresponding to,
            // or closest to, the target character.
            for (var i = 0; i < map.length; i += 3) {
              var mStart = map[i], mEnd = map[i + 1];
              if (ch < mStart) {
                start = 0; end = 1;
                collapse = "left";
              } else if (ch < mEnd) {
                start = ch - mStart;
                end = start + 1;
              } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {
                end = mEnd - mStart;
                start = end - 1;
                if (ch >= mEnd) collapse = "right";
              }
              if (start != null) {
                node = map[i + 2];
                if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
                  collapse = bias;
                if (bias == "left" && start == 0)
                  while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
                    node = map[(i -= 3) + 2];
                    collapse = "left";
                  }
                if (bias == "right" && start == mEnd - mStart)
                  while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
                    node = map[(i += 3) + 2];
                    collapse = "right";
                  }
                break;
              }
            }
        
            var rect;
            if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
              for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned
                while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;
                while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;
                if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) {
                  rect = node.parentNode.getBoundingClientRect();
                } else if (ie && cm.options.lineWrapping) {
                  var rects = range(node, start, end).getClientRects();
                  if (rects.length)
                    rect = rects[bias == "right" ? rects.length - 1 : 0];
                  else
                    rect = nullRect;
                } else {
                  rect = range(node, start, end).getBoundingClientRect() || nullRect;
                }
                if (rect.left || rect.right || start == 0) break;
                end = start;
                start = start - 1;
                collapse = "right";
              }
              if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect);
            } else { // If it is a widget, simply get the box for the whole widget.
              if (start > 0) collapse = bias = "right";
              var rects;
              if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
                rect = rects[bias == "right" ? rects.length - 1 : 0];
              else
                rect = node.getBoundingClientRect();
            }
            if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
              var rSpan = node.parentNode.getClientRects()[0];
              if (rSpan)
                rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom};
              else
                rect = nullRect;
            }
        
            var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
            var mid = (rtop + rbot) / 2;
            var heights = prepared.view.measure.heights;
            for (var i = 0; i < heights.length - 1; i++)
              if (mid < heights[i]) break;
            var top = i ? heights[i - 1] : 0, bot = heights[i];
            var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
                          right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
                          top: top, bottom: bot};
            if (!rect.left && !rect.right) result.bogus = true;
            if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
        
            return result;
          }
        
          // Work around problem with bounding client rects on ranges being
          // returned incorrectly when zoomed on IE10 and below.
          function maybeUpdateRectForZooming(measure, rect) {
            if (!window.screen || screen.logicalXDPI == null ||
                screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
              return rect;
            var scaleX = screen.logicalXDPI / screen.deviceXDPI;
            var scaleY = screen.logicalYDPI / screen.deviceYDPI;
            return {left: rect.left * scaleX, right: rect.right * scaleX,
                    top: rect.top * scaleY, bottom: rect.bottom * scaleY};
          }
        
          function clearLineMeasurementCacheFor(lineView) {
            if (lineView.measure) {
              lineView.measure.cache = {};
              lineView.measure.heights = null;
              if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
                lineView.measure.caches[i] = {};
            }
          }
        
          function clearLineMeasurementCache(cm) {
            cm.display.externalMeasure = null;
            removeChildren(cm.display.lineMeasure);
            for (var i = 0; i < cm.display.view.length; i++)
              clearLineMeasurementCacheFor(cm.display.view[i]);
          }
        
          function clearCaches(cm) {
            clearLineMeasurementCache(cm);
            cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
            if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
            cm.display.lineNumChars = null;
          }
        
          function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
          function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
        
          // Converts a {top, bottom, left, right} box from line-local
          // coordinates into another coordinate system. Context may be one of
          // "line", "div" (display.lineDiv), "local"/null (editor), or "page".
          function intoCoordSystem(cm, lineObj, rect, context) {
            if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
              var size = widgetHeight(lineObj.widgets[i]);
              rect.top += size; rect.bottom += size;
            }
            if (context == "line") return rect;
            if (!context) context = "local";
            var yOff = heightAtLine(lineObj);
            if (context == "local") yOff += paddingTop(cm.display);
            else yOff -= cm.display.viewOffset;
            if (context == "page" || context == "window") {
              var lOff = cm.display.lineSpace.getBoundingClientRect();
              yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
              var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
              rect.left += xOff; rect.right += xOff;
            }
            rect.top += yOff; rect.bottom += yOff;
            return rect;
          }
        
          // Coverts a box from "div" coords to another coordinate system.
          // Context may be "window", "page", "div", or "local"/null.
          function fromCoordSystem(cm, coords, context) {
            if (context == "div") return coords;
            var left = coords.left, top = coords.top;
            // First move into "page" coordinate system
            if (context == "page") {
              left -= pageScrollX();
              top -= pageScrollY();
            } else if (context == "local" || !context) {
              var localBox = cm.display.sizer.getBoundingClientRect();
              left += localBox.left;
              top += localBox.top;
            }
        
            var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
            return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
          }
        
          function charCoords(cm, pos, context, lineObj, bias) {
            if (!lineObj) lineObj = getLine(cm.doc, pos.line);
            return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context);
          }
        
          // Returns a box for a given cursor position, which may have an
          // 'other' property containing the position of the secondary cursor
          // on a bidi boundary.
          function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
            lineObj = lineObj || getLine(cm.doc, pos.line);
            if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj);
            function get(ch, right) {
              var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight);
              if (right) m.left = m.right; else m.right = m.left;
              return intoCoordSystem(cm, lineObj, m, context);
            }
            function getBidi(ch, partPos) {
              var part = order[partPos], right = part.level % 2;
              if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
                part = order[--partPos];
                ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
                right = true;
              } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
                part = order[++partPos];
                ch = bidiLeft(part) - part.level % 2;
                right = false;
              }
              if (right && ch == part.to && ch > part.from) return get(ch - 1);
              return get(ch, right);
            }
            var order = getOrder(lineObj), ch = pos.ch;
            if (!order) return get(ch);
            var partPos = getBidiPartAt(order, ch);
            var val = getBidi(ch, partPos);
            if (bidiOther != null) val.other = getBidi(ch, bidiOther);
            return val;
          }
        
          // Used to cheaply estimate the coordinates for a position. Used for
          // intermediate scroll updates.
          function estimateCoords(cm, pos) {
            var left = 0, pos = clipPos(cm.doc, pos);
            if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch;
            var lineObj = getLine(cm.doc, pos.line);
            var top = heightAtLine(lineObj) + paddingTop(cm.display);
            return {left: left, right: left, top: top, bottom: top + lineObj.height};
          }
        
          // Positions returned by coordsChar contain some extra information.
          // xRel is the relative x position of the input coordinates compared
          // to the found position (so xRel > 0 means the coordinates are to
          // the right of the character position, for example). When outside
          // is true, that means the coordinates lie outside the line's
          // vertical range.
          function PosWithInfo(line, ch, outside, xRel) {
            var pos = Pos(line, ch);
            pos.xRel = xRel;
            if (outside) pos.outside = true;
            return pos;
          }
        
          // Compute the character position closest to the given coordinates.
          // Input must be lineSpace-local ("div" coordinate system).
          function coordsChar(cm, x, y) {
            var doc = cm.doc;
            y += cm.display.viewOffset;
            if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
            var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
            if (lineN > last)
              return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
            if (x < 0) x = 0;
        
            var lineObj = getLine(doc, lineN);
            for (;;) {
              var found = coordsCharInner(cm, lineObj, lineN, x, y);
              var merged = collapsedSpanAtEnd(lineObj);
              var mergedPos = merged && merged.find(0, true);
              if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
                lineN = lineNo(lineObj = mergedPos.to.line);
              else
                return found;
            }
          }
        
          function coordsCharInner(cm, lineObj, lineNo, x, y) {
            var innerOff = y - heightAtLine(lineObj);
            var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
            var preparedMeasure = prepareMeasureForLine(cm, lineObj);
        
            function getX(ch) {
              var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure);
              wrongLine = true;
              if (innerOff > sp.bottom) return sp.left - adjust;
              else if (innerOff < sp.top) return sp.left + adjust;
              else wrongLine = false;
              return sp.left;
            }
        
            var bidi = getOrder(lineObj), dist = lineObj.text.length;
            var from = lineLeft(lineObj), to = lineRight(lineObj);
            var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
        
            if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
            // Do a binary search between these bounds.
            for (;;) {
              if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
                var ch = x < fromX || x - fromX <= toX - x ? from : to;
                var xDiff = x - (ch == from ? fromX : toX);
                while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
                var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
                                      xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);
                return pos;
              }
              var step = Math.ceil(dist / 2), middle = from + step;
              if (bidi) {
                middle = from;
                for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
              }
              var middleX = getX(middle);
              if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
              else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
            }
          }
        
          var measureText;
          // Compute the default text height.
          function textHeight(display) {
            if (display.cachedTextHeight != null) return display.cachedTextHeight;
            if (measureText == null) {
              measureText = elt("pre");
              // Measure a bunch of lines, for browsers that compute
              // fractional heights.
              for (var i = 0; i < 49; ++i) {
                measureText.appendChild(document.createTextNode("x"));
                measureText.appendChild(elt("br"));
              }
              measureText.appendChild(document.createTextNode("x"));
            }
            removeChildrenAndAdd(display.measure, measureText);
            var height = measureText.offsetHeight / 50;
            if (height > 3) display.cachedTextHeight = height;
            removeChildren(display.measure);
            return height || 1;
          }
        
          // Compute the default character width.
          function charWidth(display) {
            if (display.cachedCharWidth != null) return display.cachedCharWidth;
            var anchor = elt("span", "xxxxxxxxxx");
            var pre = elt("pre", [anchor]);
            removeChildrenAndAdd(display.measure, pre);
            var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
            if (width > 2) display.cachedCharWidth = width;
            return width || 10;
          }
        
          // OPERATIONS
        
          // Operations are used to wrap a series of changes to the editor
          // state in such a way that each change won't have to update the
          // cursor and display (which would be awkward, slow, and
          // error-prone). Instead, display updates are batched and then all
          // combined and executed at once.
        
          var operationGroup = null;
        
          var nextOpId = 0;
          // Start a new operation.
          function startOperation(cm) {
            cm.curOp = {
              cm: cm,
              viewChanged: false,      // Flag that indicates that lines might need to be redrawn
              startHeight: cm.doc.height, // Used to detect need to update scrollbar
              forceUpdate: false,      // Used to force a redraw
              updateInput: null,       // Whether to reset the input textarea
              typing: false,           // Whether this reset should be careful to leave existing text (for compositing)
              changeObjs: null,        // Accumulated changes, for firing change events
              cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
              cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
              selectionChanged: false, // Whether the selection needs to be redrawn
              updateMaxLine: false,    // Set when the widest line needs to be determined anew
              scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
              scrollToPos: null,       // Used to scroll to a specific position
              id: ++nextOpId           // Unique ID
            };
            if (operationGroup) {
              operationGroup.ops.push(cm.curOp);
            } else {
              cm.curOp.ownsGroup = operationGroup = {
                ops: [cm.curOp],
                delayedCallbacks: []
              };
            }
          }
        
          function fireCallbacksForOps(group) {
            // Calls delayed callbacks and cursorActivity handlers until no
            // new ones appear
            var callbacks = group.delayedCallbacks, i = 0;
            do {
              for (; i < callbacks.length; i++)
                callbacks[i]();
              for (var j = 0; j < group.ops.length; j++) {
                var op = group.ops[j];
                if (op.cursorActivityHandlers)
                  while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
                    op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm);
              }
            } while (i < callbacks.length);
          }
        
          // Finish an operation, updating the display and signalling delayed events
          function endOperation(cm) {
            var op = cm.curOp, group = op.ownsGroup;
            if (!group) return;
        
            try { fireCallbacksForOps(group); }
            finally {
              operationGroup = null;
              for (var i = 0; i < group.ops.length; i++)
                group.ops[i].cm.curOp = null;
              endOperations(group);
            }
          }
        
          // The DOM updates done when an operation finishes are batched so
          // that the minimum number of relayouts are required.
          function endOperations(group) {
            var ops = group.ops;
            for (var i = 0; i < ops.length; i++) // Read DOM
              endOperation_R1(ops[i]);
            for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
              endOperation_W1(ops[i]);
            for (var i = 0; i < ops.length; i++) // Read DOM
              endOperation_R2(ops[i]);
            for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
              endOperation_W2(ops[i]);
            for (var i = 0; i < ops.length; i++) // Read DOM
              endOperation_finish(ops[i]);
          }
        
          function endOperation_R1(op) {
            var cm = op.cm, display = cm.display;
            if (op.updateMaxLine) findMaxLine(cm);
        
            op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
              op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
                                 op.scrollToPos.to.line >= display.viewTo) ||
              display.maxLineChanged && cm.options.lineWrapping;
            op.update = op.mustUpdate &&
              new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
          }
        
          function endOperation_W1(op) {
            op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
          }
        
          function endOperation_R2(op) {
            var cm = op.cm, display = cm.display;
            if (op.updatedDisplay) updateHeightsInViewport(cm);
        
            op.barMeasure = measureForScrollbars(cm);
        
            // If the max line changed since it was last measured, measure it,
            // and ensure the document's width matches it.
            // updateDisplay_W2 will use these properties to do the actual resizing
            if (display.maxLineChanged && !cm.options.lineWrapping) {
              op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
              op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo +
                                          scrollerCutOff - display.scroller.clientWidth);
            }
        
            if (op.updatedDisplay || op.selectionChanged)
              op.newSelectionNodes = drawSelection(cm);
          }
        
          function endOperation_W2(op) {
            var cm = op.cm;
        
            if (op.adjustWidthTo != null) {
              cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
              if (op.maxScrollLeft < cm.doc.scrollLeft)
                setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true);
              cm.display.maxLineChanged = false;
            }
        
            if (op.newSelectionNodes)
              showSelection(cm, op.newSelectionNodes);
            if (op.updatedDisplay)
              setDocumentHeight(cm, op.barMeasure);
            if (op.updatedDisplay || op.startHeight != cm.doc.height)
              updateScrollbars(cm, op.barMeasure);
        
            if (op.selectionChanged) restartBlink(cm);
        
            if (cm.state.focused && op.updateInput)
              resetInput(cm, op.typing);
          }
        
          function endOperation_finish(op) {
            var cm = op.cm, display = cm.display, doc = cm.doc;
        
            if (op.adjustWidthTo != null && Math.abs(op.barMeasure.scrollWidth - cm.display.scroller.scrollWidth) > 1)
              updateScrollbars(cm);
        
            if (op.updatedDisplay) postUpdateDisplay(cm, op.update);
        
            // Abort mouse wheel delta measurement, when scrolling explicitly
            if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
              display.wheelStartX = display.wheelStartY = null;
        
            // Propagate the scroll position to the actual DOM scroller
            if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {
              var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
              display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top;
            }
            if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {
              var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft));
              display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left;
              alignHorizontally(cm);
            }
            // If we need to scroll a specific position into view, do so.
            if (op.scrollToPos) {
              var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
                                             clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
              if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);
            }
        
            // Fire events for markers that are hidden/unidden by editing or
            // undoing
            var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
            if (hidden) for (var i = 0; i < hidden.length; ++i)
              if (!hidden[i].lines.length) signal(hidden[i], "hide");
            if (unhidden) for (var i = 0; i < unhidden.length; ++i)
              if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
        
            if (display.wrapper.offsetHeight)
              doc.scrollTop = cm.display.scroller.scrollTop;
        
            // Apply workaround for two webkit bugs
            if (op.updatedDisplay && webkit) {
              if (cm.options.lineWrapping)
                checkForWebkitWidthBug(cm, op.barMeasure); // (Issue #2420)
              if (op.barMeasure.scrollWidth > op.barMeasure.clientWidth &&
                  op.barMeasure.scrollWidth < op.barMeasure.clientWidth + 1 &&
                  !hScrollbarTakesSpace(cm))
                updateScrollbars(cm); // (Issue #2562)
            }
        
            // Fire change events, and delayed event handlers
            if (op.changeObjs)
              signal(cm, "changes", cm, op.changeObjs);
          }
        
          // Run the given function in an operation
          function runInOp(cm, f) {
            if (cm.curOp) return f();
            startOperation(cm);
            try { return f(); }
            finally { endOperation(cm); }
          }
          // Wraps a function in an operation. Returns the wrapped function.
          function operation(cm, f) {
            return function() {
              if (cm.curOp) return f.apply(cm, arguments);
              startOperation(cm);
              try { return f.apply(cm, arguments); }
              finally { endOperation(cm); }
            };
          }
          // Used to add methods to editor and doc instances, wrapping them in
          // operations.
          function methodOp(f) {
            return function() {
              if (this.curOp) return f.apply(this, arguments);
              startOperation(this);
              try { return f.apply(this, arguments); }
              finally { endOperation(this); }
            };
          }
          function docMethodOp(f) {
            return function() {
              var cm = this.cm;
              if (!cm || cm.curOp) return f.apply(this, arguments);
              startOperation(cm);
              try { return f.apply(this, arguments); }
              finally { endOperation(cm); }
            };
          }
        
          // VIEW TRACKING
        
          // These objects are used to represent the visible (currently drawn)
          // part of the document. A LineView may correspond to multiple
          // logical lines, if those are connected by collapsed ranges.
          function LineView(doc, line, lineN) {
            // The starting line
            this.line = line;
            // Continuing lines, if any
            this.rest = visualLineContinued(line);
            // Number of logical lines in this visual line
            this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
            this.node = this.text = null;
            this.hidden = lineIsHidden(doc, line);
          }
        
          // Create a range of LineView objects for the given lines.
          function buildViewArray(cm, from, to) {
            var array = [], nextPos;
            for (var pos = from; pos < to; pos = nextPos) {
              var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
              nextPos = pos + view.size;
              array.push(view);
            }
            return array;
          }
        
          // Updates the display.view data structure for a given change to the
          // document. From and to are in pre-change coordinates. Lendiff is
          // the amount of lines added or subtracted by the change. This is
          // used for changes that span multiple lines, or change the way
          // lines are divided into visual lines. regLineChange (below)
          // registers single-line changes.
          function regChange(cm, from, to, lendiff) {
            if (from == null) from = cm.doc.first;
            if (to == null) to = cm.doc.first + cm.doc.size;
            if (!lendiff) lendiff = 0;
        
            var display = cm.display;
            if (lendiff && to < display.viewTo &&
                (display.updateLineNumbers == null || display.updateLineNumbers > from))
              display.updateLineNumbers = from;
        
            cm.curOp.viewChanged = true;
        
            if (from >= display.viewTo) { // Change after
              if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
                resetView(cm);
            } else if (to <= display.viewFrom) { // Change before
              if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
                resetView(cm);
              } else {
                display.viewFrom += lendiff;
                display.viewTo += lendiff;
              }
            } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
              resetView(cm);
            } else if (from <= display.viewFrom) { // Top overlap
              var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
              if (cut) {
                display.view = display.view.slice(cut.index);
                display.viewFrom = cut.lineN;
                display.viewTo += lendiff;
              } else {
                resetView(cm);
              }
            } else if (to >= display.viewTo) { // Bottom overlap
              var cut = viewCuttingPoint(cm, from, from, -1);
              if (cut) {
                display.view = display.view.slice(0, cut.index);
                display.viewTo = cut.lineN;
              } else {
                resetView(cm);
              }
            } else { // Gap in the middle
              var cutTop = viewCuttingPoint(cm, from, from, -1);
              var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
              if (cutTop && cutBot) {
                display.view = display.view.slice(0, cutTop.index)
                  .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
                  .concat(display.view.slice(cutBot.index));
                display.viewTo += lendiff;
              } else {
                resetView(cm);
              }
            }
        
            var ext = display.externalMeasured;
            if (ext) {
              if (to < ext.lineN)
                ext.lineN += lendiff;
              else if (from < ext.lineN + ext.size)
                display.externalMeasured = null;
            }
          }
        
          // Register a change to a single line. Type must be one of "text",
          // "gutter", "class", "widget"
          function regLineChange(cm, line, type) {
            cm.curOp.viewChanged = true;
            var display = cm.display, ext = cm.display.externalMeasured;
            if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
              display.externalMeasured = null;
        
            if (line < display.viewFrom || line >= display.viewTo) return;
            var lineView = display.view[findViewIndex(cm, line)];
            if (lineView.node == null) return;
            var arr = lineView.changes || (lineView.changes = []);
            if (indexOf(arr, type) == -1) arr.push(type);
          }
        
          // Clear the view.
          function resetView(cm) {
            cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
            cm.display.view = [];
            cm.display.viewOffset = 0;
          }
        
          // Find the view element corresponding to a given line. Return null
          // when the line isn't visible.
          function findViewIndex(cm, n) {
            if (n >= cm.display.viewTo) return null;
            n -= cm.display.viewFrom;
            if (n < 0) return null;
            var view = cm.display.view;
            for (var i = 0; i < view.length; i++) {
              n -= view[i].size;
              if (n < 0) return i;
            }
          }
        
          function viewCuttingPoint(cm, oldN, newN, dir) {
            var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
            if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
              return {index: index, lineN: newN};
            for (var i = 0, n = cm.display.viewFrom; i < index; i++)
              n += view[i].size;
            if (n != oldN) {
              if (dir > 0) {
                if (index == view.length - 1) return null;
                diff = (n + view[index].size) - oldN;
                index++;
              } else {
                diff = n - oldN;
              }
              oldN += diff; newN += diff;
            }
            while (visualLineNo(cm.doc, newN) != newN) {
              if (index == (dir < 0 ? 0 : view.length - 1)) return null;
              newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
              index += dir;
            }
            return {index: index, lineN: newN};
          }
        
          // Force the view to cover a given range, adding empty view element
          // or clipping off existing ones as needed.
          function adjustView(cm, from, to) {
            var display = cm.display, view = display.view;
            if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
              display.view = buildViewArray(cm, from, to);
              display.viewFrom = from;
            } else {
              if (display.viewFrom > from)
                display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view);
              else if (display.viewFrom < from)
                display.view = display.view.slice(findViewIndex(cm, from));
              display.viewFrom = from;
              if (display.viewTo < to)
                display.view = display.view.concat(buildViewArray(cm, display.viewTo, to));
              else if (display.viewTo > to)
                display.view = display.view.slice(0, findViewIndex(cm, to));
            }
            display.viewTo = to;
          }
        
          // Count the number of lines in the view whose DOM representation is
          // out of date (or nonexistent).
          function countDirtyView(cm) {
            var view = cm.display.view, dirty = 0;
            for (var i = 0; i < view.length; i++) {
              var lineView = view[i];
              if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty;
            }
            return dirty;
          }
        
          // INPUT HANDLING
        
          // Poll for input changes, using the normal rate of polling. This
          // runs as long as the editor is focused.
          function slowPoll(cm) {
            if (cm.display.pollingFast) return;
            cm.display.poll.set(cm.options.pollInterval, function() {
              readInput(cm);
              if (cm.state.focused) slowPoll(cm);
            });
          }
        
          // When an event has just come in that is likely to add or change
          // something in the input textarea, we poll faster, to ensure that
          // the change appears on the screen quickly.
          function fastPoll(cm) {
            var missed = false;
            cm.display.pollingFast = true;
            function p() {
              var changed = readInput(cm);
              if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
              else {cm.display.pollingFast = false; slowPoll(cm);}
            }
            cm.display.poll.set(20, p);
          }
        
          // This will be set to an array of strings when copying, so that,
          // when pasting, we know what kind of selections the copied text
          // was made out of.
          var lastCopied = null;
        
          // Read input from the textarea, and update the document to match.
          // When something is selected, it is present in the textarea, and
          // selected (unless it is huge, in which case a placeholder is
          // used). When nothing is selected, the cursor sits after previously
          // seen text (can be empty), which is stored in prevInput (we must
          // not reset the textarea when typing, because that breaks IME).
          function readInput(cm) {
            var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc;
            // Since this is called a *lot*, try to bail out as cheaply as
            // possible when it is clear that nothing happened. hasSelection
            // will be the case when there is a lot of text in the textarea,
            // in which case reading its value would be expensive.
            if (!cm.state.focused || (hasSelection(input) && !prevInput) || isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq)
              return false;
            // See paste handler for more on the fakedLastChar kludge
            if (cm.state.pasteIncoming && cm.state.fakedLastChar) {
              input.value = input.value.substring(0, input.value.length - 1);
              cm.state.fakedLastChar = false;
            }
            var text = input.value;
            // If nothing changed, bail.
            if (text == prevInput && !cm.somethingSelected()) return false;
            // Work around nonsensical selection resetting in IE9/10, and
            // inexplicable appearance of private area unicode characters on
            // some key combos in Mac (#2689).
            if (ie && ie_version >= 9 && cm.display.inputHasSelection === text ||
                mac && /[\uf700-\uf7ff]/.test(text)) {
              resetInput(cm);
              return false;
            }
        
            var withOp = !cm.curOp;
            if (withOp) startOperation(cm);
            cm.display.shift = false;
        
            if (text.charCodeAt(0) == 0x200b && doc.sel == cm.display.selForContextMenu && !prevInput)
              prevInput = "\u200b";
            // Find the part of the input that is actually new
            var same = 0, l = Math.min(prevInput.length, text.length);
            while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
            var inserted = text.slice(same), textLines = splitLines(inserted);
        
            // When pasing N lines into N selections, insert one line per selection
            var multiPaste = null;
            if (cm.state.pasteIncoming && doc.sel.ranges.length > 1) {
              if (lastCopied && lastCopied.join("\n") == inserted)
                multiPaste = doc.sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines);
              else if (textLines.length == doc.sel.ranges.length)
                multiPaste = map(textLines, function(l) { return [l]; });
            }
        
            // Normal behavior is to insert the new text into every selection
            for (var i = doc.sel.ranges.length - 1; i >= 0; i--) {
              var range = doc.sel.ranges[i];
              var from = range.from(), to = range.to();
              // Handle deletion
              if (same < prevInput.length)
                from = Pos(from.line, from.ch - (prevInput.length - same));
              // Handle overwrite
              else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming)
                to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
              var updateInput = cm.curOp.updateInput;
              var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
                                 origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"};
              makeChange(cm.doc, changeEvent);
              signalLater(cm, "inputRead", cm, changeEvent);
              // When an 'electric' character is inserted, immediately trigger a reindent
              if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
                  cm.options.smartIndent && range.head.ch < 100 &&
                  (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) {
                var mode = cm.getModeAt(range.head);
                var end = changeEnd(changeEvent);
                if (mode.electricChars) {
                  for (var j = 0; j < mode.electricChars.length; j++)
                    if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
                      indentLine(cm, end.line, "smart");
                      break;
                    }
                } else if (mode.electricInput) {
                  if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch)))
                    indentLine(cm, end.line, "smart");
                }
              }
            }
            ensureCursorVisible(cm);
            cm.curOp.updateInput = updateInput;
            cm.curOp.typing = true;
        
            // Don't leave long text in the textarea, since it makes further polling slow
            if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
            else cm.display.prevInput = text;
            if (withOp) endOperation(cm);
            cm.state.pasteIncoming = cm.state.cutIncoming = false;
            return true;
          }
        
          // Reset the input to correspond to the selection (or to be empty,
          // when not typing and nothing is selected)
          function resetInput(cm, typing) {
            var minimal, selected, doc = cm.doc;
            if (cm.somethingSelected()) {
              cm.display.prevInput = "";
              var range = doc.sel.primary();
              minimal = hasCopyEvent &&
                (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
              var content = minimal ? "-" : selected || cm.getSelection();
              cm.display.input.value = content;
              if (cm.state.focused) selectInput(cm.display.input);
              if (ie && ie_version >= 9) cm.display.inputHasSelection = content;
            } else if (!typing) {
              cm.display.prevInput = cm.display.input.value = "";
              if (ie && ie_version >= 9) cm.display.inputHasSelection = null;
            }
            cm.display.inaccurateSelection = minimal;
          }
        
          function focusInput(cm) {
            if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input))
              cm.display.input.focus();
          }
        
          function ensureFocus(cm) {
            if (!cm.state.focused) { focusInput(cm); onFocus(cm); }
          }
        
          function isReadOnly(cm) {
            return cm.options.readOnly || cm.doc.cantEdit;
          }
        
          // EVENT HANDLERS
        
          // Attach the necessary event handlers when initializing the editor
          function registerEventHandlers(cm) {
            var d = cm.display;
            on(d.scroller, "mousedown", operation(cm, onMouseDown));
            // Older IE's will not fire a second mousedown for a double click
            if (ie && ie_version < 11)
              on(d.scroller, "dblclick", operation(cm, function(e) {
                if (signalDOMEvent(cm, e)) return;
                var pos = posFromMouse(cm, e);
                if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
                e_preventDefault(e);
                var word = cm.findWordAt(pos);
                extendSelection(cm.doc, word.anchor, word.head);
              }));
            else
              on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
            // Prevent normal selection in the editor (we handle our own)
            on(d.lineSpace, "selectstart", function(e) {
              if (!eventInWidget(d, e)) e_preventDefault(e);
            });
            // Some browsers fire contextmenu *after* opening the menu, at
            // which point we can't mess with it anymore. Context menu is
            // handled in onMouseDown for these browsers.
            if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
        
            // Sync scrolling between fake scrollbars and real scrollable
            // area, ensure viewport is updated when scrolling.
            on(d.scroller, "scroll", function() {
              if (d.scroller.clientHeight) {
                setScrollTop(cm, d.scroller.scrollTop);
                setScrollLeft(cm, d.scroller.scrollLeft, true);
                signal(cm, "scroll", cm);
              }
            });
            on(d.scrollbarV, "scroll", function() {
              if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
            });
            on(d.scrollbarH, "scroll", function() {
              if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
            });
        
            // Listen to wheel events in order to try and update the viewport on time.
            on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
            on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
        
            // Prevent clicks in the scrollbars from killing focus
            function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
            on(d.scrollbarH, "mousedown", reFocus);
            on(d.scrollbarV, "mousedown", reFocus);
            // Prevent wrapper from ever scrolling
            on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
        
            on(d.input, "keyup", function(e) { onKeyUp.call(cm, e); });
            on(d.input, "input", function() {
              if (ie && ie_version >= 9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
              fastPoll(cm);
            });
            on(d.input, "keydown", operation(cm, onKeyDown));
            on(d.input, "keypress", operation(cm, onKeyPress));
            on(d.input, "focus", bind(onFocus, cm));
            on(d.input, "blur", bind(onBlur, cm));
        
            function drag_(e) {
              if (!signalDOMEvent(cm, e)) e_stop(e);
            }
            if (cm.options.dragDrop) {
              on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
              on(d.scroller, "dragenter", drag_);
              on(d.scroller, "dragover", drag_);
              on(d.scroller, "drop", operation(cm, onDrop));
            }
            on(d.scroller, "paste", function(e) {
              if (eventInWidget(d, e)) return;
              cm.state.pasteIncoming = true;
              focusInput(cm);
              fastPoll(cm);
            });
            on(d.input, "paste", function() {
              // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206
              // Add a char to the end of textarea before paste occur so that
              // selection doesn't span to the end of textarea.
              if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {
                var start = d.input.selectionStart, end = d.input.selectionEnd;
                d.input.value += "$";
                // The selection end needs to be set before the start, otherwise there
                // can be an intermediate non-empty selection between the two, which
                // can override the middle-click paste buffer on linux and cause the
                // wrong thing to get pasted.
                d.input.selectionEnd = end;
                d.input.selectionStart = start;
                cm.state.fakedLastChar = true;
              }
              cm.state.pasteIncoming = true;
              fastPoll(cm);
            });
        
            function prepareCopyCut(e) {
              if (cm.somethingSelected()) {
                lastCopied = cm.getSelections();
                if (d.inaccurateSelection) {
                  d.prevInput = "";
                  d.inaccurateSelection = false;
                  d.input.value = lastCopied.join("\n");
                  selectInput(d.input);
                }
              } else {
                var text = [], ranges = [];
                for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
                  var line = cm.doc.sel.ranges[i].head.line;
                  var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
                  ranges.push(lineRange);
                  text.push(cm.getRange(lineRange.anchor, lineRange.head));
                }
                if (e.type == "cut") {
                  cm.setSelections(ranges, null, sel_dontScroll);
                } else {
                  d.prevInput = "";
                  d.input.value = text.join("\n");
                  selectInput(d.input);
                }
                lastCopied = text;
              }
              if (e.type == "cut") cm.state.cutIncoming = true;
            }
            on(d.input, "cut", prepareCopyCut);
            on(d.input, "copy", prepareCopyCut);
        
            // Needed to handle Tab key in KHTML
            if (khtml) on(d.sizer, "mouseup", function() {
              if (activeElt() == d.input) d.input.blur();
              focusInput(cm);
            });
          }
        
          // Called when the window resizes
          function onResize(cm) {
            var d = cm.display;
            if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)
              return;
            // Might be a text scaling operation, clear size caches.
            d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
            cm.setSize();
          }
        
          // MOUSE EVENTS
        
          // Return true when the given mouse event happened in a widget
          function eventInWidget(display, e) {
            for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
              if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
            }
          }
        
          // Given a mouse event, find the corresponding position. If liberal
          // is false, it checks whether a gutter or scrollbar was clicked,
          // and returns null if it was. forRect is used by rectangular
          // selections, and tries to estimate a character position even for
          // coordinates beyond the right of the text.
          function posFromMouse(cm, e, liberal, forRect) {
            var display = cm.display;
            if (!liberal) {
              var target = e_target(e);
              if (target == display.scrollbarH || target == display.scrollbarV ||
                  target == display.scrollbarFiller || target == display.gutterFiller) return null;
            }
            var x, y, space = display.lineSpace.getBoundingClientRect();
            // Fails unpredictably on IE[67] when mouse is dragged around quickly.
            try { x = e.clientX - space.left; y = e.clientY - space.top; }
            catch (e) { return null; }
            var coords = coordsChar(cm, x, y), line;
            if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
              var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
              coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
            }
            return coords;
          }
        
          // A mouse down can be a single click, double click, triple click,
          // start of selection drag, start of text drag, new cursor
          // (ctrl-click), rectangle drag (alt-drag), or xwin
          // middle-click-paste. Or it might be a click on something we should
          // not interfere with, such as a scrollbar or widget.
          function onMouseDown(e) {
            if (signalDOMEvent(this, e)) return;
            var cm = this, display = cm.display;
            display.shift = e.shiftKey;
        
            if (eventInWidget(display, e)) {
              if (!webkit) {
                // Briefly turn off draggability, to allow widgets to do
                // normal dragging things.
                display.scroller.draggable = false;
                setTimeout(function(){display.scroller.draggable = true;}, 100);
              }
              return;
            }
            if (clickInGutter(cm, e)) return;
            var start = posFromMouse(cm, e);
            window.focus();
        
            switch (e_button(e)) {
            case 1:
              if (start)
                leftButtonDown(cm, e, start);
              else if (e_target(e) == display.scroller)
                e_preventDefault(e);
              break;
            case 2:
              if (webkit) cm.state.lastMiddleDown = +new Date;
              if (start) extendSelection(cm.doc, start);
              setTimeout(bind(focusInput, cm), 20);
              e_preventDefault(e);
              break;
            case 3:
              if (captureRightClick) onContextMenu(cm, e);
              break;
            }
          }
        
          var lastClick, lastDoubleClick;
          function leftButtonDown(cm, e, start) {
            setTimeout(bind(ensureFocus, cm), 0);
        
            var now = +new Date, type;
            if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
              type = "triple";
            } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {
              type = "double";
              lastDoubleClick = {time: now, pos: start};
            } else {
              type = "single";
              lastClick = {time: now, pos: start};
            }
        
            var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey;
            if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&
                type == "single" && sel.contains(start) > -1 && sel.somethingSelected())
              leftButtonStartDrag(cm, e, start, modifier);
            else
              leftButtonSelect(cm, e, start, type, modifier);
          }
        
          // Start a text drag. When it ends, see if any dragging actually
          // happen, and treat as a click if it didn't.
          function leftButtonStartDrag(cm, e, start, modifier) {
            var display = cm.display;
            var dragEnd = operation(cm, function(e2) {
              if (webkit) display.scroller.draggable = false;
              cm.state.draggingText = false;
              off(document, "mouseup", dragEnd);
              off(display.scroller, "drop", dragEnd);
              if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
                e_preventDefault(e2);
                if (!modifier)
                  extendSelection(cm.doc, start);
                focusInput(cm);
                // Work around unexplainable focus problem in IE9 (#2127)
                if (ie && ie_version == 9)
                  setTimeout(function() {document.body.focus(); focusInput(cm);}, 20);
              }
            });
            // Let the drag handler handle this.
            if (webkit) display.scroller.draggable = true;
            cm.state.draggingText = dragEnd;
            // IE's approach to draggable
            if (display.scroller.dragDrop) display.scroller.dragDrop();
            on(document, "mouseup", dragEnd);
            on(display.scroller, "drop", dragEnd);
          }
        
          // Normal selection, as opposed to text dragging.
          function leftButtonSelect(cm, e, start, type, addNew) {
            var display = cm.display, doc = cm.doc;
            e_preventDefault(e);
        
            var ourRange, ourIndex, startSel = doc.sel;
            if (addNew && !e.shiftKey) {
              ourIndex = doc.sel.contains(start);
              if (ourIndex > -1)
                ourRange = doc.sel.ranges[ourIndex];
              else
                ourRange = new Range(start, start);
            } else {
              ourRange = doc.sel.primary();
            }
        
            if (e.altKey) {
              type = "rect";
              if (!addNew) ourRange = new Range(start, start);
              start = posFromMouse(cm, e, true, true);
              ourIndex = -1;
            } else if (type == "double") {
              var word = cm.findWordAt(start);
              if (cm.display.shift || doc.extend)
                ourRange = extendRange(doc, ourRange, word.anchor, word.head);
              else
                ourRange = word;
            } else if (type == "triple") {
              var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)));
              if (cm.display.shift || doc.extend)
                ourRange = extendRange(doc, ourRange, line.anchor, line.head);
              else
                ourRange = line;
            } else {
              ourRange = extendRange(doc, ourRange, start);
            }
        
            if (!addNew) {
              ourIndex = 0;
              setSelection(doc, new Selection([ourRange], 0), sel_mouse);
              startSel = doc.sel;
            } else if (ourIndex > -1) {
              replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
            } else {
              ourIndex = doc.sel.ranges.length;
              setSelection(doc, normalizeSelection(doc.sel.ranges.concat([ourRange]), ourIndex),
                           {scroll: false, origin: "*mouse"});
            }
        
            var lastPos = start;
            function extendTo(pos) {
              if (cmp(lastPos, pos) == 0) return;
              lastPos = pos;
        
              if (type == "rect") {
                var ranges = [], tabSize = cm.options.tabSize;
                var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
                var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
                var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
                for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
                     line <= end; line++) {
                  var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
                  if (left == right)
                    ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos)));
                  else if (text.length > leftPos)
                    ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));
                }
                if (!ranges.length) ranges.push(new Range(start, start));
                setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
                             {origin: "*mouse", scroll: false});
                cm.scrollIntoView(pos);
              } else {
                var oldRange = ourRange;
                var anchor = oldRange.anchor, head = pos;
                if (type != "single") {
                  if (type == "double")
                    var range = cm.findWordAt(pos);
                  else
                    var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
                  if (cmp(range.anchor, anchor) > 0) {
                    head = range.head;
                    anchor = minPos(oldRange.from(), range.anchor);
                  } else {
                    head = range.anchor;
                    anchor = maxPos(oldRange.to(), range.head);
                  }
                }
                var ranges = startSel.ranges.slice(0);
                ranges[ourIndex] = new Range(clipPos(doc, anchor), head);
                setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse);
              }
            }
        
            var editorSize = display.wrapper.getBoundingClientRect();
            // Used to ensure timeout re-tries don't fire when another extend
            // happened in the meantime (clearTimeout isn't reliable -- at
            // least on Chrome, the timeouts still happen even when cleared,
            // if the clear happens after their scheduled firing time).
            var counter = 0;
        
            function extend(e) {
              var curCount = ++counter;
              var cur = posFromMouse(cm, e, true, type == "rect");
              if (!cur) return;
              if (cmp(cur, lastPos) != 0) {
                ensureFocus(cm);
                extendTo(cur);
                var visible = visibleLines(display, doc);
                if (cur.line >= visible.to || cur.line < visible.from)
                  setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
              } else {
                var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
                if (outside) setTimeout(operation(cm, function() {
                  if (counter != curCount) return;
                  display.scroller.scrollTop += outside;
                  extend(e);
                }), 50);
              }
            }
        
            function done(e) {
              counter = Infinity;
              e_preventDefault(e);
              focusInput(cm);
              off(document, "mousemove", move);
              off(document, "mouseup", up);
              doc.history.lastSelOrigin = null;
            }
        
            var move = operation(cm, function(e) {
              if (!e_button(e)) done(e);
              else extend(e);
            });
            var up = operation(cm, done);
            on(document, "mousemove", move);
            on(document, "mouseup", up);
          }
        
          // Determines whether an event happened in the gutter, and fires the
          // handlers for the corresponding event.
          function gutterEvent(cm, e, type, prevent, signalfn) {
            try { var mX = e.clientX, mY = e.clientY; }
            catch(e) { return false; }
            if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
            if (prevent) e_preventDefault(e);
        
            var display = cm.display;
            var lineBox = display.lineDiv.getBoundingClientRect();
        
            if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);
            mY -= lineBox.top - display.viewOffset;
        
            for (var i = 0; i < cm.options.gutters.length; ++i) {
              var g = display.gutters.childNodes[i];
              if (g && g.getBoundingClientRect().right >= mX) {
                var line = lineAtHeight(cm.doc, mY);
                var gutter = cm.options.gutters[i];
                signalfn(cm, type, cm, line, gutter, e);
                return e_defaultPrevented(e);
              }
            }
          }
        
          function clickInGutter(cm, e) {
            return gutterEvent(cm, e, "gutterClick", true, signalLater);
          }
        
          // Kludge to work around strange IE behavior where it'll sometimes
          // re-fire a series of drag-related events right after the drop (#1551)
          var lastDrop = 0;
        
          function onDrop(e) {
            var cm = this;
            if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
              return;
            e_preventDefault(e);
            if (ie) lastDrop = +new Date;
            var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
            if (!pos || isReadOnly(cm)) return;
            // Might be a file drop, in which case we simply extract the text
            // and insert it.
            if (files && files.length && window.FileReader && window.File) {
              var n = files.length, text = Array(n), read = 0;
              var loadFile = function(file, i) {
                var reader = new FileReader;
                reader.onload = operation(cm, function() {
                  text[i] = reader.result;
                  if (++read == n) {
                    pos = clipPos(cm.doc, pos);
                    var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"};
                    makeChange(cm.doc, change);
                    setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
                  }
                });
                reader.readAsText(file);
              };
              for (var i = 0; i < n; ++i) loadFile(files[i], i);
            } else { // Normal drop
              // Don't do a replace if the drop happened inside of the selected text.
              if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
                cm.state.draggingText(e);
                // Ensure the editor is re-focused
                setTimeout(bind(focusInput, cm), 20);
                return;
              }
              try {
                var text = e.dataTransfer.getData("Text");
                if (text) {
                  if (cm.state.draggingText && !(mac ? e.metaKey : e.ctrlKey))
                    var selected = cm.listSelections();
                  setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
                  if (selected) for (var i = 0; i < selected.length; ++i)
                    replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
                  cm.replaceSelection(text, "around", "paste");
                  focusInput(cm);
                }
              }
              catch(e){}
            }
          }
        
          function onDragStart(cm, e) {
            if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
            if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
        
            e.dataTransfer.setData("Text", cm.getSelection());
        
            // Use dummy image instead of default browsers image.
            // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
            if (e.dataTransfer.setDragImage && !safari) {
              var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
              img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
              if (presto) {
                img.width = img.height = 1;
                cm.display.wrapper.appendChild(img);
                // Force a relayout, or Opera won't use our image for some obscure reason
                img._top = img.offsetTop;
              }
              e.dataTransfer.setDragImage(img, 0, 0);
              if (presto) img.parentNode.removeChild(img);
            }
          }
        
          // SCROLL EVENTS
        
          // Sync the scrollable area and scrollbars, ensure the viewport
          // covers the visible area.
          function setScrollTop(cm, val) {
            if (Math.abs(cm.doc.scrollTop - val) < 2) return;
            cm.doc.scrollTop = val;
            if (!gecko) updateDisplaySimple(cm, {top: val});
            if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
            if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
            if (gecko) updateDisplaySimple(cm);
            startWorker(cm, 100);
          }
          // Sync scroller and scrollbar, ensure the gutter elements are
          // aligned.
          function setScrollLeft(cm, val, isScroller) {
            if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
            val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
            cm.doc.scrollLeft = val;
            alignHorizontally(cm);
            if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
            if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
          }
        
          // Since the delta values reported on mouse wheel events are
          // unstandardized between browsers and even browser versions, and
          // generally horribly unpredictable, this code starts by measuring
          // the scroll effect that the first few mouse wheel events have,
          // and, from that, detects the way it can convert deltas to pixel
          // offsets afterwards.
          //
          // The reason we want to know the amount a wheel event will scroll
          // is that it gives us a chance to update the display before the
          // actual scrolling happens, reducing flickering.
        
          var wheelSamples = 0, wheelPixelsPerUnit = null;
          // Fill in a browser-detected starting value on browsers where we
          // know one. These don't have to be accurate -- the result of them
          // being wrong would just be a slight flicker on the first wheel
          // scroll (if it is large enough).
          if (ie) wheelPixelsPerUnit = -.53;
          else if (gecko) wheelPixelsPerUnit = 15;
          else if (chrome) wheelPixelsPerUnit = -.7;
          else if (safari) wheelPixelsPerUnit = -1/3;
        
          function onScrollWheel(cm, e) {
            var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
            if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
            if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
            else if (dy == null) dy = e.wheelDelta;
        
            var display = cm.display, scroll = display.scroller;
            // Quit if there's nothing to scroll here
            if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
                  dy && scroll.scrollHeight > scroll.clientHeight)) return;
        
            // Webkit browsers on OS X abort momentum scrolls when the target
            // of the scroll event is removed from the scrollable element.
            // This hack (see related code in patchDisplay) makes sure the
            // element is kept around.
            if (dy && mac && webkit) {
              outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
                for (var i = 0; i < view.length; i++) {
                  if (view[i].node == cur) {
                    cm.display.currentWheelTarget = cur;
                    break outer;
                  }
                }
              }
            }
        
            // On some browsers, horizontal scrolling will cause redraws to
            // happen before the gutter has been realigned, causing it to
            // wriggle around in a most unseemly way. When we have an
            // estimated pixels/delta value, we just handle horizontal
            // scrolling entirely here. It'll be slightly off from native, but
            // better than glitching out.
            if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
              if (dy)
                setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
              setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
              e_preventDefault(e);
              display.wheelStartX = null; // Abort measurement, if in progress
              return;
            }
        
            // 'Project' the visible viewport to cover the area that is being
            // scrolled into view (if we know enough to estimate it).
            if (dy && wheelPixelsPerUnit != null) {
              var pixels = dy * wheelPixelsPerUnit;
              var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
              if (pixels < 0) top = Math.max(0, top + pixels - 50);
              else bot = Math.min(cm.doc.height, bot + pixels + 50);
              updateDisplaySimple(cm, {top: top, bottom: bot});
            }
        
            if (wheelSamples < 20) {
              if (display.wheelStartX == null) {
                display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
                display.wheelDX = dx; display.wheelDY = dy;
                setTimeout(function() {
                  if (display.wheelStartX == null) return;
                  var movedX = scroll.scrollLeft - display.wheelStartX;
                  var movedY = scroll.scrollTop - display.wheelStartY;
                  var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
                    (movedX && display.wheelDX && movedX / display.wheelDX);
                  display.wheelStartX = display.wheelStartY = null;
                  if (!sample) return;
                  wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
                  ++wheelSamples;
                }, 200);
              } else {
                display.wheelDX += dx; display.wheelDY += dy;
              }
            }
          }
        
          // KEY EVENTS
        
          // Run a handler that was bound to a key.
          function doHandleBinding(cm, bound, dropShift) {
            if (typeof bound == "string") {
              bound = commands[bound];
              if (!bound) return false;
            }
            // Ensure previous input has been read, so that the handler sees a
            // consistent view of the document
            if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
            var prevShift = cm.display.shift, done = false;
            try {
              if (isReadOnly(cm)) cm.state.suppressEdits = true;
              if (dropShift) cm.display.shift = false;
              done = bound(cm) != Pass;
            } finally {
              cm.display.shift = prevShift;
              cm.state.suppressEdits = false;
            }
            return done;
          }
        
          function lookupKeyForEditor(cm, name, handle) {
            for (var i = 0; i < cm.state.keyMaps.length; i++) {
              var result = lookupKey(name, cm.state.keyMaps[i], handle);
              if (result) return result;
            }
            return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle))
              || lookupKey(name, cm.options.keyMap, handle);
          }
        
          var stopSeq = new Delayed;
          function dispatchKey(cm, name, e, handle) {
            var seq = cm.state.keySeq;
            if (seq) {
              if (isModifierKey(name)) return "handled";
              stopSeq.set(50, function() {
                if (cm.state.keySeq == seq) {
                  cm.state.keySeq = null;
                  resetInput(cm);
                }
              });
              name = seq + " " + name;
            }
            var result = lookupKeyForEditor(cm, name, handle);
        
            if (result == "multi")
              cm.state.keySeq = name;
            if (result == "handled")
              signalLater(cm, "keyHandled", cm, name, e);
        
            if (result == "handled" || result == "multi") {
              e_preventDefault(e);
              restartBlink(cm);
            }
        
            if (seq && !result && /\'$/.test(name)) {
              e_preventDefault(e);
              return true;
            }
            return !!result;
          }
        
          // Handle a key from the keydown event.
          function handleKeyBinding(cm, e) {
            var name = keyName(e, true);
            if (!name) return false;
        
            if (e.shiftKey && !cm.state.keySeq) {
              // First try to resolve full name (including 'Shift-'). Failing
              // that, see if there is a cursor-motion command (starting with
              // 'go') bound to the keyname without 'Shift-'.
              return dispatchKey(cm, "Shift-" + name, e, function(b) {return doHandleBinding(cm, b, true);})
                  || dispatchKey(cm, name, e, function(b) {
                       if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
                         return doHandleBinding(cm, b);
                     });
            } else {
              return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); });
            }
          }
        
          // Handle a key from the keypress event
          function handleCharBinding(cm, e, ch) {
            return dispatchKey(cm, "'" + ch + "'", e,
                               function(b) { return doHandleBinding(cm, b, true); });
          }
        
          var lastStoppedKey = null;
          function onKeyDown(e) {
            var cm = this;
            ensureFocus(cm);
            if (signalDOMEvent(cm, e)) return;
            // IE does strange things with escape.
            if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false;
            var code = e.keyCode;
            cm.display.shift = code == 16 || e.shiftKey;
            var handled = handleKeyBinding(cm, e);
            if (presto) {
              lastStoppedKey = handled ? code : null;
              // Opera has no cut event... we try to at least catch the key combo
              if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
                cm.replaceSelection("", null, "cut");
            }
        
            // Turn mouse into crosshair when Alt is held on Mac.
            if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
              showCrossHair(cm);
          }
        
          function showCrossHair(cm) {
            var lineDiv = cm.display.lineDiv;
            addClass(lineDiv, "CodeMirror-crosshair");
        
            function up(e) {
              if (e.keyCode == 18 || !e.altKey) {
                rmClass(lineDiv, "CodeMirror-crosshair");
                off(document, "keyup", up);
                off(document, "mouseover", up);
              }
            }
            on(document, "keyup", up);
            on(document, "mouseover", up);
          }
        
          function onKeyUp(e) {
            if (e.keyCode == 16) this.doc.sel.shift = false;
            signalDOMEvent(this, e);
          }
        
          function onKeyPress(e) {
            var cm = this;
            if (signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return;
            var keyCode = e.keyCode, charCode = e.charCode;
            if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
            if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
            var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
            if (handleCharBinding(cm, e, ch)) return;
            if (ie && ie_version >= 9) cm.display.inputHasSelection = null;
            fastPoll(cm);
          }
        
          // FOCUS/BLUR EVENTS
        
          function onFocus(cm) {
            if (cm.options.readOnly == "nocursor") return;
            if (!cm.state.focused) {
              signal(cm, "focus", cm);
              cm.state.focused = true;
              addClass(cm.display.wrapper, "CodeMirror-focused");
              // The prevInput test prevents this from firing when a context
              // menu is closed (since the resetInput would kill the
              // select-all detection hack)
              if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
                resetInput(cm);
                if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730
              }
            }
            slowPoll(cm);
            restartBlink(cm);
          }
          function onBlur(cm) {
            if (cm.state.focused) {
              signal(cm, "blur", cm);
              cm.state.focused = false;
              rmClass(cm.display.wrapper, "CodeMirror-focused");
            }
            clearInterval(cm.display.blinker);
            setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150);
          }
        
          // CONTEXT MENU HANDLING
        
          // To make the context menu work, we need to briefly unhide the
          // textarea (making it as unobtrusive as possible) to let the
          // right-click take effect on it.
          function onContextMenu(cm, e) {
            if (signalDOMEvent(cm, e, "contextmenu")) return;
            var display = cm.display;
            if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return;
        
            var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
            if (!pos || presto) return; // Opera is difficult.
        
            // Reset the current text selection only if the click is done outside of the selection
            // and 'resetSelectionOnContextMenu' option is true.
            var reset = cm.options.resetSelectionOnContextMenu;
            if (reset && cm.doc.sel.contains(pos) == -1)
              operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
        
            var oldCSS = display.input.style.cssText;
            display.inputDiv.style.position = "absolute";
            display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
              "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
              (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
              "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
            if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)
            focusInput(cm);
            if (webkit) window.scrollTo(null, oldScrollY);
            resetInput(cm);
            // Adds "Select all" to context menu in FF
            if (!cm.somethingSelected()) display.input.value = display.prevInput = " ";
            display.selForContextMenu = cm.doc.sel;
            clearTimeout(display.detectingSelectAll);
        
            // Select-all will be greyed out if there's nothing to select, so
            // this adds a zero-width space so that we can later check whether
            // it got selected.
            function prepareSelectAllHack() {
              if (display.input.selectionStart != null) {
                var selected = cm.somethingSelected();
                var extval = display.input.value = "\u200b" + (selected ? display.input.value : "");
                display.prevInput = selected ? "" : "\u200b";
                display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
                // Re-set this, in case some other handler touched the
                // selection in the meantime.
                display.selForContextMenu = cm.doc.sel;
              }
            }
            function rehide() {
              display.inputDiv.style.position = "relative";
              display.input.style.cssText = oldCSS;
              if (ie && ie_version < 9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
              slowPoll(cm);
        
              // Try to detect the user choosing select-all
              if (display.input.selectionStart != null) {
                if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();
                var i = 0, poll = function() {
                  if (display.selForContextMenu == cm.doc.sel && display.input.selectionStart == 0)
                    operation(cm, commands.selectAll)(cm);
                  else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
                  else resetInput(cm);
                };
                display.detectingSelectAll = setTimeout(poll, 200);
              }
            }
        
            if (ie && ie_version >= 9) prepareSelectAllHack();
            if (captureRightClick) {
              e_stop(e);
              var mouseup = function() {
                off(window, "mouseup", mouseup);
                setTimeout(rehide, 20);
              };
              on(window, "mouseup", mouseup);
            } else {
              setTimeout(rehide, 50);
            }
          }
        
          function contextMenuInGutter(cm, e) {
            if (!hasHandler(cm, "gutterContextMenu")) return false;
            return gutterEvent(cm, e, "gutterContextMenu", false, signal);
          }
        
          // UPDATING
        
          // Compute the position of the end of a change (its 'to' property
          // refers to the pre-change end).
          var changeEnd = CodeMirror.changeEnd = function(change) {
            if (!change.text) return change.to;
            return Pos(change.from.line + change.text.length - 1,
                       lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
          };
        
          // Adjust a position to refer to the post-change position of the
          // same text, or the end of the change if the change covers it.
          function adjustForChange(pos, change) {
            if (cmp(pos, change.from) < 0) return pos;
            if (cmp(pos, change.to) <= 0) return changeEnd(change);
        
            var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
            if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch;
            return Pos(line, ch);
          }
        
          function computeSelAfterChange(doc, change) {
            var out = [];
            for (var i = 0; i < doc.sel.ranges.length; i++) {
              var range = doc.sel.ranges[i];
              out.push(new Range(adjustForChange(range.anchor, change),
                                 adjustForChange(range.head, change)));
            }
            return normalizeSelection(out, doc.sel.primIndex);
          }
        
          function offsetPos(pos, old, nw) {
            if (pos.line == old.line)
              return Pos(nw.line, pos.ch - old.ch + nw.ch);
            else
              return Pos(nw.line + (pos.line - old.line), pos.ch);
          }
        
          // Used by replaceSelections to allow moving the selection to the
          // start or around the replaced test. Hint may be "start" or "around".
          function computeReplacedSel(doc, changes, hint) {
            var out = [];
            var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
            for (var i = 0; i < changes.length; i++) {
              var change = changes[i];
              var from = offsetPos(change.from, oldPrev, newPrev);
              var to = offsetPos(changeEnd(change), oldPrev, newPrev);
              oldPrev = change.to;
              newPrev = to;
              if (hint == "around") {
                var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
                out[i] = new Range(inv ? to : from, inv ? from : to);
              } else {
                out[i] = new Range(from, from);
              }
            }
            return new Selection(out, doc.sel.primIndex);
          }
        
          // Allow "beforeChange" event handlers to influence a change
          function filterChange(doc, change, update) {
            var obj = {
              canceled: false,
              from: change.from,
              to: change.to,
              text: change.text,
              origin: change.origin,
              cancel: function() { this.canceled = true; }
            };
            if (update) obj.update = function(from, to, text, origin) {
              if (from) this.from = clipPos(doc, from);
              if (to) this.to = clipPos(doc, to);
              if (text) this.text = text;
              if (origin !== undefined) this.origin = origin;
            };
            signal(doc, "beforeChange", doc, obj);
            if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
        
            if (obj.canceled) return null;
            return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
          }
        
          // Apply a change to a document, and add it to the document's
          // history, and propagating it to all linked documents.
          function makeChange(doc, change, ignoreReadOnly) {
            if (doc.cm) {
              if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly);
              if (doc.cm.state.suppressEdits) return;
            }
        
            if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
              change = filterChange(doc, change, true);
              if (!change) return;
            }
        
            // Possibly split or suppress the update based on the presence
            // of read-only spans in its range.
            var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
            if (split) {
              for (var i = split.length - 1; i >= 0; --i)
                makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text});
            } else {
              makeChangeInner(doc, change);
            }
          }
        
          function makeChangeInner(doc, change) {
            if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return;
            var selAfter = computeSelAfterChange(doc, change);
            addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
        
            makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
            var rebased = [];
        
            linkedDocs(doc, function(doc, sharedHist) {
              if (!sharedHist && indexOf(rebased, doc.history) == -1) {
                rebaseHist(doc.history, change);
                rebased.push(doc.history);
              }
              makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
            });
          }
        
          // Revert a change stored in a document's history.
          function makeChangeFromHistory(doc, type, allowSelectionOnly) {
            if (doc.cm && doc.cm.state.suppressEdits) return;
        
            var hist = doc.history, event, selAfter = doc.sel;
            var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
        
            // Verify that there is a useable event (so that ctrl-z won't
            // needlessly clear selection events)
            for (var i = 0; i < source.length; i++) {
              event = source[i];
              if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
                break;
            }
            if (i == source.length) return;
            hist.lastOrigin = hist.lastSelOrigin = null;
        
            for (;;) {
              event = source.pop();
              if (event.ranges) {
                pushSelectionToHistory(event, dest);
                if (allowSelectionOnly && !event.equals(doc.sel)) {
                  setSelection(doc, event, {clearRedo: false});
                  return;
                }
                selAfter = event;
              }
              else break;
            }
        
            // Build up a reverse change object to add to the opposite history
            // stack (redo when undoing, and vice versa).
            var antiChanges = [];
            pushSelectionToHistory(selAfter, dest);
            dest.push({changes: antiChanges, generation: hist.generation});
            hist.generation = event.generation || ++hist.maxGeneration;
        
            var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
        
            for (var i = event.changes.length - 1; i >= 0; --i) {
              var change = event.changes[i];
              change.origin = type;
              if (filter && !filterChange(doc, change, false)) {
                source.length = 0;
                return;
              }
        
              antiChanges.push(historyChangeFromChange(doc, change));
        
              var after = i ? computeSelAfterChange(doc, change) : lst(source);
              makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
              if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)});
              var rebased = [];
        
              // Propagate to the linked documents
              linkedDocs(doc, function(doc, sharedHist) {
                if (!sharedHist && indexOf(rebased, doc.history) == -1) {
                  rebaseHist(doc.history, change);
                  rebased.push(doc.history);
                }
                makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
              });
            }
          }
        
          // Sub-views need their line numbers shifted when text is added
          // above or below them in the parent document.
          function shiftDoc(doc, distance) {
            if (distance == 0) return;
            doc.first += distance;
            doc.sel = new Selection(map(doc.sel.ranges, function(range) {
              return new Range(Pos(range.anchor.line + distance, range.anchor.ch),
                               Pos(range.head.line + distance, range.head.ch));
            }), doc.sel.primIndex);
            if (doc.cm) {
              regChange(doc.cm, doc.first, doc.first - distance, distance);
              for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
                regLineChange(doc.cm, l, "gutter");
            }
          }
        
          // More lower-level change function, handling only a single document
          // (not linked ones).
          function makeChangeSingleDoc(doc, change, selAfter, spans) {
            if (doc.cm && !doc.cm.curOp)
              return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
        
            if (change.to.line < doc.first) {
              shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
              return;
            }
            if (change.from.line > doc.lastLine()) return;
        
            // Clip the change to the size of this doc
            if (change.from.line < doc.first) {
              var shift = change.text.length - 1 - (doc.first - change.from.line);
              shiftDoc(doc, shift);
              change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
                        text: [lst(change.text)], origin: change.origin};
            }
            var last = doc.lastLine();
            if (change.to.line > last) {
              change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
                        text: [change.text[0]], origin: change.origin};
            }
        
            change.removed = getBetween(doc, change.from, change.to);
        
            if (!selAfter) selAfter = computeSelAfterChange(doc, change);
            if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans);
            else updateDoc(doc, change, spans);
            setSelectionNoUndo(doc, selAfter, sel_dontScroll);
          }
        
          // Handle the interaction of a change to a document with the editor
          // that this document is part of.
          function makeChangeSingleDocInEditor(cm, change, spans) {
            var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
        
            var recomputeMaxLength = false, checkWidthStart = from.line;
            if (!cm.options.lineWrapping) {
              checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
              doc.iter(checkWidthStart, to.line + 1, function(line) {
                if (line == display.maxLine) {
                  recomputeMaxLength = true;
                  return true;
                }
              });
            }
        
            if (doc.sel.contains(change.from, change.to) > -1)
              signalCursorActivity(cm);
        
            updateDoc(doc, change, spans, estimateHeight(cm));
        
            if (!cm.options.lineWrapping) {
              doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
                var len = lineLength(line);
                if (len > display.maxLineLength) {
                  display.maxLine = line;
                  display.maxLineLength = len;
                  display.maxLineChanged = true;
                  recomputeMaxLength = false;
                }
              });
              if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
            }
        
            // Adjust frontier, schedule worker
            doc.frontier = Math.min(doc.frontier, from.line);
            startWorker(cm, 400);
        
            var lendiff = change.text.length - (to.line - from.line) - 1;
            // Remember that these lines changed, for updating the display
            if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
              regLineChange(cm, from.line, "text");
            else
              regChange(cm, from.line, to.line + 1, lendiff);
        
            var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
            if (changeHandler || changesHandler) {
              var obj = {
                from: from, to: to,
                text: change.text,
                removed: change.removed,
                origin: change.origin
              };
              if (changeHandler) signalLater(cm, "change", cm, obj);
              if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj);
            }
            cm.display.selForContextMenu = null;
          }
        
          function replaceRange(doc, code, from, to, origin) {
            if (!to) to = from;
            if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
            if (typeof code == "string") code = splitLines(code);
            makeChange(doc, {from: from, to: to, text: code, origin: origin});
          }
        
          // SCROLLING THINGS INTO VIEW
        
          // If an editor sits on the top or bottom of the window, partially
          // scrolled out of view, this ensures that the cursor is visible.
          function maybeScrollWindow(cm, coords) {
            if (signalDOMEvent(cm, "scrollCursorIntoView")) return;
        
            var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
            if (coords.top + box.top < 0) doScroll = true;
            else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
            if (doScroll != null && !phantom) {
              var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
                                   (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " +
                                   (coords.bottom - coords.top + scrollerCutOff) + "px; left: " +
                                   coords.left + "px; width: 2px;");
              cm.display.lineSpace.appendChild(scrollNode);
              scrollNode.scrollIntoView(doScroll);
              cm.display.lineSpace.removeChild(scrollNode);
            }
          }
        
          // Scroll a given position into view (immediately), verifying that
          // it actually became visible (as line heights are accurately
          // measured, the position of something may 'drift' during drawing).
          function scrollPosIntoView(cm, pos, end, margin) {
            if (margin == null) margin = 0;
            for (var limit = 0; limit < 5; limit++) {
              var changed = false, coords = cursorCoords(cm, pos);
              var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
              var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
                                                 Math.min(coords.top, endCoords.top) - margin,
                                                 Math.max(coords.left, endCoords.left),
                                                 Math.max(coords.bottom, endCoords.bottom) + margin);
              var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
              if (scrollPos.scrollTop != null) {
                setScrollTop(cm, scrollPos.scrollTop);
                if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
              }
              if (scrollPos.scrollLeft != null) {
                setScrollLeft(cm, scrollPos.scrollLeft);
                if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
              }
              if (!changed) return coords;
            }
          }
        
          // Scroll a given set of coordinates into view (immediately).
          function scrollIntoView(cm, x1, y1, x2, y2) {
            var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
            if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
            if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
          }
        
          // Calculate a new scroll position needed to scroll the given
          // rectangle into view. Returns an object with scrollTop and
          // scrollLeft properties. When these are undefined, the
          // vertical/horizontal position does not need to be adjusted.
          function calculateScrollPos(cm, x1, y1, x2, y2) {
            var display = cm.display, snapMargin = textHeight(cm.display);
            if (y1 < 0) y1 = 0;
            var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
            var screen = display.scroller.clientHeight - scrollerCutOff, result = {};
            if (y2 - y1 > screen) y2 = y1 + screen;
            var docBottom = cm.doc.height + paddingVert(display);
            var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
            if (y1 < screentop) {
              result.scrollTop = atTop ? 0 : y1;
            } else if (y2 > screentop + screen) {
              var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
              if (newTop != screentop) result.scrollTop = newTop;
            }
        
            var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
            var screenw = display.scroller.clientWidth - scrollerCutOff - display.gutters.offsetWidth;
            var tooWide = x2 - x1 > screenw;
            if (tooWide) x2 = x1 + screenw;
            if (x1 < 10)
              result.scrollLeft = 0;
            else if (x1 < screenleft)
              result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));
            else if (x2 > screenw + screenleft - 3)
              result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw;
        
            return result;
          }
        
          // Store a relative adjustment to the scroll position in the current
          // operation (to be applied when the operation finishes).
          function addToScrollPos(cm, left, top) {
            if (left != null || top != null) resolveScrollToPos(cm);
            if (left != null)
              cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left;
            if (top != null)
              cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
          }
        
          // Make sure that at the end of the operation the current cursor is
          // shown.
          function ensureCursorVisible(cm) {
            resolveScrollToPos(cm);
            var cur = cm.getCursor(), from = cur, to = cur;
            if (!cm.options.lineWrapping) {
              from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur;
              to = Pos(cur.line, cur.ch + 1);
            }
            cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true};
          }
        
          // When an operation has its scrollToPos property set, and another
          // scroll action is applied before the end of the operation, this
          // 'simulates' scrolling that position into view in a cheap way, so
          // that the effect of intermediate scroll commands is not ignored.
          function resolveScrollToPos(cm) {
            var range = cm.curOp.scrollToPos;
            if (range) {
              cm.curOp.scrollToPos = null;
              var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);
              var sPos = calculateScrollPos(cm, Math.min(from.left, to.left),
                                            Math.min(from.top, to.top) - range.margin,
                                            Math.max(from.right, to.right),
                                            Math.max(from.bottom, to.bottom) + range.margin);
              cm.scrollTo(sPos.scrollLeft, sPos.scrollTop);
            }
          }
        
          // API UTILITIES
        
          // Indent the given line. The how parameter can be "smart",
          // "add"/null, "subtract", or "prev". When aggressive is false
          // (typically set to true for forced single-line indents), empty
          // lines are not indented, and places where the mode returns Pass
          // are left alone.
          function indentLine(cm, n, how, aggressive) {
            var doc = cm.doc, state;
            if (how == null) how = "add";
            if (how == "smart") {
              // Fall back to "prev" when the mode doesn't have an indentation
              // method.
              if (!doc.mode.indent) how = "prev";
              else state = getStateBefore(cm, n);
            }
        
            var tabSize = cm.options.tabSize;
            var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
            if (line.stateAfter) line.stateAfter = null;
            var curSpaceString = line.text.match(/^\s*/)[0], indentation;
            if (!aggressive && !/\S/.test(line.text)) {
              indentation = 0;
              how = "not";
            } else if (how == "smart") {
              indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
              if (indentation == Pass || indentation > 150) {
                if (!aggressive) return;
                how = "prev";
              }
            }
            if (how == "prev") {
              if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
              else indentation = 0;
            } else if (how == "add") {
              indentation = curSpace + cm.options.indentUnit;
            } else if (how == "subtract") {
              indentation = curSpace - cm.options.indentUnit;
            } else if (typeof how == "number") {
              indentation = curSpace + how;
            }
            indentation = Math.max(0, indentation);
        
            var indentString = "", pos = 0;
            if (cm.options.indentWithTabs)
              for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
            if (pos < indentation) indentString += spaceStr(indentation - pos);
        
            if (indentString != curSpaceString) {
              replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
            } else {
              // Ensure that, if the cursor was in the whitespace at the start
              // of the line, it is moved to the end of that space.
              for (var i = 0; i < doc.sel.ranges.length; i++) {
                var range = doc.sel.ranges[i];
                if (range.head.line == n && range.head.ch < curSpaceString.length) {
                  var pos = Pos(n, curSpaceString.length);
                  replaceOneSelection(doc, i, new Range(pos, pos));
                  break;
                }
              }
            }
            line.stateAfter = null;
          }
        
          // Utility for applying a change to a line by handle or number,
          // returning the number and optionally registering the line as
          // changed.
          function changeLine(doc, handle, changeType, op) {
            var no = handle, line = handle;
            if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
            else no = lineNo(handle);
            if (no == null) return null;
            if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType);
            return line;
          }
        
          // Helper for deleting text near the selection(s), used to implement
          // backspace, delete, and similar functionality.
          function deleteNearSelection(cm, compute) {
            var ranges = cm.doc.sel.ranges, kill = [];
            // Build up a set of ranges to kill first, merging overlapping
            // ranges.
            for (var i = 0; i < ranges.length; i++) {
              var toKill = compute(ranges[i]);
              while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
                var replaced = kill.pop();
                if (cmp(replaced.from, toKill.from) < 0) {
                  toKill.from = replaced.from;
                  break;
                }
              }
              kill.push(toKill);
            }
            // Next, remove those actual ranges.
            runInOp(cm, function() {
              for (var i = kill.length - 1; i >= 0; i--)
                replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete");
              ensureCursorVisible(cm);
            });
          }
        
          // Used for horizontal relative motion. Dir is -1 or 1 (left or
          // right), unit can be "char", "column" (like char, but doesn't
          // cross line boundaries), "word" (across next word), or "group" (to
          // the start of next group of word or non-word-non-whitespace
          // chars). The visually param controls whether, in right-to-left
          // text, direction 1 means to move towards the next index in the
          // string, or towards the character to the right of the current
          // position. The resulting position will have a hitSide=true
          // property if it reached the end of the document.
          function findPosH(doc, pos, dir, unit, visually) {
            var line = pos.line, ch = pos.ch, origDir = dir;
            var lineObj = getLine(doc, line);
            var possible = true;
            function findNextLine() {
              var l = line + dir;
              if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
              line = l;
              return lineObj = getLine(doc, l);
            }
            function moveOnce(boundToLine) {
              var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
              if (next == null) {
                if (!boundToLine && findNextLine()) {
                  if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
                  else ch = dir < 0 ? lineObj.text.length : 0;
                } else return (possible = false);
              } else ch = next;
              return true;
            }
        
            if (unit == "char") moveOnce();
            else if (unit == "column") moveOnce(true);
            else if (unit == "word" || unit == "group") {
              var sawType = null, group = unit == "group";
              var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
              for (var first = true;; first = false) {
                if (dir < 0 && !moveOnce(!first)) break;
                var cur = lineObj.text.charAt(ch) || "\n";
                var type = isWordChar(cur, helper) ? "w"
                  : group && cur == "\n" ? "n"
                  : !group || /\s/.test(cur) ? null
                  : "p";
                if (group && !first && !type) type = "s";
                if (sawType && sawType != type) {
                  if (dir < 0) {dir = 1; moveOnce();}
                  break;
                }
        
                if (type) sawType = type;
                if (dir > 0 && !moveOnce(!first)) break;
              }
            }
            var result = skipAtomic(doc, Pos(line, ch), origDir, true);
            if (!possible) result.hitSide = true;
            return result;
          }
        
          // For relative vertical movement. Dir may be -1 or 1. Unit can be
          // "page" or "line". The resulting position will have a hitSide=true
          // property if it reached the end of the document.
          function findPosV(cm, pos, dir, unit) {
            var doc = cm.doc, x = pos.left, y;
            if (unit == "page") {
              var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
              y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
            } else if (unit == "line") {
              y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
            }
            for (;;) {
              var target = coordsChar(cm, x, y);
              if (!target.outside) break;
              if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
              y += dir * 5;
            }
            return target;
          }
        
          // EDITOR METHODS
        
          // The publicly visible API. Note that methodOp(f) means
          // 'wrap f in an operation, performed on its `this` parameter'.
        
          // This is not the complete set of editor methods. Most of the
          // methods defined on the Doc type are also injected into
          // CodeMirror.prototype, for backwards compatibility and
          // convenience.
        
          CodeMirror.prototype = {
            constructor: CodeMirror,
            focus: function(){window.focus(); focusInput(this); fastPoll(this);},
        
            setOption: function(option, value) {
              var options = this.options, old = options[option];
              if (options[option] == value && option != "mode") return;
              options[option] = value;
              if (optionHandlers.hasOwnProperty(option))
                operation(this, optionHandlers[option])(this, value, old);
            },
        
            getOption: function(option) {return this.options[option];},
            getDoc: function() {return this.doc;},
        
            addKeyMap: function(map, bottom) {
              this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map));
            },
            removeKeyMap: function(map) {
              var maps = this.state.keyMaps;
              for (var i = 0; i < maps.length; ++i)
                if (maps[i] == map || maps[i].name == map) {
                  maps.splice(i, 1);
                  return true;
                }
            },
        
            addOverlay: methodOp(function(spec, options) {
              var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
              if (mode.startState) throw new Error("Overlays may not be stateful.");
              this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
              this.state.modeGen++;
              regChange(this);
            }),
            removeOverlay: methodOp(function(spec) {
              var overlays = this.state.overlays;
              for (var i = 0; i < overlays.length; ++i) {
                var cur = overlays[i].modeSpec;
                if (cur == spec || typeof spec == "string" && cur.name == spec) {
                  overlays.splice(i, 1);
                  this.state.modeGen++;
                  regChange(this);
                  return;
                }
              }
            }),
        
            indentLine: methodOp(function(n, dir, aggressive) {
              if (typeof dir != "string" && typeof dir != "number") {
                if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
                else dir = dir ? "add" : "subtract";
              }
              if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
            }),
            indentSelection: methodOp(function(how) {
              var ranges = this.doc.sel.ranges, end = -1;
              for (var i = 0; i < ranges.length; i++) {
                var range = ranges[i];
                if (!range.empty()) {
                  var from = range.from(), to = range.to();
                  var start = Math.max(end, from.line);
                  end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
                  for (var j = start; j < end; ++j)
                    indentLine(this, j, how);
                  var newRanges = this.doc.sel.ranges;
                  if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
                    replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll);
                } else if (range.head.line > end) {
                  indentLine(this, range.head.line, how, true);
                  end = range.head.line;
                  if (i == this.doc.sel.primIndex) ensureCursorVisible(this);
                }
              }
            }),
        
            // Fetch the parser token for a given character. Useful for hacks
            // that want to inspect the mode state (say, for completion).
            getTokenAt: function(pos, precise) {
              return takeToken(this, pos, precise);
            },
        
            getLineTokens: function(line, precise) {
              return takeToken(this, Pos(line), precise, true);
            },
        
            getTokenTypeAt: function(pos) {
              pos = clipPos(this.doc, pos);
              var styles = getLineStyles(this, getLine(this.doc, pos.line));
              var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
              var type;
              if (ch == 0) type = styles[2];
              else for (;;) {
                var mid = (before + after) >> 1;
                if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
                else if (styles[mid * 2 + 1] < ch) before = mid + 1;
                else { type = styles[mid * 2 + 2]; break; }
              }
              var cut = type ? type.indexOf("cm-overlay ") : -1;
              return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1);
            },
        
            getModeAt: function(pos) {
              var mode = this.doc.mode;
              if (!mode.innerMode) return mode;
              return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
            },
        
            getHelper: function(pos, type) {
              return this.getHelpers(pos, type)[0];
            },
        
            getHelpers: function(pos, type) {
              var found = [];
              if (!helpers.hasOwnProperty(type)) return helpers;
              var help = helpers[type], mode = this.getModeAt(pos);
              if (typeof mode[type] == "string") {
                if (help[mode[type]]) found.push(help[mode[type]]);
              } else if (mode[type]) {
                for (var i = 0; i < mode[type].length; i++) {
                  var val = help[mode[type][i]];
                  if (val) found.push(val);
                }
              } else if (mode.helperType && help[mode.helperType]) {
                found.push(help[mode.helperType]);
              } else if (help[mode.name]) {
                found.push(help[mode.name]);
              }
              for (var i = 0; i < help._global.length; i++) {
                var cur = help._global[i];
                if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)
                  found.push(cur.val);
              }
              return found;
            },
        
            getStateAfter: function(line, precise) {
              var doc = this.doc;
              line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
              return getStateBefore(this, line + 1, precise);
            },
        
            cursorCoords: function(start, mode) {
              var pos, range = this.doc.sel.primary();
              if (start == null) pos = range.head;
              else if (typeof start == "object") pos = clipPos(this.doc, start);
              else pos = start ? range.from() : range.to();
              return cursorCoords(this, pos, mode || "page");
            },
        
            charCoords: function(pos, mode) {
              return charCoords(this, clipPos(this.doc, pos), mode || "page");
            },
        
            coordsChar: function(coords, mode) {
              coords = fromCoordSystem(this, coords, mode || "page");
              return coordsChar(this, coords.left, coords.top);
            },
        
            lineAtHeight: function(height, mode) {
              height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
              return lineAtHeight(this.doc, height + this.display.viewOffset);
            },
            heightAtLine: function(line, mode) {
              var end = false, last = this.doc.first + this.doc.size - 1;
              if (line < this.doc.first) line = this.doc.first;
              else if (line > last) { line = last; end = true; }
              var lineObj = getLine(this.doc, line);
              return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top +
                (end ? this.doc.height - heightAtLine(lineObj) : 0);
            },
        
            defaultTextHeight: function() { return textHeight(this.display); },
            defaultCharWidth: function() { return charWidth(this.display); },
        
            setGutterMarker: methodOp(function(line, gutterID, value) {
              return changeLine(this.doc, line, "gutter", function(line) {
                var markers = line.gutterMarkers || (line.gutterMarkers = {});
                markers[gutterID] = value;
                if (!value && isEmpty(markers)) line.gutterMarkers = null;
                return true;
              });
            }),
        
            clearGutter: methodOp(function(gutterID) {
              var cm = this, doc = cm.doc, i = doc.first;
              doc.iter(function(line) {
                if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
                  line.gutterMarkers[gutterID] = null;
                  regLineChange(cm, i, "gutter");
                  if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
                }
                ++i;
              });
            }),
        
            addLineWidget: methodOp(function(handle, node, options) {
              return addLineWidget(this, handle, node, options);
            }),
        
            removeLineWidget: function(widget) { widget.clear(); },
        
            lineInfo: function(line) {
              if (typeof line == "number") {
                if (!isLine(this.doc, line)) return null;
                var n = line;
                line = getLine(this.doc, line);
                if (!line) return null;
              } else {
                var n = lineNo(line);
                if (n == null) return null;
              }
              return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
                      textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
                      widgets: line.widgets};
            },
        
            getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};},
        
            addWidget: function(pos, node, scroll, vert, horiz) {
              var display = this.display;
              pos = cursorCoords(this, clipPos(this.doc, pos));
              var top = pos.bottom, left = pos.left;
              node.style.position = "absolute";
              display.sizer.appendChild(node);
              if (vert == "over") {
                top = pos.top;
              } else if (vert == "above" || vert == "near") {
                var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
                hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
                // Default to positioning above (if specified and possible); otherwise default to positioning below
                if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
                  top = pos.top - node.offsetHeight;
                else if (pos.bottom + node.offsetHeight <= vspace)
                  top = pos.bottom;
                if (left + node.offsetWidth > hspace)
                  left = hspace - node.offsetWidth;
              }
              node.style.top = top + "px";
              node.style.left = node.style.right = "";
              if (horiz == "right") {
                left = display.sizer.clientWidth - node.offsetWidth;
                node.style.right = "0px";
              } else {
                if (horiz == "left") left = 0;
                else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
                node.style.left = left + "px";
              }
              if (scroll)
                scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
            },
        
            triggerOnKeyDown: methodOp(onKeyDown),
            triggerOnKeyPress: methodOp(onKeyPress),
            triggerOnKeyUp: onKeyUp,
        
            execCommand: function(cmd) {
              if (commands.hasOwnProperty(cmd))
                return commands[cmd](this);
            },
        
            findPosH: function(from, amount, unit, visually) {
              var dir = 1;
              if (amount < 0) { dir = -1; amount = -amount; }
              for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
                cur = findPosH(this.doc, cur, dir, unit, visually);
                if (cur.hitSide) break;
              }
              return cur;
            },
        
            moveH: methodOp(function(dir, unit) {
              var cm = this;
              cm.extendSelectionsBy(function(range) {
                if (cm.display.shift || cm.doc.extend || range.empty())
                  return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually);
                else
                  return dir < 0 ? range.from() : range.to();
              }, sel_move);
            }),
        
            deleteH: methodOp(function(dir, unit) {
              var sel = this.doc.sel, doc = this.doc;
              if (sel.somethingSelected())
                doc.replaceSelection("", null, "+delete");
              else
                deleteNearSelection(this, function(range) {
                  var other = findPosH(doc, range.head, dir, unit, false);
                  return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};
                });
            }),
        
            findPosV: function(from, amount, unit, goalColumn) {
              var dir = 1, x = goalColumn;
              if (amount < 0) { dir = -1; amount = -amount; }
              for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
                var coords = cursorCoords(this, cur, "div");
                if (x == null) x = coords.left;
                else coords.left = x;
                cur = findPosV(this, coords, dir, unit);
                if (cur.hitSide) break;
              }
              return cur;
            },
        
            moveV: methodOp(function(dir, unit) {
              var cm = this, doc = this.doc, goals = [];
              var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected();
              doc.extendSelectionsBy(function(range) {
                if (collapse)
                  return dir < 0 ? range.from() : range.to();
                var headPos = cursorCoords(cm, range.head, "div");
                if (range.goalColumn != null) headPos.left = range.goalColumn;
                goals.push(headPos.left);
                var pos = findPosV(cm, headPos, dir, unit);
                if (unit == "page" && range == doc.sel.primary())
                  addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top);
                return pos;
              }, sel_move);
              if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++)
                doc.sel.ranges[i].goalColumn = goals[i];
            }),
        
            // Find the word at the given position (as returned by coordsChar).
            findWordAt: function(pos) {
              var doc = this.doc, line = getLine(doc, pos.line).text;
              var start = pos.ch, end = pos.ch;
              if (line) {
                var helper = this.getHelper(pos, "wordChars");
                if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
                var startChar = line.charAt(start);
                var check = isWordChar(startChar, helper)
                  ? function(ch) { return isWordChar(ch, helper); }
                  : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
                  : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
                while (start > 0 && check(line.charAt(start - 1))) --start;
                while (end < line.length && check(line.charAt(end))) ++end;
              }
              return new Range(Pos(pos.line, start), Pos(pos.line, end));
            },
        
            toggleOverwrite: function(value) {
              if (value != null && value == this.state.overwrite) return;
              if (this.state.overwrite = !this.state.overwrite)
                addClass(this.display.cursorDiv, "CodeMirror-overwrite");
              else
                rmClass(this.display.cursorDiv, "CodeMirror-overwrite");
        
              signal(this, "overwriteToggle", this, this.state.overwrite);
            },
            hasFocus: function() { return activeElt() == this.display.input; },
        
            scrollTo: methodOp(function(x, y) {
              if (x != null || y != null) resolveScrollToPos(this);
              if (x != null) this.curOp.scrollLeft = x;
              if (y != null) this.curOp.scrollTop = y;
            }),
            getScrollInfo: function() {
              var scroller = this.display.scroller, co = scrollerCutOff;
              return {left: scroller.scrollLeft, top: scroller.scrollTop,
                      height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
                      clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
            },
        
            scrollIntoView: methodOp(function(range, margin) {
              if (range == null) {
                range = {from: this.doc.sel.primary().head, to: null};
                if (margin == null) margin = this.options.cursorScrollMargin;
              } else if (typeof range == "number") {
                range = {from: Pos(range, 0), to: null};
              } else if (range.from == null) {
                range = {from: range, to: null};
              }
              if (!range.to) range.to = range.from;
              range.margin = margin || 0;
        
              if (range.from.line != null) {
                resolveScrollToPos(this);
                this.curOp.scrollToPos = range;
              } else {
                var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left),
                                              Math.min(range.from.top, range.to.top) - range.margin,
                                              Math.max(range.from.right, range.to.right),
                                              Math.max(range.from.bottom, range.to.bottom) + range.margin);
                this.scrollTo(sPos.scrollLeft, sPos.scrollTop);
              }
            }),
        
            setSize: methodOp(function(width, height) {
              var cm = this;
              function interpret(val) {
                return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
              }
              if (width != null) cm.display.wrapper.style.width = interpret(width);
              if (height != null) cm.display.wrapper.style.height = interpret(height);
              if (cm.options.lineWrapping) clearLineMeasurementCache(this);
              var lineNo = cm.display.viewFrom;
              cm.doc.iter(lineNo, cm.display.viewTo, function(line) {
                if (line.widgets) for (var i = 0; i < line.widgets.length; i++)
                  if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; }
                ++lineNo;
              });
              cm.curOp.forceUpdate = true;
              signal(cm, "refresh", this);
            }),
        
            operation: function(f){return runInOp(this, f);},
        
            refresh: methodOp(function() {
              var oldHeight = this.display.cachedTextHeight;
              regChange(this);
              this.curOp.forceUpdate = true;
              clearCaches(this);
              this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop);
              updateGutterSpace(this);
              if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
                estimateLineHeights(this);
              signal(this, "refresh", this);
            }),
        
            swapDoc: methodOp(function(doc) {
              var old = this.doc;
              old.cm = null;
              attachDoc(this, doc);
              clearCaches(this);
              resetInput(this);
              this.scrollTo(doc.scrollLeft, doc.scrollTop);
              this.curOp.forceScroll = true;
              signalLater(this, "swapDoc", this, old);
              return old;
            }),
        
            getInputField: function(){return this.display.input;},
            getWrapperElement: function(){return this.display.wrapper;},
            getScrollerElement: function(){return this.display.scroller;},
            getGutterElement: function(){return this.display.gutters;}
          };
          eventMixin(CodeMirror);
        
          // OPTION DEFAULTS
        
          // The default configuration options.
          var defaults = CodeMirror.defaults = {};
          // Functions to run when options are changed.
          var optionHandlers = CodeMirror.optionHandlers = {};
        
          function option(name, deflt, handle, notOnInit) {
            CodeMirror.defaults[name] = deflt;
            if (handle) optionHandlers[name] =
              notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
          }
        
          // Passed to option handlers when there is no old value.
          var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
        
          // These two are, on init, called from the constructor because they
          // have to be initialized before the editor can start at all.
          option("value", "", function(cm, val) {
            cm.setValue(val);
          }, true);
          option("mode", null, function(cm, val) {
            cm.doc.modeOption = val;
            loadMode(cm);
          }, true);
        
          option("indentUnit", 2, loadMode, true);
          option("indentWithTabs", false);
          option("smartIndent", true);
          option("tabSize", 4, function(cm) {
            resetModeState(cm);
            clearCaches(cm);
            regChange(cm);
          }, true);
          option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val) {
            cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
            cm.refresh();
          }, true);
          option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
          option("electricChars", true);
          option("rtlMoveVisually", !windows);
          option("wholeLineUpdateBefore", true);
        
          option("theme", "default", function(cm) {
            themeChanged(cm);
            guttersChanged(cm);
          }, true);
          option("keyMap", "default", function(cm, val, old) {
            var next = getKeyMap(val);
            var prev = old != CodeMirror.Init && getKeyMap(old);
            if (prev && prev.detach) prev.detach(cm, next);
            if (next.attach) next.attach(cm, prev || null);
          });
          option("extraKeys", null);
        
          option("lineWrapping", false, wrappingChanged, true);
          option("gutters", [], function(cm) {
            setGuttersForLineNumbers(cm.options);
            guttersChanged(cm);
          }, true);
          option("fixedGutter", true, function(cm, val) {
            cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
            cm.refresh();
          }, true);
          option("coverGutterNextToScrollbar", false, updateScrollbars, true);
          option("lineNumbers", false, function(cm) {
            setGuttersForLineNumbers(cm.options);
            guttersChanged(cm);
          }, true);
          option("firstLineNumber", 1, guttersChanged, true);
          option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
          option("showCursorWhenSelecting", false, updateSelection, true);
        
          option("resetSelectionOnContextMenu", true);
        
          option("readOnly", false, function(cm, val) {
            if (val == "nocursor") {
              onBlur(cm);
              cm.display.input.blur();
              cm.display.disabled = true;
            } else {
              cm.display.disabled = false;
              if (!val) resetInput(cm);
            }
          });
          option("disableInput", false, function(cm, val) {if (!val) resetInput(cm);}, true);
          option("dragDrop", true);
        
          option("cursorBlinkRate", 530);
          option("cursorScrollMargin", 0);
          option("cursorHeight", 1, updateSelection, true);
          option("singleCursorHeightPerLine", true, updateSelection, true);
          option("workTime", 100);
          option("workDelay", 100);
          option("flattenSpans", true, resetModeState, true);
          option("addModeClass", false, resetModeState, true);
          option("pollInterval", 100);
          option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;});
          option("historyEventDelay", 1250);
          option("viewportMargin", 10, function(cm){cm.refresh();}, true);
          option("maxHighlightLength", 10000, resetModeState, true);
          option("moveInputWithCursor", true, function(cm, val) {
            if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
          });
        
          option("tabindex", null, function(cm, val) {
            cm.display.input.tabIndex = val || "";
          });
          option("autofocus", null);
        
          // MODE DEFINITION AND QUERYING
        
          // Known modes, by name and by MIME
          var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
        
          // Extra arguments are stored as the mode's dependencies, which is
          // used by (legacy) mechanisms like loadmode.js to automatically
          // load a mode. (Preferred mechanism is the require/define calls.)
          CodeMirror.defineMode = function(name, mode) {
            if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
            if (arguments.length > 2)
              mode.dependencies = Array.prototype.slice.call(arguments, 2);
            modes[name] = mode;
          };
        
          CodeMirror.defineMIME = function(mime, spec) {
            mimeModes[mime] = spec;
          };
        
          // Given a MIME type, a {name, ...options} config object, or a name
          // string, return a mode config object.
          CodeMirror.resolveMode = function(spec) {
            if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
              spec = mimeModes[spec];
            } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
              var found = mimeModes[spec.name];
              if (typeof found == "string") found = {name: found};
              spec = createObj(found, spec);
              spec.name = found.name;
            } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
              return CodeMirror.resolveMode("application/xml");
            }
            if (typeof spec == "string") return {name: spec};
            else return spec || {name: "null"};
          };
        
          // Given a mode spec (anything that resolveMode accepts), find and
          // initialize an actual mode object.
          CodeMirror.getMode = function(options, spec) {
            var spec = CodeMirror.resolveMode(spec);
            var mfactory = modes[spec.name];
            if (!mfactory) return CodeMirror.getMode(options, "text/plain");
            var modeObj = mfactory(options, spec);
            if (modeExtensions.hasOwnProperty(spec.name)) {
              var exts = modeExtensions[spec.name];
              for (var prop in exts) {
                if (!exts.hasOwnProperty(prop)) continue;
                if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
                modeObj[prop] = exts[prop];
              }
            }
            modeObj.name = spec.name;
            if (spec.helperType) modeObj.helperType = spec.helperType;
            if (spec.modeProps) for (var prop in spec.modeProps)
              modeObj[prop] = spec.modeProps[prop];
        
            return modeObj;
          };
        
          // Minimal default mode.
          CodeMirror.defineMode("null", function() {
            return {token: function(stream) {stream.skipToEnd();}};
          });
          CodeMirror.defineMIME("text/plain", "null");
        
          // This can be used to attach properties to mode objects from
          // outside the actual mode definition.
          var modeExtensions = CodeMirror.modeExtensions = {};
          CodeMirror.extendMode = function(mode, properties) {
            var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
            copyObj(properties, exts);
          };
        
          // EXTENSIONS
        
          CodeMirror.defineExtension = function(name, func) {
            CodeMirror.prototype[name] = func;
          };
          CodeMirror.defineDocExtension = function(name, func) {
            Doc.prototype[name] = func;
          };
          CodeMirror.defineOption = option;
        
          var initHooks = [];
          CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
        
          var helpers = CodeMirror.helpers = {};
          CodeMirror.registerHelper = function(type, name, value) {
            if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};
            helpers[type][name] = value;
          };
          CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
            CodeMirror.registerHelper(type, name, value);
            helpers[type]._global.push({pred: predicate, val: value});
          };
        
          // MODE STATE HANDLING
        
          // Utility functions for working with state. Exported because nested
          // modes need to do this for their inner modes.
        
          var copyState = CodeMirror.copyState = function(mode, state) {
            if (state === true) return state;
            if (mode.copyState) return mode.copyState(state);
            var nstate = {};
            for (var n in state) {
              var val = state[n];
              if (val instanceof Array) val = val.concat([]);
              nstate[n] = val;
            }
            return nstate;
          };
        
          var startState = CodeMirror.startState = function(mode, a1, a2) {
            return mode.startState ? mode.startState(a1, a2) : true;
          };
        
          // Given a mode and a state (for that mode), find the inner mode and
          // state at the position that the state refers to.
          CodeMirror.innerMode = function(mode, state) {
            while (mode.innerMode) {
              var info = mode.innerMode(state);
              if (!info || info.mode == mode) break;
              state = info.state;
              mode = info.mode;
            }
            return info || {mode: mode, state: state};
          };
        
          // STANDARD COMMANDS
        
          // Commands are parameter-less actions that can be performed on an
          // editor, mostly used for keybindings.
          var commands = CodeMirror.commands = {
            selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);},
            singleSelection: function(cm) {
              cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll);
            },
            killLine: function(cm) {
              deleteNearSelection(cm, function(range) {
                if (range.empty()) {
                  var len = getLine(cm.doc, range.head.line).text.length;
                  if (range.head.ch == len && range.head.line < cm.lastLine())
                    return {from: range.head, to: Pos(range.head.line + 1, 0)};
                  else
                    return {from: range.head, to: Pos(range.head.line, len)};
                } else {
                  return {from: range.from(), to: range.to()};
                }
              });
            },
            deleteLine: function(cm) {
              deleteNearSelection(cm, function(range) {
                return {from: Pos(range.from().line, 0),
                        to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};
              });
            },
            delLineLeft: function(cm) {
              deleteNearSelection(cm, function(range) {
                return {from: Pos(range.from().line, 0), to: range.from()};
              });
            },
            delWrappedLineLeft: function(cm) {
              deleteNearSelection(cm, function(range) {
                var top = cm.charCoords(range.head, "div").top + 5;
                var leftPos = cm.coordsChar({left: 0, top: top}, "div");
                return {from: leftPos, to: range.from()};
              });
            },
            delWrappedLineRight: function(cm) {
              deleteNearSelection(cm, function(range) {
                var top = cm.charCoords(range.head, "div").top + 5;
                var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
                return {from: range.from(), to: rightPos };
              });
            },
            undo: function(cm) {cm.undo();},
            redo: function(cm) {cm.redo();},
            undoSelection: function(cm) {cm.undoSelection();},
            redoSelection: function(cm) {cm.redoSelection();},
            goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
            goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
            goLineStart: function(cm) {
              cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); },
                                    {origin: "+move", bias: 1});
            },
            goLineStartSmart: function(cm) {
              cm.extendSelectionsBy(function(range) {
                return lineStartSmart(cm, range.head);
              }, {origin: "+move", bias: 1});
            },
            goLineEnd: function(cm) {
              cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); },
                                    {origin: "+move", bias: -1});
            },
            goLineRight: function(cm) {
              cm.extendSelectionsBy(function(range) {
                var top = cm.charCoords(range.head, "div").top + 5;
                return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
              }, sel_move);
            },
            goLineLeft: function(cm) {
              cm.extendSelectionsBy(function(range) {
                var top = cm.charCoords(range.head, "div").top + 5;
                return cm.coordsChar({left: 0, top: top}, "div");
              }, sel_move);
            },
            goLineLeftSmart: function(cm) {
              cm.extendSelectionsBy(function(range) {
                var top = cm.charCoords(range.head, "div").top + 5;
                var pos = cm.coordsChar({left: 0, top: top}, "div");
                if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head);
                return pos;
              }, sel_move);
            },
            goLineUp: function(cm) {cm.moveV(-1, "line");},
            goLineDown: function(cm) {cm.moveV(1, "line");},
            goPageUp: function(cm) {cm.moveV(-1, "page");},
            goPageDown: function(cm) {cm.moveV(1, "page");},
            goCharLeft: function(cm) {cm.moveH(-1, "char");},
            goCharRight: function(cm) {cm.moveH(1, "char");},
            goColumnLeft: function(cm) {cm.moveH(-1, "column");},
            goColumnRight: function(cm) {cm.moveH(1, "column");},
            goWordLeft: function(cm) {cm.moveH(-1, "word");},
            goGroupRight: function(cm) {cm.moveH(1, "group");},
            goGroupLeft: function(cm) {cm.moveH(-1, "group");},
            goWordRight: function(cm) {cm.moveH(1, "word");},
            delCharBefore: function(cm) {cm.deleteH(-1, "char");},
            delCharAfter: function(cm) {cm.deleteH(1, "char");},
            delWordBefore: function(cm) {cm.deleteH(-1, "word");},
            delWordAfter: function(cm) {cm.deleteH(1, "word");},
            delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
            delGroupAfter: function(cm) {cm.deleteH(1, "group");},
            indentAuto: function(cm) {cm.indentSelection("smart");},
            indentMore: function(cm) {cm.indentSelection("add");},
            indentLess: function(cm) {cm.indentSelection("subtract");},
            insertTab: function(cm) {cm.replaceSelection("\t");},
            insertSoftTab: function(cm) {
              var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
              for (var i = 0; i < ranges.length; i++) {
                var pos = ranges[i].from();
                var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
                spaces.push(new Array(tabSize - col % tabSize + 1).join(" "));
              }
              cm.replaceSelections(spaces);
            },
            defaultTab: function(cm) {
              if (cm.somethingSelected()) cm.indentSelection("add");
              else cm.execCommand("insertTab");
            },
            transposeChars: function(cm) {
              runInOp(cm, function() {
                var ranges = cm.listSelections(), newSel = [];
                for (var i = 0; i < ranges.length; i++) {
                  var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
                  if (line) {
                    if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);
                    if (cur.ch > 0) {
                      cur = new Pos(cur.line, cur.ch + 1);
                      cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
                                      Pos(cur.line, cur.ch - 2), cur, "+transpose");
                    } else if (cur.line > cm.doc.first) {
                      var prev = getLine(cm.doc, cur.line - 1).text;
                      if (prev)
                        cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
                                        Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
                    }
                  }
                  newSel.push(new Range(cur, cur));
                }
                cm.setSelections(newSel);
              });
            },
            newlineAndIndent: function(cm) {
              runInOp(cm, function() {
                var len = cm.listSelections().length;
                for (var i = 0; i < len; i++) {
                  var range = cm.listSelections()[i];
                  cm.replaceRange("\n", range.anchor, range.head, "+input");
                  cm.indentLine(range.from().line + 1, null, true);
                  ensureCursorVisible(cm);
                }
              });
            },
            toggleOverwrite: function(cm) {cm.toggleOverwrite();}
          };
        
        
          // STANDARD KEYMAPS
        
          var keyMap = CodeMirror.keyMap = {};
        
          keyMap.basic = {
            "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
            "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
            "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
            "Tab": "defaultTab", "Shift-Tab": "indentAuto",
            "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
            "Esc": "singleSelection"
          };
          // Note that the save and find-related commands aren't defined by
          // default. User code or addons can define them. Unknown commands
          // are simply ignored.
          keyMap.pcDefault = {
            "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
            "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
            "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
            "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
            "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
            "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
            "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
            fallthrough: "basic"
          };
          // Very basic readline/emacs-style bindings, which are standard on Mac.
          keyMap.emacsy = {
            "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
            "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
            "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
            "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
          };
          keyMap.macDefault = {
            "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
            "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
            "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
            "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
            "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
            "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
            "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
            fallthrough: ["basic", "emacsy"]
          };
          keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
        
          // KEYMAP DISPATCH
        
          function normalizeKeyName(name) {
            var parts = name.split(/-(?!$)/), name = parts[parts.length - 1];
            var alt, ctrl, shift, cmd;
            for (var i = 0; i < parts.length - 1; i++) {
              var mod = parts[i];
              if (/^(cmd|meta|m)$/i.test(mod)) cmd = true;
              else if (/^a(lt)?$/i.test(mod)) alt = true;
              else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;
              else if (/^s(hift)$/i.test(mod)) shift = true;
              else throw new Error("Unrecognized modifier name: " + mod);
            }
            if (alt) name = "Alt-" + name;
            if (ctrl) name = "Ctrl-" + name;
            if (cmd) name = "Cmd-" + name;
            if (shift) name = "Shift-" + name;
            return name;
          }
        
          // This is a kludge to keep keymaps mostly working as raw objects
          // (backwards compatibility) while at the same time support features
          // like normalization and multi-stroke key bindings. It compiles a
          // new normalized keymap, and then updates the old object to reflect
          // this.
          CodeMirror.normalizeKeyMap = function(keymap) {
            var copy = {};
            for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) {
              var value = keymap[keyname];
              if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue;
              if (value == "...") { delete keymap[keyname]; continue; }
        
              var keys = map(keyname.split(" "), normalizeKeyName);
              for (var i = 0; i < keys.length; i++) {
                var val, name;
                if (i == keys.length - 1) {
                  name = keyname;
                  val = value;
                } else {
                  name = keys.slice(0, i + 1).join(" ");
                  val = "...";
                }
                var prev = copy[name];
                if (!prev) copy[name] = val;
                else if (prev != val) throw new Error("Inconsistent bindings for " + name);
              }
              delete keymap[keyname];
            }
            for (var prop in copy) keymap[prop] = copy[prop];
            return keymap;
          };
        
          var lookupKey = CodeMirror.lookupKey = function(key, map, handle) {
            map = getKeyMap(map);
            var found = map.call ? map.call(key) : map[key];
            if (found === false) return "nothing";
            if (found === "...") return "multi";
            if (found != null && handle(found)) return "handled";
        
            if (map.fallthrough) {
              if (Object.prototype.toString.call(map.fallthrough) != "[object Array]")
                return lookupKey(key, map.fallthrough, handle);
              for (var i = 0; i < map.fallthrough.length; i++) {
                var result = lookupKey(key, map.fallthrough[i], handle);
                if (result) return result;
              }
            }
          };
        
          // Modifier key presses don't count as 'real' key presses for the
          // purpose of keymap fallthrough.
          var isModifierKey = CodeMirror.isModifierKey = function(value) {
            var name = typeof value == "string" ? value : keyNames[value.keyCode];
            return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
          };
        
          // Look up the name of a key as indicated by an event object.
          var keyName = CodeMirror.keyName = function(event, noShift) {
            if (presto && event.keyCode == 34 && event["char"]) return false;
            var base = keyNames[event.keyCode], name = base;
            if (name == null || event.altGraphKey) return false;
            if (event.altKey && base != "Alt") name = "Alt-" + name;
            if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name;
            if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name;
            if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name;
            return name;
          };
        
          function getKeyMap(val) {
            return typeof val == "string" ? keyMap[val] : val;
          }
        
          // FROMTEXTAREA
        
          CodeMirror.fromTextArea = function(textarea, options) {
            if (!options) options = {};
            options.value = textarea.value;
            if (!options.tabindex && textarea.tabindex)
              options.tabindex = textarea.tabindex;
            if (!options.placeholder && textarea.placeholder)
              options.placeholder = textarea.placeholder;
            // Set autofocus to true if this textarea is focused, or if it has
            // autofocus and no other element is focused.
            if (options.autofocus == null) {
              var hasFocus = activeElt();
              options.autofocus = hasFocus == textarea ||
                textarea.getAttribute("autofocus") != null && hasFocus == document.body;
            }
        
            function save() {textarea.value = cm.getValue();}
            if (textarea.form) {
              on(textarea.form, "submit", save);
              // Deplorable hack to make the submit method do the right thing.
              if (!options.leaveSubmitMethodAlone) {
                var form = textarea.form, realSubmit = form.submit;
                try {
                  var wrappedSubmit = form.submit = function() {
                    save();
                    form.submit = realSubmit;
                    form.submit();
                    form.submit = wrappedSubmit;
                  };
                } catch(e) {}
              }
            }
        
            textarea.style.display = "none";
            var cm = CodeMirror(function(node) {
              textarea.parentNode.insertBefore(node, textarea.nextSibling);
            }, options);
            cm.save = save;
            cm.getTextArea = function() { return textarea; };
            cm.toTextArea = function() {
              cm.toTextArea = isNaN; // Prevent this from being ran twice
              save();
              textarea.parentNode.removeChild(cm.getWrapperElement());
              textarea.style.display = "";
              if (textarea.form) {
                off(textarea.form, "submit", save);
                if (typeof textarea.form.submit == "function")
                  textarea.form.submit = realSubmit;
              }
            };
            return cm;
          };
        
          // STRING STREAM
        
          // Fed to the mode parsers, provides helper functions to make
          // parsers more succinct.
        
          var StringStream = CodeMirror.StringStream = function(string, tabSize) {
            this.pos = this.start = 0;
            this.string = string;
            this.tabSize = tabSize || 8;
            this.lastColumnPos = this.lastColumnValue = 0;
            this.lineStart = 0;
          };
        
          StringStream.prototype = {
            eol: function() {return this.pos >= this.string.length;},
            sol: function() {return this.pos == this.lineStart;},
            peek: function() {return this.string.charAt(this.pos) || undefined;},
            next: function() {
              if (this.pos < this.string.length)
                return this.string.charAt(this.pos++);
            },
            eat: function(match) {
              var ch = this.string.charAt(this.pos);
              if (typeof match == "string") var ok = ch == match;
              else var ok = ch && (match.test ? match.test(ch) : match(ch));
              if (ok) {++this.pos; return ch;}
            },
            eatWhile: function(match) {
              var start = this.pos;
              while (this.eat(match)){}
              return this.pos > start;
            },
            eatSpace: function() {
              var start = this.pos;
              while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
              return this.pos > start;
            },
            skipToEnd: function() {this.pos = this.string.length;},
            skipTo: function(ch) {
              var found = this.string.indexOf(ch, this.pos);
              if (found > -1) {this.pos = found; return true;}
            },
            backUp: function(n) {this.pos -= n;},
            column: function() {
              if (this.lastColumnPos < this.start) {
                this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
                this.lastColumnPos = this.start;
              }
              return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
            },
            indentation: function() {
              return countColumn(this.string, null, this.tabSize) -
                (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
            },
            match: function(pattern, consume, caseInsensitive) {
              if (typeof pattern == "string") {
                var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
                var substr = this.string.substr(this.pos, pattern.length);
                if (cased(substr) == cased(pattern)) {
                  if (consume !== false) this.pos += pattern.length;
                  return true;
                }
              } else {
                var match = this.string.slice(this.pos).match(pattern);
                if (match && match.index > 0) return null;
                if (match && consume !== false) this.pos += match[0].length;
                return match;
              }
            },
            current: function(){return this.string.slice(this.start, this.pos);},
            hideFirstChars: function(n, inner) {
              this.lineStart += n;
              try { return inner(); }
              finally { this.lineStart -= n; }
            }
          };
        
          // TEXTMARKERS
        
          // Created with markText and setBookmark methods. A TextMarker is a
          // handle that can be used to clear or find a marked position in the
          // document. Line objects hold arrays (markedSpans) containing
          // {from, to, marker} object pointing to such marker objects, and
          // indicating that such a marker is present on that line. Multiple
          // lines may point to the same marker when it spans across lines.
          // The spans will have null for their from/to properties when the
          // marker continues beyond the start/end of the line. Markers have
          // links back to the lines they currently touch.
        
          var TextMarker = CodeMirror.TextMarker = function(doc, type) {
            this.lines = [];
            this.type = type;
            this.doc = doc;
          };
          eventMixin(TextMarker);
        
          // Clear the marker.
          TextMarker.prototype.clear = function() {
            if (this.explicitlyCleared) return;
            var cm = this.doc.cm, withOp = cm && !cm.curOp;
            if (withOp) startOperation(cm);
            if (hasHandler(this, "clear")) {
              var found = this.find();
              if (found) signalLater(this, "clear", found.from, found.to);
            }
            var min = null, max = null;
            for (var i = 0; i < this.lines.length; ++i) {
              var line = this.lines[i];
              var span = getMarkedSpanFor(line.markedSpans, this);
              if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text");
              else if (cm) {
                if (span.to != null) max = lineNo(line);
                if (span.from != null) min = lineNo(line);
              }
              line.markedSpans = removeMarkedSpan(line.markedSpans, span);
              if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)
                updateLineHeight(line, textHeight(cm.display));
            }
            if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
              var visual = visualLine(this.lines[i]), len = lineLength(visual);
              if (len > cm.display.maxLineLength) {
                cm.display.maxLine = visual;
                cm.display.maxLineLength = len;
                cm.display.maxLineChanged = true;
              }
            }
        
            if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);
            this.lines.length = 0;
            this.explicitlyCleared = true;
            if (this.atomic && this.doc.cantEdit) {
              this.doc.cantEdit = false;
              if (cm) reCheckSelection(cm.doc);
            }
            if (cm) signalLater(cm, "markerCleared", cm, this);
            if (withOp) endOperation(cm);
            if (this.parent) this.parent.clear();
          };
        
          // Find the position of the marker in the document. Returns a {from,
          // to} object by default. Side can be passed to get a specific side
          // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
          // Pos objects returned contain a line object, rather than a line
          // number (used to prevent looking up the same line twice).
          TextMarker.prototype.find = function(side, lineObj) {
            if (side == null && this.type == "bookmark") side = 1;
            var from, to;
            for (var i = 0; i < this.lines.length; ++i) {
              var line = this.lines[i];
              var span = getMarkedSpanFor(line.markedSpans, this);
              if (span.from != null) {
                from = Pos(lineObj ? line : lineNo(line), span.from);
                if (side == -1) return from;
              }
              if (span.to != null) {
                to = Pos(lineObj ? line : lineNo(line), span.to);
                if (side == 1) return to;
              }
            }
            return from && {from: from, to: to};
          };
        
          // Signals that the marker's widget changed, and surrounding layout
          // should be recomputed.
          TextMarker.prototype.changed = function() {
            var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
            if (!pos || !cm) return;
            runInOp(cm, function() {
              var line = pos.line, lineN = lineNo(pos.line);
              var view = findViewForLine(cm, lineN);
              if (view) {
                clearLineMeasurementCacheFor(view);
                cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
              }
              cm.curOp.updateMaxLine = true;
              if (!lineIsHidden(widget.doc, line) && widget.height != null) {
                var oldHeight = widget.height;
                widget.height = null;
                var dHeight = widgetHeight(widget) - oldHeight;
                if (dHeight)
                  updateLineHeight(line, line.height + dHeight);
              }
            });
          };
        
          TextMarker.prototype.attachLine = function(line) {
            if (!this.lines.length && this.doc.cm) {
              var op = this.doc.cm.curOp;
              if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
                (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
            }
            this.lines.push(line);
          };
          TextMarker.prototype.detachLine = function(line) {
            this.lines.splice(indexOf(this.lines, line), 1);
            if (!this.lines.length && this.doc.cm) {
              var op = this.doc.cm.curOp;
              (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
            }
          };
        
          // Collapsed markers have unique ids, in order to be able to order
          // them, which is needed for uniquely determining an outer marker
          // when they overlap (they may nest, but not partially overlap).
          var nextMarkerId = 0;
        
          // Create a marker, wire it up to the right lines, and
          function markText(doc, from, to, options, type) {
            // Shared markers (across linked documents) are handled separately
            // (markTextShared will call out to this again, once per
            // document).
            if (options && options.shared) return markTextShared(doc, from, to, options, type);
            // Ensure we are in an operation.
            if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
        
            var marker = new TextMarker(doc, type), diff = cmp(from, to);
            if (options) copyObj(options, marker, false);
            // Don't connect empty markers unless clearWhenEmpty is false
            if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
              return marker;
            if (marker.replacedWith) {
              // Showing up as a widget implies collapsed (widget replaces text)
              marker.collapsed = true;
              marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget");
              if (!options.handleMouseEvents) marker.widgetNode.ignoreEvents = true;
              if (options.insertLeft) marker.widgetNode.insertLeft = true;
            }
            if (marker.collapsed) {
              if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
                  from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
                throw new Error("Inserting collapsed marker partially overlapping an existing one");
              sawCollapsedSpans = true;
            }
        
            if (marker.addToHistory)
              addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN);
        
            var curLine = from.line, cm = doc.cm, updateMaxLine;
            doc.iter(curLine, to.line + 1, function(line) {
              if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
                updateMaxLine = true;
              if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
              addMarkedSpan(line, new MarkedSpan(marker,
                                                 curLine == from.line ? from.ch : null,
                                                 curLine == to.line ? to.ch : null));
              ++curLine;
            });
            // lineIsHidden depends on the presence of the spans, so needs a second pass
            if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
              if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
            });
        
            if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
        
            if (marker.readOnly) {
              sawReadOnlySpans = true;
              if (doc.history.done.length || doc.history.undone.length)
                doc.clearHistory();
            }
            if (marker.collapsed) {
              marker.id = ++nextMarkerId;
              marker.atomic = true;
            }
            if (cm) {
              // Sync editor state
              if (updateMaxLine) cm.curOp.updateMaxLine = true;
              if (marker.collapsed)
                regChange(cm, from.line, to.line + 1);
              else if (marker.className || marker.title || marker.startStyle || marker.endStyle)
                for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
              if (marker.atomic) reCheckSelection(cm.doc);
              signalLater(cm, "markerAdded", cm, marker);
            }
            return marker;
          }
        
          // SHARED TEXTMARKERS
        
          // A shared marker spans multiple linked documents. It is
          // implemented as a meta-marker-object controlling multiple normal
          // markers.
          var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) {
            this.markers = markers;
            this.primary = primary;
            for (var i = 0; i < markers.length; ++i)
              markers[i].parent = this;
          };
          eventMixin(SharedTextMarker);
        
          SharedTextMarker.prototype.clear = function() {
            if (this.explicitlyCleared) return;
            this.explicitlyCleared = true;
            for (var i = 0; i < this.markers.length; ++i)
              this.markers[i].clear();
            signalLater(this, "clear");
          };
          SharedTextMarker.prototype.find = function(side, lineObj) {
            return this.primary.find(side, lineObj);
          };
        
          function markTextShared(doc, from, to, options, type) {
            options = copyObj(options);
            options.shared = false;
            var markers = [markText(doc, from, to, options, type)], primary = markers[0];
            var widget = options.widgetNode;
            linkedDocs(doc, function(doc) {
              if (widget) options.widgetNode = widget.cloneNode(true);
              markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
              for (var i = 0; i < doc.linked.length; ++i)
                if (doc.linked[i].isParent) return;
              primary = lst(markers);
            });
            return new SharedTextMarker(markers, primary);
          }
        
          function findSharedMarkers(doc) {
            return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),
                                 function(m) { return m.parent; });
          }
        
          function copySharedMarkers(doc, markers) {
            for (var i = 0; i < markers.length; i++) {
              var marker = markers[i], pos = marker.find();
              var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
              if (cmp(mFrom, mTo)) {
                var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
                marker.markers.push(subMark);
                subMark.parent = marker;
              }
            }
          }
        
          function detachSharedMarkers(markers) {
            for (var i = 0; i < markers.length; i++) {
              var marker = markers[i], linked = [marker.primary.doc];;
              linkedDocs(marker.primary.doc, function(d) { linked.push(d); });
              for (var j = 0; j < marker.markers.length; j++) {
                var subMarker = marker.markers[j];
                if (indexOf(linked, subMarker.doc) == -1) {
                  subMarker.parent = null;
                  marker.markers.splice(j--, 1);
                }
              }
            }
          }
        
          // TEXTMARKER SPANS
        
          function MarkedSpan(marker, from, to) {
            this.marker = marker;
            this.from = from; this.to = to;
          }
        
          // Search an array of spans for a span matching the given marker.
          function getMarkedSpanFor(spans, marker) {
            if (spans) for (var i = 0; i < spans.length; ++i) {
              var span = spans[i];
              if (span.marker == marker) return span;
            }
          }
          // Remove a span from an array, returning undefined if no spans are
          // left (we don't store arrays for lines without spans).
          function removeMarkedSpan(spans, span) {
            for (var r, i = 0; i < spans.length; ++i)
              if (spans[i] != span) (r || (r = [])).push(spans[i]);
            return r;
          }
          // Add a span to a line.
          function addMarkedSpan(line, span) {
            line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
            span.marker.attachLine(line);
          }
        
          // Used for the algorithm that adjusts markers for a change in the
          // document. These functions cut an array of spans at a given
          // character position, returning an array of remaining chunks (or
          // undefined if nothing remains).
          function markedSpansBefore(old, startCh, isInsert) {
            if (old) for (var i = 0, nw; i < old.length; ++i) {
              var span = old[i], marker = span.marker;
              var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
              if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
                var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
                (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
              }
            }
            return nw;
          }
          function markedSpansAfter(old, endCh, isInsert) {
            if (old) for (var i = 0, nw; i < old.length; ++i) {
              var span = old[i], marker = span.marker;
              var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
              if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
                var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
                (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
                                                      span.to == null ? null : span.to - endCh));
              }
            }
            return nw;
          }
        
          // Given a change object, compute the new set of marker spans that
          // cover the line in which the change took place. Removes spans
          // entirely within the change, reconnects spans belonging to the
          // same marker that appear on both sides of the change, and cuts off
          // spans partially within the change. Returns an array of span
          // arrays with one element for each line in (after) the change.
          function stretchSpansOverChange(doc, change) {
            var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
            var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
            if (!oldFirst && !oldLast) return null;
        
            var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
            // Get the spans that 'stick out' on both sides
            var first = markedSpansBefore(oldFirst, startCh, isInsert);
            var last = markedSpansAfter(oldLast, endCh, isInsert);
        
            // Next, merge those two ends
            var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
            if (first) {
              // Fix up .to properties of first
              for (var i = 0; i < first.length; ++i) {
                var span = first[i];
                if (span.to == null) {
                  var found = getMarkedSpanFor(last, span.marker);
                  if (!found) span.to = startCh;
                  else if (sameLine) span.to = found.to == null ? null : found.to + offset;
                }
              }
            }
            if (last) {
              // Fix up .from in last (or move them into first in case of sameLine)
              for (var i = 0; i < last.length; ++i) {
                var span = last[i];
                if (span.to != null) span.to += offset;
                if (span.from == null) {
                  var found = getMarkedSpanFor(first, span.marker);
                  if (!found) {
                    span.from = offset;
                    if (sameLine) (first || (first = [])).push(span);
                  }
                } else {
                  span.from += offset;
                  if (sameLine) (first || (first = [])).push(span);
                }
              }
            }
            // Make sure we didn't create any zero-length spans
            if (first) first = clearEmptySpans(first);
            if (last && last != first) last = clearEmptySpans(last);
        
            var newMarkers = [first];
            if (!sameLine) {
              // Fill gap with whole-line-spans
              var gap = change.text.length - 2, gapMarkers;
              if (gap > 0 && first)
                for (var i = 0; i < first.length; ++i)
                  if (first[i].to == null)
                    (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));
              for (var i = 0; i < gap; ++i)
                newMarkers.push(gapMarkers);
              newMarkers.push(last);
            }
            return newMarkers;
          }
        
          // Remove spans that are empty and don't have a clearWhenEmpty
          // option of false.
          function clearEmptySpans(spans) {
            for (var i = 0; i < spans.length; ++i) {
              var span = spans[i];
              if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
                spans.splice(i--, 1);
            }
            if (!spans.length) return null;
            return spans;
          }
        
          // Used for un/re-doing changes from the history. Combines the
          // result of computing the existing spans with the set of spans that
          // existed in the history (so that deleting around a span and then
          // undoing brings back the span).
          function mergeOldSpans(doc, change) {
            var old = getOldSpans(doc, change);
            var stretched = stretchSpansOverChange(doc, change);
            if (!old) return stretched;
            if (!stretched) return old;
        
            for (var i = 0; i < old.length; ++i) {
              var oldCur = old[i], stretchCur = stretched[i];
              if (oldCur && stretchCur) {
                spans: for (var j = 0; j < stretchCur.length; ++j) {
                  var span = stretchCur[j];
                  for (var k = 0; k < oldCur.length; ++k)
                    if (oldCur[k].marker == span.marker) continue spans;
                  oldCur.push(span);
                }
              } else if (stretchCur) {
                old[i] = stretchCur;
              }
            }
            return old;
          }
        
          // Used to 'clip' out readOnly ranges when making a change.
          function removeReadOnlyRanges(doc, from, to) {
            var markers = null;
            doc.iter(from.line, to.line + 1, function(line) {
              if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
                var mark = line.markedSpans[i].marker;
                if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
                  (markers || (markers = [])).push(mark);
              }
            });
            if (!markers) return null;
            var parts = [{from: from, to: to}];
            for (var i = 0; i < markers.length; ++i) {
              var mk = markers[i], m = mk.find(0);
              for (var j = 0; j < parts.length; ++j) {
                var p = parts[j];
                if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue;
                var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
                if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
                  newParts.push({from: p.from, to: m.from});
                if (dto > 0 || !mk.inclusiveRight && !dto)
                  newParts.push({from: m.to, to: p.to});
                parts.splice.apply(parts, newParts);
                j += newParts.length - 1;
              }
            }
            return parts;
          }
        
          // Connect or disconnect spans from a line.
          function detachMarkedSpans(line) {
            var spans = line.markedSpans;
            if (!spans) return;
            for (var i = 0; i < spans.length; ++i)
              spans[i].marker.detachLine(line);
            line.markedSpans = null;
          }
          function attachMarkedSpans(line, spans) {
            if (!spans) return;
            for (var i = 0; i < spans.length; ++i)
              spans[i].marker.attachLine(line);
            line.markedSpans = spans;
          }
        
          // Helpers used when computing which overlapping collapsed span
          // counts as the larger one.
          function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }
          function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }
        
          // Returns a number indicating which of two overlapping collapsed
          // spans is larger (and thus includes the other). Falls back to
          // comparing ids when the spans cover exactly the same range.
          function compareCollapsedMarkers(a, b) {
            var lenDiff = a.lines.length - b.lines.length;
            if (lenDiff != 0) return lenDiff;
            var aPos = a.find(), bPos = b.find();
            var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
            if (fromCmp) return -fromCmp;
            var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
            if (toCmp) return toCmp;
            return b.id - a.id;
          }
        
          // Find out whether a line ends or starts in a collapsed span. If
          // so, return the marker for that span.
          function collapsedSpanAtSide(line, start) {
            var sps = sawCollapsedSpans && line.markedSpans, found;
            if (sps) for (var sp, i = 0; i < sps.length; ++i) {
              sp = sps[i];
              if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
                  (!found || compareCollapsedMarkers(found, sp.marker) < 0))
                found = sp.marker;
            }
            return found;
          }
          function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }
          function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }
        
          // Test whether there exists a collapsed span that partially
          // overlaps (covers the start or end, but not both) of a new span.
          // Such overlap is not allowed.
          function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
            var line = getLine(doc, lineNo);
            var sps = sawCollapsedSpans && line.markedSpans;
            if (sps) for (var i = 0; i < sps.length; ++i) {
              var sp = sps[i];
              if (!sp.marker.collapsed) continue;
              var found = sp.marker.find(0);
              var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
              var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
              if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue;
              if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) ||
                  fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight)))
                return true;
            }
          }
        
          // A visual line is a line as drawn on the screen. Folding, for
          // example, can cause multiple logical lines to appear on the same
          // visual line. This finds the start of the visual line that the
          // given line is part of (usually that is the line itself).
          function visualLine(line) {
            var merged;
            while (merged = collapsedSpanAtStart(line))
              line = merged.find(-1, true).line;
            return line;
          }
        
          // Returns an array of logical lines that continue the visual line
          // started by the argument, or undefined if there are no such lines.
          function visualLineContinued(line) {
            var merged, lines;
            while (merged = collapsedSpanAtEnd(line)) {
              line = merged.find(1, true).line;
              (lines || (lines = [])).push(line);
            }
            return lines;
          }
        
          // Get the line number of the start of the visual line that the
          // given line number is part of.
          function visualLineNo(doc, lineN) {
            var line = getLine(doc, lineN), vis = visualLine(line);
            if (line == vis) return lineN;
            return lineNo(vis);
          }
          // Get the line number of the start of the next visual line after
          // the given line.
          function visualLineEndNo(doc, lineN) {
            if (lineN > doc.lastLine()) return lineN;
            var line = getLine(doc, lineN), merged;
            if (!lineIsHidden(doc, line)) return lineN;
            while (merged = collapsedSpanAtEnd(line))
              line = merged.find(1, true).line;
            return lineNo(line) + 1;
          }
        
          // Compute whether a line is hidden. Lines count as hidden when they
          // are part of a visual line that starts with another line, or when
          // they are entirely covered by collapsed, non-widget span.
          function lineIsHidden(doc, line) {
            var sps = sawCollapsedSpans && line.markedSpans;
            if (sps) for (var sp, i = 0; i < sps.length; ++i) {
              sp = sps[i];
              if (!sp.marker.collapsed) continue;
              if (sp.from == null) return true;
              if (sp.marker.widgetNode) continue;
              if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
                return true;
            }
          }
          function lineIsHiddenInner(doc, line, span) {
            if (span.to == null) {
              var end = span.marker.find(1, true);
              return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker));
            }
            if (span.marker.inclusiveRight && span.to == line.text.length)
              return true;
            for (var sp, i = 0; i < line.markedSpans.length; ++i) {
              sp = line.markedSpans[i];
              if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
                  (sp.to == null || sp.to != span.from) &&
                  (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
                  lineIsHiddenInner(doc, line, sp)) return true;
            }
          }
        
          // LINE WIDGETS
        
          // Line widgets are block elements displayed above or below a line.
        
          var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
            if (options) for (var opt in options) if (options.hasOwnProperty(opt))
              this[opt] = options[opt];
            this.cm = cm;
            this.node = node;
          };
          eventMixin(LineWidget);
        
          function adjustScrollWhenAboveVisible(cm, line, diff) {
            if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
              addToScrollPos(cm, null, diff);
          }
        
          LineWidget.prototype.clear = function() {
            var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
            if (no == null || !ws) return;
            for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
            if (!ws.length) line.widgets = null;
            var height = widgetHeight(this);
            runInOp(cm, function() {
              adjustScrollWhenAboveVisible(cm, line, -height);
              regLineChange(cm, no, "widget");
              updateLineHeight(line, Math.max(0, line.height - height));
            });
          };
          LineWidget.prototype.changed = function() {
            var oldH = this.height, cm = this.cm, line = this.line;
            this.height = null;
            var diff = widgetHeight(this) - oldH;
            if (!diff) return;
            runInOp(cm, function() {
              cm.curOp.forceUpdate = true;
              adjustScrollWhenAboveVisible(cm, line, diff);
              updateLineHeight(line, line.height + diff);
            });
          };
        
          function widgetHeight(widget) {
            if (widget.height != null) return widget.height;
            if (!contains(document.body, widget.node)) {
              var parentStyle = "position: relative;";
              if (widget.coverGutter)
                parentStyle += "margin-left: -" + widget.cm.getGutterElement().offsetWidth + "px;";
              removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, parentStyle));
            }
            return widget.height = widget.node.offsetHeight;
          }
        
          function addLineWidget(cm, handle, node, options) {
            var widget = new LineWidget(cm, node, options);
            if (widget.noHScroll) cm.display.alignWidgets = true;
            changeLine(cm.doc, handle, "widget", function(line) {
              var widgets = line.widgets || (line.widgets = []);
              if (widget.insertAt == null) widgets.push(widget);
              else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
              widget.line = line;
              if (!lineIsHidden(cm.doc, line)) {
                var aboveVisible = heightAtLine(line) < cm.doc.scrollTop;
                updateLineHeight(line, line.height + widgetHeight(widget));
                if (aboveVisible) addToScrollPos(cm, null, widget.height);
                cm.curOp.forceUpdate = true;
              }
              return true;
            });
            return widget;
          }
        
          // LINE DATA STRUCTURE
        
          // Line objects. These hold state related to a line, including
          // highlighting info (the styles array).
          var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
            this.text = text;
            attachMarkedSpans(this, markedSpans);
            this.height = estimateHeight ? estimateHeight(this) : 1;
          };
          eventMixin(Line);
          Line.prototype.lineNo = function() { return lineNo(this); };
        
          // Change the content (text, markers) of a line. Automatically
          // invalidates cached information and tries to re-estimate the
          // line's height.
          function updateLine(line, text, markedSpans, estimateHeight) {
            line.text = text;
            if (line.stateAfter) line.stateAfter = null;
            if (line.styles) line.styles = null;
            if (line.order != null) line.order = null;
            detachMarkedSpans(line);
            attachMarkedSpans(line, markedSpans);
            var estHeight = estimateHeight ? estimateHeight(line) : 1;
            if (estHeight != line.height) updateLineHeight(line, estHeight);
          }
        
          // Detach a line from the document tree and its markers.
          function cleanUpLine(line) {
            line.parent = null;
            detachMarkedSpans(line);
          }
        
          function extractLineClasses(type, output) {
            if (type) for (;;) {
              var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
              if (!lineClass) break;
              type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
              var prop = lineClass[1] ? "bgClass" : "textClass";
              if (output[prop] == null)
                output[prop] = lineClass[2];
              else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
                output[prop] += " " + lineClass[2];
            }
            return type;
          }
        
          function callBlankLine(mode, state) {
            if (mode.blankLine) return mode.blankLine(state);
            if (!mode.innerMode) return;
            var inner = CodeMirror.innerMode(mode, state);
            if (inner.mode.blankLine) return inner.mode.blankLine(inner.state);
          }
        
          function readToken(mode, stream, state, inner) {
            for (var i = 0; i < 10; i++) {
              if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode;
              var style = mode.token(stream, state);
              if (stream.pos > stream.start) return style;
            }
            throw new Error("Mode " + mode.name + " failed to advance stream.");
          }
        
          // Utility for getTokenAt and getLineTokens
          function takeToken(cm, pos, precise, asArray) {
            function getObj(copy) {
              return {start: stream.start, end: stream.pos,
                      string: stream.current(),
                      type: style || null,
                      state: copy ? copyState(doc.mode, state) : state};
            }
        
            var doc = cm.doc, mode = doc.mode, style;
            pos = clipPos(doc, pos);
            var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise);
            var stream = new StringStream(line.text, cm.options.tabSize), tokens;
            if (asArray) tokens = [];
            while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
              stream.start = stream.pos;
              style = readToken(mode, stream, state);
              if (asArray) tokens.push(getObj(true));
            }
            return asArray ? tokens : getObj();
          }
        
          // Run the given mode's parser over a line, calling f for each token.
          function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {
            var flattenSpans = mode.flattenSpans;
            if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
            var curStart = 0, curStyle = null;
            var stream = new StringStream(text, cm.options.tabSize), style;
            var inner = cm.options.addModeClass && [null];
            if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses);
            while (!stream.eol()) {
              if (stream.pos > cm.options.maxHighlightLength) {
                flattenSpans = false;
                if (forceToEnd) processLine(cm, text, state, stream.pos);
                stream.pos = text.length;
                style = null;
              } else {
                style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses);
              }
              if (inner) {
                var mName = inner[0].name;
                if (mName) style = "m-" + (style ? mName + " " + style : mName);
              }
              if (!flattenSpans || curStyle != style) {
                if (curStart < stream.start) f(stream.start, curStyle);
                curStart = stream.start; curStyle = style;
              }
              stream.start = stream.pos;
            }
            while (curStart < stream.pos) {
              // Webkit seems to refuse to render text nodes longer than 57444 characters
              var pos = Math.min(stream.pos, curStart + 50000);
              f(pos, curStyle);
              curStart = pos;
            }
          }
        
          // Compute a style array (an array starting with a mode generation
          // -- for invalidation -- followed by pairs of end positions and
          // style strings), which is used to highlight the tokens on the
          // line.
          function highlightLine(cm, line, state, forceToEnd) {
            // A styles array always starts with a number identifying the
            // mode/overlays that it is based on (for easy invalidation).
            var st = [cm.state.modeGen], lineClasses = {};
            // Compute the base array of styles
            runMode(cm, line.text, cm.doc.mode, state, function(end, style) {
              st.push(end, style);
            }, lineClasses, forceToEnd);
        
            // Run overlays, adjust style array.
            for (var o = 0; o < cm.state.overlays.length; ++o) {
              var overlay = cm.state.overlays[o], i = 1, at = 0;
              runMode(cm, line.text, overlay.mode, true, function(end, style) {
                var start = i;
                // Ensure there's a token end at the current position, and that i points at it
                while (at < end) {
                  var i_end = st[i];
                  if (i_end > end)
                    st.splice(i, 1, end, st[i+1], i_end);
                  i += 2;
                  at = Math.min(end, i_end);
                }
                if (!style) return;
                if (overlay.opaque) {
                  st.splice(start, i - start, end, "cm-overlay " + style);
                  i = start + 2;
                } else {
                  for (; start < i; start += 2) {
                    var cur = st[start+1];
                    st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style;
                  }
                }
              }, lineClasses);
            }
        
            return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null};
          }
        
          function getLineStyles(cm, line, updateFrontier) {
            if (!line.styles || line.styles[0] != cm.state.modeGen) {
              var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
              line.styles = result.styles;
              if (result.classes) line.styleClasses = result.classes;
              else if (line.styleClasses) line.styleClasses = null;
              if (updateFrontier === cm.doc.frontier) cm.doc.frontier++;
            }
            return line.styles;
          }
        
          // Lightweight form of highlight -- proceed over this line and
          // update state, but don't save a style array. Used for lines that
          // aren't currently visible.
          function processLine(cm, text, state, startAt) {
            var mode = cm.doc.mode;
            var stream = new StringStream(text, cm.options.tabSize);
            stream.start = stream.pos = startAt || 0;
            if (text == "") callBlankLine(mode, state);
            while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
              readToken(mode, stream, state);
              stream.start = stream.pos;
            }
          }
        
          // Convert a style as returned by a mode (either null, or a string
          // containing one or more styles) to a CSS style. This is cached,
          // and also looks for line-wide styles.
          var styleToClassCache = {}, styleToClassCacheWithMode = {};
          function interpretTokenStyle(style, options) {
            if (!style || /^\s*$/.test(style)) return null;
            var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
            return cache[style] ||
              (cache[style] = style.replace(/\S+/g, "cm-$&"));
          }
        
          // Render the DOM representation of the text of a line. Also builds
          // up a 'line map', which points at the DOM nodes that represent
          // specific stretches of text, and is used by the measuring code.
          // The returned object contains the DOM node, this map, and
          // information about line-wide styles that were set by the mode.
          function buildLineContent(cm, lineView) {
            // The padding-right forces the element to have a 'border', which
            // is needed on Webkit to be able to get line-level bounding
            // rectangles for it (in measureChar).
            var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
            var builder = {pre: elt("pre", [content]), content: content, col: 0, pos: 0, cm: cm};
            lineView.measure = {};
        
            // Iterate over the logical lines that make up this visual line.
            for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
              var line = i ? lineView.rest[i - 1] : lineView.line, order;
              builder.pos = 0;
              builder.addToken = buildToken;
              // Optionally wire in some hacks into the token-rendering
              // algorithm, to deal with browser quirks.
              if ((ie || webkit) && cm.getOption("lineWrapping"))
                builder.addToken = buildTokenSplitSpaces(builder.addToken);
              if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))
                builder.addToken = buildTokenBadBidi(builder.addToken, order);
              builder.map = [];
              var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
              insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
              if (line.styleClasses) {
                if (line.styleClasses.bgClass)
                  builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "");
                if (line.styleClasses.textClass)
                  builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "");
              }
        
              // Ensure at least a single node is present, for measuring.
              if (builder.map.length == 0)
                builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure)));
        
              // Store the map and a cache object for the current logical line
              if (i == 0) {
                lineView.measure.map = builder.map;
                lineView.measure.cache = {};
              } else {
                (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map);
                (lineView.measure.caches || (lineView.measure.caches = [])).push({});
              }
            }
        
            // See issue #2901
            if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className))
              builder.content.className = "cm-tab-wrap-hack";
        
            signal(cm, "renderLine", cm, lineView.line, builder.pre);
            if (builder.pre.className)
              builder.textClass = joinClasses(builder.pre.className, builder.textClass || "");
        
            return builder;
          }
        
          function defaultSpecialCharPlaceholder(ch) {
            var token = elt("span", "\u2022", "cm-invalidchar");
            token.title = "\\u" + ch.charCodeAt(0).toString(16);
            return token;
          }
        
          // Build up the DOM representation for a single token, and add it to
          // the line map. Takes care to render special characters separately.
          function buildToken(builder, text, style, startStyle, endStyle, title) {
            if (!text) return;
            var special = builder.cm.options.specialChars, mustWrap = false;
            if (!special.test(text)) {
              builder.col += text.length;
              var content = document.createTextNode(text);
              builder.map.push(builder.pos, builder.pos + text.length, content);
              if (ie && ie_version < 9) mustWrap = true;
              builder.pos += text.length;
            } else {
              var content = document.createDocumentFragment(), pos = 0;
              while (true) {
                special.lastIndex = pos;
                var m = special.exec(text);
                var skipped = m ? m.index - pos : text.length - pos;
                if (skipped) {
                  var txt = document.createTextNode(text.slice(pos, pos + skipped));
                  if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
                  else content.appendChild(txt);
                  builder.map.push(builder.pos, builder.pos + skipped, txt);
                  builder.col += skipped;
                  builder.pos += skipped;
                }
                if (!m) break;
                pos += skipped + 1;
                if (m[0] == "\t") {
                  var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
                  var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
                  builder.col += tabWidth;
                } else {
                  var txt = builder.cm.options.specialCharPlaceholder(m[0]);
                  if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
                  else content.appendChild(txt);
                  builder.col += 1;
                }
                builder.map.push(builder.pos, builder.pos + 1, txt);
                builder.pos++;
              }
            }
            if (style || startStyle || endStyle || mustWrap) {
              var fullStyle = style || "";
              if (startStyle) fullStyle += startStyle;
              if (endStyle) fullStyle += endStyle;
              var token = elt("span", [content], fullStyle);
              if (title) token.title = title;
              return builder.content.appendChild(token);
            }
            builder.content.appendChild(content);
          }
        
          function buildTokenSplitSpaces(inner) {
            function split(old) {
              var out = " ";
              for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
              out += " ";
              return out;
            }
            return function(builder, text, style, startStyle, endStyle, title) {
              inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title);
            };
          }
        
          // Work around nonsense dimensions being reported for stretches of
          // right-to-left text.
          function buildTokenBadBidi(inner, order) {
            return function(builder, text, style, startStyle, endStyle, title) {
              style = style ? style + " cm-force-border" : "cm-force-border";
              var start = builder.pos, end = start + text.length;
              for (;;) {
                // Find the part that overlaps with the start of this text
                for (var i = 0; i < order.length; i++) {
                  var part = order[i];
                  if (part.to > start && part.from <= start) break;
                }
                if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title);
                inner(builder, text.slice(0, part.to - start), style, startStyle, null, title);
                startStyle = null;
                text = text.slice(part.to - start);
                start = part.to;
              }
            };
          }
        
          function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
            var widget = !ignoreWidget && marker.widgetNode;
            if (widget) {
              builder.map.push(builder.pos, builder.pos + size, widget);
              builder.content.appendChild(widget);
            }
            builder.pos += size;
          }
        
          // Outputs a number of spans to make up a line, taking highlighting
          // and marked text into account.
          function insertLineContent(line, builder, styles) {
            var spans = line.markedSpans, allText = line.text, at = 0;
            if (!spans) {
              for (var i = 1; i < styles.length; i+=2)
                builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options));
              return;
            }
        
            var len = allText.length, pos = 0, i = 1, text = "", style;
            var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
            for (;;) {
              if (nextChange == pos) { // Update current marker set
                spanStyle = spanEndStyle = spanStartStyle = title = "";
                collapsed = null; nextChange = Infinity;
                var foundBookmarks = [];
                for (var j = 0; j < spans.length; ++j) {
                  var sp = spans[j], m = sp.marker;
                  if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
                    if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
                    if (m.className) spanStyle += " " + m.className;
                    if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
                    if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
                    if (m.title && !title) title = m.title;
                    if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
                      collapsed = sp;
                  } else if (sp.from > pos && nextChange > sp.from) {
                    nextChange = sp.from;
                  }
                  if (m.type == "bookmark" && sp.from == pos && m.widgetNode) foundBookmarks.push(m);
                }
                if (collapsed && (collapsed.from || 0) == pos) {
                  buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
                                     collapsed.marker, collapsed.from == null);
                  if (collapsed.to == null) return;
                }
                if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
                  buildCollapsedSpan(builder, 0, foundBookmarks[j]);
              }
              if (pos >= len) break;
        
              var upto = Math.min(len, nextChange);
              while (true) {
                if (text) {
                  var end = pos + text.length;
                  if (!collapsed) {
                    var tokenText = end > upto ? text.slice(0, upto - pos) : text;
                    builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
                                     spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
                  }
                  if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
                  pos = end;
                  spanStartStyle = "";
                }
                text = allText.slice(at, at = styles[i++]);
                style = interpretTokenStyle(styles[i++], builder.cm.options);
              }
            }
          }
        
          // DOCUMENT DATA STRUCTURE
        
          // By default, updates that start and end at the beginning of a line
          // are treated specially, in order to make the association of line
          // widgets and marker elements with the text behave more intuitive.
          function isWholeLineUpdate(doc, change) {
            return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
              (!doc.cm || doc.cm.options.wholeLineUpdateBefore);
          }
        
          // Perform a change on the document data structure.
          function updateDoc(doc, change, markedSpans, estimateHeight) {
            function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
            function update(line, text, spans) {
              updateLine(line, text, spans, estimateHeight);
              signalLater(line, "change", line, change);
            }
        
            var from = change.from, to = change.to, text = change.text;
            var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
            var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
        
            // Adjust the line structure
            if (isWholeLineUpdate(doc, change)) {
              // This is a whole-line replace. Treated specially to make
              // sure line objects move the way they are supposed to.
              for (var i = 0, added = []; i < text.length - 1; ++i)
                added.push(new Line(text[i], spansFor(i), estimateHeight));
              update(lastLine, lastLine.text, lastSpans);
              if (nlines) doc.remove(from.line, nlines);
              if (added.length) doc.insert(from.line, added);
            } else if (firstLine == lastLine) {
              if (text.length == 1) {
                update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
              } else {
                for (var added = [], i = 1; i < text.length - 1; ++i)
                  added.push(new Line(text[i], spansFor(i), estimateHeight));
                added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
                update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
                doc.insert(from.line + 1, added);
              }
            } else if (text.length == 1) {
              update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
              doc.remove(from.line + 1, nlines);
            } else {
              update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
              update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
              for (var i = 1, added = []; i < text.length - 1; ++i)
                added.push(new Line(text[i], spansFor(i), estimateHeight));
              if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
              doc.insert(from.line + 1, added);
            }
        
            signalLater(doc, "change", doc, change);
          }
        
          // The document is represented as a BTree consisting of leaves, with
          // chunk of lines in them, and branches, with up to ten leaves or
          // other branch nodes below them. The top node is always a branch
          // node, and is the document object itself (meaning it has
          // additional methods and properties).
          //
          // All nodes have parent links. The tree is used both to go from
          // line numbers to line objects, and to go from objects to numbers.
          // It also indexes by height, and is used to convert between height
          // and line object, and to find the total height of the document.
          //
          // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
        
          function LeafChunk(lines) {
            this.lines = lines;
            this.parent = null;
            for (var i = 0, height = 0; i < lines.length; ++i) {
              lines[i].parent = this;
              height += lines[i].height;
            }
            this.height = height;
          }
        
          LeafChunk.prototype = {
            chunkSize: function() { return this.lines.length; },
            // Remove the n lines at offset 'at'.
            removeInner: function(at, n) {
              for (var i = at, e = at + n; i < e; ++i) {
                var line = this.lines[i];
                this.height -= line.height;
                cleanUpLine(line);
                signalLater(line, "delete");
              }
              this.lines.splice(at, n);
            },
            // Helper used to collapse a small branch into a single leaf.
            collapse: function(lines) {
              lines.push.apply(lines, this.lines);
            },
            // Insert the given array of lines at offset 'at', count them as
            // having the given height.
            insertInner: function(at, lines, height) {
              this.height += height;
              this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
              for (var i = 0; i < lines.length; ++i) lines[i].parent = this;
            },
            // Used to iterate over a part of the tree.
            iterN: function(at, n, op) {
              for (var e = at + n; at < e; ++at)
                if (op(this.lines[at])) return true;
            }
          };
        
          function BranchChunk(children) {
            this.children = children;
            var size = 0, height = 0;
            for (var i = 0; i < children.length; ++i) {
              var ch = children[i];
              size += ch.chunkSize(); height += ch.height;
              ch.parent = this;
            }
            this.size = size;
            this.height = height;
            this.parent = null;
          }
        
          BranchChunk.prototype = {
            chunkSize: function() { return this.size; },
            removeInner: function(at, n) {
              this.size -= n;
              for (var i = 0; i < this.children.length; ++i) {
                var child = this.children[i], sz = child.chunkSize();
                if (at < sz) {
                  var rm = Math.min(n, sz - at), oldHeight = child.height;
                  child.removeInner(at, rm);
                  this.height -= oldHeight - child.height;
                  if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
                  if ((n -= rm) == 0) break;
                  at = 0;
                } else at -= sz;
              }
              // If the result is smaller than 25 lines, ensure that it is a
              // single leaf node.
              if (this.size - n < 25 &&
                  (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
                var lines = [];
                this.collapse(lines);
                this.children = [new LeafChunk(lines)];
                this.children[0].parent = this;
              }
            },
            collapse: function(lines) {
              for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines);
            },
            insertInner: function(at, lines, height) {
              this.size += lines.length;
              this.height += height;
              for (var i = 0; i < this.children.length; ++i) {
                var child = this.children[i], sz = child.chunkSize();
                if (at <= sz) {
                  child.insertInner(at, lines, height);
                  if (child.lines && child.lines.length > 50) {
                    while (child.lines.length > 50) {
                      var spilled = child.lines.splice(child.lines.length - 25, 25);
                      var newleaf = new LeafChunk(spilled);
                      child.height -= newleaf.height;
                      this.children.splice(i + 1, 0, newleaf);
                      newleaf.parent = this;
                    }
                    this.maybeSpill();
                  }
                  break;
                }
                at -= sz;
              }
            },
            // When a node has grown, check whether it should be split.
            maybeSpill: function() {
              if (this.children.length <= 10) return;
              var me = this;
              do {
                var spilled = me.children.splice(me.children.length - 5, 5);
                var sibling = new BranchChunk(spilled);
                if (!me.parent) { // Become the parent node
                  var copy = new BranchChunk(me.children);
                  copy.parent = me;
                  me.children = [copy, sibling];
                  me = copy;
                } else {
                  me.size -= sibling.size;
                  me.height -= sibling.height;
                  var myIndex = indexOf(me.parent.children, me);
                  me.parent.children.splice(myIndex + 1, 0, sibling);
                }
                sibling.parent = me.parent;
              } while (me.children.length > 10);
              me.parent.maybeSpill();
            },
            iterN: function(at, n, op) {
              for (var i = 0; i < this.children.length; ++i) {
                var child = this.children[i], sz = child.chunkSize();
                if (at < sz) {
                  var used = Math.min(n, sz - at);
                  if (child.iterN(at, used, op)) return true;
                  if ((n -= used) == 0) break;
                  at = 0;
                } else at -= sz;
              }
            }
          };
        
          var nextDocId = 0;
          var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
            if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
            if (firstLine == null) firstLine = 0;
        
            BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
            this.first = firstLine;
            this.scrollTop = this.scrollLeft = 0;
            this.cantEdit = false;
            this.cleanGeneration = 1;
            this.frontier = firstLine;
            var start = Pos(firstLine, 0);
            this.sel = simpleSelection(start);
            this.history = new History(null);
            this.id = ++nextDocId;
            this.modeOption = mode;
        
            if (typeof text == "string") text = splitLines(text);
            updateDoc(this, {from: start, to: start, text: text});
            setSelection(this, simpleSelection(start), sel_dontScroll);
          };
        
          Doc.prototype = createObj(BranchChunk.prototype, {
            constructor: Doc,
            // Iterate over the document. Supports two forms -- with only one
            // argument, it calls that for each line in the document. With
            // three, it iterates over the range given by the first two (with
            // the second being non-inclusive).
            iter: function(from, to, op) {
              if (op) this.iterN(from - this.first, to - from, op);
              else this.iterN(this.first, this.first + this.size, from);
            },
        
            // Non-public interface for adding and removing lines.
            insert: function(at, lines) {
              var height = 0;
              for (var i = 0; i < lines.length; ++i) height += lines[i].height;
              this.insertInner(at - this.first, lines, height);
            },
            remove: function(at, n) { this.removeInner(at - this.first, n); },
        
            // From here, the methods are part of the public interface. Most
            // are also available from CodeMirror (editor) instances.
        
            getValue: function(lineSep) {
              var lines = getLines(this, this.first, this.first + this.size);
              if (lineSep === false) return lines;
              return lines.join(lineSep || "\n");
            },
            setValue: docMethodOp(function(code) {
              var top = Pos(this.first, 0), last = this.first + this.size - 1;
              makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
                                text: splitLines(code), origin: "setValue"}, true);
              setSelection(this, simpleSelection(top));
            }),
            replaceRange: function(code, from, to, origin) {
              from = clipPos(this, from);
              to = to ? clipPos(this, to) : from;
              replaceRange(this, code, from, to, origin);
            },
            getRange: function(from, to, lineSep) {
              var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
              if (lineSep === false) return lines;
              return lines.join(lineSep || "\n");
            },
        
            getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
        
            getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
            getLineNumber: function(line) {return lineNo(line);},
        
            getLineHandleVisualStart: function(line) {
              if (typeof line == "number") line = getLine(this, line);
              return visualLine(line);
            },
        
            lineCount: function() {return this.size;},
            firstLine: function() {return this.first;},
            lastLine: function() {return this.first + this.size - 1;},
        
            clipPos: function(pos) {return clipPos(this, pos);},
        
            getCursor: function(start) {
              var range = this.sel.primary(), pos;
              if (start == null || start == "head") pos = range.head;
              else if (start == "anchor") pos = range.anchor;
              else if (start == "end" || start == "to" || start === false) pos = range.to();
              else pos = range.from();
              return pos;
            },
            listSelections: function() { return this.sel.ranges; },
            somethingSelected: function() {return this.sel.somethingSelected();},
        
            setCursor: docMethodOp(function(line, ch, options) {
              setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
            }),
            setSelection: docMethodOp(function(anchor, head, options) {
              setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
            }),
            extendSelection: docMethodOp(function(head, other, options) {
              extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
            }),
            extendSelections: docMethodOp(function(heads, options) {
              extendSelections(this, clipPosArray(this, heads, options));
            }),
            extendSelectionsBy: docMethodOp(function(f, options) {
              extendSelections(this, map(this.sel.ranges, f), options);
            }),
            setSelections: docMethodOp(function(ranges, primary, options) {
              if (!ranges.length) return;
              for (var i = 0, out = []; i < ranges.length; i++)
                out[i] = new Range(clipPos(this, ranges[i].anchor),
                                   clipPos(this, ranges[i].head));
              if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex);
              setSelection(this, normalizeSelection(out, primary), options);
            }),
            addSelection: docMethodOp(function(anchor, head, options) {
              var ranges = this.sel.ranges.slice(0);
              ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
              setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
            }),
        
            getSelection: function(lineSep) {
              var ranges = this.sel.ranges, lines;
              for (var i = 0; i < ranges.length; i++) {
                var sel = getBetween(this, ranges[i].from(), ranges[i].to());
                lines = lines ? lines.concat(sel) : sel;
              }
              if (lineSep === false) return lines;
              else return lines.join(lineSep || "\n");
            },
            getSelections: function(lineSep) {
              var parts = [], ranges = this.sel.ranges;
              for (var i = 0; i < ranges.length; i++) {
                var sel = getBetween(this, ranges[i].from(), ranges[i].to());
                if (lineSep !== false) sel = sel.join(lineSep || "\n");
                parts[i] = sel;
              }
              return parts;
            },
            replaceSelection: function(code, collapse, origin) {
              var dup = [];
              for (var i = 0; i < this.sel.ranges.length; i++)
                dup[i] = code;
              this.replaceSelections(dup, collapse, origin || "+input");
            },
            replaceSelections: docMethodOp(function(code, collapse, origin) {
              var changes = [], sel = this.sel;
              for (var i = 0; i < sel.ranges.length; i++) {
                var range = sel.ranges[i];
                changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};
              }
              var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
              for (var i = changes.length - 1; i >= 0; i--)
                makeChange(this, changes[i]);
              if (newSel) setSelectionReplaceHistory(this, newSel);
              else if (this.cm) ensureCursorVisible(this.cm);
            }),
            undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
            redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
            undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
            redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
        
            setExtending: function(val) {this.extend = val;},
            getExtending: function() {return this.extend;},
        
            historySize: function() {
              var hist = this.history, done = 0, undone = 0;
              for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done;
              for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone;
              return {undo: done, redo: undone};
            },
            clearHistory: function() {this.history = new History(this.history.maxGeneration);},
        
            markClean: function() {
              this.cleanGeneration = this.changeGeneration(true);
            },
            changeGeneration: function(forceSplit) {
              if (forceSplit)
                this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null;
              return this.history.generation;
            },
            isClean: function (gen) {
              return this.history.generation == (gen || this.cleanGeneration);
            },
        
            getHistory: function() {
              return {done: copyHistoryArray(this.history.done),
                      undone: copyHistoryArray(this.history.undone)};
            },
            setHistory: function(histData) {
              var hist = this.history = new History(this.history.maxGeneration);
              hist.done = copyHistoryArray(histData.done.slice(0), null, true);
              hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
            },
        
            addLineClass: docMethodOp(function(handle, where, cls) {
              return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) {
                var prop = where == "text" ? "textClass"
                         : where == "background" ? "bgClass"
                         : where == "gutter" ? "gutterClass" : "wrapClass";
                if (!line[prop]) line[prop] = cls;
                else if (classTest(cls).test(line[prop])) return false;
                else line[prop] += " " + cls;
                return true;
              });
            }),
            removeLineClass: docMethodOp(function(handle, where, cls) {
              return changeLine(this, handle, "class", function(line) {
                var prop = where == "text" ? "textClass"
                         : where == "background" ? "bgClass"
                         : where == "gutter" ? "gutterClass" : "wrapClass";
                var cur = line[prop];
                if (!cur) return false;
                else if (cls == null) line[prop] = null;
                else {
                  var found = cur.match(classTest(cls));
                  if (!found) return false;
                  var end = found.index + found[0].length;
                  line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
                }
                return true;
              });
            }),
        
            markText: function(from, to, options) {
              return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
            },
            setBookmark: function(pos, options) {
              var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
                              insertLeft: options && options.insertLeft,
                              clearWhenEmpty: false, shared: options && options.shared};
              pos = clipPos(this, pos);
              return markText(this, pos, pos, realOpts, "bookmark");
            },
            findMarksAt: function(pos) {
              pos = clipPos(this, pos);
              var markers = [], spans = getLine(this, pos.line).markedSpans;
              if (spans) for (var i = 0; i < spans.length; ++i) {
                var span = spans[i];
                if ((span.from == null || span.from <= pos.ch) &&
                    (span.to == null || span.to >= pos.ch))
                  markers.push(span.marker.parent || span.marker);
              }
              return markers;
            },
            findMarks: function(from, to, filter) {
              from = clipPos(this, from); to = clipPos(this, to);
              var found = [], lineNo = from.line;
              this.iter(from.line, to.line + 1, function(line) {
                var spans = line.markedSpans;
                if (spans) for (var i = 0; i < spans.length; i++) {
                  var span = spans[i];
                  if (!(lineNo == from.line && from.ch > span.to ||
                        span.from == null && lineNo != from.line||
                        lineNo == to.line && span.from > to.ch) &&
                      (!filter || filter(span.marker)))
                    found.push(span.marker.parent || span.marker);
                }
                ++lineNo;
              });
              return found;
            },
            getAllMarks: function() {
              var markers = [];
              this.iter(function(line) {
                var sps = line.markedSpans;
                if (sps) for (var i = 0; i < sps.length; ++i)
                  if (sps[i].from != null) markers.push(sps[i].marker);
              });
              return markers;
            },
        
            posFromIndex: function(off) {
              var ch, lineNo = this.first;
              this.iter(function(line) {
                var sz = line.text.length + 1;
                if (sz > off) { ch = off; return true; }
                off -= sz;
                ++lineNo;
              });
              return clipPos(this, Pos(lineNo, ch));
            },
            indexFromPos: function (coords) {
              coords = clipPos(this, coords);
              var index = coords.ch;
              if (coords.line < this.first || coords.ch < 0) return 0;
              this.iter(this.first, coords.line, function (line) {
                index += line.text.length + 1;
              });
              return index;
            },
        
            copy: function(copyHistory) {
              var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
              doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
              doc.sel = this.sel;
              doc.extend = false;
              if (copyHistory) {
                doc.history.undoDepth = this.history.undoDepth;
                doc.setHistory(this.getHistory());
              }
              return doc;
            },
        
            linkedDoc: function(options) {
              if (!options) options = {};
              var from = this.first, to = this.first + this.size;
              if (options.from != null && options.from > from) from = options.from;
              if (options.to != null && options.to < to) to = options.to;
              var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
              if (options.sharedHist) copy.history = this.history;
              (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
              copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
              copySharedMarkers(copy, findSharedMarkers(this));
              return copy;
            },
            unlinkDoc: function(other) {
              if (other instanceof CodeMirror) other = other.doc;
              if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
                var link = this.linked[i];
                if (link.doc != other) continue;
                this.linked.splice(i, 1);
                other.unlinkDoc(this);
                detachSharedMarkers(findSharedMarkers(this));
                break;
              }
              // If the histories were shared, split them again
              if (other.history == this.history) {
                var splitIds = [other.id];
                linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
                other.history = new History(null);
                other.history.done = copyHistoryArray(this.history.done, splitIds);
                other.history.undone = copyHistoryArray(this.history.undone, splitIds);
              }
            },
            iterLinkedDocs: function(f) {linkedDocs(this, f);},
        
            getMode: function() {return this.mode;},
            getEditor: function() {return this.cm;}
          });
        
          // Public alias.
          Doc.prototype.eachLine = Doc.prototype.iter;
        
          // Set up methods on CodeMirror's prototype to redirect to the editor's document.
          var dontDelegate = "iter insert remove copy getEditor".split(" ");
          for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
            CodeMirror.prototype[prop] = (function(method) {
              return function() {return method.apply(this.doc, arguments);};
            })(Doc.prototype[prop]);
        
          eventMixin(Doc);
        
          // Call f for all linked documents.
          function linkedDocs(doc, f, sharedHistOnly) {
            function propagate(doc, skip, sharedHist) {
              if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
                var rel = doc.linked[i];
                if (rel.doc == skip) continue;
                var shared = sharedHist && rel.sharedHist;
                if (sharedHistOnly && !shared) continue;
                f(rel.doc, shared);
                propagate(rel.doc, doc, shared);
              }
            }
            propagate(doc, null, true);
          }
        
          // Attach a document to an editor.
          function attachDoc(cm, doc) {
            if (doc.cm) throw new Error("This document is already in use.");
            cm.doc = doc;
            doc.cm = cm;
            estimateLineHeights(cm);
            loadMode(cm);
            if (!cm.options.lineWrapping) findMaxLine(cm);
            cm.options.mode = doc.modeOption;
            regChange(cm);
          }
        
          // LINE UTILITIES
        
          // Find the line object corresponding to the given line number.
          function getLine(doc, n) {
            n -= doc.first;
            if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document.");
            for (var chunk = doc; !chunk.lines;) {
              for (var i = 0;; ++i) {
                var child = chunk.children[i], sz = child.chunkSize();
                if (n < sz) { chunk = child; break; }
                n -= sz;
              }
            }
            return chunk.lines[n];
          }
        
          // Get the part of a document between two positions, as an array of
          // strings.
          function getBetween(doc, start, end) {
            var out = [], n = start.line;
            doc.iter(start.line, end.line + 1, function(line) {
              var text = line.text;
              if (n == end.line) text = text.slice(0, end.ch);
              if (n == start.line) text = text.slice(start.ch);
              out.push(text);
              ++n;
            });
            return out;
          }
          // Get the lines between from and to, as array of strings.
          function getLines(doc, from, to) {
            var out = [];
            doc.iter(from, to, function(line) { out.push(line.text); });
            return out;
          }
        
          // Update the height of a line, propagating the height change
          // upwards to parent nodes.
          function updateLineHeight(line, height) {
            var diff = height - line.height;
            if (diff) for (var n = line; n; n = n.parent) n.height += diff;
          }
        
          // Given a line object, find its line number by walking up through
          // its parent links.
          function lineNo(line) {
            if (line.parent == null) return null;
            var cur = line.parent, no = indexOf(cur.lines, line);
            for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
              for (var i = 0;; ++i) {
                if (chunk.children[i] == cur) break;
                no += chunk.children[i].chunkSize();
              }
            }
            return no + cur.first;
          }
        
          // Find the line at the given vertical position, using the height
          // information in the document tree.
          function lineAtHeight(chunk, h) {
            var n = chunk.first;
            outer: do {
              for (var i = 0; i < chunk.children.length; ++i) {
                var child = chunk.children[i], ch = child.height;
                if (h < ch) { chunk = child; continue outer; }
                h -= ch;
                n += child.chunkSize();
              }
              return n;
            } while (!chunk.lines);
            for (var i = 0; i < chunk.lines.length; ++i) {
              var line = chunk.lines[i], lh = line.height;
              if (h < lh) break;
              h -= lh;
            }
            return n + i;
          }
        
        
          // Find the height above the given line.
          function heightAtLine(lineObj) {
            lineObj = visualLine(lineObj);
        
            var h = 0, chunk = lineObj.parent;
            for (var i = 0; i < chunk.lines.length; ++i) {
              var line = chunk.lines[i];
              if (line == lineObj) break;
              else h += line.height;
            }
            for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
              for (var i = 0; i < p.children.length; ++i) {
                var cur = p.children[i];
                if (cur == chunk) break;
                else h += cur.height;
              }
            }
            return h;
          }
        
          // Get the bidi ordering for the given line (and cache it). Returns
          // false for lines that are fully left-to-right, and an array of
          // BidiSpan objects otherwise.
          function getOrder(line) {
            var order = line.order;
            if (order == null) order = line.order = bidiOrdering(line.text);
            return order;
          }
        
          // HISTORY
        
          function History(startGen) {
            // Arrays of change events and selections. Doing something adds an
            // event to done and clears undo. Undoing moves events from done
            // to undone, redoing moves them in the other direction.
            this.done = []; this.undone = [];
            this.undoDepth = Infinity;
            // Used to track when changes can be merged into a single undo
            // event
            this.lastModTime = this.lastSelTime = 0;
            this.lastOp = this.lastSelOp = null;
            this.lastOrigin = this.lastSelOrigin = null;
            // Used by the isClean() method
            this.generation = this.maxGeneration = startGen || 1;
          }
        
          // Create a history change event from an updateDoc-style change
          // object.
          function historyChangeFromChange(doc, change) {
            var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
            attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
            linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
            return histChange;
          }
        
          // Pop all selection events off the end of a history array. Stop at
          // a change event.
          function clearSelectionEvents(array) {
            while (array.length) {
              var last = lst(array);
              if (last.ranges) array.pop();
              else break;
            }
          }
        
          // Find the top change event in the history. Pop off selection
          // events that are in the way.
          function lastChangeEvent(hist, force) {
            if (force) {
              clearSelectionEvents(hist.done);
              return lst(hist.done);
            } else if (hist.done.length && !lst(hist.done).ranges) {
              return lst(hist.done);
            } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
              hist.done.pop();
              return lst(hist.done);
            }
          }
        
          // Register a change in the history. Merges changes that are within
          // a single operation, ore are close together with an origin that
          // allows merging (starting with "+") into a single event.
          function addChangeToHistory(doc, change, selAfter, opId) {
            var hist = doc.history;
            hist.undone.length = 0;
            var time = +new Date, cur;
        
            if ((hist.lastOp == opId ||
                 hist.lastOrigin == change.origin && change.origin &&
                 ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
                  change.origin.charAt(0) == "*")) &&
                (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
              // Merge this change into the last event
              var last = lst(cur.changes);
              if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
                // Optimized case for simple insertion -- don't want to add
                // new changesets for every character typed
                last.to = changeEnd(change);
              } else {
                // Add new sub-event
                cur.changes.push(historyChangeFromChange(doc, change));
              }
            } else {
              // Can not be merged, start a new event.
              var before = lst(hist.done);
              if (!before || !before.ranges)
                pushSelectionToHistory(doc.sel, hist.done);
              cur = {changes: [historyChangeFromChange(doc, change)],
                     generation: hist.generation};
              hist.done.push(cur);
              while (hist.done.length > hist.undoDepth) {
                hist.done.shift();
                if (!hist.done[0].ranges) hist.done.shift();
              }
            }
            hist.done.push(selAfter);
            hist.generation = ++hist.maxGeneration;
            hist.lastModTime = hist.lastSelTime = time;
            hist.lastOp = hist.lastSelOp = opId;
            hist.lastOrigin = hist.lastSelOrigin = change.origin;
        
            if (!last) signal(doc, "historyAdded");
          }
        
          function selectionEventCanBeMerged(doc, origin, prev, sel) {
            var ch = origin.charAt(0);
            return ch == "*" ||
              ch == "+" &&
              prev.ranges.length == sel.ranges.length &&
              prev.somethingSelected() == sel.somethingSelected() &&
              new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500);
          }
        
          // Called whenever the selection changes, sets the new selection as
          // the pending selection in the history, and pushes the old pending
          // selection into the 'done' array when it was significantly
          // different (in number of selected ranges, emptiness, or time).
          function addSelectionToHistory(doc, sel, opId, options) {
            var hist = doc.history, origin = options && options.origin;
        
            // A new event is started when the previous origin does not match
            // the current, or the origins don't allow matching. Origins
            // starting with * are always merged, those starting with + are
            // merged when similar and close together in time.
            if (opId == hist.lastSelOp ||
                (origin && hist.lastSelOrigin == origin &&
                 (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
                  selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
              hist.done[hist.done.length - 1] = sel;
            else
              pushSelectionToHistory(sel, hist.done);
        
            hist.lastSelTime = +new Date;
            hist.lastSelOrigin = origin;
            hist.lastSelOp = opId;
            if (options && options.clearRedo !== false)
              clearSelectionEvents(hist.undone);
          }
        
          function pushSelectionToHistory(sel, dest) {
            var top = lst(dest);
            if (!(top && top.ranges && top.equals(sel)))
              dest.push(sel);
          }
        
          // Used to store marked span information in the history.
          function attachLocalSpans(doc, change, from, to) {
            var existing = change["spans_" + doc.id], n = 0;
            doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
              if (line.markedSpans)
                (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
              ++n;
            });
          }
        
          // When un/re-doing restores text containing marked spans, those
          // that have been explicitly cleared should not be restored.
          function removeClearedSpans(spans) {
            if (!spans) return null;
            for (var i = 0, out; i < spans.length; ++i) {
              if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
              else if (out) out.push(spans[i]);
            }
            return !out ? spans : out.length ? out : null;
          }
        
          // Retrieve and filter the old marked spans stored in a change event.
          function getOldSpans(doc, change) {
            var found = change["spans_" + doc.id];
            if (!found) return null;
            for (var i = 0, nw = []; i < change.text.length; ++i)
              nw.push(removeClearedSpans(found[i]));
            return nw;
          }
        
          // Used both to provide a JSON-safe object in .getHistory, and, when
          // detaching a document, to split the history in two
          function copyHistoryArray(events, newGroup, instantiateSel) {
            for (var i = 0, copy = []; i < events.length; ++i) {
              var event = events[i];
              if (event.ranges) {
                copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
                continue;
              }
              var changes = event.changes, newChanges = [];
              copy.push({changes: newChanges});
              for (var j = 0; j < changes.length; ++j) {
                var change = changes[j], m;
                newChanges.push({from: change.from, to: change.to, text: change.text});
                if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
                  if (indexOf(newGroup, Number(m[1])) > -1) {
                    lst(newChanges)[prop] = change[prop];
                    delete change[prop];
                  }
                }
              }
            }
            return copy;
          }
        
          // Rebasing/resetting history to deal with externally-sourced changes
        
          function rebaseHistSelSingle(pos, from, to, diff) {
            if (to < pos.line) {
              pos.line += diff;
            } else if (from < pos.line) {
              pos.line = from;
              pos.ch = 0;
            }
          }
        
          // Tries to rebase an array of history events given a change in the
          // document. If the change touches the same lines as the event, the
          // event, and everything 'behind' it, is discarded. If the change is
          // before the event, the event's positions are updated. Uses a
          // copy-on-write scheme for the positions, to avoid having to
          // reallocate them all on every rebase, but also avoid problems with
          // shared position objects being unsafely updated.
          function rebaseHistArray(array, from, to, diff) {
            for (var i = 0; i < array.length; ++i) {
              var sub = array[i], ok = true;
              if (sub.ranges) {
                if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
                for (var j = 0; j < sub.ranges.length; j++) {
                  rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
                  rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
                }
                continue;
              }
              for (var j = 0; j < sub.changes.length; ++j) {
                var cur = sub.changes[j];
                if (to < cur.from.line) {
                  cur.from = Pos(cur.from.line + diff, cur.from.ch);
                  cur.to = Pos(cur.to.line + diff, cur.to.ch);
                } else if (from <= cur.to.line) {
                  ok = false;
                  break;
                }
              }
              if (!ok) {
                array.splice(0, i + 1);
                i = 0;
              }
            }
          }
        
          function rebaseHist(hist, change) {
            var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
            rebaseHistArray(hist.done, from, to, diff);
            rebaseHistArray(hist.undone, from, to, diff);
          }
        
          // EVENT UTILITIES
        
          // Due to the fact that we still support jurassic IE versions, some
          // compatibility wrappers are needed.
        
          var e_preventDefault = CodeMirror.e_preventDefault = function(e) {
            if (e.preventDefault) e.preventDefault();
            else e.returnValue = false;
          };
          var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) {
            if (e.stopPropagation) e.stopPropagation();
            else e.cancelBubble = true;
          };
          function e_defaultPrevented(e) {
            return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
          }
          var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);};
        
          function e_target(e) {return e.target || e.srcElement;}
          function e_button(e) {
            var b = e.which;
            if (b == null) {
              if (e.button & 1) b = 1;
              else if (e.button & 2) b = 3;
              else if (e.button & 4) b = 2;
            }
            if (mac && e.ctrlKey && b == 1) b = 3;
            return b;
          }
        
          // EVENT HANDLING
        
          // Lightweight event framework. on/off also work on DOM nodes,
          // registering native DOM handlers.
        
          var on = CodeMirror.on = function(emitter, type, f) {
            if (emitter.addEventListener)
              emitter.addEventListener(type, f, false);
            else if (emitter.attachEvent)
              emitter.attachEvent("on" + type, f);
            else {
              var map = emitter._handlers || (emitter._handlers = {});
              var arr = map[type] || (map[type] = []);
              arr.push(f);
            }
          };
        
          var off = CodeMirror.off = function(emitter, type, f) {
            if (emitter.removeEventListener)
              emitter.removeEventListener(type, f, false);
            else if (emitter.detachEvent)
              emitter.detachEvent("on" + type, f);
            else {
              var arr = emitter._handlers && emitter._handlers[type];
              if (!arr) return;
              for (var i = 0; i < arr.length; ++i)
                if (arr[i] == f) { arr.splice(i, 1); break; }
            }
          };
        
          var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
            var arr = emitter._handlers && emitter._handlers[type];
            if (!arr) return;
            var args = Array.prototype.slice.call(arguments, 2);
            for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
          };
        
          var orphanDelayedCallbacks = null;
        
          // Often, we want to signal events at a point where we are in the
          // middle of some work, but don't want the handler to start calling
          // other methods on the editor, which might be in an inconsistent
          // state or simply not expect any other events to happen.
          // signalLater looks whether there are any handlers, and schedules
          // them to be executed when the last operation ends, or, if no
          // operation is active, when a timeout fires.
          function signalLater(emitter, type /*, values...*/) {
            var arr = emitter._handlers && emitter._handlers[type];
            if (!arr) return;
            var args = Array.prototype.slice.call(arguments, 2), list;
            if (operationGroup) {
              list = operationGroup.delayedCallbacks;
            } else if (orphanDelayedCallbacks) {
              list = orphanDelayedCallbacks;
            } else {
              list = orphanDelayedCallbacks = [];
              setTimeout(fireOrphanDelayed, 0);
            }
            function bnd(f) {return function(){f.apply(null, args);};};
            for (var i = 0; i < arr.length; ++i)
              list.push(bnd(arr[i]));
          }
        
          function fireOrphanDelayed() {
            var delayed = orphanDelayedCallbacks;
            orphanDelayedCallbacks = null;
            for (var i = 0; i < delayed.length; ++i) delayed[i]();
          }
        
          // The DOM events that CodeMirror handles can be overridden by
          // registering a (non-DOM) handler on the editor for the event name,
          // and preventDefault-ing the event in that handler.
          function signalDOMEvent(cm, e, override) {
            if (typeof e == "string")
              e = {type: e, preventDefault: function() { this.defaultPrevented = true; }};
            signal(cm, override || e.type, cm, e);
            return e_defaultPrevented(e) || e.codemirrorIgnore;
          }
        
          function signalCursorActivity(cm) {
            var arr = cm._handlers && cm._handlers.cursorActivity;
            if (!arr) return;
            var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
            for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1)
              set.push(arr[i]);
          }
        
          function hasHandler(emitter, type) {
            var arr = emitter._handlers && emitter._handlers[type];
            return arr && arr.length > 0;
          }
        
          // Add on and off methods to a constructor's prototype, to make
          // registering events on such objects more convenient.
          function eventMixin(ctor) {
            ctor.prototype.on = function(type, f) {on(this, type, f);};
            ctor.prototype.off = function(type, f) {off(this, type, f);};
          }
        
          // MISC UTILITIES
        
          // Number of pixels added to scroller and sizer to hide scrollbar
          var scrollerCutOff = 30;
        
          // Returned or thrown by various protocols to signal 'I'm not
          // handling this'.
          var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
        
          // Reused option objects for setSelection & friends
          var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
        
          function Delayed() {this.id = null;}
          Delayed.prototype.set = function(ms, f) {
            clearTimeout(this.id);
            this.id = setTimeout(f, ms);
          };
        
          // Counts the column offset in a string, taking tabs into account.
          // Used mostly to find indentation.
          var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) {
            if (end == null) {
              end = string.search(/[^\s\u00a0]/);
              if (end == -1) end = string.length;
            }
            for (var i = startIndex || 0, n = startValue || 0;;) {
              var nextTab = string.indexOf("\t", i);
              if (nextTab < 0 || nextTab >= end)
                return n + (end - i);
              n += nextTab - i;
              n += tabSize - (n % tabSize);
              i = nextTab + 1;
            }
          };
        
          // The inverse of countColumn -- find the offset that corresponds to
          // a particular column.
          function findColumn(string, goal, tabSize) {
            for (var pos = 0, col = 0;;) {
              var nextTab = string.indexOf("\t", pos);
              if (nextTab == -1) nextTab = string.length;
              var skipped = nextTab - pos;
              if (nextTab == string.length || col + skipped >= goal)
                return pos + Math.min(skipped, goal - col);
              col += nextTab - pos;
              col += tabSize - (col % tabSize);
              pos = nextTab + 1;
              if (col >= goal) return pos;
            }
          }
        
          var spaceStrs = [""];
          function spaceStr(n) {
            while (spaceStrs.length <= n)
              spaceStrs.push(lst(spaceStrs) + " ");
            return spaceStrs[n];
          }
        
          function lst(arr) { return arr[arr.length-1]; }
        
          var selectInput = function(node) { node.select(); };
          if (ios) // Mobile Safari apparently has a bug where select() is broken.
            selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; };
          else if (ie) // Suppress mysterious IE10 errors
            selectInput = function(node) { try { node.select(); } catch(_e) {} };
        
          function indexOf(array, elt) {
            for (var i = 0; i < array.length; ++i)
              if (array[i] == elt) return i;
            return -1;
          }
          if ([].indexOf) indexOf = function(array, elt) { return array.indexOf(elt); };
          function map(array, f) {
            var out = [];
            for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);
            return out;
          }
          if ([].map) map = function(array, f) { return array.map(f); };
        
          function createObj(base, props) {
            var inst;
            if (Object.create) {
              inst = Object.create(base);
            } else {
              var ctor = function() {};
              ctor.prototype = base;
              inst = new ctor();
            }
            if (props) copyObj(props, inst);
            return inst;
          };
        
          function copyObj(obj, target, overwrite) {
            if (!target) target = {};
            for (var prop in obj)
              if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
                target[prop] = obj[prop];
            return target;
          }
        
          function bind(f) {
            var args = Array.prototype.slice.call(arguments, 1);
            return function(){return f.apply(null, args);};
          }
        
          var nonASCIISingleCaseWordChar = /[\u00df\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
          var isWordCharBasic = CodeMirror.isWordChar = function(ch) {
            return /\w/.test(ch) || ch > "\x80" &&
              (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
          };
          function isWordChar(ch, helper) {
            if (!helper) return isWordCharBasic(ch);
            if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true;
            return helper.test(ch);
          }
        
          function isEmpty(obj) {
            for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
            return true;
          }
        
          // Extending unicode characters. A series of a non-extending char +
          // any number of extending chars is treated as a single unit as far
          // as editing and measuring is concerned. This is not fully correct,
          // since some scripts/fonts/browsers also treat other configurations
          // of code points as a group.
          var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
          function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }
        
          // DOM UTILITIES
        
          function elt(tag, content, className, style) {
            var e = document.createElement(tag);
            if (className) e.className = className;
            if (style) e.style.cssText = style;
            if (typeof content == "string") e.appendChild(document.createTextNode(content));
            else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
            return e;
          }
        
          var range;
          if (document.createRange) range = function(node, start, end) {
            var r = document.createRange();
            r.setEnd(node, end);
            r.setStart(node, start);
            return r;
          };
          else range = function(node, start, end) {
            var r = document.body.createTextRange();
            try { r.moveToElementText(node.parentNode); }
            catch(e) { return r; }
            r.collapse(true);
            r.moveEnd("character", end);
            r.moveStart("character", start);
            return r;
          };
        
          function removeChildren(e) {
            for (var count = e.childNodes.length; count > 0; --count)
              e.removeChild(e.firstChild);
            return e;
          }
        
          function removeChildrenAndAdd(parent, e) {
            return removeChildren(parent).appendChild(e);
          }
        
          function contains(parent, child) {
            if (parent.contains)
              return parent.contains(child);
            while (child = child.parentNode)
              if (child == parent) return true;
          }
        
          function activeElt() { return document.activeElement; }
          // Older versions of IE throws unspecified error when touching
          // document.activeElement in some cases (during loading, in iframe)
          if (ie && ie_version < 11) activeElt = function() {
            try { return document.activeElement; }
            catch(e) { return document.body; }
          };
        
          function classTest(cls) { return new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)\\s*"); }
          var rmClass = CodeMirror.rmClass = function(node, cls) {
            var test = classTest(cls);
            if (test.test(node.className)) node.className = node.className.replace(test, "");
          };
          var addClass = CodeMirror.addClass = function(node, cls) {
            if (!classTest(cls).test(node.className)) node.className += " " + cls;
          };
          function joinClasses(a, b) {
            var as = a.split(" ");
            for (var i = 0; i < as.length; i++)
              if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i];
            return b;
          }
        
          // WINDOW-WIDE EVENTS
        
          // These must be handled carefully, because naively registering a
          // handler for each editor will cause the editors to never be
          // garbage collected.
        
          function forEachCodeMirror(f) {
            if (!document.body.getElementsByClassName) return;
            var byClass = document.body.getElementsByClassName("CodeMirror");
            for (var i = 0; i < byClass.length; i++) {
              var cm = byClass[i].CodeMirror;
              if (cm) f(cm);
            }
          }
        
          var globalsRegistered = false;
          function ensureGlobalHandlers() {
            if (globalsRegistered) return;
            registerGlobalHandlers();
            globalsRegistered = true;
          }
          function registerGlobalHandlers() {
            // When the window resizes, we need to refresh active editors.
            var resizeTimer;
            on(window, "resize", function() {
              if (resizeTimer == null) resizeTimer = setTimeout(function() {
                resizeTimer = null;
                knownScrollbarWidth = null;
                forEachCodeMirror(onResize);
              }, 100);
            });
            // When the window loses focus, we want to show the editor as blurred
            on(window, "blur", function() {
              forEachCodeMirror(onBlur);
            });
          }
        
          // FEATURE DETECTION
        
          // Detect drag-and-drop
          var dragAndDrop = function() {
            // There is *some* kind of drag-and-drop support in IE6-8, but I
            // couldn't get it to work yet.
            if (ie && ie_version < 9) return false;
            var div = elt('div');
            return "draggable" in div || "dragDrop" in div;
          }();
        
          var knownScrollbarWidth;
          function scrollbarWidth(measure) {
            if (knownScrollbarWidth != null) return knownScrollbarWidth;
            var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
            removeChildrenAndAdd(measure, test);
            if (test.offsetWidth)
              knownScrollbarWidth = test.offsetHeight - test.clientHeight;
            return knownScrollbarWidth || 0;
          }
        
          var zwspSupported;
          function zeroWidthElement(measure) {
            if (zwspSupported == null) {
              var test = elt("span", "\u200b");
              removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
              if (measure.firstChild.offsetHeight != 0)
                zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8);
            }
            if (zwspSupported) return elt("span", "\u200b");
            else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
          }
        
          // Feature-detect IE's crummy client rect reporting for bidi text
          var badBidiRects;
          function hasBadBidiRects(measure) {
            if (badBidiRects != null) return badBidiRects;
            var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
            var r0 = range(txt, 0, 1).getBoundingClientRect();
            if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780)
            var r1 = range(txt, 1, 2).getBoundingClientRect();
            return badBidiRects = (r1.right - r0.right < 3);
          }
        
          // See if "".split is the broken IE version, if so, provide an
          // alternative way to split lines.
          var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
            var pos = 0, result = [], l = string.length;
            while (pos <= l) {
              var nl = string.indexOf("\n", pos);
              if (nl == -1) nl = string.length;
              var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
              var rt = line.indexOf("\r");
              if (rt != -1) {
                result.push(line.slice(0, rt));
                pos += rt + 1;
              } else {
                result.push(line);
                pos = nl + 1;
              }
            }
            return result;
          } : function(string){return string.split(/\r\n?|\n/);};
        
          var hasSelection = window.getSelection ? function(te) {
            try { return te.selectionStart != te.selectionEnd; }
            catch(e) { return false; }
          } : function(te) {
            try {var range = te.ownerDocument.selection.createRange();}
            catch(e) {}
            if (!range || range.parentElement() != te) return false;
            return range.compareEndPoints("StartToEnd", range) != 0;
          };
        
          var hasCopyEvent = (function() {
            var e = elt("div");
            if ("oncopy" in e) return true;
            e.setAttribute("oncopy", "return;");
            return typeof e.oncopy == "function";
          })();
        
          var badZoomedRects = null;
          function hasBadZoomedRects(measure) {
            if (badZoomedRects != null) return badZoomedRects;
            var node = removeChildrenAndAdd(measure, elt("span", "x"));
            var normal = node.getBoundingClientRect();
            var fromRange = range(node, 0, 1).getBoundingClientRect();
            return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1;
          }
        
          // KEY NAMES
        
          var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
                          19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
                          36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
                          46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete",
                          173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
                          221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
                          63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"};
          CodeMirror.keyNames = keyNames;
          (function() {
            // Number keys
            for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
            // Alphabetic keys
            for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
            // Function keys
            for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
          })();
        
          // BIDI HELPERS
        
          function iterateBidiSections(order, from, to, f) {
            if (!order) return f(from, to, "ltr");
            var found = false;
            for (var i = 0; i < order.length; ++i) {
              var part = order[i];
              if (part.from < to && part.to > from || from == to && part.to == from) {
                f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
                found = true;
              }
            }
            if (!found) f(from, to, "ltr");
          }
        
          function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
          function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
        
          function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
          function lineRight(line) {
            var order = getOrder(line);
            if (!order) return line.text.length;
            return bidiRight(lst(order));
          }
        
          function lineStart(cm, lineN) {
            var line = getLine(cm.doc, lineN);
            var visual = visualLine(line);
            if (visual != line) lineN = lineNo(visual);
            var order = getOrder(visual);
            var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
            return Pos(lineN, ch);
          }
          function lineEnd(cm, lineN) {
            var merged, line = getLine(cm.doc, lineN);
            while (merged = collapsedSpanAtEnd(line)) {
              line = merged.find(1, true).line;
              lineN = null;
            }
            var order = getOrder(line);
            var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
            return Pos(lineN == null ? lineNo(line) : lineN, ch);
          }
          function lineStartSmart(cm, pos) {
            var start = lineStart(cm, pos.line);
            var line = getLine(cm.doc, start.line);
            var order = getOrder(line);
            if (!order || order[0].level == 0) {
              var firstNonWS = Math.max(0, line.text.search(/\S/));
              var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
              return Pos(start.line, inWS ? 0 : firstNonWS);
            }
            return start;
          }
        
          function compareBidiLevel(order, a, b) {
            var linedir = order[0].level;
            if (a == linedir) return true;
            if (b == linedir) return false;
            return a < b;
          }
          var bidiOther;
          function getBidiPartAt(order, pos) {
            bidiOther = null;
            for (var i = 0, found; i < order.length; ++i) {
              var cur = order[i];
              if (cur.from < pos && cur.to > pos) return i;
              if ((cur.from == pos || cur.to == pos)) {
                if (found == null) {
                  found = i;
                } else if (compareBidiLevel(order, cur.level, order[found].level)) {
                  if (cur.from != cur.to) bidiOther = found;
                  return i;
                } else {
                  if (cur.from != cur.to) bidiOther = i;
                  return found;
                }
              }
            }
            return found;
          }
        
          function moveInLine(line, pos, dir, byUnit) {
            if (!byUnit) return pos + dir;
            do pos += dir;
            while (pos > 0 && isExtendingChar(line.text.charAt(pos)));
            return pos;
          }
        
          // This is needed in order to move 'visually' through bi-directional
          // text -- i.e., pressing left should make the cursor go left, even
          // when in RTL text. The tricky part is the 'jumps', where RTL and
          // LTR text touch each other. This often requires the cursor offset
          // to move more than one unit, in order to visually move one unit.
          function moveVisually(line, start, dir, byUnit) {
            var bidi = getOrder(line);
            if (!bidi) return moveLogically(line, start, dir, byUnit);
            var pos = getBidiPartAt(bidi, start), part = bidi[pos];
            var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
        
            for (;;) {
              if (target > part.from && target < part.to) return target;
              if (target == part.from || target == part.to) {
                if (getBidiPartAt(bidi, target) == pos) return target;
                part = bidi[pos += dir];
                return (dir > 0) == part.level % 2 ? part.to : part.from;
              } else {
                part = bidi[pos += dir];
                if (!part) return null;
                if ((dir > 0) == part.level % 2)
                  target = moveInLine(line, part.to, -1, byUnit);
                else
                  target = moveInLine(line, part.from, 1, byUnit);
              }
            }
          }
        
          function moveLogically(line, start, dir, byUnit) {
            var target = start + dir;
            if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;
            return target < 0 || target > line.text.length ? null : target;
          }
        
          // Bidirectional ordering algorithm
          // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
          // that this (partially) implements.
        
          // One-char codes used for character types:
          // L (L):   Left-to-Right
          // R (R):   Right-to-Left
          // r (AL):  Right-to-Left Arabic
          // 1 (EN):  European Number
          // + (ES):  European Number Separator
          // % (ET):  European Number Terminator
          // n (AN):  Arabic Number
          // , (CS):  Common Number Separator
          // m (NSM): Non-Spacing Mark
          // b (BN):  Boundary Neutral
          // s (B):   Paragraph Separator
          // t (S):   Segment Separator
          // w (WS):  Whitespace
          // N (ON):  Other Neutrals
        
          // Returns null if characters are ordered as they appear
          // (left-to-right), or an array of sections ({from, to, level}
          // objects) in the order in which they occur visually.
          var bidiOrdering = (function() {
            // Character types for codepoints 0 to 0xff
            var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
            // Character types for codepoints 0x600 to 0x6ff
            var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm";
            function charType(code) {
              if (code <= 0xf7) return lowTypes.charAt(code);
              else if (0x590 <= code && code <= 0x5f4) return "R";
              else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600);
              else if (0x6ee <= code && code <= 0x8ac) return "r";
              else if (0x2000 <= code && code <= 0x200b) return "w";
              else if (code == 0x200c) return "b";
              else return "L";
            }
        
            var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
            var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
            // Browsers seem to always treat the boundaries of block elements as being L.
            var outerType = "L";
        
            function BidiSpan(level, from, to) {
              this.level = level;
              this.from = from; this.to = to;
            }
        
            return function(str) {
              if (!bidiRE.test(str)) return false;
              var len = str.length, types = [];
              for (var i = 0, type; i < len; ++i)
                types.push(type = charType(str.charCodeAt(i)));
        
              // W1. Examine each non-spacing mark (NSM) in the level run, and
              // change the type of the NSM to the type of the previous
              // character. If the NSM is at the start of the level run, it will
              // get the type of sor.
              for (var i = 0, prev = outerType; i < len; ++i) {
                var type = types[i];
                if (type == "m") types[i] = prev;
                else prev = type;
              }
        
              // W2. Search backwards from each instance of a European number
              // until the first strong type (R, L, AL, or sor) is found. If an
              // AL is found, change the type of the European number to Arabic
              // number.
              // W3. Change all ALs to R.
              for (var i = 0, cur = outerType; i < len; ++i) {
                var type = types[i];
                if (type == "1" && cur == "r") types[i] = "n";
                else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
              }
        
              // W4. A single European separator between two European numbers
              // changes to a European number. A single common separator between
              // two numbers of the same type changes to that type.
              for (var i = 1, prev = types[0]; i < len - 1; ++i) {
                var type = types[i];
                if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
                else if (type == "," && prev == types[i+1] &&
                         (prev == "1" || prev == "n")) types[i] = prev;
                prev = type;
              }
        
              // W5. A sequence of European terminators adjacent to European
              // numbers changes to all European numbers.
              // W6. Otherwise, separators and terminators change to Other
              // Neutral.
              for (var i = 0; i < len; ++i) {
                var type = types[i];
                if (type == ",") types[i] = "N";
                else if (type == "%") {
                  for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
                  var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
                  for (var j = i; j < end; ++j) types[j] = replace;
                  i = end - 1;
                }
              }
        
              // W7. Search backwards from each instance of a European number
              // until the first strong type (R, L, or sor) is found. If an L is
              // found, then change the type of the European number to L.
              for (var i = 0, cur = outerType; i < len; ++i) {
                var type = types[i];
                if (cur == "L" && type == "1") types[i] = "L";
                else if (isStrong.test(type)) cur = type;
              }
        
              // N1. A sequence of neutrals takes the direction of the
              // surrounding strong text if the text on both sides has the same
              // direction. European and Arabic numbers act as if they were R in
              // terms of their influence on neutrals. Start-of-level-run (sor)
              // and end-of-level-run (eor) are used at level run boundaries.
              // N2. Any remaining neutrals take the embedding direction.
              for (var i = 0; i < len; ++i) {
                if (isNeutral.test(types[i])) {
                  for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
                  var before = (i ? types[i-1] : outerType) == "L";
                  var after = (end < len ? types[end] : outerType) == "L";
                  var replace = before || after ? "L" : "R";
                  for (var j = i; j < end; ++j) types[j] = replace;
                  i = end - 1;
                }
              }
        
              // Here we depart from the documented algorithm, in order to avoid
              // building up an actual levels array. Since there are only three
              // levels (0, 1, 2) in an implementation that doesn't take
              // explicit embedding into account, we can build up the order on
              // the fly, without following the level-based algorithm.
              var order = [], m;
              for (var i = 0; i < len;) {
                if (countsAsLeft.test(types[i])) {
                  var start = i;
                  for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
                  order.push(new BidiSpan(0, start, i));
                } else {
                  var pos = i, at = order.length;
                  for (++i; i < len && types[i] != "L"; ++i) {}
                  for (var j = pos; j < i;) {
                    if (countsAsNum.test(types[j])) {
                      if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j));
                      var nstart = j;
                      for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
                      order.splice(at, 0, new BidiSpan(2, nstart, j));
                      pos = j;
                    } else ++j;
                  }
                  if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i));
                }
              }
              if (order[0].level == 1 && (m = str.match(/^\s+/))) {
                order[0].from = m[0].length;
                order.unshift(new BidiSpan(0, 0, m[0].length));
              }
              if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
                lst(order).to -= m[0].length;
                order.push(new BidiSpan(0, len - m[0].length, len));
              }
              if (order[0].level != lst(order).level)
                order.push(new BidiSpan(order[0].level, len, len));
        
              return order;
            };
          })();
        
          // THE END
        
          CodeMirror.version = "4.7.1";
        
          return CodeMirror;
        });
        
      • css-hint.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"), require("../../mode/css/css"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror", "../../mode/css/css"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          "use strict";
        
          var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1,
                               "first-letter": 1, "first-line": 1, "first-child": 1,
                               before: 1, after: 1, lang: 1};
        
          CodeMirror.registerHelper("hint", "css", function(cm) {
            var cur = cm.getCursor(), token = cm.getTokenAt(cur);
            var inner = CodeMirror.innerMode(cm.getMode(), token.state);
            if (inner.mode.name != "css") return;
        
            var word = token.string, start = token.start, end = token.end;
            if (/[^\w$_-]/.test(word)) {
              word = ""; start = end = cur.ch;
            }
        
            var spec = CodeMirror.resolveMode("text/css");
        
            var result = [];
            function add(keywords) {
              for (var name in keywords)
                if (!word || name.lastIndexOf(word, 0) == 0)
                  result.push(name);
            }
        
            var st = inner.state.state;
            if (st == "pseudo" || token.type == "variable-3") {
              add(pseudoClasses);
            } else if (st == "block" || st == "maybeprop") {
              add(spec.propertyKeywords);
            } else if (st == "prop" || st == "parens" || st == "at" || st == "params") {
              add(spec.valueKeywords);
              add(spec.colorKeywords);
            } else if (st == "media" || st == "media_parens") {
              add(spec.mediaTypes);
              add(spec.mediaFeatures);
            }
        
            if (result.length) return {
              list: result,
              from: CodeMirror.Pos(cur.line, start),
              to: CodeMirror.Pos(cur.line, end)
            };
          });
        });
        
      • css.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
        "use strict";
        
        CodeMirror.defineMode("css", function(config, parserConfig) {
          if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
        
          var indentUnit = config.indentUnit,
              tokenHooks = parserConfig.tokenHooks,
              mediaTypes = parserConfig.mediaTypes || {},
              mediaFeatures = parserConfig.mediaFeatures || {},
              propertyKeywords = parserConfig.propertyKeywords || {},
              nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
              colorKeywords = parserConfig.colorKeywords || {},
              valueKeywords = parserConfig.valueKeywords || {},
              fontProperties = parserConfig.fontProperties || {},
              allowNested = parserConfig.allowNested;
        
          var type, override;
          function ret(style, tp) { type = tp; return style; }
        
          // Tokenizers
        
          function tokenBase(stream, state) {
            var ch = stream.next();
            if (tokenHooks[ch]) {
              var result = tokenHooks[ch](stream, state);
              if (result !== false) return result;
            }
            if (ch == "@") {
              stream.eatWhile(/[\w\\\-]/);
              return ret("def", stream.current());
            } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
              return ret(null, "compare");
            } else if (ch == "\"" || ch == "'") {
              state.tokenize = tokenString(ch);
              return state.tokenize(stream, state);
            } else if (ch == "#") {
              stream.eatWhile(/[\w\\\-]/);
              return ret("atom", "hash");
            } else if (ch == "!") {
              stream.match(/^\s*\w*/);
              return ret("keyword", "important");
            } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
              stream.eatWhile(/[\w.%]/);
              return ret("number", "unit");
            } else if (ch === "-") {
              if (/[\d.]/.test(stream.peek())) {
                stream.eatWhile(/[\w.%]/);
                return ret("number", "unit");
              } else if (stream.match(/^\w+-/)) {
                return ret("meta", "meta");
              }
            } else if (/[,+>*\/]/.test(ch)) {
              return ret(null, "select-op");
            } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
              return ret("qualifier", "qualifier");
            } else if (/[:;{}\[\]\(\)]/.test(ch)) {
              return ret(null, ch);
            } else if (ch == "u" && stream.match("rl(")) {
              stream.backUp(1);
              state.tokenize = tokenParenthesized;
              return ret("property", "word");
            } else if (/[\w\\\-]/.test(ch)) {
              stream.eatWhile(/[\w\\\-]/);
              return ret("property", "word");
            } else {
              return ret(null, null);
            }
          }
        
          function tokenString(quote) {
            return function(stream, state) {
              var escaped = false, ch;
              while ((ch = stream.next()) != null) {
                if (ch == quote && !escaped) {
                  if (quote == ")") stream.backUp(1);
                  break;
                }
                escaped = !escaped && ch == "\\";
              }
              if (ch == quote || !escaped && quote != ")") state.tokenize = null;
              return ret("string", "string");
            };
          }
        
          function tokenParenthesized(stream, state) {
            stream.next(); // Must be '('
            if (!stream.match(/\s*[\"\')]/, false))
              state.tokenize = tokenString(")");
            else
              state.tokenize = null;
            return ret(null, "(");
          }
        
          // Context management
        
          function Context(type, indent, prev) {
            this.type = type;
            this.indent = indent;
            this.prev = prev;
          }
        
          function pushContext(state, stream, type) {
            state.context = new Context(type, stream.indentation() + indentUnit, state.context);
            return type;
          }
        
          function popContext(state) {
            state.context = state.context.prev;
            return state.context.type;
          }
        
          function pass(type, stream, state) {
            return states[state.context.type](type, stream, state);
          }
          function popAndPass(type, stream, state, n) {
            for (var i = n || 1; i > 0; i--)
              state.context = state.context.prev;
            return pass(type, stream, state);
          }
        
          // Parser
        
          function wordAsValue(stream) {
            var word = stream.current().toLowerCase();
            if (valueKeywords.hasOwnProperty(word))
              override = "atom";
            else if (colorKeywords.hasOwnProperty(word))
              override = "keyword";
            else
              override = "variable";
          }
        
          var states = {};
        
          states.top = function(type, stream, state) {
            if (type == "{") {
              return pushContext(state, stream, "block");
            } else if (type == "}" && state.context.prev) {
              return popContext(state);
            } else if (type == "@media") {
              return pushContext(state, stream, "media");
            } else if (type == "@font-face") {
              return "font_face_before";
            } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
              return "keyframes";
            } else if (type && type.charAt(0) == "@") {
              return pushContext(state, stream, "at");
            } else if (type == "hash") {
              override = "builtin";
            } else if (type == "word") {
              override = "tag";
            } else if (type == "variable-definition") {
              return "maybeprop";
            } else if (type == "interpolation") {
              return pushContext(state, stream, "interpolation");
            } else if (type == ":") {
              return "pseudo";
            } else if (allowNested && type == "(") {
              return pushContext(state, stream, "parens");
            }
            return state.context.type;
          };
        
          states.block = function(type, stream, state) {
            if (type == "word") {
              var word = stream.current().toLowerCase();
              if (propertyKeywords.hasOwnProperty(word)) {
                override = "property";
                return "maybeprop";
              } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
                override = "string-2";
                return "maybeprop";
              } else if (allowNested) {
                override = stream.match(/^\s*:/, false) ? "property" : "tag";
                return "block";
              } else {
                override += " error";
                return "maybeprop";
              }
            } else if (type == "meta") {
              return "block";
            } else if (!allowNested && (type == "hash" || type == "qualifier")) {
              override = "error";
              return "block";
            } else {
              return states.top(type, stream, state);
            }
          };
        
          states.maybeprop = function(type, stream, state) {
            if (type == ":") return pushContext(state, stream, "prop");
            return pass(type, stream, state);
          };
        
          states.prop = function(type, stream, state) {
            if (type == ";") return popContext(state);
            if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
            if (type == "}" || type == "{") return popAndPass(type, stream, state);
            if (type == "(") return pushContext(state, stream, "parens");
        
            if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
              override += " error";
            } else if (type == "word") {
              wordAsValue(stream);
            } else if (type == "interpolation") {
              return pushContext(state, stream, "interpolation");
            }
            return "prop";
          };
        
          states.propBlock = function(type, _stream, state) {
            if (type == "}") return popContext(state);
            if (type == "word") { override = "property"; return "maybeprop"; }
            return state.context.type;
          };
        
          states.parens = function(type, stream, state) {
            if (type == "{" || type == "}") return popAndPass(type, stream, state);
            if (type == ")") return popContext(state);
            if (type == "(") return pushContext(state, stream, "parens");
            if (type == "word") wordAsValue(stream);
            return "parens";
          };
        
          states.pseudo = function(type, stream, state) {
            if (type == "word") {
              override = "variable-3";
              return state.context.type;
            }
            return pass(type, stream, state);
          };
        
          states.media = function(type, stream, state) {
            if (type == "(") return pushContext(state, stream, "media_parens");
            if (type == "}") return popAndPass(type, stream, state);
            if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
        
            if (type == "word") {
              var word = stream.current().toLowerCase();
              if (word == "only" || word == "not" || word == "and")
                override = "keyword";
              else if (mediaTypes.hasOwnProperty(word))
                override = "attribute";
              else if (mediaFeatures.hasOwnProperty(word))
                override = "property";
              else
                override = "error";
            }
            return state.context.type;
          };
        
          states.media_parens = function(type, stream, state) {
            if (type == ")") return popContext(state);
            if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
            return states.media(type, stream, state);
          };
        
          states.font_face_before = function(type, stream, state) {
            if (type == "{")
              return pushContext(state, stream, "font_face");
            return pass(type, stream, state);
          };
        
          states.font_face = function(type, stream, state) {
            if (type == "}") return popContext(state);
            if (type == "word") {
              if (!fontProperties.hasOwnProperty(stream.current().toLowerCase()))
                override = "error";
              else
                override = "property";
              return "maybeprop";
            }
            return "font_face";
          };
        
          states.keyframes = function(type, stream, state) {
            if (type == "word") { override = "variable"; return "keyframes"; }
            if (type == "{") return pushContext(state, stream, "top");
            return pass(type, stream, state);
          };
        
          states.at = function(type, stream, state) {
            if (type == ";") return popContext(state);
            if (type == "{" || type == "}") return popAndPass(type, stream, state);
            if (type == "word") override = "tag";
            else if (type == "hash") override = "builtin";
            return "at";
          };
        
          states.interpolation = function(type, stream, state) {
            if (type == "}") return popContext(state);
            if (type == "{" || type == ";") return popAndPass(type, stream, state);
            if (type != "variable") override = "error";
            return "interpolation";
          };
        
          return {
            startState: function(base) {
              return {tokenize: null,
                      state: "top",
                      context: new Context("top", base || 0, null)};
            },
        
            token: function(stream, state) {
              if (!state.tokenize && stream.eatSpace()) return null;
              var style = (state.tokenize || tokenBase)(stream, state);
              if (style && typeof style == "object") {
                type = style[1];
                style = style[0];
              }
              override = style;
              state.state = states[state.state](type, stream, state);
              return override;
            },
        
            indent: function(state, textAfter) {
              var cx = state.context, ch = textAfter && textAfter.charAt(0);
              var indent = cx.indent;
              if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
              if (cx.prev &&
                  (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
                   ch == ")" && (cx.type == "parens" || cx.type == "media_parens") ||
                   ch == "{" && (cx.type == "at" || cx.type == "media"))) {
                indent = cx.indent - indentUnit;
                cx = cx.prev;
              }
              return indent;
            },
        
            electricChars: "}",
            blockCommentStart: "/*",
            blockCommentEnd: "*/",
            fold: "brace"
          };
        });
        
          function keySet(array) {
            var keys = {};
            for (var i = 0; i < array.length; ++i) {
              keys[array[i]] = true;
            }
            return keys;
          }
        
          var mediaTypes_ = [
            "all", "aural", "braille", "handheld", "print", "projection", "screen",
            "tty", "tv", "embossed"
          ], mediaTypes = keySet(mediaTypes_);
        
          var mediaFeatures_ = [
            "width", "min-width", "max-width", "height", "min-height", "max-height",
            "device-width", "min-device-width", "max-device-width", "device-height",
            "min-device-height", "max-device-height", "aspect-ratio",
            "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
            "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
            "max-color", "color-index", "min-color-index", "max-color-index",
            "monochrome", "min-monochrome", "max-monochrome", "resolution",
            "min-resolution", "max-resolution", "scan", "grid"
          ], mediaFeatures = keySet(mediaFeatures_);
        
          var propertyKeywords_ = [
            "align-content", "align-items", "align-self", "alignment-adjust",
            "alignment-baseline", "anchor-point", "animation", "animation-delay",
            "animation-direction", "animation-duration", "animation-fill-mode",
            "animation-iteration-count", "animation-name", "animation-play-state",
            "animation-timing-function", "appearance", "azimuth", "backface-visibility",
            "background", "background-attachment", "background-clip", "background-color",
            "background-image", "background-origin", "background-position",
            "background-repeat", "background-size", "baseline-shift", "binding",
            "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
            "bookmark-target", "border", "border-bottom", "border-bottom-color",
            "border-bottom-left-radius", "border-bottom-right-radius",
            "border-bottom-style", "border-bottom-width", "border-collapse",
            "border-color", "border-image", "border-image-outset",
            "border-image-repeat", "border-image-slice", "border-image-source",
            "border-image-width", "border-left", "border-left-color",
            "border-left-style", "border-left-width", "border-radius", "border-right",
            "border-right-color", "border-right-style", "border-right-width",
            "border-spacing", "border-style", "border-top", "border-top-color",
            "border-top-left-radius", "border-top-right-radius", "border-top-style",
            "border-top-width", "border-width", "bottom", "box-decoration-break",
            "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
            "caption-side", "clear", "clip", "color", "color-profile", "column-count",
            "column-fill", "column-gap", "column-rule", "column-rule-color",
            "column-rule-style", "column-rule-width", "column-span", "column-width",
            "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
            "cue-after", "cue-before", "cursor", "direction", "display",
            "dominant-baseline", "drop-initial-after-adjust",
            "drop-initial-after-align", "drop-initial-before-adjust",
            "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
            "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
            "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
            "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
            "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
            "font-stretch", "font-style", "font-synthesis", "font-variant",
            "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
            "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
            "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
            "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
            "grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
            "grid-template", "grid-template-areas", "grid-template-columns",
            "grid-template-rows", "hanging-punctuation", "height", "hyphens",
            "icon", "image-orientation", "image-rendering", "image-resolution",
            "inline-box-align", "justify-content", "left", "letter-spacing",
            "line-break", "line-height", "line-stacking", "line-stacking-ruby",
            "line-stacking-shift", "line-stacking-strategy", "list-style",
            "list-style-image", "list-style-position", "list-style-type", "margin",
            "margin-bottom", "margin-left", "margin-right", "margin-top",
            "marker-offset", "marks", "marquee-direction", "marquee-loop",
            "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
            "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
            "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
            "opacity", "order", "orphans", "outline",
            "outline-color", "outline-offset", "outline-style", "outline-width",
            "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
            "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
            "page", "page-break-after", "page-break-before", "page-break-inside",
            "page-policy", "pause", "pause-after", "pause-before", "perspective",
            "perspective-origin", "pitch", "pitch-range", "play-during", "position",
            "presentation-level", "punctuation-trim", "quotes", "region-break-after",
            "region-break-before", "region-break-inside", "region-fragment",
            "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
            "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
            "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
            "shape-outside", "size", "speak", "speak-as", "speak-header",
            "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
            "tab-size", "table-layout", "target", "target-name", "target-new",
            "target-position", "text-align", "text-align-last", "text-decoration",
            "text-decoration-color", "text-decoration-line", "text-decoration-skip",
            "text-decoration-style", "text-emphasis", "text-emphasis-color",
            "text-emphasis-position", "text-emphasis-style", "text-height",
            "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
            "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
            "text-wrap", "top", "transform", "transform-origin", "transform-style",
            "transition", "transition-delay", "transition-duration",
            "transition-property", "transition-timing-function", "unicode-bidi",
            "vertical-align", "visibility", "voice-balance", "voice-duration",
            "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
            "voice-volume", "volume", "white-space", "widows", "width", "word-break",
            "word-spacing", "word-wrap", "z-index",
            // SVG-specific
            "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
            "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
            "color-interpolation", "color-interpolation-filters",
            "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
            "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
            "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
            "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
            "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
            "glyph-orientation-vertical", "text-anchor", "writing-mode"
          ], propertyKeywords = keySet(propertyKeywords_);
        
          var nonStandardPropertyKeywords_ = [
            "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
            "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
            "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
            "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
            "searchfield-results-decoration", "zoom"
          ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
        
          var colorKeywords_ = [
            "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
            "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
            "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
            "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
            "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
            "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
            "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
            "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
            "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
            "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
            "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
            "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
            "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
            "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
            "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
            "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
            "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
            "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
            "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
            "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
            "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
            "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
            "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
            "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
            "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
            "whitesmoke", "yellow", "yellowgreen"
          ], colorKeywords = keySet(colorKeywords_);
        
          var valueKeywords_ = [
            "above", "absolute", "activeborder", "activecaption", "afar",
            "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
            "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
            "arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
            "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
            "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
            "both", "bottom", "break", "break-all", "break-word", "button", "button-bevel",
            "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
            "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
            "cell", "center", "checkbox", "circle", "cjk-earthly-branch",
            "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
            "col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
            "content-box", "context-menu", "continuous", "copy", "cover", "crop",
            "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
            "decimal-leading-zero", "default", "default-button", "destination-atop",
            "destination-in", "destination-out", "destination-over", "devanagari",
            "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
            "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
            "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
            "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
            "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
            "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
            "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
            "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
            "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
            "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
            "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
            "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
            "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
            "help", "hidden", "hide", "higher", "highlight", "highlighttext",
            "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
            "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
            "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
            "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
            "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
            "landscape", "lao", "large", "larger", "left", "level", "lighter",
            "line-through", "linear", "lines", "list-item", "listbox", "listitem",
            "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
            "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
            "lower-roman", "lowercase", "ltr", "malayalam", "match",
            "media-controls-background", "media-current-time-display",
            "media-fullscreen-button", "media-mute-button", "media-play-button",
            "media-return-to-realtime-button", "media-rewind-button",
            "media-seek-back-button", "media-seek-forward-button", "media-slider",
            "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
            "media-volume-slider-container", "media-volume-sliderthumb", "medium",
            "menu", "menulist", "menulist-button", "menulist-text",
            "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
            "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
            "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
            "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
            "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
            "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
            "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
            "painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer",
            "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
            "radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region",
            "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
            "ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
            "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
            "searchfield-cancel-button", "searchfield-decoration",
            "searchfield-results-button", "searchfield-results-decoration",
            "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
            "single", "skip-white-space", "slide", "slider-horizontal",
            "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
            "small", "small-caps", "small-caption", "smaller", "solid", "somali",
            "source-atop", "source-in", "source-out", "source-over", "space", "square",
            "square-button", "start", "static", "status-bar", "stretch", "stroke",
            "sub", "subpixel-antialiased", "super", "sw-resize", "table",
            "table-caption", "table-cell", "table-column", "table-column-group",
            "table-footer-group", "table-header-group", "table-row", "table-row-group",
            "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
            "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
            "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
            "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
            "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
            "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
            "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
            "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
            "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
            "window", "windowframe", "windowtext", "x-large", "x-small", "xor",
            "xx-large", "xx-small"
          ], valueKeywords = keySet(valueKeywords_);
        
          var fontProperties_ = [
            "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
            "font-stretch", "font-weight", "font-style"
          ], fontProperties = keySet(fontProperties_);
        
          var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_)
            .concat(nonStandardPropertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
          CodeMirror.registerHelper("hintWords", "css", allWords);
        
          function tokenCComment(stream, state) {
            var maybeEnd = false, ch;
            while ((ch = stream.next()) != null) {
              if (maybeEnd && ch == "/") {
                state.tokenize = null;
                break;
              }
              maybeEnd = (ch == "*");
            }
            return ["comment", "comment"];
          }
        
          function tokenSGMLComment(stream, state) {
            if (stream.skipTo("-->")) {
              stream.match("-->");
              state.tokenize = null;
            } else {
              stream.skipToEnd();
            }
            return ["comment", "comment"];
          }
        
          CodeMirror.defineMIME("text/css", {
            mediaTypes: mediaTypes,
            mediaFeatures: mediaFeatures,
            propertyKeywords: propertyKeywords,
            nonStandardPropertyKeywords: nonStandardPropertyKeywords,
            colorKeywords: colorKeywords,
            valueKeywords: valueKeywords,
            fontProperties: fontProperties,
            tokenHooks: {
              "<": function(stream, state) {
                if (!stream.match("!--")) return false;
                state.tokenize = tokenSGMLComment;
                return tokenSGMLComment(stream, state);
              },
              "/": function(stream, state) {
                if (!stream.eat("*")) return false;
                state.tokenize = tokenCComment;
                return tokenCComment(stream, state);
              }
            },
            name: "css"
          });
        
          CodeMirror.defineMIME("text/x-scss", {
            mediaTypes: mediaTypes,
            mediaFeatures: mediaFeatures,
            propertyKeywords: propertyKeywords,
            nonStandardPropertyKeywords: nonStandardPropertyKeywords,
            colorKeywords: colorKeywords,
            valueKeywords: valueKeywords,
            fontProperties: fontProperties,
            allowNested: true,
            tokenHooks: {
              "/": function(stream, state) {
                if (stream.eat("/")) {
                  stream.skipToEnd();
                  return ["comment", "comment"];
                } else if (stream.eat("*")) {
                  state.tokenize = tokenCComment;
                  return tokenCComment(stream, state);
                } else {
                  return ["operator", "operator"];
                }
              },
              ":": function(stream) {
                if (stream.match(/\s*\{/))
                  return [null, "{"];
                return false;
              },
              "$": function(stream) {
                stream.match(/^[\w-]+/);
                if (stream.match(/^\s*:/, false))
                  return ["variable-2", "variable-definition"];
                return ["variable-2", "variable"];
              },
              "#": function(stream) {
                if (!stream.eat("{")) return false;
                return [null, "interpolation"];
              }
            },
            name: "css",
            helperType: "scss"
          });
        
          CodeMirror.defineMIME("text/x-less", {
            mediaTypes: mediaTypes,
            mediaFeatures: mediaFeatures,
            propertyKeywords: propertyKeywords,
            nonStandardPropertyKeywords: nonStandardPropertyKeywords,
            colorKeywords: colorKeywords,
            valueKeywords: valueKeywords,
            fontProperties: fontProperties,
            allowNested: true,
            tokenHooks: {
              "/": function(stream, state) {
                if (stream.eat("/")) {
                  stream.skipToEnd();
                  return ["comment", "comment"];
                } else if (stream.eat("*")) {
                  state.tokenize = tokenCComment;
                  return tokenCComment(stream, state);
                } else {
                  return ["operator", "operator"];
                }
              },
              "@": function(stream) {
                if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
                stream.eatWhile(/[\w\\\-]/);
                if (stream.match(/^\s*:/, false))
                  return ["variable-2", "variable-definition"];
                return ["variable-2", "variable"];
              },
              "&": function() {
                return ["atom", "atom"];
              }
            },
            name: "css",
            helperType: "less"
          });
        
        });
        
      • dialog.css
        .CodeMirror-dialog {
          position: absolute;
          left: 0; right: 0;
          background: white;
          z-index: 15;
          padding: .1em .8em;
          overflow: hidden;
          color: #333;
        }
        
        .CodeMirror-dialog-top {
          border-bottom: 1px solid #eee;
          top: 0;
        }
        
        .CodeMirror-dialog-bottom {
          border-top: 1px solid #eee;
          bottom: 0;
        }
        
        .CodeMirror-dialog input {
          border: none;
          outline: none;
          background: transparent;
          width: 20em;
          color: inherit;
          font-family: monospace;
        }
        
        .CodeMirror-dialog button {
          font-size: 70%;
        }
        
      • dialog.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        // Open simple dialogs on top of an editor. Relies on dialog.css.
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          function dialogDiv(cm, template, bottom) {
            var wrap = cm.getWrapperElement();
            var dialog;
            dialog = wrap.appendChild(document.createElement("div"));
            if (bottom)
              dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
            else
              dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
        
            if (typeof template == "string") {
              dialog.innerHTML = template;
            } else { // Assuming it's a detached DOM element.
              dialog.appendChild(template);
            }
            return dialog;
          }
        
          function closeNotification(cm, newVal) {
            if (cm.state.currentNotificationClose)
              cm.state.currentNotificationClose();
            cm.state.currentNotificationClose = newVal;
          }
        
          CodeMirror.defineExtension("openDialog", function(template, callback, options) {
            if (!options) options = {};
        
            closeNotification(this, null);
        
            var dialog = dialogDiv(this, template, options.bottom);
            var closed = false, me = this;
            function close(newVal) {
              if (typeof newVal == 'string') {
                inp.value = newVal;
              } else {
                if (closed) return;
                closed = true;
                dialog.parentNode.removeChild(dialog);
                me.focus();
        
                if (options.onClose) options.onClose(dialog);
              }
            }
        
            var inp = dialog.getElementsByTagName("input")[0], button;
            if (inp) {
              if (options.value) {
                inp.value = options.value;
                inp.select();
              }
        
              if (options.onInput)
                CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
              if (options.onKeyUp)
                CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
        
              CodeMirror.on(inp, "keydown", function(e) {
                if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
                if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
                  inp.blur();
                  CodeMirror.e_stop(e);
                  close();
                }
                if (e.keyCode == 13) callback(inp.value);
              });
        
              if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
        
              inp.focus();
            } else if (button = dialog.getElementsByTagName("button")[0]) {
              CodeMirror.on(button, "click", function() {
                close();
                me.focus();
              });
        
              if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
        
              button.focus();
            }
            return close;
          });
        
          CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
            closeNotification(this, null);
            var dialog = dialogDiv(this, template, options && options.bottom);
            var buttons = dialog.getElementsByTagName("button");
            var closed = false, me = this, blurring = 1;
            function close() {
              if (closed) return;
              closed = true;
              dialog.parentNode.removeChild(dialog);
              me.focus();
            }
            buttons[0].focus();
            for (var i = 0; i < buttons.length; ++i) {
              var b = buttons[i];
              (function(callback) {
                CodeMirror.on(b, "click", function(e) {
                  CodeMirror.e_preventDefault(e);
                  close();
                  if (callback) callback(me);
                });
              })(callbacks[i]);
              CodeMirror.on(b, "blur", function() {
                --blurring;
                setTimeout(function() { if (blurring <= 0) close(); }, 200);
              });
              CodeMirror.on(b, "focus", function() { ++blurring; });
            }
          });
        
          /*
           * openNotification
           * Opens a notification, that can be closed with an optional timer
           * (default 5000ms timer) and always closes on click.
           *
           * If a notification is opened while another is opened, it will close the
           * currently opened one and open the new one immediately.
           */
          CodeMirror.defineExtension("openNotification", function(template, options) {
            closeNotification(this, close);
            var dialog = dialogDiv(this, template, options && options.bottom);
            var closed = false, doneTimer;
            var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
        
            function close() {
              if (closed) return;
              closed = true;
              clearTimeout(doneTimer);
              dialog.parentNode.removeChild(dialog);
            }
        
            CodeMirror.on(dialog, 'click', function(e) {
              CodeMirror.e_preventDefault(e);
              close();
            });
        
            if (duration)
              doneTimer = setTimeout(close, duration);
        
            return close;
          });
        });
        
      • html-hint.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror", "./xml-hint"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror", "./xml-hint"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          "use strict";
        
          var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" ");
          var targets = ["_blank", "_self", "_top", "_parent"];
          var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"];
          var methods = ["get", "post", "put", "delete"];
          var encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"];
          var media = ["all", "screen", "print", "embossed", "braille", "handheld", "print", "projection", "screen", "tty", "tv", "speech",
                       "3d-glasses", "resolution [>][<][=] [X]", "device-aspect-ratio: X/Y", "orientation:portrait",
                       "orientation:landscape", "device-height: [X]", "device-width: [X]"];
          var s = { attrs: {} }; // Simple tag, reused for a whole lot of tags
        
          var data = {
            a: {
              attrs: {
                href: null, ping: null, type: null,
                media: media,
                target: targets,
                hreflang: langs
              }
            },
            abbr: s,
            acronym: s,
            address: s,
            applet: s,
            area: {
              attrs: {
                alt: null, coords: null, href: null, target: null, ping: null,
                media: media, hreflang: langs, type: null,
                shape: ["default", "rect", "circle", "poly"]
              }
            },
            article: s,
            aside: s,
            audio: {
              attrs: {
                src: null, mediagroup: null,
                crossorigin: ["anonymous", "use-credentials"],
                preload: ["none", "metadata", "auto"],
                autoplay: ["", "autoplay"],
                loop: ["", "loop"],
                controls: ["", "controls"]
              }
            },
            b: s,
            base: { attrs: { href: null, target: targets } },
            basefont: s,
            bdi: s,
            bdo: s,
            big: s,
            blockquote: { attrs: { cite: null } },
            body: s,
            br: s,
            button: {
              attrs: {
                form: null, formaction: null, name: null, value: null,
                autofocus: ["", "autofocus"],
                disabled: ["", "autofocus"],
                formenctype: encs,
                formmethod: methods,
                formnovalidate: ["", "novalidate"],
                formtarget: targets,
                type: ["submit", "reset", "button"]
              }
            },
            canvas: { attrs: { width: null, height: null } },
            caption: s,
            center: s,
            cite: s,
            code: s,
            col: { attrs: { span: null } },
            colgroup: { attrs: { span: null } },
            command: {
              attrs: {
                type: ["command", "checkbox", "radio"],
                label: null, icon: null, radiogroup: null, command: null, title: null,
                disabled: ["", "disabled"],
                checked: ["", "checked"]
              }
            },
            data: { attrs: { value: null } },
            datagrid: { attrs: { disabled: ["", "disabled"], multiple: ["", "multiple"] } },
            datalist: { attrs: { data: null } },
            dd: s,
            del: { attrs: { cite: null, datetime: null } },
            details: { attrs: { open: ["", "open"] } },
            dfn: s,
            dir: s,
            div: s,
            dl: s,
            dt: s,
            em: s,
            embed: { attrs: { src: null, type: null, width: null, height: null } },
            eventsource: { attrs: { src: null } },
            fieldset: { attrs: { disabled: ["", "disabled"], form: null, name: null } },
            figcaption: s,
            figure: s,
            font: s,
            footer: s,
            form: {
              attrs: {
                action: null, name: null,
                "accept-charset": charsets,
                autocomplete: ["on", "off"],
                enctype: encs,
                method: methods,
                novalidate: ["", "novalidate"],
                target: targets
              }
            },
            frame: s,
            frameset: s,
            h1: s, h2: s, h3: s, h4: s, h5: s, h6: s,
            head: {
              attrs: {},
              children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"]
            },
            header: s,
            hgroup: s,
            hr: s,
            html: {
              attrs: { manifest: null },
              children: ["head", "body"]
            },
            i: s,
            iframe: {
              attrs: {
                src: null, srcdoc: null, name: null, width: null, height: null,
                sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"],
                seamless: ["", "seamless"]
              }
            },
            img: {
              attrs: {
                alt: null, src: null, ismap: null, usemap: null, width: null, height: null,
                crossorigin: ["anonymous", "use-credentials"]
              }
            },
            input: {
              attrs: {
                alt: null, dirname: null, form: null, formaction: null,
                height: null, list: null, max: null, maxlength: null, min: null,
                name: null, pattern: null, placeholder: null, size: null, src: null,
                step: null, value: null, width: null,
                accept: ["audio/*", "video/*", "image/*"],
                autocomplete: ["on", "off"],
                autofocus: ["", "autofocus"],
                checked: ["", "checked"],
                disabled: ["", "disabled"],
                formenctype: encs,
                formmethod: methods,
                formnovalidate: ["", "novalidate"],
                formtarget: targets,
                multiple: ["", "multiple"],
                readonly: ["", "readonly"],
                required: ["", "required"],
                type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month",
                       "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio",
                       "file", "submit", "image", "reset", "button"]
              }
            },
            ins: { attrs: { cite: null, datetime: null } },
            kbd: s,
            keygen: {
              attrs: {
                challenge: null, form: null, name: null,
                autofocus: ["", "autofocus"],
                disabled: ["", "disabled"],
                keytype: ["RSA"]
              }
            },
            label: { attrs: { "for": null, form: null } },
            legend: s,
            li: { attrs: { value: null } },
            link: {
              attrs: {
                href: null, type: null,
                hreflang: langs,
                media: media,
                sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"]
              }
            },
            map: { attrs: { name: null } },
            mark: s,
            menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } },
            meta: {
              attrs: {
                content: null,
                charset: charsets,
                name: ["viewport", "application-name", "author", "description", "generator", "keywords"],
                "http-equiv": ["content-language", "content-type", "default-style", "refresh"]
              }
            },
            meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } },
            nav: s,
            noframes: s,
            noscript: s,
            object: {
              attrs: {
                data: null, type: null, name: null, usemap: null, form: null, width: null, height: null,
                typemustmatch: ["", "typemustmatch"]
              }
            },
            ol: { attrs: { reversed: ["", "reversed"], start: null, type: ["1", "a", "A", "i", "I"] } },
            optgroup: { attrs: { disabled: ["", "disabled"], label: null } },
            option: { attrs: { disabled: ["", "disabled"], label: null, selected: ["", "selected"], value: null } },
            output: { attrs: { "for": null, form: null, name: null } },
            p: s,
            param: { attrs: { name: null, value: null } },
            pre: s,
            progress: { attrs: { value: null, max: null } },
            q: { attrs: { cite: null } },
            rp: s,
            rt: s,
            ruby: s,
            s: s,
            samp: s,
            script: {
              attrs: {
                type: ["text/javascript"],
                src: null,
                async: ["", "async"],
                defer: ["", "defer"],
                charset: charsets
              }
            },
            section: s,
            select: {
              attrs: {
                form: null, name: null, size: null,
                autofocus: ["", "autofocus"],
                disabled: ["", "disabled"],
                multiple: ["", "multiple"]
              }
            },
            small: s,
            source: { attrs: { src: null, type: null, media: null } },
            span: s,
            strike: s,
            strong: s,
            style: {
              attrs: {
                type: ["text/css"],
                media: media,
                scoped: null
              }
            },
            sub: s,
            summary: s,
            sup: s,
            table: s,
            tbody: s,
            td: { attrs: { colspan: null, rowspan: null, headers: null } },
            textarea: {
              attrs: {
                dirname: null, form: null, maxlength: null, name: null, placeholder: null,
                rows: null, cols: null,
                autofocus: ["", "autofocus"],
                disabled: ["", "disabled"],
                readonly: ["", "readonly"],
                required: ["", "required"],
                wrap: ["soft", "hard"]
              }
            },
            tfoot: s,
            th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } },
            thead: s,
            time: { attrs: { datetime: null } },
            title: s,
            tr: s,
            track: {
              attrs: {
                src: null, label: null, "default": null,
                kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"],
                srclang: langs
              }
            },
            tt: s,
            u: s,
            ul: s,
            "var": s,
            video: {
              attrs: {
                src: null, poster: null, width: null, height: null,
                crossorigin: ["anonymous", "use-credentials"],
                preload: ["auto", "metadata", "none"],
                autoplay: ["", "autoplay"],
                mediagroup: ["movie"],
                muted: ["", "muted"],
                controls: ["", "controls"]
              }
            },
            wbr: s
          };
        
          var globalAttrs = {
            accesskey: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
            "class": null,
            contenteditable: ["true", "false"],
            contextmenu: null,
            dir: ["ltr", "rtl", "auto"],
            draggable: ["true", "false", "auto"],
            dropzone: ["copy", "move", "link", "string:", "file:"],
            hidden: ["hidden"],
            id: null,
            inert: ["inert"],
            itemid: null,
            itemprop: null,
            itemref: null,
            itemscope: ["itemscope"],
            itemtype: null,
            lang: ["en", "es"],
            spellcheck: ["true", "false"],
            style: null,
            tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
            title: null,
            translate: ["yes", "no"],
            onclick: null,
            rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"]
          };
          function populate(obj) {
            for (var attr in globalAttrs) if (globalAttrs.hasOwnProperty(attr))
              obj.attrs[attr] = globalAttrs[attr];
          }
        
          populate(s);
          for (var tag in data) if (data.hasOwnProperty(tag) && data[tag] != s)
            populate(data[tag]);
        
          CodeMirror.htmlSchema = data;
          function htmlHint(cm, options) {
            var local = {schemaInfo: data};
            if (options) for (var opt in options) local[opt] = options[opt];
            return CodeMirror.hint.xml(cm, local);
          }
          CodeMirror.registerHelper("hint", "html", htmlHint);
        });
        
      • htmlembedded.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror", "../htmlmixed/htmlmixed"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
        "use strict";
        
        CodeMirror.defineMode("htmlembedded", function(config, parserConfig) {
        
          //config settings
          var scriptStartRegex = parserConfig.scriptStartRegex || /^<%/i,
              scriptEndRegex = parserConfig.scriptEndRegex || /^%>/i;
        
          //inner modes
          var scriptingMode, htmlMixedMode;
        
          //tokenizer when in html mode
          function htmlDispatch(stream, state) {
              if (stream.match(scriptStartRegex, false)) {
                  state.token=scriptingDispatch;
                  return scriptingMode.token(stream, state.scriptState);
                  }
              else
                  return htmlMixedMode.token(stream, state.htmlState);
            }
        
          //tokenizer when in scripting mode
          function scriptingDispatch(stream, state) {
              if (stream.match(scriptEndRegex, false))  {
                  state.token=htmlDispatch;
                  return htmlMixedMode.token(stream, state.htmlState);
                 }
              else
                  return scriptingMode.token(stream, state.scriptState);
                 }
        
        
          return {
            startState: function() {
              scriptingMode = scriptingMode || CodeMirror.getMode(config, parserConfig.scriptingModeSpec);
              htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed");
              return {
                  token :  parserConfig.startOpen ? scriptingDispatch : htmlDispatch,
                  htmlState : CodeMirror.startState(htmlMixedMode),
                  scriptState : CodeMirror.startState(scriptingMode)
              };
            },
        
            token: function(stream, state) {
              return state.token(stream, state);
            },
        
            indent: function(state, textAfter) {
              if (state.token == htmlDispatch)
                return htmlMixedMode.indent(state.htmlState, textAfter);
              else if (scriptingMode.indent)
                return scriptingMode.indent(state.scriptState, textAfter);
            },
        
            copyState: function(state) {
              return {
               token : state.token,
               htmlState : CodeMirror.copyState(htmlMixedMode, state.htmlState),
               scriptState : CodeMirror.copyState(scriptingMode, state.scriptState)
              };
            },
        
            innerMode: function(state) {
              if (state.token == scriptingDispatch) return {state: state.scriptState, mode: scriptingMode};
              else return {state: state.htmlState, mode: htmlMixedMode};
            }
          };
        }, "htmlmixed");
        
        CodeMirror.defineMIME("application/x-ejs", { name: "htmlembedded", scriptingModeSpec:"javascript"});
        CodeMirror.defineMIME("application/x-aspx", { name: "htmlembedded", scriptingModeSpec:"text/x-csharp"});
        CodeMirror.defineMIME("application/x-jsp", { name: "htmlembedded", scriptingModeSpec:"text/x-java"});
        CodeMirror.defineMIME("application/x-erb", { name: "htmlembedded", scriptingModeSpec:"ruby"});
        
        });
        
      • htmlmixed.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
        "use strict";
        
        CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
          var htmlMode = CodeMirror.getMode(config, {name: "xml",
                                                     htmlMode: true,
                                                     multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
                                                     multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
          var cssMode = CodeMirror.getMode(config, "css");
        
          var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
          scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
                            mode: CodeMirror.getMode(config, "javascript")});
          if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
            var conf = scriptTypesConf[i];
            scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
          }
          scriptTypes.push({matches: /./,
                            mode: CodeMirror.getMode(config, "text/plain")});
        
          function html(stream, state) {
            var tagName = state.htmlState.tagName;
            if (tagName) tagName = tagName.toLowerCase();
            var style = htmlMode.token(stream, state.htmlState);
            if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
              // Script block: mode to change to depends on type attribute
              var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
              scriptType = scriptType ? scriptType[1] : "";
              if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
              for (var i = 0; i < scriptTypes.length; ++i) {
                var tp = scriptTypes[i];
                if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
                  if (tp.mode) {
                    state.token = script;
                    state.localMode = tp.mode;
                    state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
                  }
                  break;
                }
              }
            } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
              state.token = css;
              state.localMode = cssMode;
              state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
            }
            return style;
          }
          function maybeBackup(stream, pat, style) {
            var cur = stream.current();
            var close = cur.search(pat), m;
            if (close > -1) stream.backUp(cur.length - close);
            else if (m = cur.match(/<\/?$/)) {
              stream.backUp(cur.length);
              if (!stream.match(pat, false)) stream.match(cur);
            }
            return style;
          }
          function script(stream, state) {
            if (stream.match(/^<\/\s*script\s*>/i, false)) {
              state.token = html;
              state.localState = state.localMode = null;
              return html(stream, state);
            }
            return maybeBackup(stream, /<\/\s*script\s*>/,
                               state.localMode.token(stream, state.localState));
          }
          function css(stream, state) {
            if (stream.match(/^<\/\s*style\s*>/i, false)) {
              state.token = html;
              state.localState = state.localMode = null;
              return html(stream, state);
            }
            return maybeBackup(stream, /<\/\s*style\s*>/,
                               cssMode.token(stream, state.localState));
          }
        
          return {
            startState: function() {
              var state = htmlMode.startState();
              return {token: html, localMode: null, localState: null, htmlState: state};
            },
        
            copyState: function(state) {
              if (state.localState)
                var local = CodeMirror.copyState(state.localMode, state.localState);
              return {token: state.token, localMode: state.localMode, localState: local,
                      htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
            },
        
            token: function(stream, state) {
              return state.token(stream, state);
            },
        
            indent: function(state, textAfter) {
              if (!state.localMode || /^\s*<\//.test(textAfter))
                return htmlMode.indent(state.htmlState, textAfter);
              else if (state.localMode.indent)
                return state.localMode.indent(state.localState, textAfter);
              else
                return CodeMirror.Pass;
            },
        
            innerMode: function(state) {
              return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
            }
          };
        }, "xml", "javascript", "css");
        
        CodeMirror.defineMIME("text/html", "htmlmixed");
        
        });
        
      • javascript-hint.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          var Pos = CodeMirror.Pos;
        
          function forEach(arr, f) {
            for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
          }
        
          function arrayContains(arr, item) {
            if (!Array.prototype.indexOf) {
              var i = arr.length;
              while (i--) {
                if (arr[i] === item) {
                  return true;
                }
              }
              return false;
            }
            return arr.indexOf(item) != -1;
          }
        
          function scriptHint(editor, keywords, getToken, options) {
            // Find the token at the cursor
            var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
            if (/\b(?:string|comment)\b/.test(token.type)) return;
            token.state = CodeMirror.innerMode(editor.getMode(), token.state).state;
        
            // If it's not a 'word-style' token, ignore the token.
            if (!/^[\w$_]*$/.test(token.string)) {
              token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
                               type: token.string == "." ? "property" : null};
            }
            // If it is a property, find out what it is a property of.
            while (tprop.type == "property") {
              tprop = getToken(editor, Pos(cur.line, tprop.start));
              if (tprop.string != ".") return;
              tprop = getToken(editor, Pos(cur.line, tprop.start));
              if (!context) var context = [];
              context.push(tprop);
            }
            return {list: getCompletions(token, context, keywords, options),
                    from: Pos(cur.line, token.start),
                    to: Pos(cur.line, token.end)};
          }
        
          function javascriptHint(editor, options) {
            return scriptHint(editor, javascriptKeywords,
                              function (e, cur) {return e.getTokenAt(cur);},
                              options);
          };
          CodeMirror.registerHelper("hint", "javascript", javascriptHint);
        
          function getCoffeeScriptToken(editor, cur) {
          // This getToken, it is for coffeescript, imitates the behavior of
          // getTokenAt method in javascript.js, that is, returning "property"
          // type and treat "." as indepenent token.
            var token = editor.getTokenAt(cur);
            if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
              token.end = token.start;
              token.string = '.';
              token.type = "property";
            }
            else if (/^\.[\w$_]*$/.test(token.string)) {
              token.type = "property";
              token.start++;
              token.string = token.string.replace(/\./, '');
            }
            return token;
          }
        
          function coffeescriptHint(editor, options) {
            return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
          }
          CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);
        
          var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
                             "toUpperCase toLowerCase split concat match replace search").split(" ");
          var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
                            "lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
          var funcProps = "prototype apply call bind".split(" ");
          var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " +
                          "if in instanceof new null return switch throw true try typeof var void while with").split(" ");
          var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
                          "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
        
          function getCompletions(token, context, keywords, options) {
            var found = [], start = token.string, global = options && options.globalScope || window;
            function maybeAdd(str) {
              if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
            }
            function gatherCompletions(obj) {
              if (typeof obj == "string") forEach(stringProps, maybeAdd);
              else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
              else if (obj instanceof Function) forEach(funcProps, maybeAdd);
              for (var name in obj) maybeAdd(name);
            }
        
            if (context && context.length) {
              // If this is a property, see if it belongs to some object we can
              // find in the current environment.
              var obj = context.pop(), base;
              if (obj.type && obj.type.indexOf("variable") === 0) {
                if (options && options.additionalContext)
                  base = options.additionalContext[obj.string];
                if (!options || options.useGlobalScope !== false)
                  base = base || global[obj.string];
              } else if (obj.type == "string") {
                base = "";
              } else if (obj.type == "atom") {
                base = 1;
              } else if (obj.type == "function") {
                if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
                    (typeof global.jQuery == 'function'))
                  base = global.jQuery();
                else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function'))
                  base = global._();
              }
              while (base != null && context.length)
                base = base[context.pop().string];
              if (base != null) gatherCompletions(base);
            } else {
              // If not, just look in the global object and any local scope
              // (reading into JS mode internals to get at the local and global variables)
              for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
              for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
              if (!options || options.useGlobalScope !== false)
                gatherCompletions(global);
              forEach(keywords, maybeAdd);
            }
            return found;
          }
        });
        
      • javascript.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        // TODO actually recognize syntax of TypeScript constructs
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
        "use strict";
        
        CodeMirror.defineMode("javascript", function(config, parserConfig) {
          var indentUnit = config.indentUnit;
          var statementIndent = parserConfig.statementIndent;
          var jsonldMode = parserConfig.jsonld;
          var jsonMode = parserConfig.json || jsonldMode;
          var isTS = parserConfig.typescript;
          var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
        
          // Tokenizer
        
          var keywords = function(){
            function kw(type) {return {type: type, style: "keyword"};}
            var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
            var operator = kw("operator"), atom = {type: "atom", style: "atom"};
        
            var jsKeywords = {
              "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
              "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
              "var": kw("var"), "const": kw("var"), "let": kw("var"),
              "function": kw("function"), "catch": kw("catch"),
              "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
              "in": operator, "typeof": operator, "instanceof": operator,
              "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
              "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
              "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
            };
        
            // Extend the 'normal' keywords with the TypeScript language extensions
            if (isTS) {
              var type = {type: "variable", style: "variable-3"};
              var tsKeywords = {
                // object-like things
                "interface": kw("interface"),
                "extends": kw("extends"),
                "constructor": kw("constructor"),
        
                // scope modifiers
                "public": kw("public"),
                "private": kw("private"),
                "protected": kw("protected"),
                "static": kw("static"),
        
                // types
                "string": type, "number": type, "bool": type, "any": type
              };
        
              for (var attr in tsKeywords) {
                jsKeywords[attr] = tsKeywords[attr];
              }
            }
        
            return jsKeywords;
          }();
        
          var isOperatorChar = /[+\-*&%=<>!?|~^]/;
          var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
        
          function readRegexp(stream) {
            var escaped = false, next, inSet = false;
            while ((next = stream.next()) != null) {
              if (!escaped) {
                if (next == "/" && !inSet) return;
                if (next == "[") inSet = true;
                else if (inSet && next == "]") inSet = false;
              }
              escaped = !escaped && next == "\\";
            }
          }
        
          // Used as scratch variables to communicate multiple values without
          // consing up tons of objects.
          var type, content;
          function ret(tp, style, cont) {
            type = tp; content = cont;
            return style;
          }
          function tokenBase(stream, state) {
            var ch = stream.next();
            if (ch == '"' || ch == "'") {
              state.tokenize = tokenString(ch);
              return state.tokenize(stream, state);
            } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
              return ret("number", "number");
            } else if (ch == "." && stream.match("..")) {
              return ret("spread", "meta");
            } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
              return ret(ch);
            } else if (ch == "=" && stream.eat(">")) {
              return ret("=>", "operator");
            } else if (ch == "0" && stream.eat(/x/i)) {
              stream.eatWhile(/[\da-f]/i);
              return ret("number", "number");
            } else if (/\d/.test(ch)) {
              stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
              return ret("number", "number");
            } else if (ch == "/") {
              if (stream.eat("*")) {
                state.tokenize = tokenComment;
                return tokenComment(stream, state);
              } else if (stream.eat("/")) {
                stream.skipToEnd();
                return ret("comment", "comment");
              } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
                       state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
                readRegexp(stream);
                stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
                return ret("regexp", "string-2");
              } else {
                stream.eatWhile(isOperatorChar);
                return ret("operator", "operator", stream.current());
              }
            } else if (ch == "`") {
              state.tokenize = tokenQuasi;
              return tokenQuasi(stream, state);
            } else if (ch == "#") {
              stream.skipToEnd();
              return ret("error", "error");
            } else if (isOperatorChar.test(ch)) {
              stream.eatWhile(isOperatorChar);
              return ret("operator", "operator", stream.current());
            } else if (wordRE.test(ch)) {
              stream.eatWhile(wordRE);
              var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
              return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
                             ret("variable", "variable", word);
            }
          }
        
          function tokenString(quote) {
            return function(stream, state) {
              var escaped = false, next;
              if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
                state.tokenize = tokenBase;
                return ret("jsonld-keyword", "meta");
              }
              while ((next = stream.next()) != null) {
                if (next == quote && !escaped) break;
                escaped = !escaped && next == "\\";
              }
              if (!escaped) state.tokenize = tokenBase;
              return ret("string", "string");
            };
          }
        
          function tokenComment(stream, state) {
            var maybeEnd = false, ch;
            while (ch = stream.next()) {
              if (ch == "/" && maybeEnd) {
                state.tokenize = tokenBase;
                break;
              }
              maybeEnd = (ch == "*");
            }
            return ret("comment", "comment");
          }
        
          function tokenQuasi(stream, state) {
            var escaped = false, next;
            while ((next = stream.next()) != null) {
              if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
                state.tokenize = tokenBase;
                break;
              }
              escaped = !escaped && next == "\\";
            }
            return ret("quasi", "string-2", stream.current());
          }
        
          var brackets = "([{}])";
          // This is a crude lookahead trick to try and notice that we're
          // parsing the argument patterns for a fat-arrow function before we
          // actually hit the arrow token. It only works if the arrow is on
          // the same line as the arguments and there's no strange noise
          // (comments) in between. Fallback is to only notice when we hit the
          // arrow, and not declare the arguments as locals for the arrow
          // body.
          function findFatArrow(stream, state) {
            if (state.fatArrowAt) state.fatArrowAt = null;
            var arrow = stream.string.indexOf("=>", stream.start);
            if (arrow < 0) return;
        
            var depth = 0, sawSomething = false;
            for (var pos = arrow - 1; pos >= 0; --pos) {
              var ch = stream.string.charAt(pos);
              var bracket = brackets.indexOf(ch);
              if (bracket >= 0 && bracket < 3) {
                if (!depth) { ++pos; break; }
                if (--depth == 0) break;
              } else if (bracket >= 3 && bracket < 6) {
                ++depth;
              } else if (wordRE.test(ch)) {
                sawSomething = true;
              } else if (sawSomething && !depth) {
                ++pos;
                break;
              }
            }
            if (sawSomething && !depth) state.fatArrowAt = pos;
          }
        
          // Parser
        
          var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
        
          function JSLexical(indented, column, type, align, prev, info) {
            this.indented = indented;
            this.column = column;
            this.type = type;
            this.prev = prev;
            this.info = info;
            if (align != null) this.align = align;
          }
        
          function inScope(state, varname) {
            for (var v = state.localVars; v; v = v.next)
              if (v.name == varname) return true;
            for (var cx = state.context; cx; cx = cx.prev) {
              for (var v = cx.vars; v; v = v.next)
                if (v.name == varname) return true;
            }
          }
        
          function parseJS(state, style, type, content, stream) {
            var cc = state.cc;
            // Communicate our context to the combinators.
            // (Less wasteful than consing up a hundred closures on every call.)
            cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
        
            if (!state.lexical.hasOwnProperty("align"))
              state.lexical.align = true;
        
            while(true) {
              var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
              if (combinator(type, content)) {
                while(cc.length && cc[cc.length - 1].lex)
                  cc.pop()();
                if (cx.marked) return cx.marked;
                if (type == "variable" && inScope(state, content)) return "variable-2";
                return style;
              }
            }
          }
        
          // Combinator utils
        
          var cx = {state: null, column: null, marked: null, cc: null};
          function pass() {
            for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
          }
          function cont() {
            pass.apply(null, arguments);
            return true;
          }
          function register(varname) {
            function inList(list) {
              for (var v = list; v; v = v.next)
                if (v.name == varname) return true;
              return false;
            }
            var state = cx.state;
            if (state.context) {
              cx.marked = "def";
              if (inList(state.localVars)) return;
              state.localVars = {name: varname, next: state.localVars};
            } else {
              if (inList(state.globalVars)) return;
              if (parserConfig.globalVars)
                state.globalVars = {name: varname, next: state.globalVars};
            }
          }
        
          // Combinators
        
          var defaultVars = {name: "this", next: {name: "arguments"}};
          function pushcontext() {
            cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
            cx.state.localVars = defaultVars;
          }
          function popcontext() {
            cx.state.localVars = cx.state.context.vars;
            cx.state.context = cx.state.context.prev;
          }
          function pushlex(type, info) {
            var result = function() {
              var state = cx.state, indent = state.indented;
              if (state.lexical.type == "stat") indent = state.lexical.indented;
              else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
                indent = outer.indented;
              state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
            };
            result.lex = true;
            return result;
          }
          function poplex() {
            var state = cx.state;
            if (state.lexical.prev) {
              if (state.lexical.type == ")")
                state.indented = state.lexical.indented;
              state.lexical = state.lexical.prev;
            }
          }
          poplex.lex = true;
        
          function expect(wanted) {
            function exp(type) {
              if (type == wanted) return cont();
              else if (wanted == ";") return pass();
              else return cont(exp);
            };
            return exp;
          }
        
          function statement(type, value) {
            if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
            if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
            if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
            if (type == "{") return cont(pushlex("}"), block, poplex);
            if (type == ";") return cont();
            if (type == "if") {
              if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
                cx.state.cc.pop()();
              return cont(pushlex("form"), expression, statement, poplex, maybeelse);
            }
            if (type == "function") return cont(functiondef);
            if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
            if (type == "variable") return cont(pushlex("stat"), maybelabel);
            if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
                                              block, poplex, poplex);
            if (type == "case") return cont(expression, expect(":"));
            if (type == "default") return cont(expect(":"));
            if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
                                             statement, poplex, popcontext);
            if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
            if (type == "class") return cont(pushlex("form"), className, poplex);
            if (type == "export") return cont(pushlex("form"), afterExport, poplex);
            if (type == "import") return cont(pushlex("form"), afterImport, poplex);
            return pass(pushlex("stat"), expression, expect(";"), poplex);
          }
          function expression(type) {
            return expressionInner(type, false);
          }
          function expressionNoComma(type) {
            return expressionInner(type, true);
          }
          function expressionInner(type, noComma) {
            if (cx.state.fatArrowAt == cx.stream.start) {
              var body = noComma ? arrowBodyNoComma : arrowBody;
              if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
              else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
            }
        
            var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
            if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
            if (type == "function") return cont(functiondef, maybeop);
            if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
            if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
            if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
            if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
            if (type == "{") return contCommasep(objprop, "}", null, maybeop);
            if (type == "quasi") { return pass(quasi, maybeop); }
            return cont();
          }
          function maybeexpression(type) {
            if (type.match(/[;\}\)\],]/)) return pass();
            return pass(expression);
          }
          function maybeexpressionNoComma(type) {
            if (type.match(/[;\}\)\],]/)) return pass();
            return pass(expressionNoComma);
          }
        
          function maybeoperatorComma(type, value) {
            if (type == ",") return cont(expression);
            return maybeoperatorNoComma(type, value, false);
          }
          function maybeoperatorNoComma(type, value, noComma) {
            var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
            var expr = noComma == false ? expression : expressionNoComma;
            if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
            if (type == "operator") {
              if (/\+\+|--/.test(value)) return cont(me);
              if (value == "?") return cont(expression, expect(":"), expr);
              return cont(expr);
            }
            if (type == "quasi") { return pass(quasi, me); }
            if (type == ";") return;
            if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
            if (type == ".") return cont(property, me);
            if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
          }
          function quasi(type, value) {
            if (type != "quasi") return pass();
            if (value.slice(value.length - 2) != "${") return cont(quasi);
            return cont(expression, continueQuasi);
          }
          function continueQuasi(type) {
            if (type == "}") {
              cx.marked = "string-2";
              cx.state.tokenize = tokenQuasi;
              return cont(quasi);
            }
          }
          function arrowBody(type) {
            findFatArrow(cx.stream, cx.state);
            return pass(type == "{" ? statement : expression);
          }
          function arrowBodyNoComma(type) {
            findFatArrow(cx.stream, cx.state);
            return pass(type == "{" ? statement : expressionNoComma);
          }
          function maybelabel(type) {
            if (type == ":") return cont(poplex, statement);
            return pass(maybeoperatorComma, expect(";"), poplex);
          }
          function property(type) {
            if (type == "variable") {cx.marked = "property"; return cont();}
          }
          function objprop(type, value) {
            if (type == "variable" || cx.style == "keyword") {
              cx.marked = "property";
              if (value == "get" || value == "set") return cont(getterSetter);
              return cont(afterprop);
            } else if (type == "number" || type == "string") {
              cx.marked = jsonldMode ? "property" : (cx.style + " property");
              return cont(afterprop);
            } else if (type == "jsonld-keyword") {
              return cont(afterprop);
            } else if (type == "[") {
              return cont(expression, expect("]"), afterprop);
            }
          }
          function getterSetter(type) {
            if (type != "variable") return pass(afterprop);
            cx.marked = "property";
            return cont(functiondef);
          }
          function afterprop(type) {
            if (type == ":") return cont(expressionNoComma);
            if (type == "(") return pass(functiondef);
          }
          function commasep(what, end) {
            function proceed(type) {
              if (type == ",") {
                var lex = cx.state.lexical;
                if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
                return cont(what, proceed);
              }
              if (type == end) return cont();
              return cont(expect(end));
            }
            return function(type) {
              if (type == end) return cont();
              return pass(what, proceed);
            };
          }
          function contCommasep(what, end, info) {
            for (var i = 3; i < arguments.length; i++)
              cx.cc.push(arguments[i]);
            return cont(pushlex(end, info), commasep(what, end), poplex);
          }
          function block(type) {
            if (type == "}") return cont();
            return pass(statement, block);
          }
          function maybetype(type) {
            if (isTS && type == ":") return cont(typedef);
          }
          function typedef(type) {
            if (type == "variable"){cx.marked = "variable-3"; return cont();}
          }
          function vardef() {
            return pass(pattern, maybetype, maybeAssign, vardefCont);
          }
          function pattern(type, value) {
            if (type == "variable") { register(value); return cont(); }
            if (type == "[") return contCommasep(pattern, "]");
            if (type == "{") return contCommasep(proppattern, "}");
          }
          function proppattern(type, value) {
            if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
              register(value);
              return cont(maybeAssign);
            }
            if (type == "variable") cx.marked = "property";
            return cont(expect(":"), pattern, maybeAssign);
          }
          function maybeAssign(_type, value) {
            if (value == "=") return cont(expressionNoComma);
          }
          function vardefCont(type) {
            if (type == ",") return cont(vardef);
          }
          function maybeelse(type, value) {
            if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
          }
          function forspec(type) {
            if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
          }
          function forspec1(type) {
            if (type == "var") return cont(vardef, expect(";"), forspec2);
            if (type == ";") return cont(forspec2);
            if (type == "variable") return cont(formaybeinof);
            return pass(expression, expect(";"), forspec2);
          }
          function formaybeinof(_type, value) {
            if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
            return cont(maybeoperatorComma, forspec2);
          }
          function forspec2(type, value) {
            if (type == ";") return cont(forspec3);
            if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
            return pass(expression, expect(";"), forspec3);
          }
          function forspec3(type) {
            if (type != ")") cont(expression);
          }
          function functiondef(type, value) {
            if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
            if (type == "variable") {register(value); return cont(functiondef);}
            if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
          }
          function funarg(type) {
            if (type == "spread") return cont(funarg);
            return pass(pattern, maybetype);
          }
          function className(type, value) {
            if (type == "variable") {register(value); return cont(classNameAfter);}
          }
          function classNameAfter(type, value) {
            if (value == "extends") return cont(expression, classNameAfter);
            if (type == "{") return cont(pushlex("}"), classBody, poplex);
          }
          function classBody(type, value) {
            if (type == "variable" || cx.style == "keyword") {
              cx.marked = "property";
              if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
              return cont(functiondef, classBody);
            }
            if (value == "*") {
              cx.marked = "keyword";
              return cont(classBody);
            }
            if (type == ";") return cont(classBody);
            if (type == "}") return cont();
          }
          function classGetterSetter(type) {
            if (type != "variable") return pass();
            cx.marked = "property";
            return cont();
          }
          function afterModule(type, value) {
            if (type == "string") return cont(statement);
            if (type == "variable") { register(value); return cont(maybeFrom); }
          }
          function afterExport(_type, value) {
            if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
            if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
            return pass(statement);
          }
          function afterImport(type) {
            if (type == "string") return cont();
            return pass(importSpec, maybeFrom);
          }
          function importSpec(type, value) {
            if (type == "{") return contCommasep(importSpec, "}");
            if (type == "variable") register(value);
            return cont();
          }
          function maybeFrom(_type, value) {
            if (value == "from") { cx.marked = "keyword"; return cont(expression); }
          }
          function arrayLiteral(type) {
            if (type == "]") return cont();
            return pass(expressionNoComma, maybeArrayComprehension);
          }
          function maybeArrayComprehension(type) {
            if (type == "for") return pass(comprehension, expect("]"));
            if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
            return pass(commasep(expressionNoComma, "]"));
          }
          function comprehension(type) {
            if (type == "for") return cont(forspec, comprehension);
            if (type == "if") return cont(expression, comprehension);
          }
        
          // Interface
        
          return {
            startState: function(basecolumn) {
              var state = {
                tokenize: tokenBase,
                lastType: "sof",
                cc: [],
                lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
                localVars: parserConfig.localVars,
                context: parserConfig.localVars && {vars: parserConfig.localVars},
                indented: 0
              };
              if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
                state.globalVars = parserConfig.globalVars;
              return state;
            },
        
            token: function(stream, state) {
              if (stream.sol()) {
                if (!state.lexical.hasOwnProperty("align"))
                  state.lexical.align = false;
                state.indented = stream.indentation();
                findFatArrow(stream, state);
              }
              if (state.tokenize != tokenComment && stream.eatSpace()) return null;
              var style = state.tokenize(stream, state);
              if (type == "comment") return style;
              state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
              return parseJS(state, style, type, content, stream);
            },
        
            indent: function(state, textAfter) {
              if (state.tokenize == tokenComment) return CodeMirror.Pass;
              if (state.tokenize != tokenBase) return 0;
              var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
              // Kludge to prevent 'maybelse' from blocking lexical scope pops
              if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
                var c = state.cc[i];
                if (c == poplex) lexical = lexical.prev;
                else if (c != maybeelse) break;
              }
              if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
              if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
                lexical = lexical.prev;
              var type = lexical.type, closing = firstChar == type;
        
              if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
              else if (type == "form" && firstChar == "{") return lexical.indented;
              else if (type == "form") return lexical.indented + indentUnit;
              else if (type == "stat")
                return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
              else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
                return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
              else if (lexical.align) return lexical.column + (closing ? 0 : 1);
              else return lexical.indented + (closing ? 0 : indentUnit);
            },
        
            electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
            blockCommentStart: jsonMode ? null : "/*",
            blockCommentEnd: jsonMode ? null : "*/",
            lineComment: jsonMode ? null : "//",
            fold: "brace",
        
            helperType: jsonMode ? "json" : "javascript",
            jsonldMode: jsonldMode,
            jsonMode: jsonMode
          };
        });
        
        CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
        
        CodeMirror.defineMIME("text/javascript", "javascript");
        CodeMirror.defineMIME("text/ecmascript", "javascript");
        CodeMirror.defineMIME("application/javascript", "javascript");
        CodeMirror.defineMIME("application/x-javascript", "javascript");
        CodeMirror.defineMIME("application/ecmascript", "javascript");
        CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
        CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
        CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
        CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
        CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
        
        });
        
      • markdown.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror", require("../xml/xml")));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror", "../xml/xml"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
        "use strict";
        
        CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
        
          var htmlFound = CodeMirror.modes.hasOwnProperty("xml");
          var htmlMode = CodeMirror.getMode(cmCfg, htmlFound ? {name: "xml", htmlMode: true} : "text/plain");
          var aliases = {
            html: "htmlmixed",
            js: "javascript",
            json: "application/json",
            c: "text/x-csrc",
            "c++": "text/x-c++src",
            java: "text/x-java",
            csharp: "text/x-csharp",
            "c#": "text/x-csharp",
            scala: "text/x-scala"
          };
        
          var getMode = (function () {
            var i, modes = {}, mimes = {}, mime;
        
            var list = [];
            for (var m in CodeMirror.modes)
              if (CodeMirror.modes.propertyIsEnumerable(m)) list.push(m);
            for (i = 0; i < list.length; i++) {
              modes[list[i]] = list[i];
            }
            var mimesList = [];
            for (var m in CodeMirror.mimeModes)
              if (CodeMirror.mimeModes.propertyIsEnumerable(m))
                mimesList.push({mime: m, mode: CodeMirror.mimeModes[m]});
            for (i = 0; i < mimesList.length; i++) {
              mime = mimesList[i].mime;
              mimes[mime] = mimesList[i].mime;
            }
        
            for (var a in aliases) {
              if (aliases[a] in modes || aliases[a] in mimes)
                modes[a] = aliases[a];
            }
        
            return function (lang) {
              return modes[lang] ? CodeMirror.getMode(cmCfg, modes[lang]) : null;
            };
          }());
        
          // Should characters that affect highlighting be highlighted separate?
          // Does not include characters that will be output (such as `1.` and `-` for lists)
          if (modeCfg.highlightFormatting === undefined)
            modeCfg.highlightFormatting = false;
        
          // Maximum number of nested blockquotes. Set to 0 for infinite nesting.
          // Excess `>` will emit `error` token.
          if (modeCfg.maxBlockquoteDepth === undefined)
            modeCfg.maxBlockquoteDepth = 0;
        
          // Should underscores in words open/close em/strong?
          if (modeCfg.underscoresBreakWords === undefined)
            modeCfg.underscoresBreakWords = true;
        
          // Turn on fenced code blocks? ("```" to start/end)
          if (modeCfg.fencedCodeBlocks === undefined) modeCfg.fencedCodeBlocks = false;
        
          // Turn on task lists? ("- [ ] " and "- [x] ")
          if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
        
          // Turn on strikethrough syntax
          if (modeCfg.strikethrough === undefined)
            modeCfg.strikethrough = false;
        
          var codeDepth = 0;
        
          var header   = 'header'
          ,   code     = 'comment'
          ,   quote    = 'quote'
          ,   list1    = 'variable-2'
          ,   list2    = 'variable-3'
          ,   list3    = 'keyword'
          ,   hr       = 'hr'
          ,   image    = 'tag'
          ,   formatting = 'formatting'
          ,   linkinline = 'link'
          ,   linkemail = 'link'
          ,   linktext = 'link'
          ,   linkhref = 'string'
          ,   em       = 'em'
          ,   strong   = 'strong'
          ,   strikethrough = 'strikethrough';
        
          var hrRE = /^([*\-=_])(?:\s*\1){2,}\s*$/
          ,   ulRE = /^[*\-+]\s+/
          ,   olRE = /^[0-9]+\.\s+/
          ,   taskListRE = /^\[(x| )\](?=\s)/ // Must follow ulRE or olRE
          ,   atxHeaderRE = /^#+/
          ,   setextHeaderRE = /^(?:\={1,}|-{1,})$/
          ,   textRE = /^[^#!\[\]*_\\<>` "'(~]+/;
        
          function switchInline(stream, state, f) {
            state.f = state.inline = f;
            return f(stream, state);
          }
        
          function switchBlock(stream, state, f) {
            state.f = state.block = f;
            return f(stream, state);
          }
        
        
          // Blocks
        
          function blankLine(state) {
            // Reset linkTitle state
            state.linkTitle = false;
            // Reset EM state
            state.em = false;
            // Reset STRONG state
            state.strong = false;
            // Reset strikethrough state
            state.strikethrough = false;
            // Reset state.quote
            state.quote = 0;
            if (!htmlFound && state.f == htmlBlock) {
              state.f = inlineNormal;
              state.block = blockNormal;
            }
            // Reset state.trailingSpace
            state.trailingSpace = 0;
            state.trailingSpaceNewLine = false;
            // Mark this line as blank
            state.thisLineHasContent = false;
            return null;
          }
        
          function blockNormal(stream, state) {
        
            var sol = stream.sol();
        
            var prevLineIsList = (state.list !== false);
            if (state.list !== false && state.indentationDiff >= 0) { // Continued list
              if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
                state.indentation -= state.indentationDiff;
              }
              state.list = null;
            } else if (state.list !== false && state.indentation > 0) {
              state.list = null;
              state.listDepth = Math.floor(state.indentation / 4);
            } else if (state.list !== false) { // No longer a list
              state.list = false;
              state.listDepth = 0;
            }
        
            var match = null;
            if (state.indentationDiff >= 4) {
              state.indentation -= 4;
              stream.skipToEnd();
              return code;
            } else if (stream.eatSpace()) {
              return null;
            } else if (match = stream.match(atxHeaderRE)) {
              state.header = match[0].length <= 6 ? match[0].length : 6;
              if (modeCfg.highlightFormatting) state.formatting = "header";
              state.f = state.inline;
              return getType(state);
            } else if (state.prevLineHasContent && (match = stream.match(setextHeaderRE))) {
              state.header = match[0].charAt(0) == '=' ? 1 : 2;
              if (modeCfg.highlightFormatting) state.formatting = "header";
              state.f = state.inline;
              return getType(state);
            } else if (stream.eat('>')) {
              state.indentation++;
              state.quote = sol ? 1 : state.quote + 1;
              if (modeCfg.highlightFormatting) state.formatting = "quote";
              stream.eatSpace();
              return getType(state);
            } else if (stream.peek() === '[') {
              return switchInline(stream, state, footnoteLink);
            } else if (stream.match(hrRE, true)) {
              return hr;
            } else if ((!state.prevLineHasContent || prevLineIsList) && (stream.match(ulRE, false) || stream.match(olRE, false))) {
              var listType = null;
              if (stream.match(ulRE, true)) {
                listType = 'ul';
              } else {
                stream.match(olRE, true);
                listType = 'ol';
              }
              state.indentation += 4;
              state.list = true;
              state.listDepth++;
              if (modeCfg.taskLists && stream.match(taskListRE, false)) {
                state.taskList = true;
              }
              state.f = state.inline;
              if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
              return getType(state);
            } else if (modeCfg.fencedCodeBlocks && stream.match(/^```([\w+#]*)/, true)) {
              // try switching mode
              state.localMode = getMode(RegExp.$1);
              if (state.localMode) state.localState = state.localMode.startState();
              switchBlock(stream, state, local);
              if (modeCfg.highlightFormatting) state.formatting = "code-block";
              state.code = true;
              return getType(state);
            }
        
            return switchInline(stream, state, state.inline);
          }
        
          function htmlBlock(stream, state) {
            var style = htmlMode.token(stream, state.htmlState);
            if ((htmlFound && state.htmlState.tagStart === null && !state.htmlState.context) ||
                (state.md_inside && stream.current().indexOf(">") > -1)) {
              state.f = inlineNormal;
              state.block = blockNormal;
              state.htmlState = null;
            }
            return style;
          }
        
          function local(stream, state) {
            if (stream.sol() && stream.match(/^```/, true)) {
              state.localMode = state.localState = null;
              state.f = inlineNormal;
              state.block = blockNormal;
              if (modeCfg.highlightFormatting) state.formatting = "code-block";
              state.code = true;
              var returnType = getType(state);
              state.code = false;
              return returnType;
            } else if (state.localMode) {
              return state.localMode.token(stream, state.localState);
            } else {
              stream.skipToEnd();
              return code;
            }
          }
        
          // Inline
          function getType(state) {
            var styles = [];
        
            if (state.formatting) {
              styles.push(formatting);
        
              if (typeof state.formatting === "string") state.formatting = [state.formatting];
        
              for (var i = 0; i < state.formatting.length; i++) {
                styles.push(formatting + "-" + state.formatting[i]);
        
                if (state.formatting[i] === "header") {
                  styles.push(formatting + "-" + state.formatting[i] + "-" + state.header);
                }
        
                // Add `formatting-quote` and `formatting-quote-#` for blockquotes
                // Add `error` instead if the maximum blockquote nesting depth is passed
                if (state.formatting[i] === "quote") {
                  if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
                    styles.push(formatting + "-" + state.formatting[i] + "-" + state.quote);
                  } else {
                    styles.push("error");
                  }
                }
              }
            }
        
            if (state.taskOpen) {
              styles.push("meta");
              return styles.length ? styles.join(' ') : null;
            }
            if (state.taskClosed) {
              styles.push("property");
              return styles.length ? styles.join(' ') : null;
            }
        
            if (state.linkHref) {
              styles.push(linkhref);
              return styles.length ? styles.join(' ') : null;
            }
        
            if (state.strong) { styles.push(strong); }
            if (state.em) { styles.push(em); }
            if (state.strikethrough) { styles.push(strikethrough); }
        
            if (state.linkText) { styles.push(linktext); }
        
            if (state.code) { styles.push(code); }
        
            if (state.header) { styles.push(header); styles.push(header + "-" + state.header); }
        
            if (state.quote) {
              styles.push(quote);
        
              // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
              if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
                styles.push(quote + "-" + state.quote);
              } else {
                styles.push(quote + "-" + modeCfg.maxBlockquoteDepth);
              }
            }
        
            if (state.list !== false) {
              var listMod = (state.listDepth - 1) % 3;
              if (!listMod) {
                styles.push(list1);
              } else if (listMod === 1) {
                styles.push(list2);
              } else {
                styles.push(list3);
              }
            }
        
            if (state.trailingSpaceNewLine) {
              styles.push("trailing-space-new-line");
            } else if (state.trailingSpace) {
              styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
            }
        
            return styles.length ? styles.join(' ') : null;
          }
        
          function handleText(stream, state) {
            if (stream.match(textRE, true)) {
              return getType(state);
            }
            return undefined;
          }
        
          function inlineNormal(stream, state) {
            var style = state.text(stream, state);
            if (typeof style !== 'undefined')
              return style;
        
            if (state.list) { // List marker (*, +, -, 1., etc)
              state.list = null;
              return getType(state);
            }
        
            if (state.taskList) {
              var taskOpen = stream.match(taskListRE, true)[1] !== "x";
              if (taskOpen) state.taskOpen = true;
              else state.taskClosed = true;
              if (modeCfg.highlightFormatting) state.formatting = "task";
              state.taskList = false;
              return getType(state);
            }
        
            state.taskOpen = false;
            state.taskClosed = false;
        
            if (state.header && stream.match(/^#+$/, true)) {
              if (modeCfg.highlightFormatting) state.formatting = "header";
              return getType(state);
            }
        
            // Get sol() value now, before character is consumed
            var sol = stream.sol();
        
            var ch = stream.next();
        
            if (ch === '\\') {
              stream.next();
              if (modeCfg.highlightFormatting) {
                var type = getType(state);
                return type ? type + " formatting-escape" : "formatting-escape";
              }
            }
        
            // Matches link titles present on next line
            if (state.linkTitle) {
              state.linkTitle = false;
              var matchCh = ch;
              if (ch === '(') {
                matchCh = ')';
              }
              matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
              var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
              if (stream.match(new RegExp(regex), true)) {
                return linkhref;
              }
            }
        
            // If this block is changed, it may need to be updated in GFM mode
            if (ch === '`') {
              var previousFormatting = state.formatting;
              if (modeCfg.highlightFormatting) state.formatting = "code";
              var t = getType(state);
              var before = stream.pos;
              stream.eatWhile('`');
              var difference = 1 + stream.pos - before;
              if (!state.code) {
                codeDepth = difference;
                state.code = true;
                return getType(state);
              } else {
                if (difference === codeDepth) { // Must be exact
                  state.code = false;
                  return t;
                }
                state.formatting = previousFormatting;
                return getType(state);
              }
            } else if (state.code) {
              return getType(state);
            }
        
            if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
              stream.match(/\[[^\]]*\]/);
              state.inline = state.f = linkHref;
              return image;
            }
        
            if (ch === '[' && stream.match(/.*\](\(| ?\[)/, false)) {
              state.linkText = true;
              if (modeCfg.highlightFormatting) state.formatting = "link";
              return getType(state);
            }
        
            if (ch === ']' && state.linkText) {
              if (modeCfg.highlightFormatting) state.formatting = "link";
              var type = getType(state);
              state.linkText = false;
              state.inline = state.f = linkHref;
              return type;
            }
        
            if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
              state.f = state.inline = linkInline;
              if (modeCfg.highlightFormatting) state.formatting = "link";
              var type = getType(state);
              if (type){
                type += " ";
              } else {
                type = "";
              }
              return type + linkinline;
            }
        
            if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
              state.f = state.inline = linkInline;
              if (modeCfg.highlightFormatting) state.formatting = "link";
              var type = getType(state);
              if (type){
                type += " ";
              } else {
                type = "";
              }
              return type + linkemail;
            }
        
            if (ch === '<' && stream.match(/^\w/, false)) {
              if (stream.string.indexOf(">") != -1) {
                var atts = stream.string.substring(1,stream.string.indexOf(">"));
                if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) {
                  state.md_inside = true;
                }
              }
              stream.backUp(1);
              state.htmlState = CodeMirror.startState(htmlMode);
              return switchBlock(stream, state, htmlBlock);
            }
        
            if (ch === '<' && stream.match(/^\/\w*?>/)) {
              state.md_inside = false;
              return "tag";
            }
        
            var ignoreUnderscore = false;
            if (!modeCfg.underscoresBreakWords) {
              if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
                var prevPos = stream.pos - 2;
                if (prevPos >= 0) {
                  var prevCh = stream.string.charAt(prevPos);
                  if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
                    ignoreUnderscore = true;
                  }
                }
              }
            }
            if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
              if (sol && stream.peek() === ' ') {
                // Do nothing, surrounded by newline and space
              } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
                if (modeCfg.highlightFormatting) state.formatting = "strong";
                var t = getType(state);
                state.strong = false;
                return t;
              } else if (!state.strong && stream.eat(ch)) { // Add STRONG
                state.strong = ch;
                if (modeCfg.highlightFormatting) state.formatting = "strong";
                return getType(state);
              } else if (state.em === ch) { // Remove EM
                if (modeCfg.highlightFormatting) state.formatting = "em";
                var t = getType(state);
                state.em = false;
                return t;
              } else if (!state.em) { // Add EM
                state.em = ch;
                if (modeCfg.highlightFormatting) state.formatting = "em";
                return getType(state);
              }
            } else if (ch === ' ') {
              if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
                if (stream.peek() === ' ') { // Surrounded by spaces, ignore
                  return getType(state);
                } else { // Not surrounded by spaces, back up pointer
                  stream.backUp(1);
                }
              }
            }
        
            if (modeCfg.strikethrough) {
              if (ch === '~' && stream.eatWhile(ch)) {
                if (state.strikethrough) {// Remove strikethrough
                  if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
                  var t = getType(state);
                  state.strikethrough = false;
                  return t;
                } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
                  state.strikethrough = true;
                  if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
                  return getType(state);
                }
              } else if (ch === ' ') {
                if (stream.match(/^~~/, true)) { // Probably surrounded by space
                  if (stream.peek() === ' ') { // Surrounded by spaces, ignore
                    return getType(state);
                  } else { // Not surrounded by spaces, back up pointer
                    stream.backUp(2);
                  }
                }
              }
            }
        
            if (ch === ' ') {
              if (stream.match(/ +$/, false)) {
                state.trailingSpace++;
              } else if (state.trailingSpace) {
                state.trailingSpaceNewLine = true;
              }
            }
        
            return getType(state);
          }
        
          function linkInline(stream, state) {
            var ch = stream.next();
        
            if (ch === ">") {
              state.f = state.inline = inlineNormal;
              if (modeCfg.highlightFormatting) state.formatting = "link";
              var type = getType(state);
              if (type){
                type += " ";
              } else {
                type = "";
              }
              return type + linkinline;
            }
        
            stream.match(/^[^>]+/, true);
        
            return linkinline;
          }
        
          function linkHref(stream, state) {
            // Check if space, and return NULL if so (to avoid marking the space)
            if(stream.eatSpace()){
              return null;
            }
            var ch = stream.next();
            if (ch === '(' || ch === '[') {
              state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]");
              if (modeCfg.highlightFormatting) state.formatting = "link-string";
              state.linkHref = true;
              return getType(state);
            }
            return 'error';
          }
        
          function getLinkHrefInside(endChar) {
            return function(stream, state) {
              var ch = stream.next();
        
              if (ch === endChar) {
                state.f = state.inline = inlineNormal;
                if (modeCfg.highlightFormatting) state.formatting = "link-string";
                var returnState = getType(state);
                state.linkHref = false;
                return returnState;
              }
        
              if (stream.match(inlineRE(endChar), true)) {
                stream.backUp(1);
              }
        
              state.linkHref = true;
              return getType(state);
            };
          }
        
          function footnoteLink(stream, state) {
            if (stream.match(/^[^\]]*\]:/, false)) {
              state.f = footnoteLinkInside;
              stream.next(); // Consume [
              if (modeCfg.highlightFormatting) state.formatting = "link";
              state.linkText = true;
              return getType(state);
            }
            return switchInline(stream, state, inlineNormal);
          }
        
          function footnoteLinkInside(stream, state) {
            if (stream.match(/^\]:/, true)) {
              state.f = state.inline = footnoteUrl;
              if (modeCfg.highlightFormatting) state.formatting = "link";
              var returnType = getType(state);
              state.linkText = false;
              return returnType;
            }
        
            stream.match(/^[^\]]+/, true);
        
            return linktext;
          }
        
          function footnoteUrl(stream, state) {
            // Check if space, and return NULL if so (to avoid marking the space)
            if(stream.eatSpace()){
              return null;
            }
            // Match URL
            stream.match(/^[^\s]+/, true);
            // Check for link title
            if (stream.peek() === undefined) { // End of line, set flag to check next line
              state.linkTitle = true;
            } else { // More content on line, check if link title
              stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
            }
            state.f = state.inline = inlineNormal;
            return linkhref;
          }
        
          var savedInlineRE = [];
          function inlineRE(endChar) {
            if (!savedInlineRE[endChar]) {
              // Escape endChar for RegExp (taken from http://stackoverflow.com/a/494122/526741)
              endChar = (endChar+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
              // Match any non-endChar, escaped character, as well as the closing
              // endChar.
              savedInlineRE[endChar] = new RegExp('^(?:[^\\\\]|\\\\.)*?(' + endChar + ')');
            }
            return savedInlineRE[endChar];
          }
        
          var mode = {
            startState: function() {
              return {
                f: blockNormal,
        
                prevLineHasContent: false,
                thisLineHasContent: false,
        
                block: blockNormal,
                htmlState: null,
                indentation: 0,
        
                inline: inlineNormal,
                text: handleText,
        
                formatting: false,
                linkText: false,
                linkHref: false,
                linkTitle: false,
                em: false,
                strong: false,
                header: 0,
                taskList: false,
                list: false,
                listDepth: 0,
                quote: 0,
                trailingSpace: 0,
                trailingSpaceNewLine: false,
                strikethrough: false
              };
            },
        
            copyState: function(s) {
              return {
                f: s.f,
        
                prevLineHasContent: s.prevLineHasContent,
                thisLineHasContent: s.thisLineHasContent,
        
                block: s.block,
                htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
                indentation: s.indentation,
        
                localMode: s.localMode,
                localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
        
                inline: s.inline,
                text: s.text,
                formatting: false,
                linkTitle: s.linkTitle,
                em: s.em,
                strong: s.strong,
                strikethrough: s.strikethrough,
                header: s.header,
                taskList: s.taskList,
                list: s.list,
                listDepth: s.listDepth,
                quote: s.quote,
                trailingSpace: s.trailingSpace,
                trailingSpaceNewLine: s.trailingSpaceNewLine,
                md_inside: s.md_inside
              };
            },
        
            token: function(stream, state) {
        
              // Reset state.formatting
              state.formatting = false;
        
              if (stream.sol()) {
                var forceBlankLine = !!state.header;
        
                // Reset state.header
                state.header = 0;
        
                if (stream.match(/^\s*$/, true) || forceBlankLine) {
                  state.prevLineHasContent = false;
                  blankLine(state);
                  return forceBlankLine ? this.token(stream, state) : null;
                } else {
                  state.prevLineHasContent = state.thisLineHasContent;
                  state.thisLineHasContent = true;
                }
        
                // Reset state.taskList
                state.taskList = false;
        
                // Reset state.code
                state.code = false;
        
                // Reset state.trailingSpace
                state.trailingSpace = 0;
                state.trailingSpaceNewLine = false;
        
                state.f = state.block;
                var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, '    ').length;
                var difference = Math.floor((indentation - state.indentation) / 4) * 4;
                if (difference > 4) difference = 4;
                var adjustedIndentation = state.indentation + difference;
                state.indentationDiff = adjustedIndentation - state.indentation;
                state.indentation = adjustedIndentation;
                if (indentation > 0) return null;
              }
              var result = state.f(stream, state);
              if (stream.start == stream.pos) return this.token(stream, state);
              else return result;
            },
        
            innerMode: function(state) {
              if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
              if (state.localState) return {state: state.localState, mode: state.localMode};
              return {state: state, mode: mode};
            },
        
            blankLine: blankLine,
        
            getType: getType,
        
            fold: "markdown"
          };
          return mode;
        }, "xml");
        
        CodeMirror.defineMIME("text/x-markdown", "markdown");
        
        });
        
      • matchbrackets.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
            (document.documentMode == null || document.documentMode < 8);
        
          var Pos = CodeMirror.Pos;
        
          var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
        
          function findMatchingBracket(cm, where, strict, config) {
            var line = cm.getLineHandle(where.line), pos = where.ch - 1;
            var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
            if (!match) return null;
            var dir = match.charAt(1) == ">" ? 1 : -1;
            if (strict && (dir > 0) != (pos == where.ch)) return null;
            var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
        
            var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
            if (found == null) return null;
            return {from: Pos(where.line, pos), to: found && found.pos,
                    match: found && found.ch == match.charAt(0), forward: dir > 0};
          }
        
          // bracketRegex is used to specify which type of bracket to scan
          // should be a regexp, e.g. /[[\]]/
          //
          // Note: If "where" is on an open bracket, then this bracket is ignored.
          //
          // Returns false when no bracket was found, null when it reached
          // maxScanLines and gave up
          function scanForBracket(cm, where, dir, style, config) {
            var maxScanLen = (config && config.maxScanLineLength) || 10000;
            var maxScanLines = (config && config.maxScanLines) || 1000;
        
            var stack = [];
            var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/;
            var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
                                  : Math.max(cm.firstLine() - 1, where.line - maxScanLines);
            for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
              var line = cm.getLine(lineNo);
              if (!line) continue;
              var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
              if (line.length > maxScanLen) continue;
              if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
              for (; pos != end; pos += dir) {
                var ch = line.charAt(pos);
                if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
                  var match = matching[ch];
                  if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
                  else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
                  else stack.pop();
                }
              }
            }
            return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
          }
        
          function matchBrackets(cm, autoclear, config) {
            // Disable brace matching in long lines, since it'll cause hugely slow updates
            var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
            var marks = [], ranges = cm.listSelections();
            for (var i = 0; i < ranges.length; i++) {
              var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config);
              if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
                var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
                marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
                if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
                  marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
              }
            }
        
            if (marks.length) {
              // Kludge to work around the IE bug from issue #1193, where text
              // input stops going to the textare whever this fires.
              if (ie_lt8 && cm.state.focused) cm.display.input.focus();
        
              var clear = function() {
                cm.operation(function() {
                  for (var i = 0; i < marks.length; i++) marks[i].clear();
                });
              };
              if (autoclear) setTimeout(clear, 800);
              else return clear;
            }
          }
        
          var currentlyHighlighted = null;
          function doMatchBrackets(cm) {
            cm.operation(function() {
              if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}
              currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
            });
          }
        
          CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
            if (old && old != CodeMirror.Init)
              cm.off("cursorActivity", doMatchBrackets);
            if (val) {
              cm.state.matchBrackets = typeof val == "object" ? val : {};
              cm.on("cursorActivity", doMatchBrackets);
            }
          });
        
          CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
          CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){
            return findMatchingBracket(this, pos, strict, config);
          });
          CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
            return scanForBracket(this, pos, dir, style, config);
          });
        });
        
      • sass.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
        "use strict";
        
        CodeMirror.defineMode("sass", function(config) {
          function tokenRegexp(words) {
            return new RegExp("^" + words.join("|"));
          }
        
          var keywords = ["true", "false", "null", "auto"];
          var keywordsRegexp = new RegExp("^" + keywords.join("|"));
        
          var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-", "\\!=", "/", "\\*", "%", "and", "or", "not"];
          var opRegexp = tokenRegexp(operators);
        
          var pseudoElementsRegexp = /^::?[\w\-]+/;
        
          function urlTokens(stream, state) {
            var ch = stream.peek();
        
            if (ch === ")") {
              stream.next();
              state.tokenizer = tokenBase;
              return "operator";
            } else if (ch === "(") {
              stream.next();
              stream.eatSpace();
        
              return "operator";
            } else if (ch === "'" || ch === '"') {
              state.tokenizer = buildStringTokenizer(stream.next());
              return "string";
            } else {
              state.tokenizer = buildStringTokenizer(")", false);
              return "string";
            }
          }
          function comment(indentation, multiLine) {
            return function(stream, state) {
              if (stream.sol() && stream.indentation() <= indentation) {
                state.tokenizer = tokenBase;
                return tokenBase(stream, state);
              }
        
              if (multiLine && stream.skipTo("*/")) {
                stream.next();
                stream.next();
                state.tokenizer = tokenBase;
              } else {
                stream.next();
              }
        
              return "comment";
            };
          }
        
          function buildStringTokenizer(quote, greedy) {
            if(greedy == null) { greedy = true; }
        
            function stringTokenizer(stream, state) {
              var nextChar = stream.next();
              var peekChar = stream.peek();
              var previousChar = stream.string.charAt(stream.pos-2);
        
              var endingString = ((nextChar !== "\\" && peekChar === quote) || (nextChar === quote && previousChar !== "\\"));
        
              if (endingString) {
                if (nextChar !== quote && greedy) { stream.next(); }
                state.tokenizer = tokenBase;
                return "string";
              } else if (nextChar === "#" && peekChar === "{") {
                state.tokenizer = buildInterpolationTokenizer(stringTokenizer);
                stream.next();
                return "operator";
              } else {
                return "string";
              }
            }
        
            return stringTokenizer;
          }
        
          function buildInterpolationTokenizer(currentTokenizer) {
            return function(stream, state) {
              if (stream.peek() === "}") {
                stream.next();
                state.tokenizer = currentTokenizer;
                return "operator";
              } else {
                return tokenBase(stream, state);
              }
            };
          }
        
          function indent(state) {
            if (state.indentCount == 0) {
              state.indentCount++;
              var lastScopeOffset = state.scopes[0].offset;
              var currentOffset = lastScopeOffset + config.indentUnit;
              state.scopes.unshift({ offset:currentOffset });
            }
          }
        
          function dedent(state) {
            if (state.scopes.length == 1) return;
        
            state.scopes.shift();
          }
        
          function tokenBase(stream, state) {
            var ch = stream.peek();
        
            // Comment
            if (stream.match("/*")) {
              state.tokenizer = comment(stream.indentation(), true);
              return state.tokenizer(stream, state);
            }
            if (stream.match("//")) {
              state.tokenizer = comment(stream.indentation(), false);
              return state.tokenizer(stream, state);
            }
        
            // Interpolation
            if (stream.match("#{")) {
              state.tokenizer = buildInterpolationTokenizer(tokenBase);
              return "operator";
            }
        
            if (ch === ".") {
              stream.next();
        
              // Match class selectors
              if (stream.match(/^[\w-]+/)) {
                indent(state);
                return "atom";
              } else if (stream.peek() === "#") {
                indent(state);
                return "atom";
              } else {
                return "operator";
              }
            }
        
            if (ch === "#") {
              stream.next();
        
              // Hex numbers
              if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/))
                return "number";
        
              // ID selectors
              if (stream.match(/^[\w-]+/)) {
                indent(state);
                return "atom";
              }
        
              if (stream.peek() === "#") {
                indent(state);
                return "atom";
              }
            }
        
            // Numbers
            if (stream.match(/^-?[0-9\.]+/))
              return "number";
        
            // Units
            if (stream.match(/^(px|em|in)\b/))
              return "unit";
        
            if (stream.match(keywordsRegexp))
              return "keyword";
        
            if (stream.match(/^url/) && stream.peek() === "(") {
              state.tokenizer = urlTokens;
              return "atom";
            }
        
            // Variables
            if (ch === "$") {
              stream.next();
              stream.eatWhile(/[\w-]/);
        
              if (stream.peek() === ":") {
                stream.next();
                return "variable-2";
              } else {
                return "variable-3";
              }
            }
        
            if (ch === "!") {
              stream.next();
              return stream.match(/^[\w]+/) ? "keyword": "operator";
            }
        
            if (ch === "=") {
              stream.next();
        
              // Match shortcut mixin definition
              if (stream.match(/^[\w-]+/)) {
                indent(state);
                return "meta";
              } else {
                return "operator";
              }
            }
        
            if (ch === "+") {
              stream.next();
        
              // Match shortcut mixin definition
              if (stream.match(/^[\w-]+/))
                return "variable-3";
              else
                return "operator";
            }
        
            // Indent Directives
            if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)) {
              indent(state);
              return "meta";
            }
        
            // Other Directives
            if (ch === "@") {
              stream.next();
              stream.eatWhile(/[\w-]/);
              return "meta";
            }
        
            // Strings
            if (ch === '"' || ch === "'") {
              stream.next();
              state.tokenizer = buildStringTokenizer(ch);
              return "string";
            }
        
            // Pseudo element selectors
            if (ch == ":" && stream.match(pseudoElementsRegexp))
              return "keyword";
        
            // atoms
            if (stream.eatWhile(/[\w-&]/)) {
              // matches a property definition
              if (stream.peek() === ":" && !stream.match(pseudoElementsRegexp, false))
                return "property";
              else
                return "atom";
            }
        
            if (stream.match(opRegexp))
              return "operator";
        
            // If we haven't returned by now, we move 1 character
            // and return an error
            stream.next();
            return null;
          }
        
          function tokenLexer(stream, state) {
            if (stream.sol()) state.indentCount = 0;
            var style = state.tokenizer(stream, state);
            var current = stream.current();
        
            if (current === "@return")
              dedent(state);
        
            if (style === "atom")
              indent(state);
        
            if (style !== null) {
              var startOfToken = stream.pos - current.length;
              var withCurrentIndent = startOfToken + (config.indentUnit * state.indentCount);
        
              var newScopes = [];
        
              for (var i = 0; i < state.scopes.length; i++) {
                var scope = state.scopes[i];
        
                if (scope.offset <= withCurrentIndent)
                  newScopes.push(scope);
              }
        
              state.scopes = newScopes;
            }
        
        
            return style;
          }
        
          return {
            startState: function() {
              return {
                tokenizer: tokenBase,
                scopes: [{offset: 0, type: "sass"}],
                indentCount: 0,
                definedVars: [],
                definedMixins: []
              };
            },
            token: function(stream, state) {
              var style = tokenLexer(stream, state);
        
              state.lastToken = { style: style, content: stream.current() };
        
              return style;
            },
        
            indent: function(state) {
              return state.scopes[0].offset;
            }
          };
        });
        
        CodeMirror.defineMIME("text/x-sass", "sass");
        
        });
        
      • search.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        // Define search commands. Depends on dialog.js or another
        // implementation of the openDialog method.
        
        // Replace works a little oddly -- it will do the replace on the next
        // Ctrl-G (or whatever is bound to findNext) press. You prevent a
        // replace by making sure the match is no longer selected when hitting
        // Ctrl-G.
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          "use strict";
          function searchOverlay(query, caseInsensitive) {
            if (typeof query == "string")
              query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
            else if (!query.global)
              query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");
        
            return {token: function(stream) {
              query.lastIndex = stream.pos;
              var match = query.exec(stream.string);
              if (match && match.index == stream.pos) {
                stream.pos += match[0].length;
                return "searching";
              } else if (match) {
                stream.pos = match.index;
              } else {
                stream.skipToEnd();
              }
            }};
          }
        
          function SearchState() {
            this.posFrom = this.posTo = this.query = null;
            this.overlay = null;
          }
          function getSearchState(cm) {
            return cm.state.search || (cm.state.search = new SearchState());
          }
          function queryCaseInsensitive(query) {
            return typeof query == "string" && query == query.toLowerCase();
          }
          function getSearchCursor(cm, query, pos) {
            // Heuristic: if the query string is all lowercase, do a case insensitive search.
            return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
          }
          function dialog(cm, text, shortText, deflt, f) {
            if (cm.openDialog) cm.openDialog(text, f, {value: deflt});
            else f(prompt(shortText, deflt));
          }
          function confirmDialog(cm, text, shortText, fs) {
            if (cm.openConfirm) cm.openConfirm(text, fs);
            else if (confirm(shortText)) fs[0]();
          }
          function parseQuery(query) {
            var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
            if (isRE) {
              query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i");
              if (query.test("")) query = /x^/;
            } else if (query == "") {
              query = /x^/;
            }
            return query;
          }
          var queryDialog =
            'Search: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
          function doSearch(cm, rev) {
            var state = getSearchState(cm);
            if (state.query) return findNext(cm, rev);
            dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) {
              cm.operation(function() {
                if (!query || state.query) return;
                state.query = parseQuery(query);
                cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
                state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
                cm.addOverlay(state.overlay);
                state.posFrom = state.posTo = cm.getCursor();
                findNext(cm, rev);
              });
            });
          }
          function findNext(cm, rev) {cm.operation(function() {
            var state = getSearchState(cm);
            var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
            if (!cursor.find(rev)) {
              cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
              if (!cursor.find(rev)) return;
            }
            cm.setSelection(cursor.from(), cursor.to());
            cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
            state.posFrom = cursor.from(); state.posTo = cursor.to();
          });}
          function clearSearch(cm) {cm.operation(function() {
            var state = getSearchState(cm);
            if (!state.query) return;
            state.query = null;
            cm.removeOverlay(state.overlay);
          });}
        
          var replaceQueryDialog =
            'Replace: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
          var replacementQueryDialog = 'With: <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
          var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
          function replace(cm, all) {
            if (cm.getOption("readOnly")) return;
            dialog(cm, replaceQueryDialog, "Replace:", cm.getSelection(), function(query) {
              if (!query) return;
              query = parseQuery(query);
              dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
                if (all) {
                  cm.operation(function() {
                    for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
                      if (typeof query != "string") {
                        var match = cm.getRange(cursor.from(), cursor.to()).match(query);
                        cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
                      } else cursor.replace(text);
                    }
                  });
                } else {
                  clearSearch(cm);
                  var cursor = getSearchCursor(cm, query, cm.getCursor());
                  var advance = function() {
                    var start = cursor.from(), match;
                    if (!(match = cursor.findNext())) {
                      cursor = getSearchCursor(cm, query);
                      if (!(match = cursor.findNext()) ||
                          (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
                    }
                    cm.setSelection(cursor.from(), cursor.to());
                    cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
                    confirmDialog(cm, doReplaceConfirm, "Replace?",
                                  [function() {doReplace(match);}, advance]);
                  };
                  var doReplace = function(match) {
                    cursor.replace(typeof query == "string" ? text :
                                   text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
                    advance();
                  };
                  advance();
                }
              });
            });
          }
        
          CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
          CodeMirror.commands.findNext = doSearch;
          CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
          CodeMirror.commands.clearSearch = clearSearch;
          CodeMirror.commands.replace = replace;
          CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
        });
        
      • searchcursor.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          "use strict";
          var Pos = CodeMirror.Pos;
        
          function SearchCursor(doc, query, pos, caseFold) {
            this.atOccurrence = false; this.doc = doc;
            if (caseFold == null && typeof query == "string") caseFold = false;
        
            pos = pos ? doc.clipPos(pos) : Pos(0, 0);
            this.pos = {from: pos, to: pos};
        
            // The matches method is filled in based on the type of query.
            // It takes a position and a direction, and returns an object
            // describing the next occurrence of the query, or null if no
            // more matches were found.
            if (typeof query != "string") { // Regexp match
              if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g");
              this.matches = function(reverse, pos) {
                if (reverse) {
                  query.lastIndex = 0;
                  var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start;
                  for (;;) {
                    query.lastIndex = cutOff;
                    var newMatch = query.exec(line);
                    if (!newMatch) break;
                    match = newMatch;
                    start = match.index;
                    cutOff = match.index + (match[0].length || 1);
                    if (cutOff == line.length) break;
                  }
                  var matchLen = (match && match[0].length) || 0;
                  if (!matchLen) {
                    if (start == 0 && line.length == 0) {match = undefined;}
                    else if (start != doc.getLine(pos.line).length) {
                      matchLen++;
                    }
                  }
                } else {
                  query.lastIndex = pos.ch;
                  var line = doc.getLine(pos.line), match = query.exec(line);
                  var matchLen = (match && match[0].length) || 0;
                  var start = match && match.index;
                  if (start + matchLen != line.length && !matchLen) matchLen = 1;
                }
                if (match && matchLen)
                  return {from: Pos(pos.line, start),
                          to: Pos(pos.line, start + matchLen),
                          match: match};
              };
            } else { // String query
              var origQuery = query;
              if (caseFold) query = query.toLowerCase();
              var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
              var target = query.split("\n");
              // Different methods for single-line and multi-line queries
              if (target.length == 1) {
                if (!query.length) {
                  // Empty string would match anything and never progress, so
                  // we define it to match nothing instead.
                  this.matches = function() {};
                } else {
                  this.matches = function(reverse, pos) {
                    if (reverse) {
                      var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig);
                      var match = line.lastIndexOf(query);
                      if (match > -1) {
                        match = adjustPos(orig, line, match);
                        return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
                      }
                     } else {
                       var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig);
                       var match = line.indexOf(query);
                       if (match > -1) {
                         match = adjustPos(orig, line, match) + pos.ch;
                         return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};
                       }
                    }
                  };
                }
              } else {
                var origTarget = origQuery.split("\n");
                this.matches = function(reverse, pos) {
                  var last = target.length - 1;
                  if (reverse) {
                    if (pos.line - (target.length - 1) < doc.firstLine()) return;
                    if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return;
                    var to = Pos(pos.line, origTarget[last].length);
                    for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln)
                      if (target[i] != fold(doc.getLine(ln))) return;
                    var line = doc.getLine(ln), cut = line.length - origTarget[0].length;
                    if (fold(line.slice(cut)) != target[0]) return;
                    return {from: Pos(ln, cut), to: to};
                  } else {
                    if (pos.line + (target.length - 1) > doc.lastLine()) return;
                    var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length;
                    if (fold(line.slice(cut)) != target[0]) return;
                    var from = Pos(pos.line, cut);
                    for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)
                      if (target[i] != fold(doc.getLine(ln))) return;
                    if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return;
                    return {from: from, to: Pos(ln, origTarget[last].length)};
                  }
                };
              }
            }
          }
        
          SearchCursor.prototype = {
            findNext: function() {return this.find(false);},
            findPrevious: function() {return this.find(true);},
        
            find: function(reverse) {
              var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);
              function savePosAndFail(line) {
                var pos = Pos(line, 0);
                self.pos = {from: pos, to: pos};
                self.atOccurrence = false;
                return false;
              }
        
              for (;;) {
                if (this.pos = this.matches(reverse, pos)) {
                  this.atOccurrence = true;
                  return this.pos.match || true;
                }
                if (reverse) {
                  if (!pos.line) return savePosAndFail(0);
                  pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length);
                }
                else {
                  var maxLine = this.doc.lineCount();
                  if (pos.line == maxLine - 1) return savePosAndFail(maxLine);
                  pos = Pos(pos.line + 1, 0);
                }
              }
            },
        
            from: function() {if (this.atOccurrence) return this.pos.from;},
            to: function() {if (this.atOccurrence) return this.pos.to;},
        
            replace: function(newText) {
              if (!this.atOccurrence) return;
              var lines = CodeMirror.splitLines(newText);
              this.doc.replaceRange(lines, this.pos.from, this.pos.to);
              this.pos.to = Pos(this.pos.from.line + lines.length - 1,
                                lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));
            }
          };
        
          // Maps a position in a case-folded line back to a position in the original line
          // (compensating for codepoints increasing in number during folding)
          function adjustPos(orig, folded, pos) {
            if (orig.length == folded.length) return pos;
            for (var pos1 = Math.min(pos, orig.length);;) {
              var len1 = orig.slice(0, pos1).toLowerCase().length;
              if (len1 < pos) ++pos1;
              else if (len1 > pos) --pos1;
              else return pos1;
            }
          }
        
          CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
            return new SearchCursor(this.doc, query, pos, caseFold);
          });
          CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
            return new SearchCursor(this, query, pos, caseFold);
          });
        
          CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
            var ranges = [], next;
            var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold);
            while (next = cur.findNext()) {
              if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break;
              ranges.push({anchor: cur.from(), head: cur.to()});
            }
            if (ranges.length)
              this.setSelections(ranges, 0);
          });
        });
        
      • show-hint.css
        .CodeMirror-hints {
          position: absolute;
          z-index: 10;
          overflow: hidden;
          list-style: none;
        
          margin: 0;
          padding: 2px;
        
          -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
          -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
          box-shadow: 2px 3px 5px rgba(0,0,0,.2);
          border-radius: 3px;
          border: 1px solid silver;
        
          background: white;
          font-size: 90%;
          font-family: monospace;
        
          max-height: 20em;
          overflow-y: auto;
        }
        
        .CodeMirror-hint {
          margin: 0;
          padding: 0 4px;
          border-radius: 2px;
          max-width: 19em;
          overflow: hidden;
          white-space: pre;
          color: black;
          cursor: pointer;
        }
        
        li.CodeMirror-hint-active {
          background: #08f;
          color: white;
        }
        
      • show-hint.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          "use strict";
        
          var HINT_ELEMENT_CLASS        = "CodeMirror-hint";
          var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
        
          // This is the old interface, kept around for now to stay
          // backwards-compatible.
          CodeMirror.showHint = function(cm, getHints, options) {
            if (!getHints) return cm.showHint(options);
            if (options && options.async) getHints.async = true;
            var newOpts = {hint: getHints};
            if (options) for (var prop in options) newOpts[prop] = options[prop];
            return cm.showHint(newOpts);
          };
        
          CodeMirror.defineExtension("showHint", function(options) {
            // We want a single cursor position.
            if (this.listSelections().length > 1 || this.somethingSelected()) return;
        
            if (this.state.completionActive) this.state.completionActive.close();
            var completion = this.state.completionActive = new Completion(this, options);
            var getHints = completion.options.hint;
            if (!getHints) return;
        
            CodeMirror.signal(this, "startCompletion", this);
            if (getHints.async)
              getHints(this, function(hints) { completion.showHints(hints); }, completion.options);
            else
              return completion.showHints(getHints(this, completion.options));
          });
        
          function Completion(cm, options) {
            this.cm = cm;
            this.options = this.buildOptions(options);
            this.widget = this.onClose = null;
          }
        
          Completion.prototype = {
            close: function() {
              if (!this.active()) return;
              this.cm.state.completionActive = null;
        
              if (this.widget) this.widget.close();
              if (this.onClose) this.onClose();
              CodeMirror.signal(this.cm, "endCompletion", this.cm);
            },
        
            active: function() {
              return this.cm.state.completionActive == this;
            },
        
            pick: function(data, i) {
              var completion = data.list[i];
              if (completion.hint) completion.hint(this.cm, data, completion);
              else this.cm.replaceRange(getText(completion), completion.from || data.from,
                                        completion.to || data.to, "complete");
              CodeMirror.signal(data, "pick", completion);
              this.close();
            },
        
            showHints: function(data) {
              if (!data || !data.list.length || !this.active()) return this.close();
        
              if (this.options.completeSingle && data.list.length == 1)
                this.pick(data, 0);
              else
                this.showWidget(data);
            },
        
            showWidget: function(data) {
              this.widget = new Widget(this, data);
              CodeMirror.signal(data, "shown");
        
              var debounce = 0, completion = this, finished;
              var closeOn = this.options.closeCharacters;
              var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length;
        
              var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
                return setTimeout(fn, 1000/60);
              };
              var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
        
              function done() {
                if (finished) return;
                finished = true;
                completion.close();
                completion.cm.off("cursorActivity", activity);
                if (data) CodeMirror.signal(data, "close");
              }
        
              function update() {
                if (finished) return;
                CodeMirror.signal(data, "update");
                var getHints = completion.options.hint;
                if (getHints.async)
                  getHints(completion.cm, finishUpdate, completion.options);
                else
                  finishUpdate(getHints(completion.cm, completion.options));
              }
              function finishUpdate(data_) {
                data = data_;
                if (finished) return;
                if (!data || !data.list.length) return done();
                if (completion.widget) completion.widget.close();
                completion.widget = new Widget(completion, data);
              }
        
              function clearDebounce() {
                if (debounce) {
                  cancelAnimationFrame(debounce);
                  debounce = 0;
                }
              }
        
              function activity() {
                clearDebounce();
                var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line);
                if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch ||
                    pos.ch < startPos.ch || completion.cm.somethingSelected() ||
                    (pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) {
                  completion.close();
                } else {
                  debounce = requestAnimationFrame(update);
                  if (completion.widget) completion.widget.close();
                }
              }
              this.cm.on("cursorActivity", activity);
              this.onClose = done;
            },
        
            buildOptions: function(options) {
              var editor = this.cm.options.hintOptions;
              var out = {};
              for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
              if (editor) for (var prop in editor)
                if (editor[prop] !== undefined) out[prop] = editor[prop];
              if (options) for (var prop in options)
                if (options[prop] !== undefined) out[prop] = options[prop];
              return out;
            }
          };
        
          function getText(completion) {
            if (typeof completion == "string") return completion;
            else return completion.text;
          }
        
          function buildKeyMap(completion, handle) {
            var baseMap = {
              Up: function() {handle.moveFocus(-1);},
              Down: function() {handle.moveFocus(1);},
              PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
              PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
              Home: function() {handle.setFocus(0);},
              End: function() {handle.setFocus(handle.length - 1);},
              Enter: handle.pick,
              Tab: handle.pick,
              Esc: handle.close
            };
            var custom = completion.options.customKeys;
            var ourMap = custom ? {} : baseMap;
            function addBinding(key, val) {
              var bound;
              if (typeof val != "string")
                bound = function(cm) { return val(cm, handle); };
              // This mechanism is deprecated
              else if (baseMap.hasOwnProperty(val))
                bound = baseMap[val];
              else
                bound = val;
              ourMap[key] = bound;
            }
            if (custom)
              for (var key in custom) if (custom.hasOwnProperty(key))
                addBinding(key, custom[key]);
            var extra = completion.options.extraKeys;
            if (extra)
              for (var key in extra) if (extra.hasOwnProperty(key))
                addBinding(key, extra[key]);
            return ourMap;
          }
        
          function getHintElement(hintsElement, el) {
            while (el && el != hintsElement) {
              if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
              el = el.parentNode;
            }
          }
        
          function Widget(completion, data) {
            this.completion = completion;
            this.data = data;
            var widget = this, cm = completion.cm;
        
            var hints = this.hints = document.createElement("ul");
            hints.className = "CodeMirror-hints";
            this.selectedHint = data.selectedHint || 0;
        
            var completions = data.list;
            for (var i = 0; i < completions.length; ++i) {
              var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
              var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
              if (cur.className != null) className = cur.className + " " + className;
              elt.className = className;
              if (cur.render) cur.render(elt, data, cur);
              else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
              elt.hintId = i;
            }
        
            var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
            var left = pos.left, top = pos.bottom, below = true;
            hints.style.left = left + "px";
            hints.style.top = top + "px";
            // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
            var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
            var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
            (completion.options.container || document.body).appendChild(hints);
            var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
            if (overlapY > 0) {
              var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
              if (curTop - height > 0) { // Fits above cursor
                hints.style.top = (top = pos.top - height) + "px";
                below = false;
              } else if (height > winH) {
                hints.style.height = (winH - 5) + "px";
                hints.style.top = (top = pos.bottom - box.top) + "px";
                var cursor = cm.getCursor();
                if (data.from.ch != cursor.ch) {
                  pos = cm.cursorCoords(cursor);
                  hints.style.left = (left = pos.left) + "px";
                  box = hints.getBoundingClientRect();
                }
              }
            }
            var overlapX = box.left - winW;
            if (overlapX > 0) {
              if (box.right - box.left > winW) {
                hints.style.width = (winW - 5) + "px";
                overlapX -= (box.right - box.left) - winW;
              }
              hints.style.left = (left = pos.left - overlapX) + "px";
            }
        
            cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
              moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
              setFocus: function(n) { widget.changeActive(n); },
              menuSize: function() { return widget.screenAmount(); },
              length: completions.length,
              close: function() { completion.close(); },
              pick: function() { widget.pick(); },
              data: data
            }));
        
            if (completion.options.closeOnUnfocus) {
              var closingOnBlur;
              cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
              cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
            }
        
            var startScroll = cm.getScrollInfo();
            cm.on("scroll", this.onScroll = function() {
              var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
              var newTop = top + startScroll.top - curScroll.top;
              var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
              if (!below) point += hints.offsetHeight;
              if (point <= editor.top || point >= editor.bottom) return completion.close();
              hints.style.top = newTop + "px";
              hints.style.left = (left + startScroll.left - curScroll.left) + "px";
            });
        
            CodeMirror.on(hints, "dblclick", function(e) {
              var t = getHintElement(hints, e.target || e.srcElement);
              if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
            });
        
            CodeMirror.on(hints, "click", function(e) {
              var t = getHintElement(hints, e.target || e.srcElement);
              if (t && t.hintId != null) {
                widget.changeActive(t.hintId);
                if (completion.options.completeOnSingleClick) widget.pick();
              }
            });
        
            CodeMirror.on(hints, "mousedown", function() {
              setTimeout(function(){cm.focus();}, 20);
            });
        
            CodeMirror.signal(data, "select", completions[0], hints.firstChild);
            return true;
          }
        
          Widget.prototype = {
            close: function() {
              if (this.completion.widget != this) return;
              this.completion.widget = null;
              this.hints.parentNode.removeChild(this.hints);
              this.completion.cm.removeKeyMap(this.keyMap);
        
              var cm = this.completion.cm;
              if (this.completion.options.closeOnUnfocus) {
                cm.off("blur", this.onBlur);
                cm.off("focus", this.onFocus);
              }
              cm.off("scroll", this.onScroll);
            },
        
            pick: function() {
              this.completion.pick(this.data, this.selectedHint);
            },
        
            changeActive: function(i, avoidWrap) {
              if (i >= this.data.list.length)
                i = avoidWrap ? this.data.list.length - 1 : 0;
              else if (i < 0)
                i = avoidWrap ? 0  : this.data.list.length - 1;
              if (this.selectedHint == i) return;
              var node = this.hints.childNodes[this.selectedHint];
              node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
              node = this.hints.childNodes[this.selectedHint = i];
              node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
              if (node.offsetTop < this.hints.scrollTop)
                this.hints.scrollTop = node.offsetTop - 3;
              else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
                this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
              CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
            },
        
            screenAmount: function() {
              return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
            }
          };
        
          CodeMirror.registerHelper("hint", "auto", function(cm, options) {
            var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
            if (helpers.length) {
              for (var i = 0; i < helpers.length; i++) {
                var cur = helpers[i](cm, options);
                if (cur && cur.list.length) return cur;
              }
            } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
              if (words) return CodeMirror.hint.fromList(cm, {words: words});
            } else if (CodeMirror.hint.anyword) {
              return CodeMirror.hint.anyword(cm, options);
            }
          });
        
          CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
            var cur = cm.getCursor(), token = cm.getTokenAt(cur);
            var found = [];
            for (var i = 0; i < options.words.length; i++) {
              var word = options.words[i];
              if (word.slice(0, token.string.length) == token.string)
                found.push(word);
            }
        
            if (found.length) return {
              list: found,
              from: CodeMirror.Pos(cur.line, token.start),
                    to: CodeMirror.Pos(cur.line, token.end)
            };
          });
        
          CodeMirror.commands.autocomplete = CodeMirror.showHint;
        
          var defaultOptions = {
            hint: CodeMirror.hint.auto,
            completeSingle: true,
            alignWithWord: true,
            closeCharacters: /[\s()\[\]{};:>,]/,
            closeOnUnfocus: true,
            completeOnSingleClick: false,
            container: null,
            customKeys: null,
            extraKeys: null
          };
        
          CodeMirror.defineOption("hintOptions", null);
        });
        
      • tern.css
        .CodeMirror-Tern-completion {
          padding-left: 22px;
          position: relative;
        }
        .CodeMirror-Tern-completion:before {
          position: absolute;
          left: 2px;
          bottom: 2px;
          border-radius: 50%;
          font-size: 12px;
          font-weight: bold;
          height: 15px;
          width: 15px;
          line-height: 16px;
          text-align: center;
          color: white;
          -moz-box-sizing: border-box;
          box-sizing: border-box;
        }
        .CodeMirror-Tern-completion-unknown:before {
          content: "?";
          background: #4bb;
        }
        .CodeMirror-Tern-completion-object:before {
          content: "O";
          background: #77c;
        }
        .CodeMirror-Tern-completion-fn:before {
          content: "F";
          background: #7c7;
        }
        .CodeMirror-Tern-completion-array:before {
          content: "A";
          background: #c66;
        }
        .CodeMirror-Tern-completion-number:before {
          content: "1";
          background: #999;
        }
        .CodeMirror-Tern-completion-string:before {
          content: "S";
          background: #999;
        }
        .CodeMirror-Tern-completion-bool:before {
          content: "B";
          background: #999;
        }
        
        .CodeMirror-Tern-completion-guess {
          color: #999;
        }
        
        .CodeMirror-Tern-tooltip {
          border: 1px solid silver;
          border-radius: 3px;
          color: #444;
          padding: 2px 5px;
          font-size: 90%;
          font-family: monospace;
          background-color: white;
          white-space: pre-wrap;
        
          max-width: 40em;
          position: absolute;
          z-index: 10;
          -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
          -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
          box-shadow: 2px 3px 5px rgba(0,0,0,.2);
        
          transition: opacity 1s;
          -moz-transition: opacity 1s;
          -webkit-transition: opacity 1s;
          -o-transition: opacity 1s;
          -ms-transition: opacity 1s;
        }
        
        .CodeMirror-Tern-hint-doc {
          max-width: 25em;
          margin-top: -3px;
        }
        
        .CodeMirror-Tern-fname { color: black; }
        .CodeMirror-Tern-farg { color: #70a; }
        .CodeMirror-Tern-farg-current { text-decoration: underline; }
        .CodeMirror-Tern-type { color: #07c; }
        .CodeMirror-Tern-fhint-guess { opacity: .7; }
        
      • tern.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        // Glue code between CodeMirror and Tern.
        //
        // Create a CodeMirror.TernServer to wrap an actual Tern server,
        // register open documents (CodeMirror.Doc instances) with it, and
        // call its methods to activate the assisting functions that Tern
        // provides.
        //
        // Options supported (all optional):
        // * defs: An array of JSON definition data structures.
        // * plugins: An object mapping plugin names to configuration
        //   options.
        // * getFile: A function(name, c) that can be used to access files in
        //   the project that haven't been loaded yet. Simply do c(null) to
        //   indicate that a file is not available.
        // * fileFilter: A function(value, docName, doc) that will be applied
        //   to documents before passing them on to Tern.
        // * switchToDoc: A function(name, doc) that should, when providing a
        //   multi-file view, switch the view or focus to the named file.
        // * showError: A function(editor, message) that can be used to
        //   override the way errors are displayed.
        // * completionTip: Customize the content in tooltips for completions.
        //   Is passed a single argument—the completion's data as returned by
        //   Tern—and may return a string, DOM node, or null to indicate that
        //   no tip should be shown. By default the docstring is shown.
        // * typeTip: Like completionTip, but for the tooltips shown for type
        //   queries.
        // * responseFilter: A function(doc, query, request, error, data) that
        //   will be applied to the Tern responses before treating them
        //
        //
        // It is possible to run the Tern server in a web worker by specifying
        // these additional options:
        // * useWorker: Set to true to enable web worker mode. You'll probably
        //   want to feature detect the actual value you use here, for example
        //   !!window.Worker.
        // * workerScript: The main script of the worker. Point this to
        //   wherever you are hosting worker.js from this directory.
        // * workerDeps: An array of paths pointing (relative to workerScript)
        //   to the Acorn and Tern libraries and any Tern plugins you want to
        //   load. Or, if you minified those into a single script and included
        //   them in the workerScript, simply leave this undefined.
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          "use strict";
          // declare global: tern
        
          CodeMirror.TernServer = function(options) {
            var self = this;
            this.options = options || {};
            var plugins = this.options.plugins || (this.options.plugins = {});
            if (!plugins.doc_comment) plugins.doc_comment = true;
            if (this.options.useWorker) {
              this.server = new WorkerServer(this);
            } else {
              this.server = new tern.Server({
                getFile: function(name, c) { return getFile(self, name, c); },
                async: true,
                defs: this.options.defs || [],
                plugins: plugins
              });
            }
            this.docs = Object.create(null);
            this.trackChange = function(doc, change) { trackChange(self, doc, change); };
        
            this.cachedArgHints = null;
            this.activeArgHints = null;
            this.jumpStack = [];
        
            this.getHint = function(cm, c) { return hint(self, cm, c); };
            this.getHint.async = true;
          };
        
          CodeMirror.TernServer.prototype = {
            addDoc: function(name, doc) {
              var data = {doc: doc, name: name, changed: null};
              this.server.addFile(name, docValue(this, data));
              CodeMirror.on(doc, "change", this.trackChange);
              return this.docs[name] = data;
            },
        
            delDoc: function(id) {
              var found = resolveDoc(this, id);
              if (!found) return;
              CodeMirror.off(found.doc, "change", this.trackChange);
              delete this.docs[found.name];
              this.server.delFile(found.name);
            },
        
            hideDoc: function(id) {
              closeArgHints(this);
              var found = resolveDoc(this, id);
              if (found && found.changed) sendDoc(this, found);
            },
        
            complete: function(cm) {
              cm.showHint({hint: this.getHint});
            },
        
            showType: function(cm, pos, c) { showType(this, cm, pos, c); },
        
            updateArgHints: function(cm) { updateArgHints(this, cm); },
        
            jumpToDef: function(cm) { jumpToDef(this, cm); },
        
            jumpBack: function(cm) { jumpBack(this, cm); },
        
            rename: function(cm) { rename(this, cm); },
        
            selectName: function(cm) { selectName(this, cm); },
        
            request: function (cm, query, c, pos) {
              var self = this;
              var doc = findDoc(this, cm.getDoc());
              var request = buildRequest(this, doc, query, pos);
        
              this.server.request(request, function (error, data) {
                if (!error && self.options.responseFilter)
                  data = self.options.responseFilter(doc, query, request, error, data);
                c(error, data);
              });
            }
          };
        
          var Pos = CodeMirror.Pos;
          var cls = "CodeMirror-Tern-";
          var bigDoc = 250;
        
          function getFile(ts, name, c) {
            var buf = ts.docs[name];
            if (buf)
              c(docValue(ts, buf));
            else if (ts.options.getFile)
              ts.options.getFile(name, c);
            else
              c(null);
          }
        
          function findDoc(ts, doc, name) {
            for (var n in ts.docs) {
              var cur = ts.docs[n];
              if (cur.doc == doc) return cur;
            }
            if (!name) for (var i = 0;; ++i) {
              n = "[doc" + (i || "") + "]";
              if (!ts.docs[n]) { name = n; break; }
            }
            return ts.addDoc(name, doc);
          }
        
          function resolveDoc(ts, id) {
            if (typeof id == "string") return ts.docs[id];
            if (id instanceof CodeMirror) id = id.getDoc();
            if (id instanceof CodeMirror.Doc) return findDoc(ts, id);
          }
        
          function trackChange(ts, doc, change) {
            var data = findDoc(ts, doc);
        
            var argHints = ts.cachedArgHints;
            if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) <= 0)
              ts.cachedArgHints = null;
        
            var changed = data.changed;
            if (changed == null)
              data.changed = changed = {from: change.from.line, to: change.from.line};
            var end = change.from.line + (change.text.length - 1);
            if (change.from.line < changed.to) changed.to = changed.to - (change.to.line - end);
            if (end >= changed.to) changed.to = end + 1;
            if (changed.from > change.from.line) changed.from = change.from.line;
        
            if (doc.lineCount() > bigDoc && change.to - changed.from > 100) setTimeout(function() {
              if (data.changed && data.changed.to - data.changed.from > 100) sendDoc(ts, data);
            }, 200);
          }
        
          function sendDoc(ts, doc) {
            ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) {
              if (error) window.console.error(error);
              else doc.changed = null;
            });
          }
        
          // Completion
        
          function hint(ts, cm, c) {
            ts.request(cm, {type: "completions", types: true, docs: true, urls: true}, function(error, data) {
              if (error) return showError(ts, cm, error);
              var completions = [], after = "";
              var from = data.start, to = data.end;
              if (cm.getRange(Pos(from.line, from.ch - 2), from) == "[\"" &&
                  cm.getRange(to, Pos(to.line, to.ch + 2)) != "\"]")
                after = "\"]";
        
              for (var i = 0; i < data.completions.length; ++i) {
                var completion = data.completions[i], className = typeToIcon(completion.type);
                if (data.guess) className += " " + cls + "guess";
                completions.push({text: completion.name + after,
                                  displayText: completion.name,
                                  className: className,
                                  data: completion});
              }
        
              var obj = {from: from, to: to, list: completions};
              var tooltip = null;
              CodeMirror.on(obj, "close", function() { remove(tooltip); });
              CodeMirror.on(obj, "update", function() { remove(tooltip); });
              CodeMirror.on(obj, "select", function(cur, node) {
                remove(tooltip);
                var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc;
                if (content) {
                  tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset,
                                        node.getBoundingClientRect().top + window.pageYOffset, content);
                  tooltip.className += " " + cls + "hint-doc";
                }
              });
              c(obj);
            });
          }
        
          function typeToIcon(type) {
            var suffix;
            if (type == "?") suffix = "unknown";
            else if (type == "number" || type == "string" || type == "bool") suffix = type;
            else if (/^fn\(/.test(type)) suffix = "fn";
            else if (/^\[/.test(type)) suffix = "array";
            else suffix = "object";
            return cls + "completion " + cls + "completion-" + suffix;
          }
        
          // Type queries
        
          function showType(ts, cm, pos, c) {
            ts.request(cm, "type", function(error, data) {
              if (error) return showError(ts, cm, error);
              if (ts.options.typeTip) {
                var tip = ts.options.typeTip(data);
              } else {
                var tip = elt("span", null, elt("strong", null, data.type || "not found"));
                if (data.doc)
                  tip.appendChild(document.createTextNode(" — " + data.doc));
                if (data.url) {
                  tip.appendChild(document.createTextNode(" "));
                  tip.appendChild(elt("a", null, "[docs]")).href = data.url;
                }
              }
              tempTooltip(cm, tip);
              if (c) c();
            }, pos);
          }
        
          // Maintaining argument hints
        
          function updateArgHints(ts, cm) {
            closeArgHints(ts);
        
            if (cm.somethingSelected()) return;
            var state = cm.getTokenAt(cm.getCursor()).state;
            var inner = CodeMirror.innerMode(cm.getMode(), state);
            if (inner.mode.name != "javascript") return;
            var lex = inner.state.lexical;
            if (lex.info != "call") return;
        
            var ch, argPos = lex.pos || 0, tabSize = cm.getOption("tabSize");
            for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) {
              var str = cm.getLine(line), extra = 0;
              for (var pos = 0;;) {
                var tab = str.indexOf("\t", pos);
                if (tab == -1) break;
                extra += tabSize - (tab + extra) % tabSize - 1;
                pos = tab + 1;
              }
              ch = lex.column - extra;
              if (str.charAt(ch) == "(") {found = true; break;}
            }
            if (!found) return;
        
            var start = Pos(line, ch);
            var cache = ts.cachedArgHints;
            if (cache && cache.doc == cm.getDoc() && cmpPos(start, cache.start) == 0)
              return showArgHints(ts, cm, argPos);
        
            ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) {
              if (error || !data.type || !(/^fn\(/).test(data.type)) return;
              ts.cachedArgHints = {
                start: pos,
                type: parseFnType(data.type),
                name: data.exprName || data.name || "fn",
                guess: data.guess,
                doc: cm.getDoc()
              };
              showArgHints(ts, cm, argPos);
            });
          }
        
          function showArgHints(ts, cm, pos) {
            closeArgHints(ts);
        
            var cache = ts.cachedArgHints, tp = cache.type;
            var tip = elt("span", cache.guess ? cls + "fhint-guess" : null,
                          elt("span", cls + "fname", cache.name), "(");
            for (var i = 0; i < tp.args.length; ++i) {
              if (i) tip.appendChild(document.createTextNode(", "));
              var arg = tp.args[i];
              tip.appendChild(elt("span", cls + "farg" + (i == pos ? " " + cls + "farg-current" : ""), arg.name || "?"));
              if (arg.type != "?") {
                tip.appendChild(document.createTextNode(":\u00a0"));
                tip.appendChild(elt("span", cls + "type", arg.type));
              }
            }
            tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")"));
            if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype));
            var place = cm.cursorCoords(null, "page");
            ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip);
          }
        
          function parseFnType(text) {
            var args = [], pos = 3;
        
            function skipMatching(upto) {
              var depth = 0, start = pos;
              for (;;) {
                var next = text.charAt(pos);
                if (upto.test(next) && !depth) return text.slice(start, pos);
                if (/[{\[\(]/.test(next)) ++depth;
                else if (/[}\]\)]/.test(next)) --depth;
                ++pos;
              }
            }
        
            // Parse arguments
            if (text.charAt(pos) != ")") for (;;) {
              var name = text.slice(pos).match(/^([^, \(\[\{]+): /);
              if (name) {
                pos += name[0].length;
                name = name[1];
              }
              args.push({name: name, type: skipMatching(/[\),]/)});
              if (text.charAt(pos) == ")") break;
              pos += 2;
            }
        
            var rettype = text.slice(pos).match(/^\) -> (.*)$/);
        
            return {args: args, rettype: rettype && rettype[1]};
          }
        
          // Moving to the definition of something
        
          function jumpToDef(ts, cm) {
            function inner(varName) {
              var req = {type: "definition", variable: varName || null};
              var doc = findDoc(ts, cm.getDoc());
              ts.server.request(buildRequest(ts, doc, req), function(error, data) {
                if (error) return showError(ts, cm, error);
                if (!data.file && data.url) { window.open(data.url); return; }
        
                if (data.file) {
                  var localDoc = ts.docs[data.file], found;
                  if (localDoc && (found = findContext(localDoc.doc, data))) {
                    ts.jumpStack.push({file: doc.name,
                                       start: cm.getCursor("from"),
                                       end: cm.getCursor("to")});
                    moveTo(ts, doc, localDoc, found.start, found.end);
                    return;
                  }
                }
                showError(ts, cm, "Could not find a definition.");
              });
            }
        
            if (!atInterestingExpression(cm))
              dialog(cm, "Jump to variable", function(name) { if (name) inner(name); });
            else
              inner();
          }
        
          function jumpBack(ts, cm) {
            var pos = ts.jumpStack.pop(), doc = pos && ts.docs[pos.file];
            if (!doc) return;
            moveTo(ts, findDoc(ts, cm.getDoc()), doc, pos.start, pos.end);
          }
        
          function moveTo(ts, curDoc, doc, start, end) {
            doc.doc.setSelection(start, end);
            if (curDoc != doc && ts.options.switchToDoc) {
              closeArgHints(ts);
              ts.options.switchToDoc(doc.name, doc.doc);
            }
          }
        
          // The {line,ch} representation of positions makes this rather awkward.
          function findContext(doc, data) {
            var before = data.context.slice(0, data.contextOffset).split("\n");
            var startLine = data.start.line - (before.length - 1);
            var start = Pos(startLine, (before.length == 1 ? data.start.ch : doc.getLine(startLine).length) - before[0].length);
        
            var text = doc.getLine(startLine).slice(start.ch);
            for (var cur = startLine + 1; cur < doc.lineCount() && text.length < data.context.length; ++cur)
              text += "\n" + doc.getLine(cur);
            if (text.slice(0, data.context.length) == data.context) return data;
        
            var cursor = doc.getSearchCursor(data.context, 0, false);
            var nearest, nearestDist = Infinity;
            while (cursor.findNext()) {
              var from = cursor.from(), dist = Math.abs(from.line - start.line) * 10000;
              if (!dist) dist = Math.abs(from.ch - start.ch);
              if (dist < nearestDist) { nearest = from; nearestDist = dist; }
            }
            if (!nearest) return null;
        
            if (before.length == 1)
              nearest.ch += before[0].length;
            else
              nearest = Pos(nearest.line + (before.length - 1), before[before.length - 1].length);
            if (data.start.line == data.end.line)
              var end = Pos(nearest.line, nearest.ch + (data.end.ch - data.start.ch));
            else
              var end = Pos(nearest.line + (data.end.line - data.start.line), data.end.ch);
            return {start: nearest, end: end};
          }
        
          function atInterestingExpression(cm) {
            var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos);
            if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false;
            return /\w/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
          }
        
          // Variable renaming
        
          function rename(ts, cm) {
            var token = cm.getTokenAt(cm.getCursor());
            if (!/\w/.test(token.string)) return showError(ts, cm, "Not at a variable");
            dialog(cm, "New name for " + token.string, function(newName) {
              ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) {
                if (error) return showError(ts, cm, error);
                applyChanges(ts, data.changes);
              });
            });
          }
        
          function selectName(ts, cm) {
            var name = findDoc(ts, cm.doc).name;
            ts.request(cm, {type: "refs"}, function(error, data) {
              if (error) return showError(ts, cm, error);
              var ranges = [], cur = 0;
              for (var i = 0; i < data.refs.length; i++) {
                var ref = data.refs[i];
                if (ref.file == name) {
                  ranges.push({anchor: ref.start, head: ref.end});
                  if (cmpPos(cur, ref.start) >= 0 && cmpPos(cur, ref.end) <= 0)
                    cur = ranges.length - 1;
                }
              }
              cm.setSelections(ranges, cur);
            });
          }
        
          var nextChangeOrig = 0;
          function applyChanges(ts, changes) {
            var perFile = Object.create(null);
            for (var i = 0; i < changes.length; ++i) {
              var ch = changes[i];
              (perFile[ch.file] || (perFile[ch.file] = [])).push(ch);
            }
            for (var file in perFile) {
              var known = ts.docs[file], chs = perFile[file];;
              if (!known) continue;
              chs.sort(function(a, b) { return cmpPos(b.start, a.start); });
              var origin = "*rename" + (++nextChangeOrig);
              for (var i = 0; i < chs.length; ++i) {
                var ch = chs[i];
                known.doc.replaceRange(ch.text, ch.start, ch.end, origin);
              }
            }
          }
        
          // Generic request-building helper
        
          function buildRequest(ts, doc, query, pos) {
            var files = [], offsetLines = 0, allowFragments = !query.fullDocs;
            if (!allowFragments) delete query.fullDocs;
            if (typeof query == "string") query = {type: query};
            query.lineCharPositions = true;
            if (query.end == null) {
              query.end = pos || doc.doc.getCursor("end");
              if (doc.doc.somethingSelected())
                query.start = doc.doc.getCursor("start");
            }
            var startPos = query.start || query.end;
        
            if (doc.changed) {
              if (doc.doc.lineCount() > bigDoc && allowFragments !== false &&
                  doc.changed.to - doc.changed.from < 100 &&
                  doc.changed.from <= startPos.line && doc.changed.to > query.end.line) {
                files.push(getFragmentAround(doc, startPos, query.end));
                query.file = "#0";
                var offsetLines = files[0].offsetLines;
                if (query.start != null) query.start = Pos(query.start.line - -offsetLines, query.start.ch);
                query.end = Pos(query.end.line - offsetLines, query.end.ch);
              } else {
                files.push({type: "full",
                            name: doc.name,
                            text: docValue(ts, doc)});
                query.file = doc.name;
                doc.changed = null;
              }
            } else {
              query.file = doc.name;
            }
            for (var name in ts.docs) {
              var cur = ts.docs[name];
              if (cur.changed && cur != doc) {
                files.push({type: "full", name: cur.name, text: docValue(ts, cur)});
                cur.changed = null;
              }
            }
        
            return {query: query, files: files};
          }
        
          function getFragmentAround(data, start, end) {
            var doc = data.doc;
            var minIndent = null, minLine = null, endLine, tabSize = 4;
            for (var p = start.line - 1, min = Math.max(0, p - 50); p >= min; --p) {
              var line = doc.getLine(p), fn = line.search(/\bfunction\b/);
              if (fn < 0) continue;
              var indent = CodeMirror.countColumn(line, null, tabSize);
              if (minIndent != null && minIndent <= indent) continue;
              minIndent = indent;
              minLine = p;
            }
            if (minLine == null) minLine = min;
            var max = Math.min(doc.lastLine(), end.line + 20);
            if (minIndent == null || minIndent == CodeMirror.countColumn(doc.getLine(start.line), null, tabSize))
              endLine = max;
            else for (endLine = end.line + 1; endLine < max; ++endLine) {
              var indent = CodeMirror.countColumn(doc.getLine(endLine), null, tabSize);
              if (indent <= minIndent) break;
            }
            var from = Pos(minLine, 0);
        
            return {type: "part",
                    name: data.name,
                    offsetLines: from.line,
                    text: doc.getRange(from, Pos(endLine, 0))};
          }
        
          // Generic utilities
        
          var cmpPos = CodeMirror.cmpPos;
        
          function elt(tagname, cls /*, ... elts*/) {
            var e = document.createElement(tagname);
            if (cls) e.className = cls;
            for (var i = 2; i < arguments.length; ++i) {
              var elt = arguments[i];
              if (typeof elt == "string") elt = document.createTextNode(elt);
              e.appendChild(elt);
            }
            return e;
          }
        
          function dialog(cm, text, f) {
            if (cm.openDialog)
              cm.openDialog(text + ": <input type=text>", f);
            else
              f(prompt(text, ""));
          }
        
          // Tooltips
        
          function tempTooltip(cm, content) {
            var where = cm.cursorCoords();
            var tip = makeTooltip(where.right + 1, where.bottom, content);
            function clear() {
              if (!tip.parentNode) return;
              cm.off("cursorActivity", clear);
              fadeOut(tip);
            }
            setTimeout(clear, 1700);
            cm.on("cursorActivity", clear);
          }
        
          function makeTooltip(x, y, content) {
            var node = elt("div", cls + "tooltip", content);
            node.style.left = x + "px";
            node.style.top = y + "px";
            document.body.appendChild(node);
            return node;
          }
        
          function remove(node) {
            var p = node && node.parentNode;
            if (p) p.removeChild(node);
          }
        
          function fadeOut(tooltip) {
            tooltip.style.opacity = "0";
            setTimeout(function() { remove(tooltip); }, 1100);
          }
        
          function showError(ts, cm, msg) {
            if (ts.options.showError)
              ts.options.showError(cm, msg);
            else
              tempTooltip(cm, String(msg));
          }
        
          function closeArgHints(ts) {
            if (ts.activeArgHints) { remove(ts.activeArgHints); ts.activeArgHints = null; }
          }
        
          function docValue(ts, doc) {
            var val = doc.doc.getValue();
            if (ts.options.fileFilter) val = ts.options.fileFilter(val, doc.name, doc.doc);
            return val;
          }
        
          // Worker wrapper
        
          function WorkerServer(ts) {
            var worker = new Worker(ts.options.workerScript);
            worker.postMessage({type: "init",
                                defs: ts.options.defs,
                                plugins: ts.options.plugins,
                                scripts: ts.options.workerDeps});
            var msgId = 0, pending = {};
        
            function send(data, c) {
              if (c) {
                data.id = ++msgId;
                pending[msgId] = c;
              }
              worker.postMessage(data);
            }
            worker.onmessage = function(e) {
              var data = e.data;
              if (data.type == "getFile") {
                getFile(ts, data.name, function(err, text) {
                  send({type: "getFile", err: String(err), text: text, id: data.id});
                });
              } else if (data.type == "debug") {
                window.console.log(data.message);
              } else if (data.id && pending[data.id]) {
                pending[data.id](data.err, data.body);
                delete pending[data.id];
              }
            };
            worker.onerror = function(e) {
              for (var id in pending) pending[id](e);
              pending = {};
            };
        
            this.addFile = function(name, text) { send({type: "add", name: name, text: text}); };
            this.delFile = function(name) { send({type: "del", name: name}); };
            this.request = function(body, c) { send({type: "req", body: body}, c); };
          }
        });
        
      • xml-hint.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
          "use strict";
        
          var Pos = CodeMirror.Pos;
        
          function getHints(cm, options) {
            var tags = options && options.schemaInfo;
            var quote = (options && options.quoteChar) || '"';
            if (!tags) return;
            var cur = cm.getCursor(), token = cm.getTokenAt(cur);
            var inner = CodeMirror.innerMode(cm.getMode(), token.state);
            if (inner.mode.name != "xml") return;
            var result = [], replaceToken = false, prefix;
            var tag = /\btag\b/.test(token.type), tagName = tag && /^\w/.test(token.string), tagStart;
            if (tagName) {
              var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start);
              var tagType = /<\/$/.test(before) ? "close" : /<$/.test(before) ? "open" : null;
              if (tagType) tagStart = token.start - (tagType == "close" ? 2 : 1);
            } else if (tag && token.string == "<") {
              tagType = "open";
            } else if (tag && token.string == "</") {
              tagType = "close";
            }
            if (!tag && !inner.state.tagName || tagType) {
              if (tagName)
                prefix = token.string;
              replaceToken = tagType;
              var cx = inner.state.context, curTag = cx && tags[cx.tagName];
              var childList = cx ? curTag && curTag.children : tags["!top"];
              if (childList && tagType != "close") {
                for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0)
                  result.push("<" + childList[i]);
              } else if (tagType != "close") {
                for (var name in tags)
                  if (tags.hasOwnProperty(name) && name != "!top" && name != "!attrs" && (!prefix || name.lastIndexOf(prefix, 0) == 0))
                    result.push("<" + name);
              }
              if (cx && (!prefix || tagType == "close" && cx.tagName.lastIndexOf(prefix, 0) == 0))
                result.push("</" + cx.tagName + ">");
            } else {
              // Attribute completion
              var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs;
              var globalAttrs = tags["!attrs"];
              if (!attrs && !globalAttrs) return;
              if (!attrs) {
                attrs = globalAttrs;
              } else if (globalAttrs) { // Combine tag-local and global attributes
                var set = {};
                for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm];
                for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm];
                attrs = set;
              }
              if (token.type == "string" || token.string == "=") { // A value
                var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)),
                                         Pos(cur.line, token.type == "string" ? token.start : token.end));
                var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues;
                if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return;
                if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget
                if (token.type == "string") {
                  prefix = token.string;
                  var n = 0;
                  if (/['"]/.test(token.string.charAt(0))) {
                    quote = token.string.charAt(0);
                    prefix = token.string.slice(1);
                    n++;
                  }
                  var len = token.string.length;
                  if (/['"]/.test(token.string.charAt(len - 1))) {
                    quote = token.string.charAt(len - 1);
                    prefix = token.string.substr(n, len - 2);
                  }
                  replaceToken = true;
                }
                for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0)
                  result.push(quote + atValues[i] + quote);
              } else { // An attribute name
                if (token.type == "attribute") {
                  prefix = token.string;
                  replaceToken = true;
                }
                for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0))
                  result.push(attr);
              }
            }
            return {
              list: result,
              from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur,
              to: replaceToken ? Pos(cur.line, token.end) : cur
            };
          }
        
          CodeMirror.registerHelper("hint", "xml", getHints);
        });
        
      • xml.js
        // CodeMirror, copyright (c) by Marijn Haverbeke and others
        // Distributed under an MIT license: http://codemirror.net/LICENSE
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            mod(require("../../lib/codemirror"));
          else if (typeof define == "function" && define.amd) // AMD
            define(["../../lib/codemirror"], mod);
          else // Plain browser env
            mod(CodeMirror);
        })(function(CodeMirror) {
        "use strict";
        
        CodeMirror.defineMode("xml", function(config, parserConfig) {
          var indentUnit = config.indentUnit;
          var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
          var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag;
          if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true;
        
          var Kludges = parserConfig.htmlMode ? {
            autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
                              'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
                              'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
                              'track': true, 'wbr': true, 'menuitem': true},
            implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
                               'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
                               'th': true, 'tr': true},
            contextGrabbers: {
              'dd': {'dd': true, 'dt': true},
              'dt': {'dd': true, 'dt': true},
              'li': {'li': true},
              'option': {'option': true, 'optgroup': true},
              'optgroup': {'optgroup': true},
              'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
                    'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
                    'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
                    'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
                    'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
              'rp': {'rp': true, 'rt': true},
              'rt': {'rp': true, 'rt': true},
              'tbody': {'tbody': true, 'tfoot': true},
              'td': {'td': true, 'th': true},
              'tfoot': {'tbody': true},
              'th': {'td': true, 'th': true},
              'thead': {'tbody': true, 'tfoot': true},
              'tr': {'tr': true}
            },
            doNotIndent: {"pre": true},
            allowUnquoted: true,
            allowMissing: true,
            caseFold: true
          } : {
            autoSelfClosers: {},
            implicitlyClosed: {},
            contextGrabbers: {},
            doNotIndent: {},
            allowUnquoted: false,
            allowMissing: false,
            caseFold: false
          };
          var alignCDATA = parserConfig.alignCDATA;
        
          // Return variables for tokenizers
          var type, setStyle;
        
          function inText(stream, state) {
            function chain(parser) {
              state.tokenize = parser;
              return parser(stream, state);
            }
        
            var ch = stream.next();
            if (ch == "<") {
              if (stream.eat("!")) {
                if (stream.eat("[")) {
                  if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
                  else return null;
                } else if (stream.match("--")) {
                  return chain(inBlock("comment", "-->"));
                } else if (stream.match("DOCTYPE", true, true)) {
                  stream.eatWhile(/[\w\._\-]/);
                  return chain(doctype(1));
                } else {
                  return null;
                }
              } else if (stream.eat("?")) {
                stream.eatWhile(/[\w\._\-]/);
                state.tokenize = inBlock("meta", "?>");
                return "meta";
              } else {
                type = stream.eat("/") ? "closeTag" : "openTag";
                state.tokenize = inTag;
                return "tag bracket";
              }
            } else if (ch == "&") {
              var ok;
              if (stream.eat("#")) {
                if (stream.eat("x")) {
                  ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
                } else {
                  ok = stream.eatWhile(/[\d]/) && stream.eat(";");
                }
              } else {
                ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
              }
              return ok ? "atom" : "error";
            } else {
              stream.eatWhile(/[^&<]/);
              return null;
            }
          }
        
          function inTag(stream, state) {
            var ch = stream.next();
            if (ch == ">" || (ch == "/" && stream.eat(">"))) {
              state.tokenize = inText;
              type = ch == ">" ? "endTag" : "selfcloseTag";
              return "tag bracket";
            } else if (ch == "=") {
              type = "equals";
              return null;
            } else if (ch == "<") {
              state.tokenize = inText;
              state.state = baseState;
              state.tagName = state.tagStart = null;
              var next = state.tokenize(stream, state);
              return next ? next + " tag error" : "tag error";
            } else if (/[\'\"]/.test(ch)) {
              state.tokenize = inAttribute(ch);
              state.stringStartCol = stream.column();
              return state.tokenize(stream, state);
            } else {
              stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
              return "word";
            }
          }
        
          function inAttribute(quote) {
            var closure = function(stream, state) {
              while (!stream.eol()) {
                if (stream.next() == quote) {
                  state.tokenize = inTag;
                  break;
                }
              }
              return "string";
            };
            closure.isInAttribute = true;
            return closure;
          }
        
          function inBlock(style, terminator) {
            return function(stream, state) {
              while (!stream.eol()) {
                if (stream.match(terminator)) {
                  state.tokenize = inText;
                  break;
                }
                stream.next();
              }
              return style;
            };
          }
          function doctype(depth) {
            return function(stream, state) {
              var ch;
              while ((ch = stream.next()) != null) {
                if (ch == "<") {
                  state.tokenize = doctype(depth + 1);
                  return state.tokenize(stream, state);
                } else if (ch == ">") {
                  if (depth == 1) {
                    state.tokenize = inText;
                    break;
                  } else {
                    state.tokenize = doctype(depth - 1);
                    return state.tokenize(stream, state);
                  }
                }
              }
              return "meta";
            };
          }
        
          function Context(state, tagName, startOfLine) {
            this.prev = state.context;
            this.tagName = tagName;
            this.indent = state.indented;
            this.startOfLine = startOfLine;
            if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
              this.noIndent = true;
          }
          function popContext(state) {
            if (state.context) state.context = state.context.prev;
          }
          function maybePopContext(state, nextTagName) {
            var parentTagName;
            while (true) {
              if (!state.context) {
                return;
              }
              parentTagName = state.context.tagName;
              if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
                  !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
                return;
              }
              popContext(state);
            }
          }
        
          function baseState(type, stream, state) {
            if (type == "openTag") {
              state.tagStart = stream.column();
              return tagNameState;
            } else if (type == "closeTag") {
              return closeTagNameState;
            } else {
              return baseState;
            }
          }
          function tagNameState(type, stream, state) {
            if (type == "word") {
              state.tagName = stream.current();
              setStyle = "tag";
              return attrState;
            } else {
              setStyle = "error";
              return tagNameState;
            }
          }
          function closeTagNameState(type, stream, state) {
            if (type == "word") {
              var tagName = stream.current();
              if (state.context && state.context.tagName != tagName &&
                  Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName))
                popContext(state);
              if (state.context && state.context.tagName == tagName) {
                setStyle = "tag";
                return closeState;
              } else {
                setStyle = "tag error";
                return closeStateErr;
              }
            } else {
              setStyle = "error";
              return closeStateErr;
            }
          }
        
          function closeState(type, _stream, state) {
            if (type != "endTag") {
              setStyle = "error";
              return closeState;
            }
            popContext(state);
            return baseState;
          }
          function closeStateErr(type, stream, state) {
            setStyle = "error";
            return closeState(type, stream, state);
          }
        
          function attrState(type, _stream, state) {
            if (type == "word") {
              setStyle = "attribute";
              return attrEqState;
            } else if (type == "endTag" || type == "selfcloseTag") {
              var tagName = state.tagName, tagStart = state.tagStart;
              state.tagName = state.tagStart = null;
              if (type == "selfcloseTag" ||
                  Kludges.autoSelfClosers.hasOwnProperty(tagName)) {
                maybePopContext(state, tagName);
              } else {
                maybePopContext(state, tagName);
                state.context = new Context(state, tagName, tagStart == state.indented);
              }
              return baseState;
            }
            setStyle = "error";
            return attrState;
          }
          function attrEqState(type, stream, state) {
            if (type == "equals") return attrValueState;
            if (!Kludges.allowMissing) setStyle = "error";
            return attrState(type, stream, state);
          }
          function attrValueState(type, stream, state) {
            if (type == "string") return attrContinuedState;
            if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
            setStyle = "error";
            return attrState(type, stream, state);
          }
          function attrContinuedState(type, stream, state) {
            if (type == "string") return attrContinuedState;
            return attrState(type, stream, state);
          }
        
          return {
            startState: function() {
              return {tokenize: inText,
                      state: baseState,
                      indented: 0,
                      tagName: null, tagStart: null,
                      context: null};
            },
        
            token: function(stream, state) {
              if (!state.tagName && stream.sol())
                state.indented = stream.indentation();
        
              if (stream.eatSpace()) return null;
              type = null;
              var style = state.tokenize(stream, state);
              if ((style || type) && style != "comment") {
                setStyle = null;
                state.state = state.state(type || style, stream, state);
                if (setStyle)
                  style = setStyle == "error" ? style + " error" : setStyle;
              }
              return style;
            },
        
            indent: function(state, textAfter, fullLine) {
              var context = state.context;
              // Indent multi-line strings (e.g. css).
              if (state.tokenize.isInAttribute) {
                if (state.tagStart == state.indented)
                  return state.stringStartCol + 1;
                else
                  return state.indented + indentUnit;
              }
              if (context && context.noIndent) return CodeMirror.Pass;
              if (state.tokenize != inTag && state.tokenize != inText)
                return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
              // Indent the starts of attribute names.
              if (state.tagName) {
                if (multilineTagIndentPastTag)
                  return state.tagStart + state.tagName.length + 2;
                else
                  return state.tagStart + indentUnit * multilineTagIndentFactor;
              }
              if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
              var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
              if (tagAfter && tagAfter[1]) { // Closing tag spotted
                while (context) {
                  if (context.tagName == tagAfter[2]) {
                    context = context.prev;
                    break;
                  } else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) {
                    context = context.prev;
                  } else {
                    break;
                  }
                }
              } else if (tagAfter) { // Opening tag spotted
                while (context) {
                  var grabbers = Kludges.contextGrabbers[context.tagName];
                  if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
                    context = context.prev;
                  else
                    break;
                }
              }
              while (context && !context.startOfLine)
                context = context.prev;
              if (context) return context.indent + indentUnit;
              else return 0;
            },
        
            electricInput: /<\/[\s\w:]+>$/,
            blockCommentStart: "<!--",
            blockCommentEnd: "-->",
        
            configuration: parserConfig.htmlMode ? "html" : "xml",
            helperType: parserConfig.htmlMode ? "html" : "xml"
          };
        });
        
        CodeMirror.defineMIME("text/xml", "xml");
        CodeMirror.defineMIME("application/xml", "xml");
        if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
          CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
        
        });
        
    • knockout
      • knockout-3.2.0.js
        (function(){(function(p){var s=this||(0,eval)("this"),v=s.document,L=s.navigator,w=s.jQuery,D=s.JSON;(function(p){"function"===typeof require&&"object"===typeof exports&&"object"===typeof module?p(module.exports||exports,require):"function"===typeof define&&define.amd?define(["exports","require"],p):p(s.ko={})})(function(M,N){function H(a,d){return null===a||typeof a in R?a===d:!1}function S(a,d){var c;return function(){c||(c=setTimeout(function(){c=p;a()},d))}}function T(a,d){var c;return function(){clearTimeout(c);c=setTimeout(a,d)}}function I(b,d,c,e){a.d[b]={init:function(b,h,k,f,m){var l,q;a.s(function(){var f=a.a.c(h()),k=!c!==!f,z=!q;if(z||d||k!==l)z&&a.Y.la()&&(q=a.a.ia(a.f.childNodes(b),!0)),k?(z||a.f.T(b,a.a.ia(q)),a.Ca(e?e(m,f):m,b)):a.f.ja(b),l=k},null,{o:b});return{controlsDescendantBindings:!0}}};a.h.ha[b]=!1;a.f.Q[b]=!0}var a="undefined"!==typeof M?M:{};a.b=function(b,d){for(var c=b.split("."),e=a,g=0;g<c.length-1;g++)e=e[c[g]];e[c[c.length-1]]=d};a.A=function(a,d,c){a[d]=c};a.version="3.2.0";a.b("version",a.version);a.a=function(){function b(a,b){for(var c in a)a.hasOwnProperty(c)&&b(c,a[c])}function d(a,b){if(b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function c(a,b){a.__proto__=b;return a}var e={__proto__:[]}instanceof Array,g={},h={};g[L&&/Firefox\/2/i.test(L.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"];g.MouseEvents="click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave".split(" ");b(g,function(a,b){if(b.length)for(var c=0,d=b.length;c<d;c++)h[b[c]]=a});var k={propertychange:!0},f=v&&function(){for(var a=3,b=v.createElement("div"),c=b.getElementsByTagName("i");b.innerHTML="\x3c!--[if gt IE "+ ++a+"]><i></i><![endif]--\x3e",c[0];);return 4<a?a:p}();return{vb:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],u:function(a,b){for(var c=0,d=a.length;c<d;c++)b(a[c],c)},m:function(a,b){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(a,b);for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},qb:function(a,b,c){for(var d=0,f=a.length;d<f;d++)if(b.call(c,a[d],d))return a[d];return null},ua:function(m,b){var c=a.a.m(m,b);0<c?m.splice(c,1):0===c&&m.shift()},rb:function(m){m=m||[];for(var b=[],c=0,d=m.length;c<d;c++)0>a.a.m(b,m[c])&&b.push(m[c]);return b},Da:function(a,b){a=a||[];for(var c=[],d=0,f=a.length;d<f;d++)c.push(b(a[d],d));return c},ta:function(a,b){a=a||[];for(var c=[],d=0,f=a.length;d<f;d++)b(a[d],d)&&c.push(a[d]);return c},ga:function(a,b){if(b instanceof
        Array)a.push.apply(a,b);else for(var c=0,d=b.length;c<d;c++)a.push(b[c]);return a},ea:function(b,c,d){var f=a.a.m(a.a.Xa(b),c);0>f?d&&b.push(c):d||b.splice(f,1)},xa:e,extend:d,za:c,Aa:e?c:d,G:b,na:function(a,b){if(!a)return a;var c={},d;for(d in a)a.hasOwnProperty(d)&&(c[d]=b(a[d],d,a));return c},Ka:function(b){for(;b.firstChild;)a.removeNode(b.firstChild)},oc:function(b){b=a.a.S(b);for(var c=v.createElement("div"),d=0,f=b.length;d<f;d++)c.appendChild(a.R(b[d]));return c},ia:function(b,c){for(var d=0,f=b.length,e=[];d<f;d++){var k=b[d].cloneNode(!0);e.push(c?a.R(k):k)}return e},T:function(b,c){a.a.Ka(b);if(c)for(var d=0,f=c.length;d<f;d++)b.appendChild(c[d])},Lb:function(b,c){var d=b.nodeType?[b]:b;if(0<d.length){for(var f=d[0],e=f.parentNode,k=0,g=c.length;k<g;k++)e.insertBefore(c[k],f);k=0;for(g=d.length;k<g;k++)a.removeNode(d[k])}},ka:function(a,b){if(a.length){for(b=8===b.nodeType&&b.parentNode||b;a.length&&a[0].parentNode!==b;)a.shift();if(1<a.length){var c=a[0],d=a[a.length-1];for(a.length=0;c!==d;)if(a.push(c),c=c.nextSibling,!c)return;a.push(d)}}return a},Nb:function(a,b){7>f?a.setAttribute("selected",b):a.selected=b},cb:function(a){return null===a||a===p?"":a.trim?a.trim():a.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},vc:function(a,b){a=a||"";return b.length>a.length?!1:a.substring(0,b.length)===b},cc:function(a,b){if(a===b)return!0;if(11===a.nodeType)return!1;if(b.contains)return b.contains(3===a.nodeType?a.parentNode:a);if(b.compareDocumentPosition)return 16==(b.compareDocumentPosition(a)&16);for(;a&&a!=b;)a=a.parentNode;return!!a},Ja:function(b){return a.a.cc(b,b.ownerDocument.documentElement)},ob:function(b){return!!a.a.qb(b,a.a.Ja)},t:function(a){return a&&a.tagName&&a.tagName.toLowerCase()},n:function(b,c,d){var e=f&&k[c];if(!e&&w)w(b).bind(c,d);else if(e||"function"!=typeof b.addEventListener)if("undefined"!=typeof b.attachEvent){var g=function(a){d.call(b,a)},h="on"+c;b.attachEvent(h,g);a.a.w.da(b,function(){b.detachEvent(h,g)})}else throw Error("Browser doesn't support addEventListener or attachEvent");else b.addEventListener(c,d,!1)},oa:function(b,c){if(!b||!b.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var d;"input"===a.a.t(b)&&b.type&&"click"==c.toLowerCase()?(d=b.type,d="checkbox"==d||"radio"==d):d=!1;if(w&&!d)w(b).trigger(c);else if("function"==typeof v.createEvent)if("function"==typeof b.dispatchEvent)d=v.createEvent(h[c]||"HTMLEvents"),d.initEvent(c,!0,!0,s,0,0,0,0,0,!1,!1,!1,!1,0,b),b.dispatchEvent(d);else throw Error("The supplied element doesn't support dispatchEvent");else if(d&&b.click)b.click();else if("undefined"!=typeof b.fireEvent)b.fireEvent("on"+c);else throw Error("Browser doesn't support triggering events");},c:function(b){return a.C(b)?b():b},Xa:function(b){return a.C(b)?b.v():b},Ba:function(b,c,d){if(c){var f=/\S+/g,e=b.className.match(f)||[];a.a.u(c.match(f),function(b){a.a.ea(e,b,d)});b.className=e.join(" ")}},bb:function(b,c){var d=a.a.c(c);if(null===d||d===p)d="";var f=a.f.firstChild(b);!f||3!=f.nodeType||a.f.nextSibling(f)?a.f.T(b,[b.ownerDocument.createTextNode(d)]):f.data=d;a.a.fc(b)},Mb:function(a,b){a.name=b;if(7>=f)try{a.mergeAttributes(v.createElement("<input name='"+a.name+"'/>"),!1)}catch(c){}},fc:function(a){9<=f&&(a=1==a.nodeType?a:a.parentNode,a.style&&(a.style.zoom=a.style.zoom))},dc:function(a){if(f){var b=a.style.width;a.style.width=0;a.style.width=b}},sc:function(b,c){b=a.a.c(b);c=a.a.c(c);for(var d=[],f=b;f<=c;f++)d.push(f);return d},S:function(a){for(var b=[],c=0,d=a.length;c<d;c++)b.push(a[c]);return b},yc:6===f,zc:7===f,L:f,xb:function(b,c){for(var d=a.a.S(b.getElementsByTagName("input")).concat(a.a.S(b.getElementsByTagName("textarea"))),f="string"==typeof c?function(a){return a.name===c}:function(a){return c.test(a.name)},e=[],k=d.length-1;0<=k;k--)f(d[k])&&e.push(d[k]);return e},pc:function(b){return"string"==typeof b&&(b=a.a.cb(b))?D&&D.parse?D.parse(b):(new Function("return "+b))():null},eb:function(b,c,d){if(!D||!D.stringify)throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");return D.stringify(a.a.c(b),c,d)},qc:function(c,d,f){f=f||{};var e=f.params||{},k=f.includeFields||this.vb,g=c;if("object"==typeof c&&"form"===a.a.t(c))for(var g=c.action,h=k.length-1;0<=h;h--)for(var r=a.a.xb(c,k[h]),E=r.length-1;0<=E;E--)e[r[E].name]=r[E].value;d=a.a.c(d);var y=v.createElement("form");y.style.display="none";y.action=g;y.method="post";for(var p in d)c=v.createElement("input"),c.type="hidden",c.name=p,c.value=a.a.eb(a.a.c(d[p])),y.appendChild(c);b(e,function(a,b){var c=v.createElement("input");c.type="hidden";c.name=a;c.value=b;y.appendChild(c)});v.body.appendChild(y);f.submitter?f.submitter(y):y.submit();setTimeout(function(){y.parentNode.removeChild(y)},0)}}}();a.b("utils",a.a);a.b("utils.arrayForEach",a.a.u);a.b("utils.arrayFirst",a.a.qb);a.b("utils.arrayFilter",a.a.ta);a.b("utils.arrayGetDistinctValues",a.a.rb);a.b("utils.arrayIndexOf",a.a.m);a.b("utils.arrayMap",a.a.Da);a.b("utils.arrayPushAll",a.a.ga);a.b("utils.arrayRemoveItem",a.a.ua);a.b("utils.extend",a.a.extend);a.b("utils.fieldsIncludedWithJsonPost",a.a.vb);a.b("utils.getFormFields",a.a.xb);a.b("utils.peekObservable",a.a.Xa);a.b("utils.postJson",a.a.qc);a.b("utils.parseJson",a.a.pc);a.b("utils.registerEventHandler",a.a.n);a.b("utils.stringifyJson",a.a.eb);a.b("utils.range",a.a.sc);a.b("utils.toggleDomNodeCssClass",a.a.Ba);a.b("utils.triggerEvent",a.a.oa);a.b("utils.unwrapObservable",a.a.c);a.b("utils.objectForEach",a.a.G);a.b("utils.addOrRemoveItem",a.a.ea);a.b("unwrap",a.a.c);Function.prototype.bind||(Function.prototype.bind=function(a){var d=this,c=Array.prototype.slice.call(arguments);a=c.shift();return function(){return d.apply(a,c.concat(Array.prototype.slice.call(arguments)))}});a.a.e=new function(){function a(b,h){var k=b[c];if(!k||"null"===k||!e[k]){if(!h)return p;k=b[c]="ko"+d++;e[k]={}}return e[k]}var d=0,c="__ko__"+(new Date).getTime(),e={};return{get:function(c,d){var e=a(c,!1);return e===p?p:e[d]},set:function(c,d,e){if(e!==p||a(c,!1)!==p)a(c,!0)[d]=e},clear:function(a){var b=a[c];return b?(delete e[b],a[c]=null,!0):!1},F:function(){return d++ +c}}};a.b("utils.domData",a.a.e);a.b("utils.domData.clear",a.a.e.clear);a.a.w=new function(){function b(b,d){var f=a.a.e.get(b,c);f===p&&d&&(f=[],a.a.e.set(b,c,f));return f}function d(c){var e=b(c,!1);if(e)for(var e=e.slice(0),f=0;f<e.length;f++)e[f](c);a.a.e.clear(c);a.a.w.cleanExternalData(c);if(g[c.nodeType])for(e=c.firstChild;c=e;)e=c.nextSibling,8===c.nodeType&&d(c)}var c=a.a.e.F(),e={1:!0,8:!0,9:!0},g={1:!0,9:!0};return{da:function(a,c){if("function"!=typeof c)throw Error("Callback must be a function");b(a,!0).push(c)},Kb:function(d,e){var f=b(d,!1);f&&(a.a.ua(f,e),0==f.length&&a.a.e.set(d,c,p))},R:function(b){if(e[b.nodeType]&&(d(b),g[b.nodeType])){var c=[];a.a.ga(c,b.getElementsByTagName("*"));for(var f=0,m=c.length;f<m;f++)d(c[f])}return b},removeNode:function(b){a.R(b);b.parentNode&&b.parentNode.removeChild(b)},cleanExternalData:function(a){w&&"function"==typeof w.cleanData&&w.cleanData([a])}}};a.R=a.a.w.R;a.removeNode=a.a.w.removeNode;a.b("cleanNode",a.R);a.b("removeNode",a.removeNode);a.b("utils.domNodeDisposal",a.a.w);a.b("utils.domNodeDisposal.addDisposeCallback",a.a.w.da);a.b("utils.domNodeDisposal.removeDisposeCallback",a.a.w.Kb);(function(){a.a.ba=function(b){var d;if(w)if(w.parseHTML)d=w.parseHTML(b)||[];else{if((d=w.clean([b]))&&d[0]){for(b=d[0];b.parentNode&&11!==b.parentNode.nodeType;)b=b.parentNode;b.parentNode&&b.parentNode.removeChild(b)}}else{var c=a.a.cb(b).toLowerCase();d=v.createElement("div");c=c.match(/^<(thead|tbody|tfoot)/)&&[1,"<table>","</table>"]||!c.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!c.indexOf("<td")||!c.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||[0,"",""];b="ignored<div>"+c[1]+b+c[2]+"</div>";for("function"==typeof s.innerShiv?d.appendChild(s.innerShiv(b)):d.innerHTML=b;c[0]--;)d=d.lastChild;d=a.a.S(d.lastChild.childNodes)}return d};a.a.$a=function(b,d){a.a.Ka(b);d=a.a.c(d);if(null!==d&&d!==p)if("string"!=typeof d&&(d=d.toString()),w)w(b).html(d);else for(var c=a.a.ba(d),e=0;e<c.length;e++)b.appendChild(c[e])}})();a.b("utils.parseHtmlFragment",a.a.ba);a.b("utils.setHtml",a.a.$a);a.D=function(){function b(c,d){if(c)if(8==c.nodeType){var g=a.D.Gb(c.nodeValue);null!=g&&d.push({bc:c,mc:g})}else if(1==c.nodeType)for(var g=0,h=c.childNodes,k=h.length;g<k;g++)b(h[g],d)}var d={};return{Ua:function(a){if("function"!=typeof a)throw Error("You can only pass a function to ko.memoization.memoize()");var b=(4294967296*(1+Math.random())|0).toString(16).substring(1)+(4294967296*(1+Math.random())|0).toString(16).substring(1);d[b]=a;return"\x3c!--[ko_memo:"+b+"]--\x3e"},Rb:function(a,b){var g=d[a];if(g===p)throw Error("Couldn't find any memo with ID "+a+". Perhaps it's already been unmemoized.");try{return g.apply(null,b||[]),!0}finally{delete d[a]}},Sb:function(c,d){var g=[];b(c,g);for(var h=0,k=g.length;h<k;h++){var f=g[h].bc,m=[f];d&&a.a.ga(m,d);a.D.Rb(g[h].mc,m);f.nodeValue="";f.parentNode&&f.parentNode.removeChild(f)}},Gb:function(a){return(a=a.match(/^\[ko_memo\:(.*?)\]$/))?a[1]:null}}}();a.b("memoization",a.D);a.b("memoization.memoize",a.D.Ua);a.b("memoization.unmemoize",a.D.Rb);a.b("memoization.parseMemoText",a.D.Gb);a.b("memoization.unmemoizeDomNodeAndDescendants",a.D.Sb);a.La={throttle:function(b,d){b.throttleEvaluation=d;var c=null;return a.j({read:b,write:function(a){clearTimeout(c);c=setTimeout(function(){b(a)},d)}})},rateLimit:function(a,d){var c,e,g;"number"==typeof d?c=d:(c=d.timeout,e=d.method);g="notifyWhenChangesStop"==e?T:S;a.Ta(function(a){return g(a,c)})},notify:function(a,d){a.equalityComparer="always"==d?null:H}};var R={undefined:1,"boolean":1,number:1,string:1};a.b("extenders",a.La);a.Pb=function(b,d,c){this.target=b;this.wa=d;this.ac=c;this.Cb=!1;a.A(this,"dispose",this.K)};a.Pb.prototype.K=function(){this.Cb=!0;this.ac()};a.P=function(){a.a.Aa(this,a.P.fn);this.M={}};var G="change",A={U:function(b,d,c){var e=this;c=c||G;var g=new a.Pb(e,d?b.bind(d):b,function(){a.a.ua(e.M[c],g);e.nb&&e.nb()});e.va&&e.va(c);e.M[c]||(e.M[c]=[]);e.M[c].push(g);return g},notifySubscribers:function(b,d){d=d||G;if(this.Ab(d))try{a.k.Ea();for(var c=this.M[d].slice(0),e=0,g;g=c[e];++e)g.Cb||g.wa(b)}finally{a.k.end()}},Ta:function(b){var d=this,c=a.C(d),e,g,h;d.qa||(d.qa=d.notifySubscribers,d.notifySubscribers=function(a,b){b&&b!==G?"beforeChange"===b?d.kb(a):d.qa(a,b):d.lb(a)});var k=b(function(){c&&h===d&&(h=d());e=!1;d.Pa(g,h)&&d.qa(g=h)});d.lb=function(a){e=!0;h=a;k()};d.kb=function(a){e||(g=a,d.qa(a,"beforeChange"))}},Ab:function(a){return this.M[a]&&this.M[a].length},yb:function(){var b=0;a.a.G(this.M,function(a,c){b+=c.length});return b},Pa:function(a,d){return!this.equalityComparer||!this.equalityComparer(a,d)},extend:function(b){var d=this;b&&a.a.G(b,function(b,e){var g=a.La[b];"function"==typeof g&&(d=g(d,e)||d)});return d}};a.A(A,"subscribe",A.U);a.A(A,"extend",A.extend);a.A(A,"getSubscriptionsCount",A.yb);a.a.xa&&a.a.za(A,Function.prototype);a.P.fn=A;a.Db=function(a){return null!=a&&"function"==typeof a.U&&"function"==typeof a.notifySubscribers};a.b("subscribable",a.P);a.b("isSubscribable",a.Db);a.Y=a.k=function(){function b(a){c.push(e);e=a}function d(){e=c.pop()}var c=[],e,g=0;return{Ea:b,end:d,Jb:function(b){if(e){if(!a.Db(b))throw Error("Only subscribable things can act as dependencies");e.wa(b,b.Vb||(b.Vb=++g))}},B:function(a,c,f){try{return b(),a.apply(c,f||[])}finally{d()}},la:function(){if(e)return e.s.la()},ma:function(){if(e)return e.ma}}}();a.b("computedContext",a.Y);a.b("computedContext.getDependenciesCount",a.Y.la);a.b("computedContext.isInitial",a.Y.ma);a.b("computedContext.isSleeping",a.Y.Ac);a.p=function(b){function d(){if(0<arguments.length)return d.Pa(c,arguments[0])&&(d.X(),c=arguments[0],d.W()),this;a.k.Jb(d);return c}var c=b;a.P.call(d);a.a.Aa(d,a.p.fn);d.v=function(){return c};d.W=function(){d.notifySubscribers(c)};d.X=function(){d.notifySubscribers(c,"beforeChange")};a.A(d,"peek",d.v);a.A(d,"valueHasMutated",d.W);a.A(d,"valueWillMutate",d.X);return d};a.p.fn={equalityComparer:H};var F=a.p.rc="__ko_proto__";a.p.fn[F]=a.p;a.a.xa&&a.a.za(a.p.fn,a.P.fn);a.Ma=function(b,d){return null===b||b===p||b[F]===p?!1:b[F]===d?!0:a.Ma(b[F],d)};a.C=function(b){return a.Ma(b,a.p)};a.Ra=function(b){return"function"==typeof b&&b[F]===a.p||"function"==typeof b&&b[F]===a.j&&b.hc?!0:!1};a.b("observable",a.p);a.b("isObservable",a.C);a.b("isWriteableObservable",a.Ra);a.b("isWritableObservable",a.Ra);a.aa=function(b){b=b||[];if("object"!=typeof b||!("length"in b))throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");b=a.p(b);a.a.Aa(b,a.aa.fn);return b.extend({trackArrayChanges:!0})};a.aa.fn={remove:function(b){for(var d=this.v(),c=[],e="function"!=typeof b||a.C(b)?function(a){return a===b}:b,g=0;g<d.length;g++){var h=d[g];e(h)&&(0===c.length&&this.X(),c.push(h),d.splice(g,1),g--)}c.length&&this.W();return c},removeAll:function(b){if(b===p){var d=this.v(),c=d.slice(0);this.X();d.splice(0,d.length);this.W();return c}return b?this.remove(function(c){return 0<=a.a.m(b,c)}):[]},destroy:function(b){var d=this.v(),c="function"!=typeof b||a.C(b)?function(a){return a===b}:b;this.X();for(var e=d.length-1;0<=e;e--)c(d[e])&&(d[e]._destroy=!0);this.W()},destroyAll:function(b){return b===p?this.destroy(function(){return!0}):b?this.destroy(function(d){return 0<=a.a.m(b,d)}):[]},indexOf:function(b){var d=this();return a.a.m(d,b)},replace:function(a,d){var c=this.indexOf(a);0<=c&&(this.X(),this.v()[c]=d,this.W())}};a.a.u("pop push reverse shift sort splice unshift".split(" "),function(b){a.aa.fn[b]=function(){var a=this.v();this.X();this.sb(a,b,arguments);a=a[b].apply(a,arguments);this.W();return a}});a.a.u(["slice"],function(b){a.aa.fn[b]=function(){var a=this();return a[b].apply(a,arguments)}});a.a.xa&&a.a.za(a.aa.fn,a.p.fn);a.b("observableArray",a.aa);var J="arrayChange";a.La.trackArrayChanges=function(b){function d(){if(!c){c=!0;var d=b.notifySubscribers;b.notifySubscribers=function(a,b){b&&b!==G||++g;return d.apply(this,arguments)};var f=[].concat(b.v()||[]);e=null;b.U(function(c){c=[].concat(c||[]);if(b.Ab(J)){var d;if(!e||1<g)e=a.a.Fa(f,c,{sparse:!0});d=e;d.length&&b.notifySubscribers(d,J)}f=c;e=null;g=0})}}if(!b.sb){var c=!1,e=null,g=0,h=b.U;b.U=b.subscribe=function(a,b,c){c===J&&d();return h.apply(this,arguments)};b.sb=function(b,d,m){function l(a,b,c){return q[q.length]={status:a,value:b,index:c}}if(c&&!g){var q=[],h=b.length,t=m.length,z=0;switch(d){case"push":z=h;case"unshift":for(d=0;d<t;d++)l("added",m[d],z+d);break;case"pop":z=h-1;case"shift":h&&l("deleted",b[z],z);break;case"splice":d=Math.min(Math.max(0,0>m[0]?h+m[0]:m[0]),h);for(var h=1===t?h:Math.min(d+(m[1]||0),h),t=d+t-2,z=Math.max(h,t),u=[],r=[],E=2;d<z;++d,++E)d<h&&r.push(l("deleted",b[d],d)),d<t&&u.push(l("added",m[E],d));a.a.wb(r,u);break;default:return}e=q}}}};a.s=a.j=function(b,d,c){function e(){a.a.G(v,function(a,b){b.K()});v={}}function g(){e();C=0;u=!0;n=!1}function h(){var a=f.throttleEvaluation;a&&0<=a?(clearTimeout(P),P=setTimeout(k,a)):f.ib?f.ib():k()}function k(b){if(t){if(E)throw Error("A 'pure' computed must not be called recursively");}else if(!u){if(w&&w()){if(!z){s();return}}else z=!1;t=!0;if(y)try{var c={};a.k.Ea({wa:function(a,b){c[b]||(c[b]=1,++C)},s:f,ma:p});C=0;q=r.call(d)}finally{a.k.end(),t=!1}else try{var e=v,m=C;a.k.Ea({wa:function(a,b){u||(m&&e[b]?(v[b]=e[b],++C,delete e[b],--m):v[b]||(v[b]=a.U(h),++C))},s:f,ma:E?p:!C});v={};C=0;try{var l=d?r.call(d):r()}finally{a.k.end(),m&&a.a.G(e,function(a,b){b.K()}),n=!1}f.Pa(q,l)&&(f.notifySubscribers(q,"beforeChange"),q=l,!0!==b&&f.notifySubscribers(q))}finally{t=!1}C||s()}}function f(){if(0<arguments.length){if("function"===typeof O)O.apply(d,arguments);else throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");return this}a.k.Jb(f);n&&k(!0);return q}function m(){n&&!C&&k(!0);return q}function l(){return n||0<C}var q,n=!0,t=!1,z=!1,u=!1,r=b,E=!1,y=!1;r&&"object"==typeof r?(c=r,r=c.read):(c=c||{},r||(r=c.read));if("function"!=typeof r)throw Error("Pass a function that returns the value of the ko.computed");var O=c.write,x=c.disposeWhenNodeIsRemoved||c.o||null,B=c.disposeWhen||c.Ia,w=B,s=g,v={},C=0,P=null;d||(d=c.owner);a.P.call(f);a.a.Aa(f,a.j.fn);f.v=m;f.la=function(){return C};f.hc="function"===typeof c.write;f.K=function(){s()};f.Z=l;var A=f.Ta;f.Ta=function(a){A.call(f,a);f.ib=function(){f.kb(q);n=!0;f.lb(f)}};c.pure?(y=E=!0,f.va=function(){y&&(y=!1,k(!0))},f.nb=function(){f.yb()||(e(),y=n=!0)}):c.deferEvaluation&&(f.va=function(){m();delete f.va});a.A(f,"peek",f.v);a.A(f,"dispose",f.K);a.A(f,"isActive",f.Z);a.A(f,"getDependenciesCount",f.la);x&&(z=!0,x.nodeType&&(w=function(){return!a.a.Ja(x)||B&&B()}));y||c.deferEvaluation||k();x&&l()&&x.nodeType&&(s=function(){a.a.w.Kb(x,s);g()},a.a.w.da(x,s));return f};a.jc=function(b){return a.Ma(b,a.j)};A=a.p.rc;a.j[A]=a.p;a.j.fn={equalityComparer:H};a.j.fn[A]=a.j;a.a.xa&&a.a.za(a.j.fn,a.P.fn);a.b("dependentObservable",a.j);a.b("computed",a.j);a.b("isComputed",a.jc);a.Ib=function(b,d){if("function"===typeof b)return a.s(b,d,{pure:!0});b=a.a.extend({},b);b.pure=!0;return a.s(b,d)};a.b("pureComputed",a.Ib);(function(){function b(a,g,h){h=h||new c;a=g(a);if("object"!=typeof a||null===a||a===p||a instanceof Date||a instanceof String||a instanceof Number||a instanceof Boolean)return a;var k=a instanceof Array?[]:{};h.save(a,k);d(a,function(c){var d=g(a[c]);switch(typeof d){case"boolean":case"number":case"string":case"function":k[c]=d;break;case"object":case"undefined":var l=h.get(d);k[c]=l!==p?l:b(d,g,h)}});return k}function d(a,b){if(a instanceof Array){for(var c=0;c<a.length;c++)b(c);"function"==typeof a.toJSON&&b("toJSON")}else for(c in a)b(c)}function c(){this.keys=[];this.hb=[]}a.Qb=function(c){if(0==arguments.length)throw Error("When calling ko.toJS, pass the object you want to convert.");return b(c,function(b){for(var c=0;a.C(b)&&10>c;c++)b=b();return b})};a.toJSON=function(b,c,d){b=a.Qb(b);return a.a.eb(b,c,d)};c.prototype={save:function(b,c){var d=a.a.m(this.keys,b);0<=d?this.hb[d]=c:(this.keys.push(b),this.hb.push(c))},get:function(b){b=a.a.m(this.keys,b);return 0<=b?this.hb[b]:p}}})();a.b("toJS",a.Qb);a.b("toJSON",a.toJSON);(function(){a.i={q:function(b){switch(a.a.t(b)){case"option":return!0===b.__ko__hasDomDataOptionValue__?a.a.e.get(b,a.d.options.Va):7>=a.a.L?b.getAttributeNode("value")&&b.getAttributeNode("value").specified?b.value:b.text:b.value;case"select":return 0<=b.selectedIndex?a.i.q(b.options[b.selectedIndex]):p;default:return b.value}},ca:function(b,d,c){switch(a.a.t(b)){case"option":switch(typeof d){case"string":a.a.e.set(b,a.d.options.Va,p);"__ko__hasDomDataOptionValue__"in
        b&&delete b.__ko__hasDomDataOptionValue__;b.value=d;break;default:a.a.e.set(b,a.d.options.Va,d),b.__ko__hasDomDataOptionValue__=!0,b.value="number"===typeof d?d:""}break;case"select":if(""===d||null===d)d=p;for(var e=-1,g=0,h=b.options.length,k;g<h;++g)if(k=a.i.q(b.options[g]),k==d||""==k&&d===p){e=g;break}if(c||0<=e||d===p&&1<b.size)b.selectedIndex=e;break;default:if(null===d||d===p)d="";b.value=d}}}})();a.b("selectExtensions",a.i);a.b("selectExtensions.readValue",a.i.q);a.b("selectExtensions.writeValue",a.i.ca);a.h=function(){function b(b){b=a.a.cb(b);123===b.charCodeAt(0)&&(b=b.slice(1,-1));var c=[],d=b.match(e),k,n,t=0;if(d){d.push(",");for(var z=0,u;u=d[z];++z){var r=u.charCodeAt(0);if(44===r){if(0>=t){k&&c.push(n?{key:k,value:n.join("")}:{unknown:k});k=n=t=0;continue}}else if(58===r){if(!n)continue}else if(47===r&&z&&1<u.length)(r=d[z-1].match(g))&&!h[r[0]]&&(b=b.substr(b.indexOf(u)+1),d=b.match(e),d.push(","),z=-1,u="/");else if(40===r||123===r||91===r)++t;else if(41===r||125===r||93===r)--t;else if(!k&&!n){k=34===r||39===r?u.slice(1,-1):u;continue}n?n.push(u):n=[u]}}return c}var d=["true","false","null","undefined"],c=/^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i,e=RegExp("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|/(?:[^/\\\\]|\\\\.)*/w*|[^\\s:,/][^,\"'{}()/:[\\]]*[^\\s,\"'{}()/:[\\]]|[^\\s]","g"),g=/[\])"'A-Za-z0-9_$]+$/,h={"in":1,"return":1,"typeof":1},k={};return{ha:[],V:k,Wa:b,ya:function(f,m){function e(b,m){var f;if(!z){var u=a.getBindingHandler(b);if(u&&u.preprocess&&!(m=u.preprocess(m,b,e)))return;if(u=k[b])f=m,0<=a.a.m(d,f)?f=!1:(u=f.match(c),f=null===u?!1:u[1]?"Object("+u[1]+")"+u[2]:f),u=f;u&&h.push("'"+b+"':function(_z){"+f+"=_z}")}t&&(m="function(){return "+m+" }");g.push("'"+b+"':"+m)}m=m||{};var g=[],h=[],t=m.valueAccessors,z=m.bindingParams,u="string"===typeof f?b(f):f;a.a.u(u,function(a){e(a.key||a.unknown,a.value)});h.length&&e("_ko_property_writers","{"+h.join(",")+" }");return g.join(",")},lc:function(a,b){for(var c=0;c<a.length;c++)if(a[c].key==b)return!0;return!1},pa:function(b,c,d,e,k){if(b&&a.C(b))!a.Ra(b)||k&&b.v()===e||b(e);else if((b=c.get("_ko_property_writers"))&&b[d])b[d](e)}}}();a.b("expressionRewriting",a.h);a.b("expressionRewriting.bindingRewriteValidators",a.h.ha);a.b("expressionRewriting.parseObjectLiteral",a.h.Wa);a.b("expressionRewriting.preProcessBindings",a.h.ya);a.b("expressionRewriting._twoWayBindings",a.h.V);a.b("jsonExpressionRewriting",a.h);a.b("jsonExpressionRewriting.insertPropertyAccessorsIntoJson",a.h.ya);(function(){function b(a){return 8==a.nodeType&&h.test(g?a.text:a.nodeValue)}function d(a){return 8==a.nodeType&&k.test(g?a.text:a.nodeValue)}function c(a,c){for(var f=a,e=1,k=[];f=f.nextSibling;){if(d(f)&&(e--,0===e))return k;k.push(f);b(f)&&e++}if(!c)throw Error("Cannot find closing comment tag to match: "+a.nodeValue);return null}function e(a,b){var d=c(a,b);return d?0<d.length?d[d.length-1].nextSibling:a.nextSibling:null}var g=v&&"\x3c!--test--\x3e"===v.createComment("test").text,h=g?/^\x3c!--\s*ko(?:\s+([\s\S]+))?\s*--\x3e$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,k=g?/^\x3c!--\s*\/ko\s*--\x3e$/:/^\s*\/ko\s*$/,f={ul:!0,ol:!0};a.f={Q:{},childNodes:function(a){return b(a)?c(a):a.childNodes},ja:function(c){if(b(c)){c=a.f.childNodes(c);for(var d=0,f=c.length;d<f;d++)a.removeNode(c[d])}else a.a.Ka(c)},T:function(c,d){if(b(c)){a.f.ja(c);for(var f=c.nextSibling,e=0,k=d.length;e<k;e++)f.parentNode.insertBefore(d[e],f)}else a.a.T(c,d)},Hb:function(a,c){b(a)?a.parentNode.insertBefore(c,a.nextSibling):a.firstChild?a.insertBefore(c,a.firstChild):a.appendChild(c)},Bb:function(c,d,f){f?b(c)?c.parentNode.insertBefore(d,f.nextSibling):f.nextSibling?c.insertBefore(d,f.nextSibling):c.appendChild(d):a.f.Hb(c,d)},firstChild:function(a){return b(a)?!a.nextSibling||d(a.nextSibling)?null:a.nextSibling:a.firstChild},nextSibling:function(a){b(a)&&(a=e(a));return a.nextSibling&&d(a.nextSibling)?null:a.nextSibling},gc:b,xc:function(a){return(a=(g?a.text:a.nodeValue).match(h))?a[1]:null},Fb:function(c){if(f[a.a.t(c)]){var k=c.firstChild;if(k){do if(1===k.nodeType){var g;g=k.firstChild;var h=null;if(g){do if(h)h.push(g);else if(b(g)){var t=e(g,!0);t?g=t:h=[g]}else d(g)&&(h=[g]);while(g=g.nextSibling)}if(g=h)for(h=k.nextSibling,t=0;t<g.length;t++)h?c.insertBefore(g[t],h):c.appendChild(g[t])}while(k=k.nextSibling)}}}}})();a.b("virtualElements",a.f);a.b("virtualElements.allowedBindings",a.f.Q);a.b("virtualElements.emptyNode",a.f.ja);a.b("virtualElements.insertAfter",a.f.Bb);a.b("virtualElements.prepend",a.f.Hb);a.b("virtualElements.setDomNodeChildren",a.f.T);(function(){a.J=function(){this.Yb={}};a.a.extend(a.J.prototype,{nodeHasBindings:function(b){switch(b.nodeType){case 1:return null!=b.getAttribute("data-bind")||a.g.getComponentNameForNode(b);case 8:return a.f.gc(b);default:return!1}},getBindings:function(b,d){var c=this.getBindingsString(b,d),c=c?this.parseBindingsString(c,d,b):null;return a.g.mb(c,b,d,!1)},getBindingAccessors:function(b,d){var c=this.getBindingsString(b,d),c=c?this.parseBindingsString(c,d,b,{valueAccessors:!0}):null;return a.g.mb(c,b,d,!0)},getBindingsString:function(b){switch(b.nodeType){case 1:return b.getAttribute("data-bind");case 8:return a.f.xc(b);default:return null}},parseBindingsString:function(b,d,c,e){try{var g=this.Yb,h=b+(e&&e.valueAccessors||""),k;if(!(k=g[h])){var f,m="with($context){with($data||{}){return{"+a.h.ya(b,e)+"}}}";f=new Function("$context","$element",m);k=g[h]=f}return k(d,c)}catch(l){throw l.message="Unable to parse bindings.\nBindings value: "+b+"\nMessage: "+l.message,l;}}});a.J.instance=new a.J})();a.b("bindingProvider",a.J);(function(){function b(a){return function(){return a}}function d(a){return a()}
        function c(b){return a.a.na(a.k.B(b),function(a,c){return function(){return b()[c]}})}function e(a,b){return c(this.getBindings.bind(this,a,b))}function g(b,c,d){var f,e=a.f.firstChild(c),k=a.J.instance,g=k.preprocessNode;if(g){for(;f=e;)e=a.f.nextSibling(f),g.call(k,f);e=a.f.firstChild(c)}for(;f=e;)e=a.f.nextSibling(f),h(b,f,d)}function h(b,c,d){var e=!0,k=1===c.nodeType;k&&a.f.Fb(c);if(k&&d||a.J.instance.nodeHasBindings(c))e=f(c,null,b,d).shouldBindDescendants;e&&!l[a.a.t(c)]&&g(b,c,!k)}function k(b){var c=[],d={},f=[];a.a.G(b,function y(e){if(!d[e]){var k=a.getBindingHandler(e);k&&(k.after&&(f.push(e),a.a.u(k.after,function(c){if(b[c]){if(-1!==a.a.m(f,c))throw Error("Cannot combine the following bindings, because they have a cyclic dependency: "+f.join(", "));y(c)}}),f.length--),c.push({key:e,zb:k}));d[e]=!0}});return c}function f(b,c,f,g){var m=a.a.e.get(b,q);if(!c){if(m)throw Error("You cannot apply bindings multiple times to the same element.");a.a.e.set(b,q,!0)}!m&&g&&a.Ob(b,f);var l;if(c&&"function"!==typeof c)l=c;else{var h=a.J.instance,n=h.getBindingAccessors||e,s=a.j(function(){(l=c?c(f,b):n.call(h,b,f))&&f.I&&f.I();return l},null,{o:b});l&&s.Z()||(s=null)}var v;if(l){var w=s?function(a){return function(){return d(s()[a])}}:function(a){return l[a]},A=function(){return a.a.na(s?s():l,d)};A.get=function(a){return l[a]&&d(w(a))};A.has=function(a){return a in l};g=k(l);a.a.u(g,function(c){var d=c.zb.init,e=c.zb.update,k=c.key;if(8===b.nodeType&&!a.f.Q[k])throw Error("The binding '"+k+"' cannot be used with virtual elements");try{"function"==typeof d&&a.k.B(function(){var a=d(b,w(k),A,f.$data,f);if(a&&a.controlsDescendantBindings){if(v!==p)throw Error("Multiple bindings ("+v+" and "+k+") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.");v=k}}),"function"==typeof e&&a.j(function(){e(b,w(k),A,f.$data,f)},null,{o:b})}catch(g){throw g.message='Unable to process binding "'+k+": "+l[k]+'"\nMessage: '+g.message,g;}})}return{shouldBindDescendants:v===p}}
        function m(b){return b&&b instanceof a.N?b:new a.N(b)}a.d={};var l={script:!0};a.getBindingHandler=function(b){return a.d[b]};a.N=function(b,c,d,f){var e=this,k="function"==typeof b&&!a.C(b),g,m=a.j(function(){var g=k?b():b,l=a.a.c(g);c?(c.I&&c.I(),a.a.extend(e,c),m&&(e.I=m)):(e.$parents=[],e.$root=l,e.ko=a);e.$rawData=g;e.$data=l;d&&(e[d]=l);f&&f(e,c,l);return e.$data},null,{Ia:function(){return g&&!a.a.ob(g)},o:!0});m.Z()&&(e.I=m,m.equalityComparer=null,g=[],m.Tb=function(b){g.push(b);a.a.w.da(b,function(b){a.a.ua(g,b);g.length||(m.K(),e.I=m=p)})})};a.N.prototype.createChildContext=function(b,c,d){return new a.N(b,this,c,function(a,b){a.$parentContext=b;a.$parent=b.$data;a.$parents=(b.$parents||[]).slice(0);a.$parents.unshift(a.$parent);d&&d(a)})};a.N.prototype.extend=function(b){return new a.N(this.I||this.$data,this,null,function(c,d){c.$rawData=d.$rawData;a.a.extend(c,"function"==typeof b?b():b)})};var q=a.a.e.F(),n=a.a.e.F();a.Ob=function(b,c){if(2==arguments.length)a.a.e.set(b,n,c),c.I&&c.I.Tb(b);else return a.a.e.get(b,n)};a.ra=function(b,c,d){1===b.nodeType&&a.f.Fb(b);return f(b,c,m(d),!0)};a.Wb=function(d,f,e){e=m(e);return a.ra(d,"function"===typeof f?c(f.bind(null,e,d)):a.a.na(f,b),e)};a.Ca=function(a,b){1!==b.nodeType&&8!==b.nodeType||g(m(a),b,!0)};a.pb=function(a,b){!w&&s.jQuery&&(w=s.jQuery);if(b&&1!==b.nodeType&&8!==b.nodeType)throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");b=b||s.document.body;h(m(a),b,!0)};a.Ha=function(b){switch(b.nodeType){case 1:case 8:var c=a.Ob(b);if(c)return c;if(b.parentNode)return a.Ha(b.parentNode)}return p};a.$b=function(b){return(b=a.Ha(b))?b.$data:p};a.b("bindingHandlers",a.d);a.b("applyBindings",a.pb);a.b("applyBindingsToDescendants",a.Ca);a.b("applyBindingAccessorsToNode",a.ra);a.b("applyBindingsToNode",a.Wb);a.b("contextFor",a.Ha);a.b("dataFor",a.$b)})();(function(b){function d(d,f){var e=g.hasOwnProperty(d)?g[d]:b,l;e||(e=g[d]=new a.P,c(d,function(a){h[d]=a;delete g[d];l?e.notifySubscribers(a):setTimeout(function(){e.notifySubscribers(a)},0)}),l=!0);e.U(f)}function c(a,b){e("getConfig",[a],function(c){c?e("loadComponent",[a,c],function(a){b(a)}):b(null)})}function e(c,d,g,l){l||(l=a.g.loaders.slice(0));var h=l.shift();if(h){var n=h[c];if(n){var t=!1;if(n.apply(h,d.concat(function(a){t?g(null):null!==a?g(a):e(c,d,g,l)}))!==b&&(t=!0,!h.suppressLoaderExceptions))throw Error("Component loaders must supply values by invoking the callback, not by returning values synchronously.");}else e(c,d,g,l)}else g(null)}var g={},h={};a.g={get:function(a,c){var e=h.hasOwnProperty(a)?h[a]:b;e?setTimeout(function(){c(e)},0):d(a,c)},tb:function(a){delete h[a]},jb:e};a.g.loaders=[];a.b("components",a.g);a.b("components.get",a.g.get);a.b("components.clearCachedDefinition",a.g.tb)})();(function(){function b(b,c,d,e){function k(){0===--u&&e(h)}var h={},u=2,r=d.template;d=d.viewModel;r?g(c,r,function(c){a.g.jb("loadTemplate",[b,c],function(a){h.template=a;k()})}):k();d?g(c,d,function(c){a.g.jb("loadViewModel",[b,c],function(a){h[f]=a;k()})}):k()}function d(a,b,c){if("function"===typeof b)c(function(a){return new b(a)});else if("function"===typeof b[f])c(b[f]);else if("instance"in b){var e=b.instance;c(function(){return e})}else"viewModel"in b?d(a,b.viewModel,c):a("Unknown viewModel value: "+b)}function c(b){switch(a.a.t(b)){case"script":return a.a.ba(b.text);case"textarea":return a.a.ba(b.value);case"template":if(e(b.content))return a.a.ia(b.content.childNodes)}return a.a.ia(b.childNodes)}function e(a){return s.DocumentFragment?a instanceof DocumentFragment:a&&11===a.nodeType}function g(a,b,c){"string"===typeof b.require?N||s.require?(N||s.require)([b.require],c):a("Uses require, but no AMD loader is present"):c(b)}function h(a){return function(b){throw Error("Component '"+a+"': "+b);}}var k={};a.g.tc=function(b,c){if(!c)throw Error("Invalid configuration for "+b);if(a.g.Qa(b))throw Error("Component "+b+" is already registered");k[b]=c};a.g.Qa=function(a){return a in k};a.g.wc=function(b){delete k[b];a.g.tb(b)};a.g.ub={getConfig:function(a,b){b(k.hasOwnProperty(a)?k[a]:null)},loadComponent:function(a,c,d){var e=h(a);g(e,c,function(c){b(a,e,c,d)})},loadTemplate:function(b,d,f){b=h(b);if("string"===typeof d)f(a.a.ba(d));else if(d instanceof Array)f(d);else if(e(d))f(a.a.S(d.childNodes));else if(d.element)if(d=d.element,s.HTMLElement?d instanceof HTMLElement:d&&d.tagName&&1===d.nodeType)f(c(d));else if("string"===typeof d){var k=v.getElementById(d);k?f(c(k)):b("Cannot find element with ID "+d)}else b("Unknown element type: "+d);else b("Unknown template value: "+d)},loadViewModel:function(a,b,c){d(h(a),b,c)}};var f="createViewModel";a.b("components.register",a.g.tc);a.b("components.isRegistered",a.g.Qa);a.b("components.unregister",a.g.wc);a.b("components.defaultLoader",a.g.ub);a.g.loaders.push(a.g.ub);a.g.Ub=k})();(function(){function b(b,e){var g=b.getAttribute("params");if(g){var g=d.parseBindingsString(g,e,b,{valueAccessors:!0,bindingParams:!0}),g=a.a.na(g,function(d){return a.s(d,null,{o:b})}),h=a.a.na(g,function(d){return d.Z()?a.s(function(){return a.a.c(d())},null,{o:b}):d.v()});h.hasOwnProperty("$raw")||(h.$raw=g);return h}return{$raw:{}}}a.g.getComponentNameForNode=function(b){b=a.a.t(b);return a.g.Qa(b)&&b};a.g.mb=function(c,d,g,h){if(1===d.nodeType){var k=a.g.getComponentNameForNode(d);if(k){c=c||{};if(c.component)throw Error('Cannot use the "component" binding on a custom element matching a component');var f={name:k,params:b(d,g)};c.component=h?function(){return f}:f}}return c};var d=new a.J;9>a.a.L&&(a.g.register=function(a){return function(b){v.createElement(b);return a.apply(this,arguments)}}(a.g.register),v.createDocumentFragment=function(b){return function(){var d=b(),g=a.g.Ub,h;for(h in g)g.hasOwnProperty(h)&&d.createElement(h);return d}}(v.createDocumentFragment))})();(function(){var b=0;a.d.component={init:function(d,c,e,g,h){function k(){var a=f&&f.dispose;"function"===typeof a&&a.call(f);m=null}var f,m;a.a.w.da(d,k);a.s(function(){var e=a.a.c(c()),g,n;"string"===typeof e?g=e:(g=a.a.c(e.name),n=a.a.c(e.params));if(!g)throw Error("No component name specified");var t=m=++b;a.g.get(g,function(b){if(m===t){k();if(!b)throw Error("Unknown component '"+g+"'");var c=b.template;if(!c)throw Error("Component '"+g+"' has no template");c=a.a.ia(c);a.f.T(d,c);var c=n,e=b.createViewModel;b=e?e.call(b,c,{element:d}):c;c=h.createChildContext(b);f=b;a.Ca(c,d)}})},null,{o:d});return{controlsDescendantBindings:!0}}};a.f.Q.component=!0})();var Q={"class":"className","for":"htmlFor"};a.d.attr={update:function(b,d){var c=a.a.c(d())||{};a.a.G(c,function(c,d){d=a.a.c(d);var h=!1===d||null===d||d===p;h&&b.removeAttribute(c);8>=a.a.L&&c in Q?(c=Q[c],h?b.removeAttribute(c):b[c]=d):h||b.setAttribute(c,d.toString());"name"===c&&a.a.Mb(b,h?"":d.toString())})}};(function(){a.d.checked={after:["value","attr"],init:function(b,d,c){function e(){var e=b.checked,k=q?h():e;if(!a.Y.ma()&&(!f||e)){var g=a.k.B(d);m?l!==k?(e&&(a.a.ea(g,k,!0),a.a.ea(g,l,!1)),l=k):a.a.ea(g,k,e):a.h.pa(g,c,"checked",k,!0)}}function g(){var c=a.a.c(d());b.checked=m?0<=a.a.m(c,h()):k?c:h()===c}var h=a.Ib(function(){return c.has("checkedValue")?a.a.c(c.get("checkedValue")):c.has("value")?a.a.c(c.get("value")):b.value}),k="checkbox"==b.type,f="radio"==b.type;if(k||f){var m=k&&a.a.c(d())instanceof Array,l=m?h():p,q=f||m;f&&!b.name&&a.d.uniqueName.init(b,function(){return!0});a.s(e,null,{o:b});a.a.n(b,"click",e);a.s(g,null,{o:b})}}};a.h.V.checked=!0;a.d.checkedValue={update:function(b,d){b.value=a.a.c(d())}}})();a.d.css={update:function(b,d){var c=a.a.c(d());"object"==typeof c?a.a.G(c,function(c,d){d=a.a.c(d);a.a.Ba(b,c,d)}):(c=String(c||""),a.a.Ba(b,b.__ko__cssValue,!1),b.__ko__cssValue=c,a.a.Ba(b,c,!0))}};a.d.enable={update:function(b,d){var c=a.a.c(d());c&&b.disabled?b.removeAttribute("disabled"):c||b.disabled||(b.disabled=!0)}};a.d.disable={update:function(b,d){a.d.enable.update(b,function(){return!a.a.c(d())})}};a.d.event={init:function(b,d,c,e,g){var h=d()||{};a.a.G(h,function(k){"string"==typeof k&&a.a.n(b,k,function(b){var h,l=d()[k];if(l){try{var q=a.a.S(arguments);e=g.$data;q.unshift(e);h=l.apply(e,q)}finally{!0!==h&&(b.preventDefault?b.preventDefault():b.returnValue=!1)}!1===c.get(k+"Bubble")&&(b.cancelBubble=!0,b.stopPropagation&&b.stopPropagation())}})})}};a.d.foreach={Eb:function(b){return function(){var d=b(),c=a.a.Xa(d);if(!c||"number"==typeof c.length)return{foreach:d,templateEngine:a.O.Oa};a.a.c(d);return{foreach:c.data,as:c.as,includeDestroyed:c.includeDestroyed,afterAdd:c.afterAdd,beforeRemove:c.beforeRemove,afterRender:c.afterRender,beforeMove:c.beforeMove,afterMove:c.afterMove,templateEngine:a.O.Oa}}},init:function(b,d){return a.d.template.init(b,a.d.foreach.Eb(d))},update:function(b,d,c,e,g){return a.d.template.update(b,a.d.foreach.Eb(d),c,e,g)}};a.h.ha.foreach=!1;a.f.Q.foreach=!0;a.d.hasfocus={init:function(b,d,c){function e(e){b.__ko_hasfocusUpdating=!0;var f=b.ownerDocument;if("activeElement"in f){var g;try{g=f.activeElement}catch(h){g=f.body}e=g===b}f=d();a.h.pa(f,c,"hasfocus",e,!0);b.__ko_hasfocusLastValue=e;b.__ko_hasfocusUpdating=!1}var g=e.bind(null,!0),h=e.bind(null,!1);a.a.n(b,"focus",g);a.a.n(b,"focusin",g);a.a.n(b,"blur",h);a.a.n(b,"focusout",h)},update:function(b,d){var c=!!a.a.c(d());b.__ko_hasfocusUpdating||b.__ko_hasfocusLastValue===c||(c?b.focus():b.blur(),a.k.B(a.a.oa,null,[b,c?"focusin":"focusout"]))}};a.h.V.hasfocus=!0;a.d.hasFocus=a.d.hasfocus;a.h.V.hasFocus=!0;a.d.html={init:function(){return{controlsDescendantBindings:!0}},update:function(b,d){a.a.$a(b,d())}};I("if");I("ifnot",!1,!0);I("with",!0,!1,function(a,d){return a.createChildContext(d)});var K={};a.d.options={init:function(b){if("select"!==a.a.t(b))throw Error("options binding applies only to SELECT elements");for(;0<b.length;)b.remove(0);return{controlsDescendantBindings:!0}},update:function(b,d,c){function e(){return a.a.ta(b.options,function(a){return a.selected})}function g(a,b,c){var d=typeof b;return"function"==d?b(a):"string"==d?a[b]:c}function h(c,d){if(q.length){var e=0<=a.a.m(q,a.i.q(d[0]));a.a.Nb(d[0],e);n&&!e&&a.k.B(a.a.oa,null,[b,"change"])}}var k=0!=b.length&&b.multiple?b.scrollTop:null,f=a.a.c(d()),m=c.get("optionsIncludeDestroyed");d={};var l,q;q=b.multiple?a.a.Da(e(),a.i.q):0<=b.selectedIndex?[a.i.q(b.options[b.selectedIndex])]:[];f&&("undefined"==typeof f.length&&(f=[f]),l=a.a.ta(f,function(b){return m||b===p||null===b||!a.a.c(b._destroy)}),c.has("optionsCaption")&&(f=a.a.c(c.get("optionsCaption")),null!==f&&f!==p&&l.unshift(K)));var n=!1;d.beforeRemove=function(a){b.removeChild(a)};f=h;c.has("optionsAfterRender")&&(f=function(b,d){h(0,d);a.k.B(c.get("optionsAfterRender"),null,[d[0],b!==K?b:p])});a.a.Za(b,l,function(d,e,f){f.length&&(q=f[0].selected?[a.i.q(f[0])]:[],n=!0);e=b.ownerDocument.createElement("option");d===K?(a.a.bb(e,c.get("optionsCaption")),a.i.ca(e,p)):(f=g(d,c.get("optionsValue"),d),a.i.ca(e,a.a.c(f)),d=g(d,c.get("optionsText"),f),a.a.bb(e,d));return[e]},d,f);a.k.B(function(){c.get("valueAllowUnset")&&c.has("value")?a.i.ca(b,a.a.c(c.get("value")),!0):(b.multiple?q.length&&e().length<q.length:q.length&&0<=b.selectedIndex?a.i.q(b.options[b.selectedIndex])!==q[0]:q.length||0<=b.selectedIndex)&&a.a.oa(b,"change")});a.a.dc(b);k&&20<Math.abs(k-b.scrollTop)&&(b.scrollTop=k)}};a.d.options.Va=a.a.e.F();a.d.selectedOptions={after:["options","foreach"],init:function(b,d,c){a.a.n(b,"change",function(){var e=d(),g=[];a.a.u(b.getElementsByTagName("option"),function(b){b.selected&&g.push(a.i.q(b))});a.h.pa(e,c,"selectedOptions",g)})},update:function(b,d){if("select"!=a.a.t(b))throw Error("values binding applies only to SELECT elements");var c=a.a.c(d());c&&"number"==typeof c.length&&a.a.u(b.getElementsByTagName("option"),function(b){var d=0<=a.a.m(c,a.i.q(b));a.a.Nb(b,d)})}};a.h.V.selectedOptions=!0;a.d.style={update:function(b,d){var c=a.a.c(d()||{});a.a.G(c,function(c,d){d=a.a.c(d);if(null===d||d===p||!1===d)d="";b.style[c]=d})}};a.d.submit={init:function(b,d,c,e,g){if("function"!=typeof d())throw Error("The value for a submit binding must be a function");a.a.n(b,"submit",function(a){var c,e=d();try{c=e.call(g.$data,b)}finally{!0!==c&&(a.preventDefault?a.preventDefault():a.returnValue=!1)}})}};a.d.text={init:function(){return{controlsDescendantBindings:!0}},update:function(b,d){a.a.bb(b,d())}};a.f.Q.text=!0;(function(){if(s&&s.navigator)var b=function(a){if(a)return parseFloat(a[1])},d=s.opera&&s.opera.version&&parseInt(s.opera.version()),c=s.navigator.userAgent,e=b(c.match(/^(?:(?!chrome).)*version\/([^ ]*) safari/i)),g=b(c.match(/Firefox\/([^ ]*)/));if(10>a.a.L)var h=a.a.e.F(),k=a.a.e.F(),f=function(b){var c=this.activeElement;(c=c&&a.a.e.get(c,k))&&c(b)},m=function(b,c){var d=b.ownerDocument;a.a.e.get(d,h)||(a.a.e.set(d,h,!0),a.a.n(d,"selectionchange",f));a.a.e.set(b,k,c)};a.d.textInput={init:function(b,c,f){function k(c,d){a.a.n(b,c,d)}function h(){var d=a.a.c(c());if(null===d||d===p)d="";v!==p&&d===v?setTimeout(h,4):b.value!==d&&(s=d,b.value=d)}function u(){y||(v=b.value,y=setTimeout(r,4))}function r(){clearTimeout(y);v=y=p;var d=b.value;s!==d&&(s=d,a.h.pa(c(),f,"textInput",d))}var s=b.value,y,v;10>a.a.L?(k("propertychange",function(a){"value"===a.propertyName&&r()}),8==a.a.L&&(k("keyup",r),k("keydown",r)),8<=a.a.L&&(m(b,r),k("dragend",u))):(k("input",r),5>e&&"textarea"===a.a.t(b)?(k("keydown",u),k("paste",u),k("cut",u)):11>d?k("keydown",u):4>g&&(k("DOMAutoComplete",r),k("dragdrop",r),k("drop",r)));k("change",r);a.s(h,null,{o:b})}};a.h.V.textInput=!0;a.d.textinput={preprocess:function(a,b,c){c("textInput",a)}}})();a.d.uniqueName={init:function(b,d){if(d()){var c="ko_unique_"+ ++a.d.uniqueName.Zb;a.a.Mb(b,c)}}};a.d.uniqueName.Zb=0;a.d.value={after:["options","foreach"],init:function(b,d,c){if("input"!=b.tagName.toLowerCase()||"checkbox"!=b.type&&"radio"!=b.type){var e=["change"],g=c.get("valueUpdate"),h=!1,k=null;g&&("string"==typeof g&&(g=[g]),a.a.ga(e,g),e=a.a.rb(e));var f=function(){k=null;h=!1;var e=d(),f=a.i.q(b);a.h.pa(e,c,"value",f)};!a.a.L||"input"!=b.tagName.toLowerCase()||"text"!=b.type||"off"==b.autocomplete||b.form&&"off"==b.form.autocomplete||-1!=a.a.m(e,"propertychange")||(a.a.n(b,"propertychange",function(){h=!0}),a.a.n(b,"focus",function(){h=!1}),a.a.n(b,"blur",function(){h&&f()}));a.a.u(e,function(c){var d=f;a.a.vc(c,"after")&&(d=function(){k=a.i.q(b);setTimeout(f,0)},c=c.substring(5));a.a.n(b,c,d)});var m=function(){var e=a.a.c(d()),f=a.i.q(b);if(null!==k&&e===k)setTimeout(m,0);else if(e!==f)if("select"===a.a.t(b)){var g=c.get("valueAllowUnset"),f=function(){a.i.ca(b,e,g)};f();g||e===a.i.q(b)?setTimeout(f,0):a.k.B(a.a.oa,null,[b,"change"])}else a.i.ca(b,e)};a.s(m,null,{o:b})}else a.ra(b,{checkedValue:d})},update:function(){}};a.h.V.value=!0;a.d.visible={update:function(b,d){var c=a.a.c(d()),e="none"!=b.style.display;c&&!e?b.style.display="":!c&&e&&(b.style.display="none")}};(function(b){a.d[b]={init:function(d,c,e,g,h){return a.d.event.init.call(this,d,function(){var a={};a[b]=c();return a},e,g,h)}}})("click");a.H=function(){};a.H.prototype.renderTemplateSource=function(){throw Error("Override renderTemplateSource");};a.H.prototype.createJavaScriptEvaluatorBlock=function(){throw Error("Override createJavaScriptEvaluatorBlock");};a.H.prototype.makeTemplateSource=function(b,d){if("string"==typeof b){d=d||v;var c=d.getElementById(b);if(!c)throw Error("Cannot find template with ID "+b);return new a.r.l(c)}if(1==b.nodeType||8==b.nodeType)return new a.r.fa(b);throw Error("Unknown template type: "+b);};a.H.prototype.renderTemplate=function(a,d,c,e){a=this.makeTemplateSource(a,e);return this.renderTemplateSource(a,d,c)};a.H.prototype.isTemplateRewritten=function(a,d){return!1===this.allowTemplateRewriting?!0:this.makeTemplateSource(a,d).data("isRewritten")};a.H.prototype.rewriteTemplate=function(a,d,c){a=this.makeTemplateSource(a,c);d=d(a.text());a.text(d);a.data("isRewritten",!0)};a.b("templateEngine",a.H);a.fb=function(){function b(b,c,d,k){b=a.h.Wa(b);for(var f=a.h.ha,m=0;m<b.length;m++){var l=b[m].key;if(f.hasOwnProperty(l)){var q=f[l];if("function"===typeof q){if(l=q(b[m].value))throw Error(l);}else if(!q)throw Error("This template engine does not support the '"+l+"' binding within its templates");}}d="ko.__tr_ambtns(function($context,$element){return(function(){return{ "+a.h.ya(b,{valueAccessors:!0})+" } })()},'"+d.toLowerCase()+"')";return k.createJavaScriptEvaluatorBlock(d)+c}var d=/(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,c=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g;return{ec:function(b,c,d){c.isTemplateRewritten(b,d)||c.rewriteTemplate(b,function(b){return a.fb.nc(b,c)},d)},nc:function(a,g){return a.replace(d,function(a,c,d,e,l){return b(l,c,d,g)}).replace(c,function(a,c){return b(c,"\x3c!-- ko --\x3e","#comment",g)})},Xb:function(b,c){return a.D.Ua(function(d,k){var f=d.nextSibling;f&&f.nodeName.toLowerCase()===c&&a.ra(f,b,k)})}}}();a.b("__tr_ambtns",a.fb.Xb);(function(){a.r={};a.r.l=function(a){this.l=a};a.r.l.prototype.text=function(){var b=a.a.t(this.l),b="script"===b?"text":"textarea"===b?"value":"innerHTML";if(0==arguments.length)return this.l[b];var d=arguments[0];"innerHTML"===b?a.a.$a(this.l,d):this.l[b]=d};var b=a.a.e.F()+"_";a.r.l.prototype.data=function(c){if(1===arguments.length)return a.a.e.get(this.l,b+c);a.a.e.set(this.l,b+c,arguments[1])};var d=a.a.e.F();a.r.fa=function(a){this.l=a};a.r.fa.prototype=new a.r.l;a.r.fa.prototype.text=function(){if(0==arguments.length){var b=a.a.e.get(this.l,d)||{};b.gb===p&&b.Ga&&(b.gb=b.Ga.innerHTML);return b.gb}a.a.e.set(this.l,d,{gb:arguments[0]})};a.r.l.prototype.nodes=function(){if(0==arguments.length)return(a.a.e.get(this.l,d)||{}).Ga;a.a.e.set(this.l,d,{Ga:arguments[0]})};a.b("templateSources",a.r);a.b("templateSources.domElement",a.r.l);a.b("templateSources.anonymousTemplate",a.r.fa)})();(function(){function b(b,c,d){var e;for(c=a.f.nextSibling(c);b&&(e=b)!==c;)b=a.f.nextSibling(e),d(e,b)}function d(c,d){if(c.length){var e=c[0],g=c[c.length-1],h=e.parentNode,n=a.J.instance,t=n.preprocessNode;if(t){b(e,g,function(a,b){var c=a.previousSibling,d=t.call(n,a);d&&(a===e&&(e=d[0]||b),a===g&&(g=d[d.length-1]||c))});c.length=0;if(!e)return;e===g?c.push(e):(c.push(e,g),a.a.ka(c,h))}b(e,g,function(b){1!==b.nodeType&&8!==b.nodeType||a.pb(d,b)});b(e,g,function(b){1!==b.nodeType&&8!==b.nodeType||a.D.Sb(b,[d])});a.a.ka(c,h)}}function c(a){return a.nodeType?a:0<a.length?a[0]:null}function e(b,e,h,l,q){q=q||{};var n=b&&c(b),n=n&&n.ownerDocument,t=q.templateEngine||g;a.fb.ec(h,t,n);h=t.renderTemplate(h,l,q,n);if("number"!=typeof h.length||0<h.length&&"number"!=typeof h[0].nodeType)throw Error("Template engine must return an array of DOM nodes");n=!1;switch(e){case"replaceChildren":a.f.T(b,h);n=!0;break;case"replaceNode":a.a.Lb(b,h);n=!0;break;case"ignoreTargetNode":break;default:throw Error("Unknown renderMode: "+e);}n&&(d(h,l),q.afterRender&&a.k.B(q.afterRender,null,[h,l.$data]));return h}var g;a.ab=function(b){if(b!=p&&!(b instanceof a.H))throw Error("templateEngine must inherit from ko.templateEngine");g=b};a.Ya=function(b,d,h,l,q){h=h||{};if((h.templateEngine||g)==p)throw Error("Set a template engine before calling renderTemplate");q=q||"replaceChildren";if(l){var n=c(l);return a.j(function(){var g=d&&d instanceof a.N?d:new a.N(a.a.c(d)),p=a.C(b)?b():"function"===typeof b?b(g.$data,g):b,g=e(l,q,p,g,h);"replaceNode"==q&&(l=g,n=c(l))},null,{Ia:function(){return!n||!a.a.Ja(n)},o:n&&"replaceNode"==q?n.parentNode:n})}return a.D.Ua(function(c){a.Ya(b,d,h,c,"replaceNode")})};a.uc=function(b,c,g,h,q){function n(a,b){d(b,s);g.afterRender&&g.afterRender(b,a)}function t(c,d){s=q.createChildContext(c,g.as,function(a){a.$index=d});var f=a.C(b)?b():"function"===typeof b?b(c,s):b;return e(null,"ignoreTargetNode",f,s,g)}var s;return a.j(function(){var b=a.a.c(c)||[];"undefined"==typeof b.length&&(b=[b]);b=a.a.ta(b,function(b){return g.includeDestroyed||b===p||null===b||!a.a.c(b._destroy)});a.k.B(a.a.Za,null,[h,b,t,g,n])},null,{o:h})};var h=a.a.e.F();a.d.template={init:function(b,c){var d=a.a.c(c());"string"==typeof d||d.name?a.f.ja(b):(d=a.f.childNodes(b),d=a.a.oc(d),(new a.r.fa(b)).nodes(d));return{controlsDescendantBindings:!0}},update:function(b,c,d,e,g){var n=c(),t;c=a.a.c(n);d=!0;e=null;"string"==typeof c?c={}:(n=c.name,"if"in c&&(d=a.a.c(c["if"])),d&&"ifnot"in c&&(d=!a.a.c(c.ifnot)),t=a.a.c(c.data));"foreach"in c?e=a.uc(n||b,d&&c.foreach||[],c,b,g):d?(g="data"in c?g.createChildContext(t,c.as):g,e=a.Ya(n||b,g,c,b)):a.f.ja(b);g=e;(t=a.a.e.get(b,h))&&"function"==typeof t.K&&t.K();a.a.e.set(b,h,g&&g.Z()?g:p)}};a.h.ha.template=function(b){b=a.h.Wa(b);return 1==b.length&&b[0].unknown||a.h.lc(b,"name")?null:"This template engine does not support anonymous templates nested within its templates"};a.f.Q.template=!0})();a.b("setTemplateEngine",a.ab);a.b("renderTemplate",a.Ya);a.a.wb=function(a,d,c){if(a.length&&d.length){var e,g,h,k,f;for(e=g=0;(!c||e<c)&&(k=a[g]);++g){for(h=0;f=d[h];++h)if(k.value===f.value){k.moved=f.index;f.moved=k.index;d.splice(h,1);e=h=0;break}e+=h}}};a.a.Fa=function(){function b(b,c,e,g,h){var k=Math.min,f=Math.max,m=[],l,q=b.length,n,p=c.length,s=p-q||1,u=q+p+1,r,v,w;for(l=0;l<=q;l++)for(v=r,m.push(r=[]),w=k(p,l+s),n=f(0,l-1);n<=w;n++)r[n]=n?l?b[l-1]===c[n-1]?v[n-1]:k(v[n]||u,r[n-1]||u)+1:n+1:l+1;k=[];f=[];s=[];l=q;for(n=p;l||n;)p=m[l][n]-1,n&&p===m[l][n-1]?f.push(k[k.length]={status:e,value:c[--n],index:n}):l&&p===m[l-1][n]?s.push(k[k.length]={status:g,value:b[--l],index:l}):(--n,--l,h.sparse||k.push({status:"retained",value:c[n]}));a.a.wb(f,s,10*q);return k.reverse()}return function(a,c,e){e="boolean"===typeof e?{dontLimitMoves:e}:e||{};a=a||[];c=c||[];return a.length<=c.length?b(a,c,"added","deleted",e):b(c,a,"deleted","added",e)}}();a.b("utils.compareArrays",a.a.Fa);(function(){function b(b,d,g,h,k){var f=[],m=a.j(function(){var l=d(g,k,a.a.ka(f,b))||[];0<f.length&&(a.a.Lb(f,l),h&&a.k.B(h,null,[g,l,k]));f.length=0;a.a.ga(f,l)},null,{o:b,Ia:function(){return!a.a.ob(f)}});return{$:f,j:m.Z()?m:p}}var d=a.a.e.F();a.a.Za=function(c,e,g,h,k){function f(b,d){x=q[d];r!==d&&(A[b]=x);x.Na(r++);a.a.ka(x.$,c);s.push(x);w.push(x)}function m(b,c){if(b)for(var d=0,e=c.length;d<e;d++)c[d]&&a.a.u(c[d].$,function(a){b(a,d,c[d].sa)})}e=e||[];h=h||{};var l=a.a.e.get(c,d)===p,q=a.a.e.get(c,d)||[],n=a.a.Da(q,function(a){return a.sa}),t=a.a.Fa(n,e,h.dontLimitMoves),s=[],u=0,r=0,v=[],w=[];e=[];for(var A=[],n=[],x,B=0,D,F;D=t[B];B++)switch(F=D.moved,D.status){case"deleted":F===p&&(x=q[u],x.j&&x.j.K(),v.push.apply(v,a.a.ka(x.$,c)),h.beforeRemove&&(e[B]=x,w.push(x)));u++;break;case"retained":f(B,u++);break;case"added":F!==p?f(B,F):(x={sa:D.value,Na:a.p(r++)},s.push(x),w.push(x),l||(n[B]=x))}m(h.beforeMove,A);a.a.u(v,h.beforeRemove?a.R:a.removeNode);for(var B=0,l=a.f.firstChild(c),G;x=w[B];B++){x.$||a.a.extend(x,b(c,g,x.sa,k,x.Na));for(u=0;t=x.$[u];l=t.nextSibling,G=t,u++)t!==l&&a.f.Bb(c,t,G);!x.ic&&k&&(k(x.sa,x.$,x.Na),x.ic=!0)}m(h.beforeRemove,e);m(h.afterMove,A);m(h.afterAdd,n);a.a.e.set(c,d,s)}})();a.b("utils.setDomNodeChildrenFromArrayMapping",a.a.Za);a.O=function(){this.allowTemplateRewriting=!1};a.O.prototype=new a.H;a.O.prototype.renderTemplateSource=function(b){var d=(9>a.a.L?0:b.nodes)?b.nodes():null;if(d)return a.a.S(d.cloneNode(!0).childNodes);b=b.text();return a.a.ba(b)};a.O.Oa=new a.O;a.ab(a.O.Oa);a.b("nativeTemplateEngine",a.O);(function(){a.Sa=function(){var a=this.kc=function(){if(!w||!w.tmpl)return 0;try{if(0<=w.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(b,e,g){g=g||{};if(2>a)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var h=b.data("precompiled");h||(h=b.text()||"",h=w.template(null,"{{ko_with $item.koBindingContext}}"+h+"{{/ko_with}}"),b.data("precompiled",h));b=[e.$data];e=w.extend({koBindingContext:e},g.templateOptions);e=w.tmpl(h,b,e);e.appendTo(v.createElement("div"));w.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){v.write("<script type='text/html' id='"+a+"'>"+b+"\x3c/script>")};0<a&&(w.tmpl.tag.ko_code={open:"__.push($1 || '');"},w.tmpl.tag.ko_with={open:"with($1) {",close:"} "})};a.Sa.prototype=new a.H;var b=new a.Sa;0<b.kc&&a.ab(b);a.b("jqueryTmplTemplateEngine",a.Sa)})()})})();})();
    • marked
      • marked.js
        /**
         * marked - a markdown parser
         * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
         * https://github.com/chjj/marked
         */
        
        ;(function() {
        
        /**
         * Block-Level Grammar
         */
        
        var block = {
          newline: /^\n+/,
          code: /^( {4}[^\n]+\n*)+/,
          fences: noop,
          hr: /^( *[-*_]){3,} *(?:\n+|$)/,
          heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
          nptable: noop,
          lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
          blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
          list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
          html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
          def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
          table: noop,
          paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
          text: /^[^\n]+/
        };
        
        block.bullet = /(?:[*+-]|\d+\.)/;
        block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
        block.item = replace(block.item, 'gm')
          (/bull/g, block.bullet)
          ();
        
        block.list = replace(block.list)
          (/bull/g, block.bullet)
          ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
          ('def', '\\n+(?=' + block.def.source + ')')
          ();
        
        block.blockquote = replace(block.blockquote)
          ('def', block.def)
          ();
        
        block._tag = '(?!(?:'
          + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
          + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
          + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
        
        block.html = replace(block.html)
          ('comment', /<!--[\s\S]*?-->/)
          ('closed', /<(tag)[\s\S]+?<\/\1>/)
          ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
          (/tag/g, block._tag)
          ();
        
        block.paragraph = replace(block.paragraph)
          ('hr', block.hr)
          ('heading', block.heading)
          ('lheading', block.lheading)
          ('blockquote', block.blockquote)
          ('tag', '<' + block._tag)
          ('def', block.def)
          ();
        
        /**
         * Normal Block Grammar
         */
        
        block.normal = merge({}, block);
        
        /**
         * GFM Block Grammar
         */
        
        block.gfm = merge({}, block.normal, {
          fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,
          paragraph: /^/
        });
        
        block.gfm.paragraph = replace(block.paragraph)
          ('(?!', '(?!'
            + block.gfm.fences.source.replace('\\1', '\\2') + '|'
            + block.list.source.replace('\\1', '\\3') + '|')
          ();
        
        /**
         * GFM + Tables Block Grammar
         */
        
        block.tables = merge({}, block.gfm, {
          nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
          table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
        });
        
        /**
         * Block Lexer
         */
        
        function Lexer(options) {
          this.tokens = [];
          this.tokens.links = {};
          this.options = options || marked.defaults;
          this.rules = block.normal;
        
          if (this.options.gfm) {
            if (this.options.tables) {
              this.rules = block.tables;
            } else {
              this.rules = block.gfm;
            }
          }
        }
        
        /**
         * Expose Block Rules
         */
        
        Lexer.rules = block;
        
        /**
         * Static Lex Method
         */
        
        Lexer.lex = function(src, options) {
          var lexer = new Lexer(options);
          return lexer.lex(src);
        };
        
        /**
         * Preprocessing
         */
        
        Lexer.prototype.lex = function(src) {
          src = src
            .replace(/\r\n|\r/g, '\n')
            .replace(/\t/g, '    ')
            .replace(/\u00a0/g, ' ')
            .replace(/\u2424/g, '\n');
        
          return this.token(src, true);
        };
        
        /**
         * Lexing
         */
        
        Lexer.prototype.token = function(src, top, bq) {
          var src = src.replace(/^ +$/gm, '')
            , next
            , loose
            , cap
            , bull
            , b
            , item
            , space
            , i
            , l;
        
          while (src) {
            // newline
            if (cap = this.rules.newline.exec(src)) {
              src = src.substring(cap[0].length);
              if (cap[0].length > 1) {
                this.tokens.push({
                  type: 'space'
                });
              }
            }
        
            // code
            if (cap = this.rules.code.exec(src)) {
              src = src.substring(cap[0].length);
              cap = cap[0].replace(/^ {4}/gm, '');
              this.tokens.push({
                type: 'code',
                text: !this.options.pedantic
                  ? cap.replace(/\n+$/, '')
                  : cap
              });
              continue;
            }
        
            // fences (gfm)
            if (cap = this.rules.fences.exec(src)) {
              src = src.substring(cap[0].length);
              this.tokens.push({
                type: 'code',
                lang: cap[2],
                text: cap[3]
              });
              continue;
            }
        
            // heading
            if (cap = this.rules.heading.exec(src)) {
              src = src.substring(cap[0].length);
              this.tokens.push({
                type: 'heading',
                depth: cap[1].length,
                text: cap[2]
              });
              continue;
            }
        
            // table no leading pipe (gfm)
            if (top && (cap = this.rules.nptable.exec(src))) {
              src = src.substring(cap[0].length);
        
              item = {
                type: 'table',
                header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
                align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
                cells: cap[3].replace(/\n$/, '').split('\n')
              };
        
              for (i = 0; i < item.align.length; i++) {
                if (/^ *-+: *$/.test(item.align[i])) {
                  item.align[i] = 'right';
                } else if (/^ *:-+: *$/.test(item.align[i])) {
                  item.align[i] = 'center';
                } else if (/^ *:-+ *$/.test(item.align[i])) {
                  item.align[i] = 'left';
                } else {
                  item.align[i] = null;
                }
              }
        
              for (i = 0; i < item.cells.length; i++) {
                item.cells[i] = item.cells[i].split(/ *\| */);
              }
        
              this.tokens.push(item);
        
              continue;
            }
        
            // lheading
            if (cap = this.rules.lheading.exec(src)) {
              src = src.substring(cap[0].length);
              this.tokens.push({
                type: 'heading',
                depth: cap[2] === '=' ? 1 : 2,
                text: cap[1]
              });
              continue;
            }
        
            // hr
            if (cap = this.rules.hr.exec(src)) {
              src = src.substring(cap[0].length);
              this.tokens.push({
                type: 'hr'
              });
              continue;
            }
        
            // blockquote
            if (cap = this.rules.blockquote.exec(src)) {
              src = src.substring(cap[0].length);
        
              this.tokens.push({
                type: 'blockquote_start'
              });
        
              cap = cap[0].replace(/^ *> ?/gm, '');
        
              // Pass `top` to keep the current
              // "toplevel" state. This is exactly
              // how markdown.pl works.
              this.token(cap, top, true);
        
              this.tokens.push({
                type: 'blockquote_end'
              });
        
              continue;
            }
        
            // list
            if (cap = this.rules.list.exec(src)) {
              src = src.substring(cap[0].length);
              bull = cap[2];
        
              this.tokens.push({
                type: 'list_start',
                ordered: bull.length > 1
              });
        
              // Get each top-level item.
              cap = cap[0].match(this.rules.item);
        
              next = false;
              l = cap.length;
              i = 0;
        
              for (; i < l; i++) {
                item = cap[i];
        
                // Remove the list item's bullet
                // so it is seen as the next token.
                space = item.length;
                item = item.replace(/^ *([*+-]|\d+\.) +/, '');
        
                // Outdent whatever the
                // list item contains. Hacky.
                if (~item.indexOf('\n ')) {
                  space -= item.length;
                  item = !this.options.pedantic
                    ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
                    : item.replace(/^ {1,4}/gm, '');
                }
        
                // Determine whether the next list item belongs here.
                // Backpedal if it does not belong in this list.
                if (this.options.smartLists && i !== l - 1) {
                  b = block.bullet.exec(cap[i + 1])[0];
                  if (bull !== b && !(bull.length > 1 && b.length > 1)) {
                    src = cap.slice(i + 1).join('\n') + src;
                    i = l - 1;
                  }
                }
        
                // Determine whether item is loose or not.
                // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
                // for discount behavior.
                loose = next || /\n\n(?!\s*$)/.test(item);
                if (i !== l - 1) {
                  next = item.charAt(item.length - 1) === '\n';
                  if (!loose) loose = next;
                }
        
                this.tokens.push({
                  type: loose
                    ? 'loose_item_start'
                    : 'list_item_start'
                });
        
                // Recurse.
                this.token(item, false, bq);
        
                this.tokens.push({
                  type: 'list_item_end'
                });
              }
        
              this.tokens.push({
                type: 'list_end'
              });
        
              continue;
            }
        
            // html
            if (cap = this.rules.html.exec(src)) {
              src = src.substring(cap[0].length);
              this.tokens.push({
                type: this.options.sanitize
                  ? 'paragraph'
                  : 'html',
                pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',
                text: cap[0]
              });
              continue;
            }
        
            // def
            if ((!bq && top) && (cap = this.rules.def.exec(src))) {
              src = src.substring(cap[0].length);
              this.tokens.links[cap[1].toLowerCase()] = {
                href: cap[2],
                title: cap[3]
              };
              continue;
            }
        
            // table (gfm)
            if (top && (cap = this.rules.table.exec(src))) {
              src = src.substring(cap[0].length);
        
              item = {
                type: 'table',
                header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
                align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
                cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
              };
        
              for (i = 0; i < item.align.length; i++) {
                if (/^ *-+: *$/.test(item.align[i])) {
                  item.align[i] = 'right';
                } else if (/^ *:-+: *$/.test(item.align[i])) {
                  item.align[i] = 'center';
                } else if (/^ *:-+ *$/.test(item.align[i])) {
                  item.align[i] = 'left';
                } else {
                  item.align[i] = null;
                }
              }
        
              for (i = 0; i < item.cells.length; i++) {
                item.cells[i] = item.cells[i]
                  .replace(/^ *\| *| *\| *$/g, '')
                  .split(/ *\| */);
              }
        
              this.tokens.push(item);
        
              continue;
            }
        
            // top-level paragraph
            if (top && (cap = this.rules.paragraph.exec(src))) {
              src = src.substring(cap[0].length);
              this.tokens.push({
                type: 'paragraph',
                text: cap[1].charAt(cap[1].length - 1) === '\n'
                  ? cap[1].slice(0, -1)
                  : cap[1]
              });
              continue;
            }
        
            // text
            if (cap = this.rules.text.exec(src)) {
              // Top-level should never reach here.
              src = src.substring(cap[0].length);
              this.tokens.push({
                type: 'text',
                text: cap[0]
              });
              continue;
            }
        
            if (src) {
              throw new
                Error('Infinite loop on byte: ' + src.charCodeAt(0));
            }
          }
        
          return this.tokens;
        };
        
        /**
         * Inline-Level Grammar
         */
        
        var inline = {
          escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
          autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
          url: noop,
          tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
          link: /^!?\[(inside)\]\(href\)/,
          reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
          nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
          strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
          em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
          code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
          br: /^ {2,}\n(?!\s*$)/,
          del: noop,
          text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
        };
        
        inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
        inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
        
        inline.link = replace(inline.link)
          ('inside', inline._inside)
          ('href', inline._href)
          ();
        
        inline.reflink = replace(inline.reflink)
          ('inside', inline._inside)
          ();
        
        /**
         * Normal Inline Grammar
         */
        
        inline.normal = merge({}, inline);
        
        /**
         * Pedantic Inline Grammar
         */
        
        inline.pedantic = merge({}, inline.normal, {
          strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
          em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
        });
        
        /**
         * GFM Inline Grammar
         */
        
        inline.gfm = merge({}, inline.normal, {
          escape: replace(inline.escape)('])', '~|])')(),
          url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
          del: /^~~(?=\S)([\s\S]*?\S)~~/,
          text: replace(inline.text)
            (']|', '~]|')
            ('|', '|https?://|')
            ()
        });
        
        /**
         * GFM + Line Breaks Inline Grammar
         */
        
        inline.breaks = merge({}, inline.gfm, {
          br: replace(inline.br)('{2,}', '*')(),
          text: replace(inline.gfm.text)('{2,}', '*')()
        });
        
        /**
         * Inline Lexer & Compiler
         */
        
        function InlineLexer(links, options) {
          this.options = options || marked.defaults;
          this.links = links;
          this.rules = inline.normal;
          this.renderer = this.options.renderer || new Renderer;
          this.renderer.options = this.options;
        
          if (!this.links) {
            throw new
              Error('Tokens array requires a `links` property.');
          }
        
          if (this.options.gfm) {
            if (this.options.breaks) {
              this.rules = inline.breaks;
            } else {
              this.rules = inline.gfm;
            }
          } else if (this.options.pedantic) {
            this.rules = inline.pedantic;
          }
        }
        
        /**
         * Expose Inline Rules
         */
        
        InlineLexer.rules = inline;
        
        /**
         * Static Lexing/Compiling Method
         */
        
        InlineLexer.output = function(src, links, options) {
          var inline = new InlineLexer(links, options);
          return inline.output(src);
        };
        
        /**
         * Lexing/Compiling
         */
        
        InlineLexer.prototype.output = function(src) {
          var out = ''
            , link
            , text
            , href
            , cap;
        
          while (src) {
            // escape
            if (cap = this.rules.escape.exec(src)) {
              src = src.substring(cap[0].length);
              out += cap[1];
              continue;
            }
        
            // autolink
            if (cap = this.rules.autolink.exec(src)) {
              src = src.substring(cap[0].length);
              if (cap[2] === '@') {
                text = cap[1].charAt(6) === ':'
                  ? this.mangle(cap[1].substring(7))
                  : this.mangle(cap[1]);
                href = this.mangle('mailto:') + text;
              } else {
                text = escape(cap[1]);
                href = text;
              }
              out += this.renderer.link(href, null, text);
              continue;
            }
        
            // url (gfm)
            if (!this.inLink && (cap = this.rules.url.exec(src))) {
              src = src.substring(cap[0].length);
              text = escape(cap[1]);
              href = text;
              out += this.renderer.link(href, null, text);
              continue;
            }
        
            // tag
            if (cap = this.rules.tag.exec(src)) {
              if (!this.inLink && /^<a /i.test(cap[0])) {
                this.inLink = true;
              } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
                this.inLink = false;
              }
              src = src.substring(cap[0].length);
              out += this.options.sanitize
                ? escape(cap[0])
                : cap[0];
              continue;
            }
        
            // link
            if (cap = this.rules.link.exec(src)) {
              src = src.substring(cap[0].length);
              this.inLink = true;
              out += this.outputLink(cap, {
                href: cap[2],
                title: cap[3]
              });
              this.inLink = false;
              continue;
            }
        
            // reflink, nolink
            if ((cap = this.rules.reflink.exec(src))
                || (cap = this.rules.nolink.exec(src))) {
              src = src.substring(cap[0].length);
              link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
              link = this.links[link.toLowerCase()];
              if (!link || !link.href) {
                out += cap[0].charAt(0);
                src = cap[0].substring(1) + src;
                continue;
              }
              this.inLink = true;
              out += this.outputLink(cap, link);
              this.inLink = false;
              continue;
            }
        
            // strong
            if (cap = this.rules.strong.exec(src)) {
              src = src.substring(cap[0].length);
              out += this.renderer.strong(this.output(cap[2] || cap[1]));
              continue;
            }
        
            // em
            if (cap = this.rules.em.exec(src)) {
              src = src.substring(cap[0].length);
              out += this.renderer.em(this.output(cap[2] || cap[1]));
              continue;
            }
        
            // code
            if (cap = this.rules.code.exec(src)) {
              src = src.substring(cap[0].length);
              out += this.renderer.codespan(escape(cap[2], true));
              continue;
            }
        
            // br
            if (cap = this.rules.br.exec(src)) {
              src = src.substring(cap[0].length);
              out += this.renderer.br();
              continue;
            }
        
            // del (gfm)
            if (cap = this.rules.del.exec(src)) {
              src = src.substring(cap[0].length);
              out += this.renderer.del(this.output(cap[1]));
              continue;
            }
        
            // text
            if (cap = this.rules.text.exec(src)) {
              src = src.substring(cap[0].length);
              out += escape(this.smartypants(cap[0]));
              continue;
            }
        
            if (src) {
              throw new
                Error('Infinite loop on byte: ' + src.charCodeAt(0));
            }
          }
        
          return out;
        };
        
        /**
         * Compile Link
         */
        
        InlineLexer.prototype.outputLink = function(cap, link) {
          var href = escape(link.href)
            , title = link.title ? escape(link.title) : null;
        
          return cap[0].charAt(0) !== '!'
            ? this.renderer.link(href, title, this.output(cap[1]))
            : this.renderer.image(href, title, escape(cap[1]));
        };
        
        /**
         * Smartypants Transformations
         */
        
        InlineLexer.prototype.smartypants = function(text) {
          if (!this.options.smartypants) return text;
          return text
            // em-dashes
            .replace(/--/g, '\u2014')
            // opening singles
            .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
            // closing singles & apostrophes
            .replace(/'/g, '\u2019')
            // opening doubles
            .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
            // closing doubles
            .replace(/"/g, '\u201d')
            // ellipses
            .replace(/\.{3}/g, '\u2026');
        };
        
        /**
         * Mangle Links
         */
        
        InlineLexer.prototype.mangle = function(text) {
          var out = ''
            , l = text.length
            , i = 0
            , ch;
        
          for (; i < l; i++) {
            ch = text.charCodeAt(i);
            if (Math.random() > 0.5) {
              ch = 'x' + ch.toString(16);
            }
            out += '&#' + ch + ';';
          }
        
          return out;
        };
        
        /**
         * Renderer
         */
        
        function Renderer(options) {
          this.options = options || {};
        }
        
        Renderer.prototype.code = function(code, lang, escaped) {
          if (this.options.highlight) {
            var out = this.options.highlight(code, lang);
            if (out != null && out !== code) {
              escaped = true;
              code = out;
            }
          }
        
          if (!lang) {
            return '<pre><code>'
              + (escaped ? code : escape(code, true))
              + '\n</code></pre>';
          }
        
          return '<pre><code class="'
            + this.options.langPrefix
            + escape(lang, true)
            + '">'
            + (escaped ? code : escape(code, true))
            + '\n</code></pre>\n';
        };
        
        Renderer.prototype.blockquote = function(quote) {
          return '<blockquote>\n' + quote + '</blockquote>\n';
        };
        
        Renderer.prototype.html = function(html) {
          return html;
        };
        
        Renderer.prototype.heading = function(text, level, raw) {
          return '<h'
            + level
            + ' id="'
            + this.options.headerPrefix
            + raw.toLowerCase().replace(/[^\w]+/g, '-')
            + '">'
            + text
            + '</h'
            + level
            + '>\n';
        };
        
        Renderer.prototype.hr = function() {
          return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
        };
        
        Renderer.prototype.list = function(body, ordered) {
          var type = ordered ? 'ol' : 'ul';
          return '<' + type + '>\n' + body + '</' + type + '>\n';
        };
        
        Renderer.prototype.listitem = function(text) {
          return '<li>' + text + '</li>\n';
        };
        
        Renderer.prototype.paragraph = function(text) {
          return '<p>' + text + '</p>\n';
        };
        
        Renderer.prototype.table = function(header, body) {
          return '<table>\n'
            + '<thead>\n'
            + header
            + '</thead>\n'
            + '<tbody>\n'
            + body
            + '</tbody>\n'
            + '</table>\n';
        };
        
        Renderer.prototype.tablerow = function(content) {
          return '<tr>\n' + content + '</tr>\n';
        };
        
        Renderer.prototype.tablecell = function(content, flags) {
          var type = flags.header ? 'th' : 'td';
          var tag = flags.align
            ? '<' + type + ' style="text-align:' + flags.align + '">'
            : '<' + type + '>';
          return tag + content + '</' + type + '>\n';
        };
        
        // span level renderer
        Renderer.prototype.strong = function(text) {
          return '<strong>' + text + '</strong>';
        };
        
        Renderer.prototype.em = function(text) {
          return '<em>' + text + '</em>';
        };
        
        Renderer.prototype.codespan = function(text) {
          return '<code>' + text + '</code>';
        };
        
        Renderer.prototype.br = function() {
          return this.options.xhtml ? '<br/>' : '<br>';
        };
        
        Renderer.prototype.del = function(text) {
          return '<del>' + text + '</del>';
        };
        
        Renderer.prototype.link = function(href, title, text) {
          if (this.options.sanitize) {
            try {
              var prot = decodeURIComponent(unescape(href))
                .replace(/[^\w:]/g, '')
                .toLowerCase();
            } catch (e) {
              return '';
            }
            if (prot.indexOf('javascript:') === 0) {
              return '';
            }
          }
          var out = '<a href="' + href + '"';
          if (title) {
            out += ' title="' + title + '"';
          }
          out += '>' + text + '</a>';
          return out;
        };
        
        Renderer.prototype.image = function(href, title, text) {
          var out = '<img src="' + href + '" alt="' + text + '"';
          if (title) {
            out += ' title="' + title + '"';
          }
          out += this.options.xhtml ? '/>' : '>';
          return out;
        };
        
        /**
         * Parsing & Compiling
         */
        
        function Parser(options) {
          this.tokens = [];
          this.token = null;
          this.options = options || marked.defaults;
          this.options.renderer = this.options.renderer || new Renderer;
          this.renderer = this.options.renderer;
          this.renderer.options = this.options;
        }
        
        /**
         * Static Parse Method
         */
        
        Parser.parse = function(src, options, renderer) {
          var parser = new Parser(options, renderer);
          return parser.parse(src);
        };
        
        /**
         * Parse Loop
         */
        
        Parser.prototype.parse = function(src) {
          this.inline = new InlineLexer(src.links, this.options, this.renderer);
          this.tokens = src.reverse();
        
          var out = '';
          while (this.next()) {
            out += this.tok();
          }
        
          return out;
        };
        
        /**
         * Next Token
         */
        
        Parser.prototype.next = function() {
          return this.token = this.tokens.pop();
        };
        
        /**
         * Preview Next Token
         */
        
        Parser.prototype.peek = function() {
          return this.tokens[this.tokens.length - 1] || 0;
        };
        
        /**
         * Parse Text Tokens
         */
        
        Parser.prototype.parseText = function() {
          var body = this.token.text;
        
          while (this.peek().type === 'text') {
            body += '\n' + this.next().text;
          }
        
          return this.inline.output(body);
        };
        
        /**
         * Parse Current Token
         */
        
        Parser.prototype.tok = function() {
          switch (this.token.type) {
            case 'space': {
              return '';
            }
            case 'hr': {
              return this.renderer.hr();
            }
            case 'heading': {
              return this.renderer.heading(
                this.inline.output(this.token.text),
                this.token.depth,
                this.token.text);
            }
            case 'code': {
              return this.renderer.code(this.token.text,
                this.token.lang,
                this.token.escaped);
            }
            case 'table': {
              var header = ''
                , body = ''
                , i
                , row
                , cell
                , flags
                , j;
        
              // header
              cell = '';
              for (i = 0; i < this.token.header.length; i++) {
                flags = { header: true, align: this.token.align[i] };
                cell += this.renderer.tablecell(
                  this.inline.output(this.token.header[i]),
                  { header: true, align: this.token.align[i] }
                );
              }
              header += this.renderer.tablerow(cell);
        
              for (i = 0; i < this.token.cells.length; i++) {
                row = this.token.cells[i];
        
                cell = '';
                for (j = 0; j < row.length; j++) {
                  cell += this.renderer.tablecell(
                    this.inline.output(row[j]),
                    { header: false, align: this.token.align[j] }
                  );
                }
        
                body += this.renderer.tablerow(cell);
              }
              return this.renderer.table(header, body);
            }
            case 'blockquote_start': {
              var body = '';
        
              while (this.next().type !== 'blockquote_end') {
                body += this.tok();
              }
        
              return this.renderer.blockquote(body);
            }
            case 'list_start': {
              var body = ''
                , ordered = this.token.ordered;
        
              while (this.next().type !== 'list_end') {
                body += this.tok();
              }
        
              return this.renderer.list(body, ordered);
            }
            case 'list_item_start': {
              var body = '';
        
              while (this.next().type !== 'list_item_end') {
                body += this.token.type === 'text'
                  ? this.parseText()
                  : this.tok();
              }
        
              return this.renderer.listitem(body);
            }
            case 'loose_item_start': {
              var body = '';
        
              while (this.next().type !== 'list_item_end') {
                body += this.tok();
              }
        
              return this.renderer.listitem(body);
            }
            case 'html': {
              var html = !this.token.pre && !this.options.pedantic
                ? this.inline.output(this.token.text)
                : this.token.text;
              return this.renderer.html(html);
            }
            case 'paragraph': {
              return this.renderer.paragraph(this.inline.output(this.token.text));
            }
            case 'text': {
              return this.renderer.paragraph(this.parseText());
            }
          }
        };
        
        /**
         * Helpers
         */
        
        function escape(html, encode) {
          return html
            .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;');
        }
        
        function unescape(html) {
          return html.replace(/&([#\w]+);/g, function(_, n) {
            n = n.toLowerCase();
            if (n === 'colon') return ':';
            if (n.charAt(0) === '#') {
              return n.charAt(1) === 'x'
                ? String.fromCharCode(parseInt(n.substring(2), 16))
                : String.fromCharCode(+n.substring(1));
            }
            return '';
          });
        }
        
        function replace(regex, opt) {
          regex = regex.source;
          opt = opt || '';
          return function self(name, val) {
            if (!name) return new RegExp(regex, opt);
            val = val.source || val;
            val = val.replace(/(^|[^\[])\^/g, '$1');
            regex = regex.replace(name, val);
            return self;
          };
        }
        
        function noop() {}
        noop.exec = noop;
        
        function merge(obj) {
          var i = 1
            , target
            , key;
        
          for (; i < arguments.length; i++) {
            target = arguments[i];
            for (key in target) {
              if (Object.prototype.hasOwnProperty.call(target, key)) {
                obj[key] = target[key];
              }
            }
          }
        
          return obj;
        }
        
        
        /**
         * Marked
         */
        
        function marked(src, opt, callback) {
          if (callback || typeof opt === 'function') {
            if (!callback) {
              callback = opt;
              opt = null;
            }
        
            opt = merge({}, marked.defaults, opt || {});
        
            var highlight = opt.highlight
              , tokens
              , pending
              , i = 0;
        
            try {
              tokens = Lexer.lex(src, opt)
            } catch (e) {
              return callback(e);
            }
        
            pending = tokens.length;
        
            var done = function(err) {
              if (err) {
                opt.highlight = highlight;
                return callback(err);
              }
        
              var out;
        
              try {
                out = Parser.parse(tokens, opt);
              } catch (e) {
                err = e;
              }
        
              opt.highlight = highlight;
        
              return err
                ? callback(err)
                : callback(null, out);
            };
        
            if (!highlight || highlight.length < 3) {
              return done();
            }
        
            delete opt.highlight;
        
            if (!pending) return done();
        
            for (; i < tokens.length; i++) {
              (function(token) {
                if (token.type !== 'code') {
                  return --pending || done();
                }
                return highlight(token.text, token.lang, function(err, code) {
                  if (err) return done(err);
                  if (code == null || code === token.text) {
                    return --pending || done();
                  }
                  token.text = code;
                  token.escaped = true;
                  --pending || done();
                });
              })(tokens[i]);
            }
        
            return;
          }
          try {
            if (opt) opt = merge({}, marked.defaults, opt);
            return Parser.parse(Lexer.lex(src, opt), opt);
          } catch (e) {
            e.message += '\nPlease report this to https://github.com/chjj/marked.';
            if ((opt || marked.defaults).silent) {
              return '<p>An error occured:</p><pre>'
                + escape(e.message + '', true)
                + '</pre>';
            }
            throw e;
          }
        }
        
        /**
         * Options
         */
        
        marked.options =
        marked.setOptions = function(opt) {
          merge(marked.defaults, opt);
          return marked;
        };
        
        marked.defaults = {
          gfm: true,
          tables: true,
          breaks: false,
          pedantic: false,
          sanitize: false,
          smartLists: false,
          silent: false,
          highlight: null,
          langPrefix: 'lang-',
          smartypants: false,
          headerPrefix: '',
          renderer: new Renderer,
          xhtml: false
        };
        
        /**
         * Expose
         */
        
        marked.Parser = Parser;
        marked.parser = Parser.parse;
        
        marked.Renderer = Renderer;
        
        marked.Lexer = Lexer;
        marked.lexer = Lexer.lex;
        
        marked.InlineLexer = InlineLexer;
        marked.inlineLexer = InlineLexer.output;
        
        marked.parse = marked;
        
        if (typeof module !== 'undefined' && typeof exports === 'object') {
          module.exports = marked;
        } else if (typeof define === 'function' && define.amd) {
          define(function() { return marked; });
        } else {
          this.marked = marked;
        }
        
        }).call(function() {
          return this || (typeof window !== 'undefined' ? window : global);
        }());
        
    • tern
      • comment.js
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            return mod(exports);
          if (typeof define == "function" && define.amd) // AMD
            return define(["exports"], mod);
          mod(tern.comment || (tern.comment = {}));
        })(function(exports) {
          function isSpace(ch) {
            return (ch < 14 && ch > 8) || ch === 32 || ch === 160;
          }
        
          function onOwnLine(text, pos) {
            for (; pos > 0; --pos) {
              var ch = text.charCodeAt(pos - 1);
              if (ch == 10) break;
              if (!isSpace(ch)) return false;
            }
            return true;
          }
        
          // Gather comments directly before a function
          exports.commentsBefore = function(text, pos) {
            var found = null, emptyLines = 0, topIsLineComment;
            out: while (pos > 0) {
              var prev = text.charCodeAt(pos - 1);
              if (prev == 10) {
                for (var scan = --pos, sawNonWS = false; scan > 0; --scan) {
                  prev = text.charCodeAt(scan - 1);
                  if (prev == 47 && text.charCodeAt(scan - 2) == 47) {
                    if (!onOwnLine(text, scan - 2)) break out;
                    var content = text.slice(scan, pos);
                    if (!emptyLines && topIsLineComment) found[0] = content + "\n" + found[0];
                    else (found || (found = [])).unshift(content);
                    topIsLineComment = true;
                    emptyLines = 0;
                    pos = scan - 2;
                    break;
                  } else if (prev == 10) {
                    if (!sawNonWS && ++emptyLines > 1) break out;
                    break;
                  } else if (!sawNonWS && !isSpace(prev)) {
                    sawNonWS = true;
                  }
                }
              } else if (prev == 47 && text.charCodeAt(pos - 2) == 42) {
                for (var scan = pos - 2; scan > 1; --scan) {
                  if (text.charCodeAt(scan - 1) == 42 && text.charCodeAt(scan - 2) == 47) {
                    if (!onOwnLine(text, scan - 2)) break out;
                    (found || (found = [])).unshift(text.slice(scan, pos - 2));
                    topIsLineComment = false;
                    emptyLines = 0;
                    break;
                  }
                }
                pos = scan - 2;
              } else if (isSpace(prev)) {
                --pos;
              } else {
                break;
              }
            }
            return found;
          };
        
          exports.commentAfter = function(text, pos) {
            while (pos < text.length) {
              var next = text.charCodeAt(pos);
              if (next == 47) {
                var after = text.charCodeAt(pos + 1), end;
                if (after == 47) // line comment
                  end = text.indexOf("\n", pos + 2);
                else if (after == 42) // block comment
                  end = text.indexOf("*/", pos + 2);
                else
                  return;
                return text.slice(pos + 2, end < 0 ? text.length : end);
              } else if (isSpace(next)) {
                ++pos;
              }
            }
          };
        
          exports.ensureCommentsBefore = function(text, node) {
            if (node.hasOwnProperty("commentsBefore")) return node.commentsBefore;
            return node.commentsBefore = exports.commentsBefore(text, node.start);
          };
        });
        
      • def.js
        // Type description parser
        //
        // Type description JSON files (such as ecma5.json and browser.json)
        // are used to
        //
        // A) describe types that come from native code
        //
        // B) to cheaply load the types for big libraries, or libraries that
        //    can't be inferred well
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            return exports.init = mod;
          if (typeof define == "function" && define.amd) // AMD
            return define({init: mod});
          tern.def = {init: mod};
        })(function(exports, infer) {
          "use strict";
        
          function hop(obj, prop) {
            return Object.prototype.hasOwnProperty.call(obj, prop);
          }
        
          var TypeParser = exports.TypeParser = function(spec, start, base, forceNew) {
            this.pos = start || 0;
            this.spec = spec;
            this.base = base;
            this.forceNew = forceNew;
          };
          TypeParser.prototype = {
            eat: function(str) {
              if (str.length == 1 ? this.spec.charAt(this.pos) == str : this.spec.indexOf(str, this.pos) == this.pos) {
                this.pos += str.length;
                return true;
              }
            },
            word: function(re) {
              var word = "", ch, re = re || /[\w$]/;
              while ((ch = this.spec.charAt(this.pos)) && re.test(ch)) { word += ch; ++this.pos; }
              return word;
            },
            error: function() {
              throw new Error("Unrecognized type spec: " + this.spec + " (at " + this.pos + ")");
            },
            parseFnType: function(name, top) {
              var args = [], names = [];
              if (!this.eat(")")) for (var i = 0; ; ++i) {
                var colon = this.spec.indexOf(": ", this.pos), argname;
                if (colon != -1) {
                  argname = this.spec.slice(this.pos, colon);
                  if (/^[$\w?]+$/.test(argname))
                    this.pos = colon + 2;
                  else
                    argname = null;
                }
                names.push(argname);
                args.push(this.parseType());
                if (!this.eat(", ")) {
                  this.eat(")") || this.error();
                  break;
                }
              }
              var retType, computeRet, computeRetStart, fn;
              if (this.eat(" -> ")) {
                if (top && this.spec.indexOf("!", this.pos) > -1) {
                  retType = infer.ANull;
                  computeRetStart = this.pos;
                  computeRet = this.parseRetType();
                } else retType = this.parseType();
              } else retType = infer.ANull;
              if (top && (fn = this.base))
                infer.Fn.call(this.base, name, infer.ANull, args, names, retType);
              else
                fn = new infer.Fn(name, infer.ANull, args, names, retType);
              if (computeRet) fn.computeRet = computeRet;
              if (computeRetStart != null) fn.computeRetSource = this.spec.slice(computeRetStart, this.pos);
              return fn;
            },
            parseType: function(name, top) {
              if (this.eat("fn(")) {
                return this.parseFnType(name, top);
              } else if (this.eat("[")) {
                var inner = this.parseType();
                this.eat("]") || this.error();
                if (top && this.base) {
                  infer.Arr.call(this.base, inner);
                  return this.base;
                }
                return new infer.Arr(inner);
              } else if (this.eat("+")) {
                var path = this.word(/[\w$<>\.!]/);
                var base = parsePath(path + ".prototype");
                if (!(base instanceof infer.Obj)) base = parsePath(path);
                if (!(base instanceof infer.Obj)) return base;
                if (top && this.forceNew) return new infer.Obj(base);
                return infer.getInstance(base);
              } else if (this.eat("?")) {
                return infer.ANull;
              } else {
                return this.fromWord(this.word(/[\w$<>\.!`]/));
              }
            },
            fromWord: function(spec) {
              var cx = infer.cx();
              switch (spec) {
              case "number": return cx.num;
              case "string": return cx.str;
              case "bool": return cx.bool;
              case "<top>": return cx.topScope;
              }
              if (cx.localDefs && spec in cx.localDefs) return cx.localDefs[spec];
              return parsePath(spec);
            },
            parseBaseRetType: function() {
              if (this.eat("[")) {
                var inner = this.parseRetType();
                this.eat("]") || this.error();
                return function(self, args) { return new infer.Arr(inner(self, args)); };
              } else if (this.eat("+")) {
                var base = this.parseRetType();
                return function(self, args) { return infer.getInstance(base(self, args)); };
              } else if (this.eat("!")) {
                var arg = this.word(/\d/);
                if (arg) {
                  arg = Number(arg);
                  return function(_self, args) {return args[arg] || infer.ANull;};
                } else if (this.eat("this")) {
                  return function(self) {return self;};
                } else if (this.eat("custom:")) {
                  var fname = this.word(/[\w$]/);
                  return customFunctions[fname] || function() { return infer.ANull; };
                } else {
                  return this.fromWord("!" + arg + this.word(/[\w$<>\.!]/));
                }
              }
              var t = this.parseType();
              return function(){return t;};
            },
            extendRetType: function(base) {
              var propName = this.word(/[\w<>$!]/) || this.error();
              if (propName == "!ret") return function(self, args) {
                var lhs = base(self, args);
                if (lhs.retval) return lhs.retval;
                var rv = new infer.AVal;
                lhs.propagate(new infer.IsCallee(infer.ANull, [], null, rv));
                return rv;
              };
              return function(self, args) {return base(self, args).getProp(propName);};
            },
            parseRetType: function() {
              var tp = this.parseBaseRetType();
              while (this.eat(".")) tp = this.extendRetType(tp);
              return tp;
            }
          };
        
          function parseType(spec, name, base, forceNew) {
            var type = new TypeParser(spec, null, base, forceNew).parseType(name, true);
            if (/^fn\(/.test(spec)) for (var i = 0; i < type.args.length; ++i) (function(i) {
              var arg = type.args[i];
              if (arg instanceof infer.Fn && arg.args && arg.args.length) addEffect(type, function(_self, fArgs) {
                var fArg = fArgs[i];
                if (fArg) fArg.propagate(new infer.IsCallee(infer.cx().topScope, arg.args, null, infer.ANull));
              });
            })(i);
            return type;
          }
        
          function addEffect(fn, handler, replaceRet) {
            var oldCmp = fn.computeRet, rv = fn.retval;
            fn.computeRet = function(self, args, argNodes) {
              var handled = handler(self, args, argNodes);
              var old = oldCmp ? oldCmp(self, args, argNodes) : rv;
              return replaceRet ? handled : old;
            };
          }
        
          var parseEffect = exports.parseEffect = function(effect, fn) {
            var m;
            if (effect.indexOf("propagate ") == 0) {
              var p = new TypeParser(effect, 10);
              var getOrigin = p.parseRetType();
              if (!p.eat(" ")) p.error();
              var getTarget = p.parseRetType();
              addEffect(fn, function(self, args) {
                getOrigin(self, args).propagate(getTarget(self, args));
              });
            } else if (effect.indexOf("call ") == 0) {
              var andRet = effect.indexOf("and return ", 5) == 5;
              var p = new TypeParser(effect, andRet ? 16 : 5);
              var getCallee = p.parseRetType(), getSelf = null, getArgs = [];
              if (p.eat(" this=")) getSelf = p.parseRetType();
              while (p.eat(" ")) getArgs.push(p.parseRetType());
              addEffect(fn, function(self, args) {
                var callee = getCallee(self, args);
                var slf = getSelf ? getSelf(self, args) : infer.ANull, as = [];
                for (var i = 0; i < getArgs.length; ++i) as.push(getArgs[i](self, args));
                var result = andRet ? new infer.AVal : infer.ANull;
                callee.propagate(new infer.IsCallee(slf, as, null, result));
                return result;
              }, andRet);
            } else if (m = effect.match(/^custom (\S+)\s*(.*)/)) {
              var customFunc = customFunctions[m[1]];
              if (customFunc) addEffect(fn, m[2] ? customFunc(m[2]) : customFunc);
            } else if (effect.indexOf("copy ") == 0) {
              var p = new TypeParser(effect, 5);
              var getFrom = p.parseRetType();
              p.eat(" ");
              var getTo = p.parseRetType();
              addEffect(fn, function(self, args) {
                var from = getFrom(self, args), to = getTo(self, args);
                from.forAllProps(function(prop, val, local) {
                  if (local && prop != "<i>")
                    to.propagate(new infer.PropHasSubset(prop, val));
                });
              });
            } else {
              throw new Error("Unknown effect type: " + effect);
            }
          };
        
          var currentTopScope;
        
          var parsePath = exports.parsePath = function(path, scope) {
            var cx = infer.cx(), cached = cx.paths[path], origPath = path;
            if (cached != null) return cached;
            cx.paths[path] = infer.ANull;
        
            var base = scope || currentTopScope || cx.topScope;
        
            if (cx.localDefs) for (var name in cx.localDefs) {
              if (path.indexOf(name) == 0) {
                if (path == name) return cx.paths[path] = cx.localDefs[path];
                if (path.charAt(name.length) == ".") {
                  base = cx.localDefs[name];
                  path = path.slice(name.length + 1);
                  break;
                }
              }
            }
        
            var parts = path.split(".");
            for (var i = 0; i < parts.length && base != infer.ANull; ++i) {
              var prop = parts[i];
              if (prop.charAt(0) == "!") {
                if (prop == "!proto") {
                  base = (base instanceof infer.Obj && base.proto) || infer.ANull;
                } else {
                  var fn = base.getFunctionType();
                  if (!fn) {
                    base = infer.ANull;
                  } else if (prop == "!ret") {
                    base = fn.retval && fn.retval.getType(false) || infer.ANull;
                  } else {
                    var arg = fn.args && fn.args[Number(prop.slice(1))];
                    base = (arg && arg.getType(false)) || infer.ANull;
                  }
                }
              } else if (base instanceof infer.Obj) {
                var propVal = (prop == "prototype" && base instanceof infer.Fn) ? base.getProp(prop) : base.props[prop];
                if (!propVal || propVal.isEmpty())
                  base = infer.ANull;
                else
                  base = propVal.types[0];
              }
            }
            // Uncomment this to get feedback on your poorly written .json files
            // if (base == infer.ANull) console.error("bad path: " + origPath + " (" + cx.curOrigin + ")");
            cx.paths[origPath] = base == infer.ANull ? null : base;
            return base;
          };
        
          function emptyObj(ctor) {
            var empty = Object.create(ctor.prototype);
            empty.props = Object.create(null);
            empty.isShell = true;
            return empty;
          }
        
          function isSimpleAnnotation(spec) {
            if (!spec["!type"] || /^(fn\(|\[)/.test(spec["!type"])) return false;
            for (var prop in spec)
              if (prop != "!type" && prop != "!doc" && prop != "!url" && prop != "!span" && prop != "!data")
                return false;
            return true;
          }
        
          function passOne(base, spec, path) {
            if (!base) {
              var tp = spec["!type"];
              if (tp) {
                if (/^fn\(/.test(tp)) base = emptyObj(infer.Fn);
                else if (tp.charAt(0) == "[") base = emptyObj(infer.Arr);
                else throw new Error("Invalid !type spec: " + tp);
              } else if (spec["!stdProto"]) {
                base = infer.cx().protos[spec["!stdProto"]];
              } else {
                base = emptyObj(infer.Obj);
              }
              base.name = path;
            }
        
            for (var name in spec) if (hop(spec, name) && name.charCodeAt(0) != 33) {
              var inner = spec[name];
              if (typeof inner == "string" || isSimpleAnnotation(inner)) continue;
              var prop = base.defProp(name);
              passOne(prop.getType(false), inner, path ? path + "." + name : name).propagate(prop);
            }
            return base;
          }
        
          function passTwo(base, spec, path) {
            if (base.isShell) {
              delete base.isShell;
              var tp = spec["!type"];
              if (tp) {
                parseType(tp, path, base);
              } else {
                var proto = spec["!proto"] && parseType(spec["!proto"]);
                infer.Obj.call(base, proto instanceof infer.Obj ? proto : true, path);
              }
            }
        
            var effects = spec["!effects"];
            if (effects && base instanceof infer.Fn) for (var i = 0; i < effects.length; ++i)
              parseEffect(effects[i], base);
            copyInfo(spec, base);
        
            for (var name in spec) if (hop(spec, name) && name.charCodeAt(0) != 33) {
              var inner = spec[name], known = base.defProp(name), innerPath = path ? path + "." + name : name;
              var type = known.getType(false);
              if (typeof inner == "string") {
                if (type) continue;
                parseType(inner, innerPath).propagate(known);
              } else {
                if (!isSimpleAnnotation(inner)) {
                  passTwo(type, inner, innerPath);
                } else if (!type) {
                  parseType(inner["!type"], innerPath, null, true).propagate(known);
                  type = known.getType(false);
                  if (type instanceof infer.Obj) copyInfo(inner, type);
                } else continue;
                if (inner["!doc"]) known.doc = inner["!doc"];
                if (inner["!url"]) known.url = inner["!url"];
                if (inner["!span"]) known.span = inner["!span"];
              }
            }
            return base;
          }
        
          function copyInfo(spec, type) {
            if (spec["!doc"]) type.doc = spec["!doc"];
            if (spec["!url"]) type.url = spec["!url"];
            if (spec["!span"]) type.span = spec["!span"];
            if (spec["!data"]) type.metaData = spec["!data"];
          }
        
          function runPasses(type, arg) {
            var parent = infer.cx().parent, pass = parent && parent.passes && parent.passes[type];
            if (pass) for (var i = 0; i < pass.length; i++) pass[i](arg);
          }
        
          function doLoadEnvironment(data, scope) {
            var cx = infer.cx();
        
            infer.addOrigin(cx.curOrigin = data["!name"] || "env#" + cx.origins.length);
            cx.localDefs = cx.definitions[cx.curOrigin] = Object.create(null);
        
            runPasses("preLoadDef", data);
        
            passOne(scope, data);
        
            var def = data["!define"];
            if (def) {
              for (var name in def) {
                var spec = def[name];
                cx.localDefs[name] = typeof spec == "string" ? parsePath(spec) : passOne(null, spec, name);
              }
              for (var name in def) {
                var spec = def[name];
                if (typeof spec != "string") passTwo(cx.localDefs[name], def[name], name);
              }
            }
        
            passTwo(scope, data);
        
            runPasses("postLoadDef", data);
        
            cx.curOrigin = cx.localDefs = null;
          }
        
          exports.load = function(data, scope) {
            if (!scope) scope = infer.cx().topScope;
            var oldScope = currentTopScope;
            currentTopScope = scope;
            try {
              doLoadEnvironment(data, scope);
            } finally {
              currentTopScope = oldScope;
            }
          };
        
          exports.parse = function(data, origin, path) {
            var cx = infer.cx();
            if (origin) {
              cx.origin = origin;
              cx.localDefs = cx.definitions[origin];
            }
        
            try {
              if (typeof data == "string")
                return parseType(data, path);
              else
                return passTwo(passOne(null, data, path), data, path);
            } finally {
              if (origin) cx.origin = cx.localDefs = null;
            }
          };
        
          // Used to register custom logic for more involved effect or type
          // computation.
          var customFunctions = Object.create(null);
          infer.registerFunction = function(name, f) { customFunctions[name] = f; };
        
          var IsCreated = infer.constraint("created, target, spec", {
            addType: function(tp) {
              if (tp instanceof infer.Obj && this.created++ < 5) {
                var derived = new infer.Obj(tp), spec = this.spec;
                if (spec instanceof infer.AVal) spec = spec.getType(false);
                if (spec instanceof infer.Obj) for (var prop in spec.props) {
                  var cur = spec.props[prop].types[0];
                  var p = derived.defProp(prop);
                  if (cur && cur instanceof infer.Obj && cur.props.value) {
                    var vtp = cur.props.value.getType(false);
                    if (vtp) p.addType(vtp);
                  }
                }
                this.target.addType(derived);
              }
            }
          });
        
          infer.registerFunction("Object_create", function(_self, args, argNodes) {
            if (argNodes && argNodes.length && argNodes[0].type == "Literal" && argNodes[0].value == null)
              return new infer.Obj();
        
            var result = new infer.AVal;
            if (args[0]) args[0].propagate(new IsCreated(0, result, args[1]));
            return result;
          });
        
          var IsBound = infer.constraint("self, args, target", {
            addType: function(tp) {
              if (!(tp instanceof infer.Fn)) return;
              this.target.addType(new infer.Fn(tp.name, tp.self, tp.args.slice(this.args.length),
                                               tp.argNames.slice(this.args.length), tp.retval));
              this.self.propagate(tp.self);
              for (var i = 0; i < Math.min(tp.args.length, this.args.length); ++i)
                this.args[i].propagate(tp.args[i]);
            }
          });
        
          infer.registerFunction("Function_bind", function(self, args) {
            if (!args.length) return infer.ANull;
            var result = new infer.AVal;
            self.propagate(new IsBound(args[0], args.slice(1), result));
            return result;
          });
        
          infer.registerFunction("Array_ctor", function(_self, args) {
            var arr = new infer.Arr;
            if (args.length != 1 || !args[0].hasType(infer.cx().num)) {
              var content = arr.getProp("<i>");
              for (var i = 0; i < args.length; ++i) args[i].propagate(content);
            }
            return arr;
          });
        
          return exports;
        });
        
      • doc_comment.js
        // Parses comments above variable declarations, function declarations,
        // and object properties as docstrings and JSDoc-style type
        // annotations.
        
        (function(mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            return mod(require("../lib/infer"), require("../lib/tern"), require("../lib/comment"),
                       require("acorn/acorn"), require("acorn/util/walk"));
          if (typeof define == "function" && define.amd) // AMD
            return define(["../lib/infer", "../lib/tern", "../lib/comment", "acorn/acorn", "acorn/util/walk"], mod);
          mod(tern, tern, tern.comment, acorn, acorn.walk);
        })(function(infer, tern, comment, acorn, walk) {
          "use strict";
        
          tern.registerPlugin("doc_comment", function(server) {
            server.jsdocTypedefs = Object.create(null);
            server.on("reset", function() {
              server.jsdocTypedefs = Object.create(null);
            });
        
            return {
              passes: {
                postParse: postParse,
                postInfer: postInfer,
                postLoadDef: postLoadDef
              }
            };
          });
        
          function postParse(ast, text) {
            function attachComments(node) { comment.ensureCommentsBefore(text, node); }
        
            walk.simple(ast, {
              VariableDeclaration: attachComments,
              FunctionDeclaration: attachComments,
              AssignmentExpression: function(node) {
                if (node.operator == "=") attachComments(node);
              },
              ObjectExpression: function(node) {
                for (var i = 0; i < node.properties.length; ++i)
                  attachComments(node.properties[i].key);
              }
            });
          }
        
          function postInfer(ast, scope) {
            jsdocParseTypedefs(ast.sourceFile.text, scope);
        
            walk.simple(ast, {
              VariableDeclaration: function(node, scope) {
                if (node.commentsBefore)
                  interpretComments(node, node.commentsBefore, scope,
                                    scope.getProp(node.declarations[0].id.name));
              },
              FunctionDeclaration: function(node, scope) {
                if (node.commentsBefore)
                  interpretComments(node, node.commentsBefore, scope,
                                    scope.getProp(node.id.name),
                                    node.body.scope.fnType);
              },
              AssignmentExpression: function(node, scope) {
                if (node.commentsBefore)
                  interpretComments(node, node.commentsBefore, scope,
                                    infer.expressionType({node: node.left, state: scope}));
              },
              ObjectExpression: function(node, scope) {
                for (var i = 0; i < node.properties.length; ++i) {
                  var prop = node.properties[i], key = prop.key;
                  if (key.commentsBefore)
                    interpretComments(prop, key.commentsBefore, scope,
                                      node.objType.getProp(key.name));
                }
              }
            }, infer.searchVisitor, scope);
          }
        
          function postLoadDef(data) {
            var defs = data["!typedef"];
            var cx = infer.cx(), orig = data["!name"];
            if (defs) for (var name in defs)
              cx.parent.jsdocTypedefs[name] =
                maybeInstance(infer.def.parse(defs[name], orig, name), name);
          }
        
          // COMMENT INTERPRETATION
        
          function interpretComments(node, comments, scope, aval, type) {
            jsdocInterpretComments(node, scope, aval, comments);
        
            if (!type && aval instanceof infer.AVal && aval.types.length) {
              type = aval.types[aval.types.length - 1];
              if (!(type instanceof infer.Obj) || type.origin != infer.cx().curOrigin || type.doc)
                type = null;
            }
        
            var first = comments[0], dot = first.search(/\.\s/);
            if (dot > 5) first = first.slice(0, dot + 1);
            first = first.trim().replace(/\s*\n\s*\*\s*|\s{1,}/g, " ");
            if (aval instanceof infer.AVal) aval.doc = first;
            if (type) type.doc = first;
          }
        
          // Parses a subset of JSDoc-style comments in order to include the
          // explicitly defined types in the analysis.
        
          function skipSpace(str, pos) {
            while (/\s/.test(str.charAt(pos))) ++pos;
            return pos;
          }
        
          function isIdentifier(string) {
            if (!acorn.isIdentifierStart(string.charCodeAt(0))) return false;
            for (var i = 1; i < string.length; i++)
              if (!acorn.isIdentifierChar(string.charCodeAt(i))) return false;
            return true;
          }
        
          function parseLabelList(scope, str, pos, close) {
            var labels = [], types = [];
            for (var first = true; ; first = false) {
              pos = skipSpace(str, pos);
              if (first && str.charAt(pos) == close) break;
              var colon = str.indexOf(":", pos);
              if (colon < 0) return null;
              var label = str.slice(pos, colon);
              if (!isIdentifier(label)) return null;
              labels.push(label);
              pos = colon + 1;
              var type = parseType(scope, str, pos);
              if (!type) return null;
              pos = type.end;
              types.push(type.type);
              pos = skipSpace(str, pos);
              var next = str.charAt(pos);
              ++pos;
              if (next == close) break;
              if (next != ",") return null;
            }
            return {labels: labels, types: types, end: pos};
          }
        
          function parseType(scope, str, pos) {
            pos = skipSpace(str, pos);
            var type;
        
            if (str.indexOf("function(", pos) == pos) {
              var args = parseLabelList(scope, str, pos + 9, ")"), ret = infer.ANull;
              if (!args) return null;
              pos = skipSpace(str, args.end);
              if (str.charAt(pos) == ":") {
                ++pos;
                var retType = parseType(scope, str, pos + 1);
                if (!retType) return null;
                pos = retType.end;
                ret = retType.type;
              }
              type = new infer.Fn(null, infer.ANull, args.types, args.labels, ret);
            } else if (str.charAt(pos) == "[") {
              var inner = parseType(scope, str, pos + 1);
              if (!inner) return null;
              pos = skipSpace(str, inner.end);
              if (str.charAt(pos) != "]") return null;
              ++pos;
              type = new infer.Arr(inner.type);
            } else if (str.charAt(pos) == "{") {
              var fields = parseLabelList(scope, str, pos + 1, "}");
              if (!fields) return null;
              type = new infer.Obj(true);
              for (var i = 0; i < fields.types.length; ++i) {
                var field = type.defProp(fields.labels[i]);
                field.initializer = true;
                fields.types[i].propagate(field);
              }
              pos = fields.end;
            } else {
              var start = pos;
              if (!acorn.isIdentifierStart(str.charCodeAt(pos))) return null;
              while (acorn.isIdentifierChar(str.charCodeAt(pos))) ++pos;
              if (start == pos) return null;
              var word = str.slice(start, pos);
              if (/^(number|integer)$/i.test(word)) type = infer.cx().num;
              else if (/^bool(ean)?$/i.test(word)) type = infer.cx().bool;
              else if (/^string$/i.test(word)) type = infer.cx().str;
              else if (/^array$/i.test(word)) {
                var inner = null;
                if (str.charAt(pos) == "." && str.charAt(pos + 1) == "<") {
                  var inAngles = parseType(scope, str, pos + 2);
                  if (!inAngles) return null;
                  pos = skipSpace(str, inAngles.end);
                  if (str.charAt(pos++) != ">") return null;
                  inner = inAngles.type;
                }
                type = new infer.Arr(inner);
              } else if (/^object$/i.test(word)) {
                type = new infer.Obj(true);
                if (str.charAt(pos) == "." && str.charAt(pos + 1) == "<") {
                  var key = parseType(scope, str, pos + 2);
                  if (!key) return null;
                  pos = skipSpace(str, key.end);
                  if (str.charAt(pos++) != ",") return null;
                  var val = parseType(scope, str, pos);
                  if (!val) return null;
                  pos = skipSpace(str, val.end);
                  if (str.charAt(pos++) != ">") return null;
                  val.type.propagate(type.defProp("<i>"));
                }
              } else {
                while (str.charCodeAt(pos) == 46 ||
                       acorn.isIdentifierChar(str.charCodeAt(pos))) ++pos;
                var path = str.slice(start, pos);
                var cx = infer.cx(), defs = cx.parent && cx.parent.jsdocTypedefs, found;
                if (defs && (path in defs))
                  type = defs[path];
                else if (found = infer.def.parsePath(path, scope).getType())
                  type = maybeInstance(found, path); 
                else
                  type = infer.ANull;
              }
            }
        
            var isOptional = false;
            if (str.charAt(pos) == "=") {
              ++pos;
              isOptional = true;
            }
            return {type: type, end: pos, isOptional: isOptional};
          }
        
          function maybeInstance(type, path) {
            if (type instanceof infer.Fn && /^[A-Z]/.test(path)) {
              var proto = type.getProp("prototype").getType();
              if (proto instanceof infer.Obj) return infer.getInstance(proto);
            }
            return type;
          }
        
          function parseTypeOuter(scope, str, pos) {
            pos = skipSpace(str, pos || 0);
            if (str.charAt(pos) != "{") return null;
            var result = parseType(scope, str, pos + 1);
            if (!result) return null;
            var end = skipSpace(str, result.end);
            if (str.charAt(end) != "}") return null;
            result.end = end + 1;
            return result;
          }
        
          function jsdocInterpretComments(node, scope, aval, comments) {
            var type, args, ret, foundOne, self, parsed;
        
            for (var i = 0; i < comments.length; ++i) {
              var comment = comments[i];
              var decl = /(?:\n|$|\*)\s*@(type|param|arg(?:ument)?|returns?|this)\s+(.*)/g, m;
              while (m = decl.exec(comment)) {
                if (m[1] == "this" && (parsed = parseType(scope, m[2], 0))) {
                  self = parsed.type;
                  foundOne = true;
                  continue;
                }
        
                if (!(parsed = parseTypeOuter(scope, m[2]))) continue;
                foundOne = true;
        
                switch(m[1]) {
                case "returns": case "return":
                  ret = parsed.type; break;
                case "type":
                  type = parsed.type; break;
                case "param": case "arg": case "argument":
                  var name = m[2].slice(parsed.end).match(/^\s*(\S+)/);
                  if (!name) continue;
                  var argname = name[1] + (parsed.isOptional ? "?" : "");
                  (args || (args = Object.create(null)))[argname] = parsed.type;
                  break;
                }
              }
            }
        
            if (foundOne) applyType(type, self, args, ret, node, aval);
          };
        
          function jsdocParseTypedefs(text, scope) {
            var cx = infer.cx();
        
            var re = /\s@typedef\s+(.*)/g, m;
            while (m = re.exec(text)) {
              var parsed = parseTypeOuter(scope, m[1]);
              var name = parsed && m[1].slice(parsed.end).match(/^\s*(\S+)/);
              if (name)
                cx.parent.jsdocTypedefs[name[1]] = parsed.type;
            }
          }
        
          function applyType(type, self, args, ret, node, aval) {
            var fn;
            if (node.type == "VariableDeclaration") {
              var decl = node.declarations[0];
              if (decl.init && decl.init.type == "FunctionExpression") fn = decl.init.body.scope.fnType;
            } else if (node.type == "FunctionDeclaration") {
              fn = node.body.scope.fnType;
            } else if (node.type == "AssignmentExpression") {
              if (node.right.type == "FunctionExpression")
                fn = node.right.body.scope.fnType;
            } else { // An object property
              if (node.value.type == "FunctionExpression") fn = node.value.body.scope.fnType;
            }
        
            if (fn && (args || ret || self)) {
              if (args) for (var i = 0; i < fn.argNames.length; ++i) {
                var name = fn.argNames[i], known = args[name];
                if (!known && (known = args[name + "?"]))
                  fn.argNames[i] += "?";
                if (known) known.propagate(fn.args[i]);
              }
              if (ret) ret.propagate(fn.retval);
              if (self) self.propagate(fn.self);
            } else if (type) {
              type.propagate(aval);
            }
          };
        });
        
      • infer.js
        // Main type inference engine
        
        // Walks an AST, building up a graph of abstract values and constraints
        // that cause types to flow from one node to another. Also defines a
        // number of utilities for accessing ASTs and scopes.
        
        // Analysis is done in a context, which is tracked by the dynamically
        // bound cx variable. Use withContext to set the current context.
        
        // For memory-saving reasons, individual types export an interface
        // similar to abstract values (which can hold multiple types), and can
        // thus be used in place abstract values that only ever contain a
        // single type.
        
        (function(root, mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            return mod(exports, require("acorn/acorn"), require("acorn/acorn_loose"), require("acorn/util/walk"),
                       require("./def"), require("./signal"));
          if (typeof define == "function" && define.amd) // AMD
            return define(["exports", "acorn/acorn", "acorn/acorn_loose", "acorn/util/walk", "./def", "./signal"], mod);
          mod(root.tern || (root.tern = {}), acorn, acorn, acorn.walk, tern.def, tern.signal); // Plain browser env
        })(this, function(exports, acorn, acorn_loose, walk, def, signal) {
          "use strict";
        
          var toString = exports.toString = function(type, maxDepth, parent) {
            return !type || type == parent ? "?": type.toString(maxDepth);
          };
        
          // A variant of AVal used for unknown, dead-end values. Also serves
          // as prototype for AVals, Types, and Constraints because it
          // implements 'empty' versions of all the methods that the code
          // expects.
          var ANull = exports.ANull = signal.mixin({
            addType: function() {},
            propagate: function() {},
            getProp: function() { return ANull; },
            forAllProps: function() {},
            hasType: function() { return false; },
            isEmpty: function() { return true; },
            getFunctionType: function() {},
            getType: function() {},
            gatherProperties: function() {},
            propagatesTo: function() {},
            typeHint: function() {},
            propHint: function() {}
          });
        
          function extend(proto, props) {
            var obj = Object.create(proto);
            if (props) for (var prop in props) obj[prop] = props[prop];
            return obj;
          }
        
          // ABSTRACT VALUES
        
          var WG_DEFAULT = 100, WG_NEW_INSTANCE = 90, WG_MADEUP_PROTO = 10, WG_MULTI_MEMBER = 5,
              WG_CATCH_ERROR = 5, WG_GLOBAL_THIS = 90, WG_SPECULATIVE_THIS = 2;
        
          var AVal = exports.AVal = function() {
            this.types = [];
            this.forward = null;
            this.maxWeight = 0;
          };
          AVal.prototype = extend(ANull, {
            addType: function(type, weight) {
              weight = weight || WG_DEFAULT;
              if (this.maxWeight < weight) {
                this.maxWeight = weight;
                if (this.types.length == 1 && this.types[0] == type) return;
                this.types.length = 0;
              } else if (this.maxWeight > weight || this.types.indexOf(type) > -1) {
                return;
              }
        
              this.signal("addType", type);
              this.types.push(type);
              var forward = this.forward;
              if (forward) withWorklist(function(add) {
                for (var i = 0; i < forward.length; ++i) add(type, forward[i], weight);
              });
            },
        
            propagate: function(target, weight) {
              if (target == ANull || (target instanceof Type)) return;
              if (weight && weight < WG_DEFAULT) target = new Muffle(target, weight);
              (this.forward || (this.forward = [])).push(target);
              var types = this.types;
              if (types.length) withWorklist(function(add) {
                for (var i = 0; i < types.length; ++i) add(types[i], target, weight);
              });
            },
        
            getProp: function(prop) {
              if (prop == "__proto__" || prop == "✖") return ANull;
              var found = (this.props || (this.props = Object.create(null)))[prop];
              if (!found) {
                found = this.props[prop] = new AVal;
                this.propagate(new PropIsSubset(prop, found));
              }
              return found;
            },
        
            forAllProps: function(c) {
              this.propagate(new ForAllProps(c));
            },
        
            hasType: function(type) {
              return this.types.indexOf(type) > -1;
            },
            isEmpty: function() { return this.types.length === 0; },
            getFunctionType: function() {
              for (var i = this.types.length - 1; i >= 0; --i)
                if (this.types[i] instanceof Fn) return this.types[i];
            },
        
            getType: function(guess) {
              if (this.types.length === 0 && guess !== false) return this.makeupType();
              if (this.types.length === 1) return this.types[0];
              return canonicalType(this.types);
            },
        
            computedPropType: function() {
              if (!this.propertyOf || !this.propertyOf.hasProp("<i>")) return null;
              var computedProp = this.propertyOf.getProp("<i>");
              if (computedProp == this) return null;
              return computedProp.getType();
            },
        
            makeupType: function() {
              var computed = this.computedPropType();
              if (computed) return computed;
        
              if (!this.forward) return null;
              for (var i = this.forward.length - 1; i >= 0; --i) {
                var hint = this.forward[i].typeHint();
                if (hint && !hint.isEmpty()) {guessing = true; return hint;}
              }
        
              var props = Object.create(null), foundProp = null;
              for (var i = 0; i < this.forward.length; ++i) {
                var prop = this.forward[i].propHint();
                if (prop && prop != "length" && prop != "<i>" && prop != "✖" && prop != cx.completingProperty) {
                  props[prop] = true;
                  foundProp = prop;
                }
              }
              if (!foundProp) return null;
        
              var objs = objsWithProp(foundProp);
              if (objs) {
                var matches = [];
                search: for (var i = 0; i < objs.length; ++i) {
                  var obj = objs[i];
                  for (var prop in props) if (!obj.hasProp(prop)) continue search;
                  if (obj.hasCtor) obj = getInstance(obj);
                  matches.push(obj);
                }
                var canon = canonicalType(matches);
                if (canon) {guessing = true; return canon;}
              }
            },
        
            typeHint: function() { return this.types.length ? this.getType() : null; },
            propagatesTo: function() { return this; },
        
            gatherProperties: function(f, depth) {
              for (var i = 0; i < this.types.length; ++i)
                this.types[i].gatherProperties(f, depth);
            },
        
            guessProperties: function(f) {
              if (this.forward) for (var i = 0; i < this.forward.length; ++i) {
                var prop = this.forward[i].propHint();
                if (prop) f(prop, null, 0);
              }
              var guessed = this.makeupType();
              if (guessed) guessed.gatherProperties(f);
            }
          });
        
          function canonicalType(types) {
            var arrays = 0, fns = 0, objs = 0, prim = null;
            for (var i = 0; i < types.length; ++i) {
              var tp = types[i];
              if (tp instanceof Arr) ++arrays;
              else if (tp instanceof Fn) ++fns;
              else if (tp instanceof Obj) ++objs;
              else if (tp instanceof Prim) {
                if (prim && tp.name != prim.name) return null;
                prim = tp;
              }
            }
            var kinds = (arrays && 1) + (fns && 1) + (objs && 1) + (prim && 1);
            if (kinds > 1) return null;
            if (prim) return prim;
        
            var maxScore = 0, maxTp = null;
            for (var i = 0; i < types.length; ++i) {
              var tp = types[i], score = 0;
              if (arrays) {
                score = tp.getProp("<i>").isEmpty() ? 1 : 2;
              } else if (fns) {
                score = 1;
                for (var j = 0; j < tp.args.length; ++j) if (!tp.args[j].isEmpty()) ++score;
                if (!tp.retval.isEmpty()) ++score;
              } else if (objs) {
                score = tp.name ? 100 : 2;
              }
              if (score >= maxScore) { maxScore = score; maxTp = tp; }
            }
            return maxTp;
          }
        
          // PROPAGATION STRATEGIES
        
          function Constraint() {}
          Constraint.prototype = extend(ANull, {
            init: function() { this.origin = cx.curOrigin; }
          });
        
          var constraint = exports.constraint = function(props, methods) {
            var body = "this.init();";
            props = props ? props.split(", ") : [];
            for (var i = 0; i < props.length; ++i)
              body += "this." + props[i] + " = " + props[i] + ";";
            var ctor = Function.apply(null, props.concat([body]));
            ctor.prototype = Object.create(Constraint.prototype);
            for (var m in methods) if (methods.hasOwnProperty(m)) ctor.prototype[m] = methods[m];
            return ctor;
          };
        
          var PropIsSubset = constraint("prop, target", {
            addType: function(type, weight) {
              if (type.getProp)
                type.getProp(this.prop).propagate(this.target, weight);
            },
            propHint: function() { return this.prop; },
            propagatesTo: function() {
              if (this.prop == "<i>" || !/[^\w_]/.test(this.prop))
                return {target: this.target, pathExt: "." + this.prop};
            }
          });
        
          var PropHasSubset = exports.PropHasSubset = constraint("prop, type, originNode", {
            addType: function(type, weight) {
              if (!(type instanceof Obj)) return;
              var prop = type.defProp(this.prop, this.originNode);
              prop.origin = this.origin;
              this.type.propagate(prop, weight);
            },
            propHint: function() { return this.prop; }
          });
        
          var ForAllProps = constraint("c", {
            addType: function(type) {
              if (!(type instanceof Obj)) return;
              type.forAllProps(this.c);
            }
          });
        
          function withDisabledComputing(fn, body) {
            cx.disabledComputing = {fn: fn, prev: cx.disabledComputing};
            try {
              return body();
            } finally {
              cx.disabledComputing = cx.disabledComputing.prev;
            }
          }
          var IsCallee = exports.IsCallee = constraint("self, args, argNodes, retval", {
            init: function() {
              Constraint.prototype.init.call(this);
              this.disabled = cx.disabledComputing;
            },
            addType: function(fn, weight) {
              if (!(fn instanceof Fn)) return;
              for (var i = 0; i < this.args.length; ++i) {
                if (i < fn.args.length) this.args[i].propagate(fn.args[i], weight);
                if (fn.arguments) this.args[i].propagate(fn.arguments, weight);
              }
              this.self.propagate(fn.self, this.self == cx.topScope ? WG_GLOBAL_THIS : weight);
              var compute = fn.computeRet;
              if (compute) for (var d = this.disabled; d; d = d.prev)
                if (d.fn == fn || fn.name && d.fn.name == fn.name) compute = null;
              if (compute)
                compute(this.self, this.args, this.argNodes).propagate(this.retval, weight);
              else
                fn.retval.propagate(this.retval, weight);
            },
            typeHint: function() {
              var names = [];
              for (var i = 0; i < this.args.length; ++i) names.push("?");
              return new Fn(null, this.self, this.args, names, ANull);
            },
            propagatesTo: function() {
              return {target: this.retval, pathExt: ".!ret"};
            }
          });
        
          var HasMethodCall = constraint("propName, args, argNodes, retval", {
            init: function() {
              Constraint.prototype.init.call(this);
              this.disabled = cx.disabledComputing;
            },
            addType: function(obj, weight) {
              var callee = new IsCallee(obj, this.args, this.argNodes, this.retval);
              callee.disabled = this.disabled;
              obj.getProp(this.propName).propagate(callee, weight);
            },
            propHint: function() { return this.propName; }
          });
        
          var IsCtor = exports.IsCtor = constraint("target, noReuse", {
            addType: function(f, weight) {
              if (!(f instanceof Fn)) return;
              if (cx.parent && !cx.parent.options.reuseInstances) this.noReuse = true;
              f.getProp("prototype").propagate(new IsProto(this.noReuse ? false : f, this.target), weight);
            }
          });
        
          var getInstance = exports.getInstance = function(obj, ctor) {
            if (ctor === false) return new Obj(obj);
        
            if (!ctor) ctor = obj.hasCtor;
            if (!obj.instances) obj.instances = [];
            for (var i = 0; i < obj.instances.length; ++i) {
              var cur = obj.instances[i];
              if (cur.ctor == ctor) return cur.instance;
            }
            var instance = new Obj(obj, ctor && ctor.name);
            instance.origin = obj.origin;
            obj.instances.push({ctor: ctor, instance: instance});
            return instance;
          };
        
          var IsProto = exports.IsProto = constraint("ctor, target", {
            addType: function(o, _weight) {
              if (!(o instanceof Obj)) return;
              if ((this.count = (this.count || 0) + 1) > 8) return;
              if (o == cx.protos.Array)
                this.target.addType(new Arr);
              else
                this.target.addType(getInstance(o, this.ctor));
            }
          });
        
          var FnPrototype = constraint("fn", {
            addType: function(o, _weight) {
              if (o instanceof Obj && !o.hasCtor) {
                o.hasCtor = this.fn;
                var adder = new SpeculativeThis(o, this.fn);
                adder.addType(this.fn);
                o.forAllProps(function(_prop, val, local) {
                  if (local) val.propagate(adder);
                });
              }
            }
          });
        
          var IsAdded = constraint("other, target", {
            addType: function(type, weight) {
              if (type == cx.str)
                this.target.addType(cx.str, weight);
              else if (type == cx.num && this.other.hasType(cx.num))
                this.target.addType(cx.num, weight);
            },
            typeHint: function() { return this.other; }
          });
        
          var IfObj = exports.IfObj = constraint("target", {
            addType: function(t, weight) {
              if (t instanceof Obj) this.target.addType(t, weight);
            },
            propagatesTo: function() { return this.target; }
          });
        
          var SpeculativeThis = constraint("obj, ctor", {
            addType: function(tp) {
              if (tp instanceof Fn && tp.self && tp.self.isEmpty())
                tp.self.addType(getInstance(this.obj, this.ctor), WG_SPECULATIVE_THIS);
            }
          });
        
          var Muffle = constraint("inner, weight", {
            addType: function(tp, weight) {
              this.inner.addType(tp, Math.min(weight, this.weight));
            },
            propagatesTo: function() { return this.inner.propagatesTo(); },
            typeHint: function() { return this.inner.typeHint(); },
            propHint: function() { return this.inner.propHint(); }
          });
        
          // TYPE OBJECTS
        
          var Type = exports.Type = function() {};
          Type.prototype = extend(ANull, {
            constructor: Type,
            propagate: function(c, w) { c.addType(this, w); },
            hasType: function(other) { return other == this; },
            isEmpty: function() { return false; },
            typeHint: function() { return this; },
            getType: function() { return this; }
          });
        
          var Prim = exports.Prim = function(proto, name) { this.name = name; this.proto = proto; };
          Prim.prototype = extend(Type.prototype, {
            constructor: Prim,
            toString: function() { return this.name; },
            getProp: function(prop) {return this.proto.hasProp(prop) || ANull;},
            gatherProperties: function(f, depth) {
              if (this.proto) this.proto.gatherProperties(f, depth);
            }
          });
        
          var Obj = exports.Obj = function(proto, name) {
            if (!this.props) this.props = Object.create(null);
            this.proto = proto === true ? cx.protos.Object : proto;
            if (proto && !name && proto.name && !(this instanceof Fn)) {
              var match = /^(.*)\.prototype$/.exec(this.proto.name);
              if (match) name = match[1];
            }
            this.name = name;
            this.maybeProps = null;
            this.origin = cx.curOrigin;
          };
          Obj.prototype = extend(Type.prototype, {
            constructor: Obj,
            toString: function(maxDepth) {
              if (!maxDepth && this.name) return this.name;
              var props = [], etc = false;
              for (var prop in this.props) if (prop != "<i>") {
                if (props.length > 5) { etc = true; break; }
                if (maxDepth)
                  props.push(prop + ": " + toString(this.props[prop].getType(), maxDepth - 1));
                else
                  props.push(prop);
              }
              props.sort();
              if (etc) props.push("...");
              return "{" + props.join(", ") + "}";
            },
            hasProp: function(prop, searchProto) {
              var found = this.props[prop];
              if (searchProto !== false)
                for (var p = this.proto; p && !found; p = p.proto) found = p.props[prop];
              return found;
            },
            defProp: function(prop, originNode) {
              var found = this.hasProp(prop, false);
              if (found) {
                if (originNode && !found.originNode) found.originNode = originNode;
                return found;
              }
              if (prop == "__proto__" || prop == "✖") return ANull;
        
              var av = this.maybeProps && this.maybeProps[prop];
              if (av) {
                delete this.maybeProps[prop];
                this.maybeUnregProtoPropHandler();
              } else {
                av = new AVal;
                av.propertyOf = this;
              }
        
              this.props[prop] = av;
              av.originNode = originNode;
              av.origin = cx.curOrigin;
              this.broadcastProp(prop, av, true);
              return av;
            },
            getProp: function(prop) {
              var found = this.hasProp(prop, true) || (this.maybeProps && this.maybeProps[prop]);
              if (found) return found;
              if (prop == "__proto__" || prop == "✖") return ANull;
              var av = this.ensureMaybeProps()[prop] = new AVal;
              av.propertyOf = this;
              return av;
            },
            broadcastProp: function(prop, val, local) {
              if (local) {
                this.signal("addProp", prop, val);
                // If this is a scope, it shouldn't be registered
                if (!(this instanceof Scope)) registerProp(prop, this);
              }
        
              if (this.onNewProp) for (var i = 0; i < this.onNewProp.length; ++i) {
                var h = this.onNewProp[i];
                h.onProtoProp ? h.onProtoProp(prop, val, local) : h(prop, val, local);
              }
            },
            onProtoProp: function(prop, val, _local) {
              var maybe = this.maybeProps && this.maybeProps[prop];
              if (maybe) {
                delete this.maybeProps[prop];
                this.maybeUnregProtoPropHandler();
                this.proto.getProp(prop).propagate(maybe);
              }
              this.broadcastProp(prop, val, false);
            },
            ensureMaybeProps: function() {
              if (!this.maybeProps) {
                if (this.proto) this.proto.forAllProps(this);
                this.maybeProps = Object.create(null);
              }
              return this.maybeProps;
            },
            removeProp: function(prop) {
              var av = this.props[prop];
              delete this.props[prop];
              this.ensureMaybeProps()[prop] = av;
              av.types.length = 0;
            },
            forAllProps: function(c) {
              if (!this.onNewProp) {
                this.onNewProp = [];
                if (this.proto) this.proto.forAllProps(this);
              }
              this.onNewProp.push(c);
              for (var o = this; o; o = o.proto) for (var prop in o.props) {
                if (c.onProtoProp)
                  c.onProtoProp(prop, o.props[prop], o == this);
                else
                  c(prop, o.props[prop], o == this);
              }
            },
            maybeUnregProtoPropHandler: function() {
              if (this.maybeProps) {
                for (var _n in this.maybeProps) return;
                this.maybeProps = null;
              }
              if (!this.proto || this.onNewProp && this.onNewProp.length) return;
              this.proto.unregPropHandler(this);
            },
            unregPropHandler: function(handler) {
              for (var i = 0; i < this.onNewProp.length; ++i)
                if (this.onNewProp[i] == handler) { this.onNewProp.splice(i, 1); break; }
              this.maybeUnregProtoPropHandler();
            },
            gatherProperties: function(f, depth) {
              for (var prop in this.props) if (prop != "<i>")
                f(prop, this, depth);
              if (this.proto) this.proto.gatherProperties(f, depth + 1);
            }
          });
        
          var Fn = exports.Fn = function(name, self, args, argNames, retval) {
            Obj.call(this, cx.protos.Function, name);
            this.self = self;
            this.args = args;
            this.argNames = argNames;
            this.retval = retval;
          };
          Fn.prototype = extend(Obj.prototype, {
            constructor: Fn,
            toString: function(maxDepth) {
              if (maxDepth) maxDepth--;
              var str = "fn(";
              for (var i = 0; i < this.args.length; ++i) {
                if (i) str += ", ";
                var name = this.argNames[i];
                if (name && name != "?") str += name + ": ";
                str += toString(this.args[i].getType(), maxDepth, this);
              }
              str += ")";
              if (!this.retval.isEmpty())
                str += " -> " + toString(this.retval.getType(), maxDepth, this);
              return str;
            },
            getProp: function(prop) {
              if (prop == "prototype") {
                var known = this.hasProp(prop, false);
                if (!known) {
                  known = this.defProp(prop);
                  var proto = new Obj(true, this.name && this.name + ".prototype");
                  proto.origin = this.origin;
                  known.addType(proto, WG_MADEUP_PROTO);
                }
                return known;
              }
              return Obj.prototype.getProp.call(this, prop);
            },
            defProp: function(prop, originNode) {
              if (prop == "prototype") {
                var found = this.hasProp(prop, false);
                if (found) return found;
                found = Obj.prototype.defProp.call(this, prop, originNode);
                found.origin = this.origin;
                found.propagate(new FnPrototype(this));
                return found;
              }
              return Obj.prototype.defProp.call(this, prop, originNode);
            },
            getFunctionType: function() { return this; }
          });
        
          var Arr = exports.Arr = function(contentType) {
            Obj.call(this, cx.protos.Array);
            var content = this.defProp("<i>");
            if (contentType) contentType.propagate(content);
          };
          Arr.prototype = extend(Obj.prototype, {
            constructor: Arr,
            toString: function(maxDepth) {
              return "[" + toString(this.getProp("<i>").getType(), maxDepth, this) + "]";
            }
          });
        
          // THE PROPERTY REGISTRY
        
          function registerProp(prop, obj) {
            var data = cx.props[prop] || (cx.props[prop] = []);
            data.push(obj);
          }
        
          function objsWithProp(prop) {
            return cx.props[prop];
          }
        
          // INFERENCE CONTEXT
        
          exports.Context = function(defs, parent) {
            this.parent = parent;
            this.props = Object.create(null);
            this.protos = Object.create(null);
            this.origins = [];
            this.curOrigin = "ecma5";
            this.paths = Object.create(null);
            this.definitions = Object.create(null);
            this.purgeGen = 0;
            this.workList = null;
            this.disabledComputing = null;
        
            exports.withContext(this, function() {
              cx.protos.Object = new Obj(null, "Object.prototype");
              cx.topScope = new Scope();
              cx.topScope.name = "<top>";
              cx.protos.Array = new Obj(true, "Array.prototype");
              cx.protos.Function = new Obj(true, "Function.prototype");
              cx.protos.RegExp = new Obj(true, "RegExp.prototype");
              cx.protos.String = new Obj(true, "String.prototype");
              cx.protos.Number = new Obj(true, "Number.prototype");
              cx.protos.Boolean = new Obj(true, "Boolean.prototype");
              cx.str = new Prim(cx.protos.String, "string");
              cx.bool = new Prim(cx.protos.Boolean, "bool");
              cx.num = new Prim(cx.protos.Number, "number");
              cx.curOrigin = null;
        
              if (defs) for (var i = 0; i < defs.length; ++i)
                def.load(defs[i]);
            });
          };
        
          var cx = null;
          exports.cx = function() { return cx; };
        
          exports.withContext = function(context, f) {
            var old = cx;
            cx = context;
            try { return f(); }
            finally { cx = old; }
          };
        
          exports.TimedOut = function() {
            this.message = "Timed out";
            this.stack = (new Error()).stack;
          };
          exports.TimedOut.prototype = Object.create(Error.prototype);
          exports.TimedOut.prototype.name = "infer.TimedOut";
        
          var timeout;
          exports.withTimeout = function(ms, f) {
            var end = +new Date + ms;
            var oldEnd = timeout;
            if (oldEnd && oldEnd < end) return f();
            timeout = end;
            try { return f(); }
            finally { timeout = oldEnd; }
          };
        
          exports.addOrigin = function(origin) {
            if (cx.origins.indexOf(origin) < 0) cx.origins.push(origin);
          };
        
          var baseMaxWorkDepth = 20, reduceMaxWorkDepth = 0.0001;
          function withWorklist(f) {
            if (cx.workList) return f(cx.workList);
        
            var list = [], depth = 0;
            var add = cx.workList = function(type, target, weight) {
              if (depth < baseMaxWorkDepth - reduceMaxWorkDepth * list.length)
                list.push(type, target, weight, depth);
            };
            try {
              var ret = f(add);
              for (var i = 0; i < list.length; i += 4) {
                if (timeout && +new Date >= timeout)
                  throw new exports.TimedOut();
                depth = list[i + 3] + 1;
                list[i + 1].addType(list[i], list[i + 2]);
              }
              return ret;
            } finally {
              cx.workList = null;
            }
          }
        
          // SCOPES
        
          var Scope = exports.Scope = function(prev) {
            Obj.call(this, prev || true);
            this.prev = prev;
          };
          Scope.prototype = extend(Obj.prototype, {
            constructor: Scope,
            defVar: function(name, originNode) {
              for (var s = this; ; s = s.proto) {
                var found = s.props[name];
                if (found) return found;
                if (!s.prev) return s.defProp(name, originNode);
              }
            }
          });
        
          // RETVAL COMPUTATION HEURISTICS
        
          function maybeInstantiate(scope, score) {
            if (scope.fnType)
              scope.fnType.instantiateScore = (scope.fnType.instantiateScore || 0) + score;
          }
        
          var NotSmaller = {};
          function nodeSmallerThan(node, n) {
            try {
              walk.simple(node, {Expression: function() { if (--n <= 0) throw NotSmaller; }});
              return true;
            } catch(e) {
              if (e == NotSmaller) return false;
              throw e;
            }
          }
        
          function maybeTagAsInstantiated(node, scope) {
            var score = scope.fnType.instantiateScore;
            if (!cx.disabledComputing && score && scope.fnType.args.length && nodeSmallerThan(node, score * 5)) {
              maybeInstantiate(scope.prev, score / 2);
              setFunctionInstantiated(node, scope);
              return true;
            } else {
              scope.fnType.instantiateScore = null;
            }
          }
        
          function setFunctionInstantiated(node, scope) {
            var fn = scope.fnType;
            // Disconnect the arg avals, so that we can add info to them without side effects
            for (var i = 0; i < fn.args.length; ++i) fn.args[i] = new AVal;
            fn.self = new AVal;
            fn.computeRet = function(self, args) {
              // Prevent recursion
              return withDisabledComputing(fn, function() {
                var oldOrigin = cx.curOrigin;
                cx.curOrigin = fn.origin;
                var scopeCopy = new Scope(scope.prev);
                scopeCopy.originNode = scope.originNode;
                for (var v in scope.props) {
                  var local = scopeCopy.defProp(v, scope.props[v].originNode);
                  for (var i = 0; i < args.length; ++i) if (fn.argNames[i] == v && i < args.length)
                    args[i].propagate(local);
                }
                var argNames = fn.argNames.length != args.length ? fn.argNames.slice(0, args.length) : fn.argNames;
                while (argNames.length < args.length) argNames.push("?");
                scopeCopy.fnType = new Fn(fn.name, self, args, argNames, ANull);
                if (fn.arguments) {
                  var argset = scopeCopy.fnType.arguments = new AVal;
                  scopeCopy.defProp("arguments").addType(new Arr(argset));
                  for (var i = 0; i < args.length; ++i) args[i].propagate(argset);
                }
                node.body.scope = scopeCopy;
                walk.recursive(node.body, scopeCopy, null, scopeGatherer);
                walk.recursive(node.body, scopeCopy, null, inferWrapper);
                cx.curOrigin = oldOrigin;
                return scopeCopy.fnType.retval;
              });
            };
          }
        
          function maybeTagAsGeneric(scope) {
            var fn = scope.fnType, target = fn.retval;
            if (target == ANull) return;
            var targetInner, asArray;
            if (!target.isEmpty() && (targetInner = target.getType()) instanceof Arr)
              target = asArray = targetInner.getProp("<i>");
        
            function explore(aval, path, depth) {
              if (depth > 3 || !aval.forward) return;
              for (var i = 0; i < aval.forward.length; ++i) {
                var prop = aval.forward[i].propagatesTo();
                if (!prop) continue;
                var newPath = path, dest;
                if (prop instanceof AVal) {
                  dest = prop;
                } else if (prop.target instanceof AVal) {
                  newPath += prop.pathExt;
                  dest = prop.target;
                } else continue;
                if (dest == target) return newPath;
                var found = explore(dest, newPath, depth + 1);
                if (found) return found;
              }
            }
        
            var foundPath = explore(fn.self, "!this", 0);
            for (var i = 0; !foundPath && i < fn.args.length; ++i)
              foundPath = explore(fn.args[i], "!" + i, 0);
        
            if (foundPath) {
              if (asArray) foundPath = "[" + foundPath + "]";
              var p = new def.TypeParser(foundPath);
              fn.computeRet = p.parseRetType();
              fn.computeRetSource = foundPath;
              return true;
            }
          }
        
          // SCOPE GATHERING PASS
        
          function addVar(scope, nameNode) {
            return scope.defProp(nameNode.name, nameNode);
          }
        
          var scopeGatherer = walk.make({
            Function: function(node, scope, c) {
              var inner = node.body.scope = new Scope(scope);
              inner.originNode = node;
              var argVals = [], argNames = [];
              for (var i = 0; i < node.params.length; ++i) {
                var param = node.params[i];
                argNames.push(param.name);
                argVals.push(addVar(inner, param));
              }
              inner.fnType = new Fn(node.id && node.id.name, new AVal, argVals, argNames, ANull);
              inner.fnType.originNode = node;
              if (node.id) {
                var decl = node.type == "FunctionDeclaration";
                addVar(decl ? scope : inner, node.id);
              }
              c(node.body, inner, "ScopeBody");
            },
            TryStatement: function(node, scope, c) {
              c(node.block, scope, "Statement");
              if (node.handler) {
                var v = addVar(scope, node.handler.param);
                c(node.handler.body, scope, "ScopeBody");
                var e5 = cx.definitions.ecma5;
                if (e5 && v.isEmpty()) getInstance(e5["Error.prototype"]).propagate(v, WG_CATCH_ERROR);
              }
              if (node.finalizer) c(node.finalizer, scope, "Statement");
            },
            VariableDeclaration: function(node, scope, c) {
              for (var i = 0; i < node.declarations.length; ++i) {
                var decl = node.declarations[i];
                addVar(scope, decl.id);
                if (decl.init) c(decl.init, scope, "Expression");
              }
            }
          });
        
          // CONSTRAINT GATHERING PASS
        
          function propName(node, scope, c) {
            var prop = node.property;
            if (!node.computed) return prop.name;
            if (prop.type == "Literal" && typeof prop.value == "string") return prop.value;
            if (c) infer(prop, scope, c, ANull);
            return "<i>";
          }
        
          function unopResultType(op) {
            switch (op) {
            case "+": case "-": case "~": return cx.num;
            case "!": return cx.bool;
            case "typeof": return cx.str;
            case "void": case "delete": return ANull;
            }
          }
          function binopIsBoolean(op) {
            switch (op) {
            case "==": case "!=": case "===": case "!==": case "<": case ">": case ">=": case "<=":
            case "in": case "instanceof": return true;
            }
          }
          function literalType(val) {
            switch (typeof val) {
            case "boolean": return cx.bool;
            case "number": return cx.num;
            case "string": return cx.str;
            case "object":
            case "function":
              if (!val) return ANull;
              return getInstance(cx.protos.RegExp);
            }
          }
        
          function ret(f) {
            return function(node, scope, c, out, name) {
              var r = f(node, scope, c, name);
              if (out) r.propagate(out);
              return r;
            };
          }
          function fill(f) {
            return function(node, scope, c, out, name) {
              if (!out) out = new AVal;
              f(node, scope, c, out, name);
              return out;
            };
          }
        
          var inferExprVisitor = {
            ArrayExpression: ret(function(node, scope, c) {
              var eltval = new AVal;
              for (var i = 0; i < node.elements.length; ++i) {
                var elt = node.elements[i];
                if (elt) infer(elt, scope, c, eltval);
              }
              return new Arr(eltval);
            }),
            ObjectExpression: ret(function(node, scope, c, name) {
              var obj = node.objType = new Obj(true, name);
              obj.originNode = node;
        
              for (var i = 0; i < node.properties.length; ++i) {
                var prop = node.properties[i], key = prop.key, name;
                if (prop.value.name == "✖") {
                  continue;
                } else if (key.type == "Identifier") {
                  name = key.name;
                } else if (typeof key.value == "string") {
                  name = key.value;
                } else {
                  infer(prop.value, scope, c, ANull);
                  continue;
                }
                var val = obj.defProp(name, key);
                val.initializer = true;
                infer(prop.value, scope, c, val, name);
              }
              return obj;
            }),
            FunctionExpression: ret(function(node, scope, c, name) {
              var inner = node.body.scope, fn = inner.fnType;
              if (name && !fn.name) fn.name = name;
              c(node.body, scope, "ScopeBody");
              maybeTagAsInstantiated(node, inner) || maybeTagAsGeneric(inner);
              if (node.id) inner.getProp(node.id.name).addType(fn);
              return fn;
            }),
            SequenceExpression: ret(function(node, scope, c) {
              for (var i = 0, l = node.expressions.length - 1; i < l; ++i)
                infer(node.expressions[i], scope, c, ANull);
              return infer(node.expressions[l], scope, c);
            }),
            UnaryExpression: ret(function(node, scope, c) {
              infer(node.argument, scope, c, ANull);
              return unopResultType(node.operator);
            }),
            UpdateExpression: ret(function(node, scope, c) {
              infer(node.argument, scope, c, ANull);
              return cx.num;
            }),
            BinaryExpression: ret(function(node, scope, c) {
              if (node.operator == "+") {
                var lhs = infer(node.left, scope, c);
                var rhs = infer(node.right, scope, c);
                if (lhs.hasType(cx.str) || rhs.hasType(cx.str)) return cx.str;
                if (lhs.hasType(cx.num) && rhs.hasType(cx.num)) return cx.num;
                var result = new AVal;
                lhs.propagate(new IsAdded(rhs, result));
                rhs.propagate(new IsAdded(lhs, result));
                return result;
              } else {
                infer(node.left, scope, c, ANull);
                infer(node.right, scope, c, ANull);
                return binopIsBoolean(node.operator) ? cx.bool : cx.num;
              }
            }),
            AssignmentExpression: ret(function(node, scope, c) {
              var rhs, name, pName;
              if (node.left.type == "MemberExpression") {
                pName = propName(node.left, scope, c);
                if (node.left.object.type == "Identifier")
                  name = node.left.object.name + "." + pName;
              } else {
                name = node.left.name;
              }
        
              if (node.operator != "=" && node.operator != "+=") {
                infer(node.right, scope, c, ANull);
                rhs = cx.num;
              } else {
                rhs = infer(node.right, scope, c, null, name);
              }
        
              if (node.left.type == "MemberExpression") {
                var obj = infer(node.left.object, scope, c);
                if (pName == "prototype") maybeInstantiate(scope, 20);
                if (pName == "<i>") {
                  // This is a hack to recognize for/in loops that copy
                  // properties, and do the copying ourselves, insofar as we
                  // manage, because such loops tend to be relevant for type
                  // information.
                  var v = node.left.property.name, local = scope.props[v], over = local && local.iteratesOver;
                  if (over) {
                    maybeInstantiate(scope, 20);
                    var fromRight = node.right.type == "MemberExpression" && node.right.computed && node.right.property.name == v;
                    over.forAllProps(function(prop, val, local) {
                      if (local && prop != "prototype" && prop != "<i>")
                        obj.propagate(new PropHasSubset(prop, fromRight ? val : ANull));
                    });
                    return rhs;
                  }
                }
                obj.propagate(new PropHasSubset(pName, rhs, node.left.property));
              } else { // Identifier
                rhs.propagate(scope.defVar(node.left.name, node.left));
              }
              return rhs;
            }),
            LogicalExpression: fill(function(node, scope, c, out) {
              infer(node.left, scope, c, out);
              infer(node.right, scope, c, out);
            }),
            ConditionalExpression: fill(function(node, scope, c, out) {
              infer(node.test, scope, c, ANull);
              infer(node.consequent, scope, c, out);
              infer(node.alternate, scope, c, out);
            }),
            NewExpression: fill(function(node, scope, c, out, name) {
              if (node.callee.type == "Identifier" && node.callee.name in scope.props)
                maybeInstantiate(scope, 20);
        
              for (var i = 0, args = []; i < node.arguments.length; ++i)
                args.push(infer(node.arguments[i], scope, c));
              var callee = infer(node.callee, scope, c);
              var self = new AVal;
              callee.propagate(new IsCtor(self, name && /\.prototype$/.test(name)));
              self.propagate(out, WG_NEW_INSTANCE);
              callee.propagate(new IsCallee(self, args, node.arguments, new IfObj(out)));
            }),
            CallExpression: fill(function(node, scope, c, out) {
              for (var i = 0, args = []; i < node.arguments.length; ++i)
                args.push(infer(node.arguments[i], scope, c));
              if (node.callee.type == "MemberExpression") {
                var self = infer(node.callee.object, scope, c);
                var pName = propName(node.callee, scope, c);
                if ((pName == "call" || pName == "apply") &&
                    scope.fnType && scope.fnType.args.indexOf(self) > -1)
                  maybeInstantiate(scope, 30);
                self.propagate(new HasMethodCall(pName, args, node.arguments, out));
              } else {
                var callee = infer(node.callee, scope, c);
                if (scope.fnType && scope.fnType.args.indexOf(callee) > -1)
                  maybeInstantiate(scope, 30);
                var knownFn = callee.getFunctionType();
                if (knownFn && knownFn.instantiateScore && scope.fnType)
                  maybeInstantiate(scope, knownFn.instantiateScore / 5);
                callee.propagate(new IsCallee(cx.topScope, args, node.arguments, out));
              }
            }),
            MemberExpression: fill(function(node, scope, c, out) {
              var name = propName(node, scope);
              var obj = infer(node.object, scope, c);
              var prop = obj.getProp(name);
              if (name == "<i>") {
                var propType = infer(node.property, scope, c);
                if (!propType.hasType(cx.num))
                  return prop.propagate(out, WG_MULTI_MEMBER);
              }
              prop.propagate(out);
            }),
            Identifier: ret(function(node, scope) {
              if (node.name == "arguments" && scope.fnType && !(node.name in scope.props))
                scope.defProp(node.name, scope.fnType.originNode)
                  .addType(new Arr(scope.fnType.arguments = new AVal));
              return scope.getProp(node.name);
            }),
            ThisExpression: ret(function(_node, scope) {
              return scope.fnType ? scope.fnType.self : cx.topScope;
            }),
            Literal: ret(function(node) {
              return literalType(node.value);
            })
          };
        
          function infer(node, scope, c, out, name) {
            return inferExprVisitor[node.type](node, scope, c, out, name);
          }
        
          var inferWrapper = walk.make({
            Expression: function(node, scope, c) {
              infer(node, scope, c, ANull);
            },
        
            FunctionDeclaration: function(node, scope, c) {
              var inner = node.body.scope, fn = inner.fnType;
              c(node.body, scope, "ScopeBody");
              maybeTagAsInstantiated(node, inner) || maybeTagAsGeneric(inner);
              var prop = scope.getProp(node.id.name);
              prop.addType(fn);
            },
        
            VariableDeclaration: function(node, scope, c) {
              for (var i = 0; i < node.declarations.length; ++i) {
                var decl = node.declarations[i], prop = scope.getProp(decl.id.name);
                if (decl.init)
                  infer(decl.init, scope, c, prop, decl.id.name);
              }
            },
        
            ReturnStatement: function(node, scope, c) {
              if (!node.argument) return;
              var output = ANull;
              if (scope.fnType) {
                if (scope.fnType.retval == ANull) scope.fnType.retval = new AVal;
                output = scope.fnType.retval;
              }
              infer(node.argument, scope, c, output);
            },
        
            ForInStatement: function(node, scope, c) {
              var source = infer(node.right, scope, c);
              if ((node.right.type == "Identifier" && node.right.name in scope.props) ||
                  (node.right.type == "MemberExpression" && node.right.property.name == "prototype")) {
                maybeInstantiate(scope, 5);
                var varName;
                if (node.left.type == "Identifier") {
                  varName = node.left.name;
                } else if (node.left.type == "VariableDeclaration") {
                  varName = node.left.declarations[0].id.name;
                }
                if (varName && varName in scope.props)
                  scope.getProp(varName).iteratesOver = source;
              }
              c(node.body, scope, "Statement");
            },
        
            ScopeBody: function(node, scope, c) { c(node, node.scope || scope); }
          });
        
          // PARSING
        
          function runPasses(passes, pass) {
            var arr = passes && passes[pass];
            var args = Array.prototype.slice.call(arguments, 2);
            if (arr) for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
          }
        
          var parse = exports.parse = function(text, passes, options) {
            var ast;
            try { ast = acorn.parse(text, options); }
            catch(e) { ast = acorn_loose.parse_dammit(text, options); }
            runPasses(passes, "postParse", ast, text);
            return ast;
          };
        
          // ANALYSIS INTERFACE
        
          exports.analyze = function(ast, name, scope, passes) {
            if (typeof ast == "string") ast = parse(ast);
        
            if (!name) name = "file#" + cx.origins.length;
            exports.addOrigin(cx.curOrigin = name);
        
            if (!scope) scope = cx.topScope;
            walk.recursive(ast, scope, null, scopeGatherer);
            runPasses(passes, "preInfer", ast, scope);
            walk.recursive(ast, scope, null, inferWrapper);
            runPasses(passes, "postInfer", ast, scope);
        
            cx.curOrigin = null;
          };
        
          // PURGING
        
          exports.purge = function(origins, start, end) {
            var test = makePredicate(origins, start, end);
            ++cx.purgeGen;
            cx.topScope.purge(test);
            for (var prop in cx.props) {
              var list = cx.props[prop];
              for (var i = 0; i < list.length; ++i) {
                var obj = list[i], av = obj.props[prop];
                if (!av || test(av, av.originNode)) list.splice(i--, 1);
              }
              if (!list.length) delete cx.props[prop];
            }
          };
        
          function makePredicate(origins, start, end) {
            var arr = Array.isArray(origins);
            if (arr && origins.length == 1) { origins = origins[0]; arr = false; }
            if (arr) {
              if (end == null) return function(n) { return origins.indexOf(n.origin) > -1; };
              return function(n, pos) { return pos && pos.start >= start && pos.end <= end && origins.indexOf(n.origin) > -1; };
            } else {
              if (end == null) return function(n) { return n.origin == origins; };
              return function(n, pos) { return pos && pos.start >= start && pos.end <= end && n.origin == origins; };
            }
          }
        
          AVal.prototype.purge = function(test) {
            if (this.purgeGen == cx.purgeGen) return;
            this.purgeGen = cx.purgeGen;
            for (var i = 0; i < this.types.length; ++i) {
              var type = this.types[i];
              if (test(type, type.originNode))
                this.types.splice(i--, 1);
              else
                type.purge(test);
            }
            if (this.forward) for (var i = 0; i < this.forward.length; ++i) {
              var f = this.forward[i];
              if (test(f)) {
                this.forward.splice(i--, 1);
                if (this.props) this.props = null;
              } else if (f.purge) {
                f.purge(test);
              }
            }
          };
          ANull.purge = function() {};
          Obj.prototype.purge = function(test) {
            if (this.purgeGen == cx.purgeGen) return true;
            this.purgeGen = cx.purgeGen;
            for (var p in this.props) {
              var av = this.props[p];
              if (test(av, av.originNode))
                this.removeProp(p);
              av.purge(test);
            }
          };
          Fn.prototype.purge = function(test) {
            if (Obj.prototype.purge.call(this, test)) return;
            this.self.purge(test);
            this.retval.purge(test);
            for (var i = 0; i < this.args.length; ++i) this.args[i].purge(test);
          };
        
          // EXPRESSION TYPE DETERMINATION
        
          function findByPropertyName(name) {
            guessing = true;
            var found = objsWithProp(name);
            if (found) for (var i = 0; i < found.length; ++i) {
              var val = found[i].getProp(name);
              if (!val.isEmpty()) return val;
            }
            return ANull;
          }
        
          var typeFinder = {
            ArrayExpression: function(node, scope) {
              var eltval = new AVal;
              for (var i = 0; i < node.elements.length; ++i) {
                var elt = node.elements[i];
                if (elt) findType(elt, scope).propagate(eltval);
              }
              return new Arr(eltval);
            },
            ObjectExpression: function(node) {
              return node.objType;
            },
            FunctionExpression: function(node) {
              return node.body.scope.fnType;
            },
            SequenceExpression: function(node, scope) {
              return findType(node.expressions[node.expressions.length-1], scope);
            },
            UnaryExpression: function(node) {
              return unopResultType(node.operator);
            },
            UpdateExpression: function() {
              return cx.num;
            },
            BinaryExpression: function(node, scope) {
              if (binopIsBoolean(node.operator)) return cx.bool;
              if (node.operator == "+") {
                var lhs = findType(node.left, scope);
                var rhs = findType(node.right, scope);
                if (lhs.hasType(cx.str) || rhs.hasType(cx.str)) return cx.str;
              }
              return cx.num;
            },
            AssignmentExpression: function(node, scope) {
              return findType(node.right, scope);
            },
            LogicalExpression: function(node, scope) {
              var lhs = findType(node.left, scope);
              return lhs.isEmpty() ? findType(node.right, scope) : lhs;
            },
            ConditionalExpression: function(node, scope) {
              var lhs = findType(node.consequent, scope);
              return lhs.isEmpty() ? findType(node.alternate, scope) : lhs;
            },
            NewExpression: function(node, scope) {
              var f = findType(node.callee, scope).getFunctionType();
              var proto = f && f.getProp("prototype").getType();
              if (!proto) return ANull;
              return getInstance(proto, f);
            },
            CallExpression: function(node, scope) {
              var f = findType(node.callee, scope).getFunctionType();
              if (!f) return ANull;
              if (f.computeRet) {
                for (var i = 0, args = []; i < node.arguments.length; ++i)
                  args.push(findType(node.arguments[i], scope));
                var self = ANull;
                if (node.callee.type == "MemberExpression")
                  self = findType(node.callee.object, scope);
                return f.computeRet(self, args, node.arguments);
              } else {
                return f.retval;
              }
            },
            MemberExpression: function(node, scope) {
              var propN = propName(node, scope), obj = findType(node.object, scope).getType();
              if (obj) return obj.getProp(propN);
              if (propN == "<i>") return ANull;
              return findByPropertyName(propN);
            },
            Identifier: function(node, scope) {
              return scope.hasProp(node.name) || ANull;
            },
            ThisExpression: function(_node, scope) {
              return scope.fnType ? scope.fnType.self : cx.topScope;
            },
            Literal: function(node) {
              return literalType(node.value);
            }
          };
        
          function findType(node, scope) {
            var found = typeFinder[node.type](node, scope);
            return found;
          }
        
          var searchVisitor = exports.searchVisitor = walk.make({
            Function: function(node, _st, c) {
              var scope = node.body.scope;
              if (node.id) c(node.id, scope);
              for (var i = 0; i < node.params.length; ++i)
                c(node.params[i], scope);
              c(node.body, scope, "ScopeBody");
            },
            TryStatement: function(node, st, c) {
              if (node.handler)
                c(node.handler.param, st);
              walk.base.TryStatement(node, st, c);
            },
            VariableDeclaration: function(node, st, c) {
              for (var i = 0; i < node.declarations.length; ++i) {
                var decl = node.declarations[i];
                c(decl.id, st);
                if (decl.init) c(decl.init, st, "Expression");
              }
            }
          });
          exports.fullVisitor = walk.make({
            MemberExpression: function(node, st, c) {
              c(node.object, st, "Expression");
              c(node.property, st, node.computed ? "Expression" : null);
            },
            ObjectExpression: function(node, st, c) {
              for (var i = 0; i < node.properties.length; ++i) {
                c(node.properties[i].value, st, "Expression");
                c(node.properties[i].key, st);
              }
            }
          }, searchVisitor);
        
          exports.findExpressionAt = function(ast, start, end, defaultScope, filter) {
            var test = filter || function(_t, node) {return typeFinder.hasOwnProperty(node.type);};
            return walk.findNodeAt(ast, start, end, test, searchVisitor, defaultScope || cx.topScope);
          };
        
          exports.findExpressionAround = function(ast, start, end, defaultScope, filter) {
            var test = filter || function(_t, node) {
              if (start != null && node.start > start) return false;
              return typeFinder.hasOwnProperty(node.type);
            };
            return walk.findNodeAround(ast, end, test, searchVisitor, defaultScope || cx.topScope);
          };
        
          exports.expressionType = function(found) {
            return findType(found.node, found.state);
          };
        
          // Flag used to indicate that some wild guessing was used to produce
          // a type or set of completions.
          var guessing = false;
        
          exports.resetGuessing = function(val) { guessing = val; };
          exports.didGuess = function() { return guessing; };
        
          exports.forAllPropertiesOf = function(type, f) {
            type.gatherProperties(f, 0);
          };
        
          var refFindWalker = walk.make({}, searchVisitor);
        
          exports.findRefs = function(ast, baseScope, name, refScope, f) {
            refFindWalker.Identifier = function(node, scope) {
              if (node.name != name) return;
              for (var s = scope; s; s = s.prev) {
                if (s == refScope) f(node, scope);
                if (name in s.props) return;
              }
            };
            walk.recursive(ast, baseScope, null, refFindWalker);
          };
        
          var simpleWalker = walk.make({
            Function: function(node, _st, c) { c(node.body, node.body.scope, "ScopeBody"); }
          });
        
          exports.findPropRefs = function(ast, scope, objType, propName, f) {
            walk.simple(ast, {
              MemberExpression: function(node, scope) {
                if (node.computed || node.property.name != propName) return;
                if (findType(node.object, scope).getType() == objType) f(node.property);
              },
              ObjectExpression: function(node, scope) {
                if (findType(node, scope).getType() != objType) return;
                for (var i = 0; i < node.properties.length; ++i)
                  if (node.properties[i].key.name == propName) f(node.properties[i].key);
              }
            }, simpleWalker, scope);
          };
        
          // LOCAL-VARIABLE QUERIES
        
          var scopeAt = exports.scopeAt = function(ast, pos, defaultScope) {
            var found = walk.findNodeAround(ast, pos, function(tp, node) {
              return tp == "ScopeBody" && node.scope;
            });
            if (found) return found.node.scope;
            else return defaultScope || cx.topScope;
          };
        
          exports.forAllLocalsAt = function(ast, pos, defaultScope, f) {
            var scope = scopeAt(ast, pos, defaultScope);
            scope.gatherProperties(f, 0);
          };
        
          // INIT DEF MODULE
        
          // Delayed initialization because of cyclic dependencies.
          def = exports.def = def.init({}, exports);
        });
        
      • signal.js
        (function(root, mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            return mod(exports);
          if (typeof define == "function" && define.amd) // AMD
            return define(["exports"], mod);
          mod((root.tern || (root.tern = {})).signal = {}); // Plain browser env
        })(this, function(exports) {
          function on(type, f) {
            var handlers = this._handlers || (this._handlers = Object.create(null));
            (handlers[type] || (handlers[type] = [])).push(f);
          }
          function off(type, f) {
            var arr = this._handlers && this._handlers[type];
            if (arr) for (var i = 0; i < arr.length; ++i)
              if (arr[i] == f) { arr.splice(i, 1); break; }
          }
          function signal(type, a1, a2, a3, a4) {
            var arr = this._handlers && this._handlers[type];
            if (arr) for (var i = 0; i < arr.length; ++i) arr[i].call(this, a1, a2, a3, a4);
          }
        
          exports.mixin = function(obj) {
            obj.on = on; obj.off = off; obj.signal = signal;
            return obj;
          };
        });
        
      • tern.js
        // The Tern server object
        
        // A server is a stateful object that manages the analysis for a
        // project, and defines an interface for querying the code in the
        // project.
        
        (function(root, mod) {
          if (typeof exports == "object" && typeof module == "object") // CommonJS
            return mod(exports, require("./infer"), require("./signal"),
                       require("acorn/acorn"), require("acorn/util/walk"));
          if (typeof define == "function" && define.amd) // AMD
            return define(["exports", "./infer", "./signal", "acorn/acorn", "acorn/util/walk"], mod);
          mod(root.tern || (root.tern = {}), tern, tern.signal, acorn, acorn.walk); // Plain browser env
        })(this, function(exports, infer, signal, acorn, walk) {
          "use strict";
        
          var plugins = Object.create(null);
          exports.registerPlugin = function(name, init) { plugins[name] = init; };
        
          var defaultOptions = exports.defaultOptions = {
            debug: false,
            async: false,
            getFile: function(_f, c) { if (this.async) c(null, null); },
            defs: [],
            plugins: {},
            fetchTimeout: 1000,
            dependencyBudget: 20000,
            reuseInstances: true
          };
        
          var queryTypes = {
            completions: {
              takesFile: true,
              run: findCompletions
            },
            properties: {
              run: findProperties
            },
            type: {
              takesFile: true,
              run: findTypeAt
            },
            documentation: {
              takesFile: true,
              run: findDocs
            },
            definition: {
              takesFile: true,
              run: findDef
            },
            refs: {
              takesFile: true,
              fullFile: true,
              run: findRefs
            },
            rename: {
              takesFile: true,
              fullFile: true,
              run: buildRename
            },
            files: {
              run: listFiles
            }
          };
        
          exports.defineQueryType = function(name, desc) { queryTypes[name] = desc; };
        
          function File(name, parent) {
            this.name = name;
            this.parent = parent;
            this.scope = this.text = this.ast = this.lineOffsets = null;
          }
          File.prototype.asLineChar = function(pos) { return asLineChar(this, pos); };
        
          function updateText(file, text, srv) {
            file.text = text;
            file.ast = infer.parse(text, srv.passes, {directSourceFile: file, allowReturnOutsideFunction: true});
            file.lineOffsets = null;
          }
        
          var Server = exports.Server = function(options) {
            this.cx = null;
            this.options = options || {};
            for (var o in defaultOptions) if (!options.hasOwnProperty(o))
              options[o] = defaultOptions[o];
        
            this.handlers = Object.create(null);
            this.files = [];
            this.fileMap = Object.create(null);
            this.needsPurge = [];
            this.budgets = Object.create(null);
            this.uses = 0;
            this.pending = 0;
            this.asyncError = null;
            this.passes = Object.create(null);
        
            this.defs = options.defs.slice(0);
            for (var plugin in options.plugins) if (options.plugins.hasOwnProperty(plugin) && plugin in plugins) {
              var init = plugins[plugin](this, options.plugins[plugin]);
              if (init && init.defs) {
                if (init.loadFirst) this.defs.unshift(init.defs);
                else this.defs.push(init.defs);
              }
              if (init && init.passes) for (var type in init.passes) if (init.passes.hasOwnProperty(type))
                (this.passes[type] || (this.passes[type] = [])).push(init.passes[type]);
            }
        
            this.reset();
          };
          Server.prototype = signal.mixin({
            addFile: function(name, /*optional*/ text, parent) {
              // Don't crash when sloppy plugins pass non-existent parent ids
              if (parent && !(parent in this.fileMap)) parent = null;
              ensureFile(this, name, parent, text);
            },
            delFile: function(name) {
              var file = this.findFile(name);
              if (file) {
                this.needsPurge.push(file.name);
                this.files.splice(this.files.indexOf(file), 1);
                delete this.fileMap[name];
              }
            },
            reset: function() {
              this.signal("reset");
              this.cx = new infer.Context(this.defs, this);
              this.uses = 0;
              this.budgets = Object.create(null);
              for (var i = 0; i < this.files.length; ++i) {
                var file = this.files[i];
                file.scope = null;
              }
            },
        
            request: function(doc, c) {
              var inv = invalidDoc(doc);
              if (inv) return c(inv);
        
              var self = this;
              doRequest(this, doc, function(err, data) {
                c(err, data);
                if (self.uses > 40) {
                  self.reset();
                  analyzeAll(self, null, function(){});
                }
              });
            },
        
            findFile: function(name) {
              return this.fileMap[name];
            },
        
            flush: function(c) {
              var cx = this.cx;
              analyzeAll(this, null, function(err) {
                if (err) return c(err);
                infer.withContext(cx, c);
              });
            },
        
            startAsyncAction: function() {
              ++this.pending;
            },
            finishAsyncAction: function(err) {
              if (err) this.asyncError = err;
              if (--this.pending === 0) this.signal("everythingFetched");
            }
          });
        
          function doRequest(srv, doc, c) {
            if (doc.query && !queryTypes.hasOwnProperty(doc.query.type))
              return c("No query type '" + doc.query.type + "' defined");
        
            var query = doc.query;
            // Respond as soon as possible when this just uploads files
            if (!query) c(null, {});
        
            var files = doc.files || [];
            if (files.length) ++srv.uses;
            for (var i = 0; i < files.length; ++i) {
              var file = files[i];
              ensureFile(srv, file.name, null, file.type == "full" ? file.text : null);
            }
        
            var timeBudget = typeof doc.timeout == "number" ? [doc.timeout] : null;
            if (!query) {
              analyzeAll(srv, timeBudget, function(){});
              return;
            }
        
            var queryType = queryTypes[query.type];
            if (queryType.takesFile) {
              if (typeof query.file != "string") return c(".query.file must be a string");
              if (!/^#/.test(query.file)) ensureFile(srv, query.file, null);
            }
        
            analyzeAll(srv, timeBudget, function(err) {
              if (err) return c(err);
              var file = queryType.takesFile && resolveFile(srv, files, query.file);
              if (queryType.fullFile && file.type == "part")
                return c("Can't run a " + query.type + " query on a file fragment");
        
              function run() {
                var result;
                try {
                  result = queryType.run(srv, query, file);
                } catch (e) {
                  if (srv.options.debug && e.name != "TernError") console.error(e.stack);
                  return c(e);
                }
                c(null, result);
              }
              infer.withContext(srv.cx, timeBudget ? function() { infer.withTimeout(timeBudget[0], run); } : run);
            });
          }
        
          function analyzeFile(srv, file) {
            infer.withContext(srv.cx, function() {
              file.scope = srv.cx.topScope;
              srv.signal("beforeLoad", file);
              infer.analyze(file.ast, file.name, file.scope, srv.passes);
              srv.signal("afterLoad", file);
            });
            return file;
          }
        
          function ensureFile(srv, name, parent, text) {
            var known = srv.findFile(name);
            if (known) {
              if (text != null) {
                if (known.scope) {
                  srv.needsPurge.push(name);
                  known.scope = null;
                }
                updateText(known, text, srv);
              }
              if (parentDepth(srv, known.parent) > parentDepth(srv, parent)) {
                known.parent = parent;
                if (known.excluded) known.excluded = null;
              }
              return;
            }
        
            var file = new File(name, parent);
            srv.files.push(file);
            srv.fileMap[name] = file;
            if (text != null) {
              updateText(file, text, srv);
            } else if (srv.options.async) {
              srv.startAsyncAction();
              srv.options.getFile(name, function(err, text) {
                updateText(file, text || "", srv);
                srv.finishAsyncAction(err);
              });
            } else {
              updateText(file, srv.options.getFile(name) || "", srv);
            }
          }
        
          function fetchAll(srv, c) {
            var done = true, returned = false;
            srv.files.forEach(function(file) {
              if (file.text != null) return;
              if (srv.options.async) {
                done = false;
                srv.options.getFile(file.name, function(err, text) {
                  if (err && !returned) { returned = true; return c(err); }
                  updateText(file, text || "", srv);
                  fetchAll(srv, c);
                });
              } else {
                try {
                  updateText(file, srv.options.getFile(file.name) || "", srv);
                } catch (e) { return c(e); }
              }
            });
            if (done) c();
          }
        
          function waitOnFetch(srv, timeBudget, c) {
            var done = function() {
              srv.off("everythingFetched", done);
              clearTimeout(timeout);
              analyzeAll(srv, timeBudget, c);
            };
            srv.on("everythingFetched", done);
            var timeout = setTimeout(done, srv.options.fetchTimeout);
          }
        
          function analyzeAll(srv, timeBudget, c) {
            if (srv.pending) return waitOnFetch(srv, timeBudget, c);
        
            var e = srv.fetchError;
            if (e) { srv.fetchError = null; return c(e); }
        
            if (srv.needsPurge.length > 0) infer.withContext(srv.cx, function() {
              infer.purge(srv.needsPurge);
              srv.needsPurge.length = 0;
            });
        
            var done = true;
            // The second inner loop might add new files. The outer loop keeps
            // repeating both inner loops until all files have been looked at.
            for (var i = 0; i < srv.files.length;) {
              var toAnalyze = [];
              for (; i < srv.files.length; ++i) {
                var file = srv.files[i];
                if (file.text == null) done = false;
                else if (file.scope == null && !file.excluded) toAnalyze.push(file);
              }
              toAnalyze.sort(function(a, b) {
                return parentDepth(srv, a.parent) - parentDepth(srv, b.parent);
              });
              for (var j = 0; j < toAnalyze.length; j++) {
                var file = toAnalyze[j];
                if (file.parent && !chargeOnBudget(srv, file)) {
                  file.excluded = true;
                } else if (timeBudget) {
                  var startTime = +new Date;
                  infer.withTimeout(timeBudget[0], function() { analyzeFile(srv, file); });
                  timeBudget[0] -= +new Date - startTime;
                } else {
                  analyzeFile(srv, file);
                }
              }
            }
            if (done) c();
            else waitOnFetch(srv, timeBudget, c);
          }
        
          function firstLine(str) {
            var end = str.indexOf("\n");
            if (end < 0) return str;
            return str.slice(0, end);
          }
        
          function findMatchingPosition(line, file, near) {
            var pos = Math.max(0, near - 500), closest = null;
            if (!/^\s*$/.test(line)) for (;;) {
              var found = file.indexOf(line, pos);
              if (found < 0 || found > near + 500) break;
              if (closest == null || Math.abs(closest - near) > Math.abs(found - near))
                closest = found;
              pos = found + line.length;
            }
            return closest;
          }
        
          function scopeDepth(s) {
            for (var i = 0; s; ++i, s = s.prev) {}
            return i;
          }
        
          function ternError(msg) {
            var err = new Error(msg);
            err.name = "TernError";
            return err;
          }
        
          function resolveFile(srv, localFiles, name) {
            var isRef = name.match(/^#(\d+)$/);
            if (!isRef) return srv.findFile(name);
        
            var file = localFiles[isRef[1]];
            if (!file) throw ternError("Reference to unknown file " + name);
            if (file.type == "full") return srv.findFile(file.name);
        
            // This is a partial file
        
            var realFile = file.backing = srv.findFile(file.name);
            var offset = file.offset;
            if (file.offsetLines) offset = {line: file.offsetLines, ch: 0};
            file.offset = offset = resolvePos(realFile, file.offsetLines == null ? file.offset : {line: file.offsetLines, ch: 0}, true);
            var line = firstLine(file.text);
            var foundPos = findMatchingPosition(line, realFile.text, offset);
            var pos = foundPos == null ? Math.max(0, realFile.text.lastIndexOf("\n", offset)) : foundPos;
            var inObject, atFunction;
        
            infer.withContext(srv.cx, function() {
              infer.purge(file.name, pos, pos + file.text.length);
        
              var text = file.text, m;
              if (m = text.match(/(?:"([^"]*)"|([\w$]+))\s*:\s*function\b/)) {
                var objNode = walk.findNodeAround(file.backing.ast, pos, "ObjectExpression");
                if (objNode && objNode.node.objType)
                  inObject = {type: objNode.node.objType, prop: m[2] || m[1]};
              }
              if (foundPos && (m = line.match(/^(.*?)\bfunction\b/))) {
                var cut = m[1].length, white = "";
                for (var i = 0; i < cut; ++i) white += " ";
                text = white + text.slice(cut);
                atFunction = true;
              }
        
              var scopeStart = infer.scopeAt(realFile.ast, pos, realFile.scope);
              var scopeEnd = infer.scopeAt(realFile.ast, pos + text.length, realFile.scope);
              var scope = file.scope = scopeDepth(scopeStart) < scopeDepth(scopeEnd) ? scopeEnd : scopeStart;
              file.ast = infer.parse(file.text, srv.passes, {directSourceFile: file, allowReturnOutsideFunction: true});
              infer.analyze(file.ast, file.name, scope, srv.passes);
        
              // This is a kludge to tie together the function types (if any)
              // outside and inside of the fragment, so that arguments and
              // return values have some information known about them.
              tieTogether: if (inObject || atFunction) {
                var newInner = infer.scopeAt(file.ast, line.length, scopeStart);
                if (!newInner.fnType) break tieTogether;
                if (inObject) {
                  var prop = inObject.type.getProp(inObject.prop);
                  prop.addType(newInner.fnType);
                } else if (atFunction) {
                  var inner = infer.scopeAt(realFile.ast, pos + line.length, realFile.scope);
                  if (inner == scopeStart || !inner.fnType) break tieTogether;
                  var fOld = inner.fnType, fNew = newInner.fnType;
                  if (!fNew || (fNew.name != fOld.name && fOld.name)) break tieTogether;
                  for (var i = 0, e = Math.min(fOld.args.length, fNew.args.length); i < e; ++i)
                    fOld.args[i].propagate(fNew.args[i]);
                  fOld.self.propagate(fNew.self);
                  fNew.retval.propagate(fOld.retval);
                }
              }
            });
            return file;
          }
        
          // Budget management
        
          function astSize(node) {
            var size = 0;
            walk.simple(node, {Expression: function() { ++size; }});
            return size;
          }
        
          function parentDepth(srv, parent) {
            var depth = 0;
            while (parent) {
              parent = srv.findFile(parent).parent;
              ++depth;
            }
            return depth;
          }
        
          function budgetName(srv, file) {
            for (;;) {
              var parent = srv.findFile(file.parent);
              if (!parent.parent) break;
              file = parent;
            }
            return file.name;
          }
        
          function chargeOnBudget(srv, file) {
            var bName = budgetName(srv, file);
            var size = astSize(file.ast);
            var known = srv.budgets[bName];
            if (known == null)
              known = srv.budgets[bName] = srv.options.dependencyBudget;
            if (known < size) return false;
            srv.budgets[bName] = known - size;
            return true;
          }
        
          // Query helpers
        
          function isPosition(val) {
            return typeof val == "number" || typeof val == "object" &&
              typeof val.line == "number" && typeof val.ch == "number";
          }
        
          // Baseline query document validation
          function invalidDoc(doc) {
            if (doc.query) {
              if (typeof doc.query.type != "string") return ".query.type must be a string";
              if (doc.query.start && !isPosition(doc.query.start)) return ".query.start must be a position";
              if (doc.query.end && !isPosition(doc.query.end)) return ".query.end must be a position";
            }
            if (doc.files) {
              if (!Array.isArray(doc.files)) return "Files property must be an array";
              for (var i = 0; i < doc.files.length; ++i) {
                var file = doc.files[i];
                if (typeof file != "object") return ".files[n] must be objects";
                else if (typeof file.text != "string") return ".files[n].text must be a string";
                else if (typeof file.name != "string") return ".files[n].name must be a string";
                else if (file.type == "part") {
                  if (!isPosition(file.offset) && typeof file.offsetLines != "number")
                    return ".files[n].offset must be a position";
                } else if (file.type != "full") return ".files[n].type must be \"full\" or \"part\"";
              }
            }
          }
        
          var offsetSkipLines = 25;
        
          function findLineStart(file, line) {
            var text = file.text, offsets = file.lineOffsets || (file.lineOffsets = [0]);
            var pos = 0, curLine = 0;
            var storePos = Math.min(Math.floor(line / offsetSkipLines), offsets.length - 1);
            var pos = offsets[storePos], curLine = storePos * offsetSkipLines;
        
            while (curLine < line) {
              ++curLine;
              pos = text.indexOf("\n", pos) + 1;
              if (pos === 0) return null;
              if (curLine % offsetSkipLines === 0) offsets.push(pos);
            }
            return pos;
          }
        
          function resolvePos(file, pos, tolerant) {
            if (typeof pos != "number") {
              var lineStart = findLineStart(file, pos.line);
              if (lineStart == null) {
                if (tolerant) pos = file.text.length;
                else throw ternError("File doesn't contain a line " + pos.line);
              } else {
                pos = lineStart + pos.ch;
              }
            }
            if (pos > file.text.length) {
              if (tolerant) pos = file.text.length;
              else throw ternError("Position " + pos + " is outside of file.");
            }
            return pos;
          }
        
          function asLineChar(file, pos) {
            if (!file) return {line: 0, ch: 0};
            var offsets = file.lineOffsets || (file.lineOffsets = [0]);
            var text = file.text, line, lineStart;
            for (var i = offsets.length - 1; i >= 0; --i) if (offsets[i] <= pos) {
              line = i * offsetSkipLines;
              lineStart = offsets[i];
            }
            for (;;) {
              var eol = text.indexOf("\n", lineStart);
              if (eol >= pos || eol < 0) break;
              lineStart = eol + 1;
              ++line;
            }
            return {line: line, ch: pos - lineStart};
          }
        
          function outputPos(query, file, pos) {
            if (query.lineCharPositions) {
              var out = asLineChar(file, pos);
              if (file.type == "part")
                out.line += file.offsetLines != null ? file.offsetLines : asLineChar(file.backing, file.offset).line;
              return out;
            } else {
              return pos + (file.type == "part" ? file.offset : 0);
            }
          }
        
          // Delete empty fields from result objects
          function clean(obj) {
            for (var prop in obj) if (obj[prop] == null) delete obj[prop];
            return obj;
          }
          function maybeSet(obj, prop, val) {
            if (val != null) obj[prop] = val;
          }
        
          // Built-in query types
        
          function compareCompletions(a, b) {
            if (typeof a != "string") { a = a.name; b = b.name; }
            var aUp = /^[A-Z]/.test(a), bUp = /^[A-Z]/.test(b);
            if (aUp == bUp) return a < b ? -1 : a == b ? 0 : 1;
            else return aUp ? 1 : -1;
          }
        
          function isStringAround(node, start, end) {
            return node.type == "Literal" && typeof node.value == "string" &&
              node.start == start - 1 && node.end <= end + 1;
          }
        
          var jsKeywords = ("break do instanceof typeof case else new var " +
            "catch finally return void continue for switch while debugger " +
            "function this with default if throw delete in try").split(" ");
        
          function findCompletions(srv, query, file) {
            if (query.end == null) throw ternError("missing .query.end field");
            var wordStart = resolvePos(file, query.end), wordEnd = wordStart, text = file.text;
            while (wordStart && acorn.isIdentifierChar(text.charCodeAt(wordStart - 1))) --wordStart;
            if (query.expandWordForward !== false)
              while (wordEnd < text.length && acorn.isIdentifierChar(text.charCodeAt(wordEnd))) ++wordEnd;
            var word = text.slice(wordStart, wordEnd), completions = [];
            if (query.caseInsensitive) word = word.toLowerCase();
            var wrapAsObjs = query.types || query.depths || query.docs || query.urls || query.origins;
        
            function gather(prop, obj, depth, addInfo) {
              // 'hasOwnProperty' and such are usually just noise, leave them
              // out when no prefix is provided.
              if (query.omitObjectPrototype !== false && obj == srv.cx.protos.Object && !word) return;
              if (query.filter !== false && word &&
                  (query.caseInsensitive ? prop.toLowerCase() : prop).indexOf(word) !== 0) return;
              for (var i = 0; i < completions.length; ++i) {
                var c = completions[i];
                if ((wrapAsObjs ? c.name : c) == prop) return;
              }
              var rec = wrapAsObjs ? {name: prop} : prop;
              completions.push(rec);
        
              if (obj && (query.types || query.docs || query.urls || query.origins)) {
                var val = obj.props[prop];
                infer.resetGuessing();
                var type = val.getType();
                rec.guess = infer.didGuess();
                if (query.types)
                  rec.type = infer.toString(type);
                if (query.docs)
                  maybeSet(rec, "doc", val.doc || type && type.doc);
                if (query.urls)
                  maybeSet(rec, "url", val.url || type && type.url);
                if (query.origins)
                  maybeSet(rec, "origin", val.origin || type && type.origin);
              }
              if (query.depths) rec.depth = depth;
              if (wrapAsObjs && addInfo) addInfo(rec);
            }
        
            var hookname, prop, objType;
            var memberExpr = infer.findExpressionAround(file.ast, null, wordStart, file.scope, "MemberExpression");
        
            if (memberExpr &&
                (memberExpr.node.computed ? isStringAround(memberExpr.node.property, wordStart, wordEnd)
                                          : memberExpr.node.object.end < wordStart)) {
              prop = memberExpr.node.property;
              prop = prop.type == "Literal" ? prop.value.slice(1) : prop.name;
        
              memberExpr.node = memberExpr.node.object;
              objType = infer.expressionType(memberExpr);
            } else if (text.charAt(wordStart - 1) == ".") {
              var pathStart = wordStart - 1;
              while (pathStart && (text.charAt(pathStart - 1) == "." || acorn.isIdentifierChar(text.charCodeAt(pathStart - 1)))) pathStart--;
              var path = text.slice(pathStart, wordStart - 1);
              if (path) {
                objType = infer.def.parsePath(path, file.scope).getType();
                prop = word;
              }
            }
        
            if (prop != null) {
              srv.cx.completingProperty = prop;
        
              if (objType) infer.forAllPropertiesOf(objType, gather);
        
              if (!completions.length && query.guess !== false && objType && objType.guessProperties)
                objType.guessProperties(function(p, o, d) {if (p != prop && p != "✖") gather(p, o, d);});
              if (!completions.length && word.length >= 2 && query.guess !== false)
                for (var prop in srv.cx.props) gather(prop, srv.cx.props[prop][0], 0);
              hookname = "memberCompletion";
            } else {
              infer.forAllLocalsAt(file.ast, wordStart, file.scope, gather);
              if (query.includeKeywords) jsKeywords.forEach(function(kw) {
                gather(kw, null, 0, function(rec) { rec.isKeyword = true; });
              });
              hookname = "completion";
            }
            if (srv.passes[hookname])
              srv.passes[hookname].forEach(function(hook) {hook(file, wordStart, wordEnd, gather);});
        
            if (query.sort !== false) completions.sort(compareCompletions);
            srv.cx.completingProperty = null;
        
            return {start: outputPos(query, file, wordStart),
                    end: outputPos(query, file, wordEnd),
                    isProperty: hookname == "memberCompletion",
                    completions: completions};
          }
        
          function findProperties(srv, query) {
            var prefix = query.prefix, found = [];
            for (var prop in srv.cx.props)
              if (prop != "<i>" && (!prefix || prop.indexOf(prefix) === 0)) found.push(prop);
            if (query.sort !== false) found.sort(compareCompletions);
            return {completions: found};
          }
        
          var findExpr = exports.findQueryExpr = function(file, query, wide) {
            if (query.end == null) throw ternError("missing .query.end field");
        
            if (query.variable) {
              var scope = infer.scopeAt(file.ast, resolvePos(file, query.end), file.scope);
              return {node: {type: "Identifier", name: query.variable, start: query.end, end: query.end + 1},
                      state: scope};
            } else {
              var start = query.start && resolvePos(file, query.start), end = resolvePos(file, query.end);
              var expr = infer.findExpressionAt(file.ast, start, end, file.scope);
              if (expr) return expr;
              expr = infer.findExpressionAround(file.ast, start, end, file.scope);
              if (expr && (wide || (start == null ? end : start) - expr.node.start < 20 || expr.node.end - end < 20))
                return expr;
              return null;
            }
          };
        
          function findExprOrThrow(file, query, wide) {
            var expr = findExpr(file, query, wide);
            if (expr) return expr;
            throw ternError("No expression at the given position.");
          }
        
          function findExprType(srv, query, file, expr) {
            var type;
            if (expr) {
              infer.resetGuessing();
              type = infer.expressionType(expr);
            }
            if (srv.passes["typeAt"]) {
              var pos = resolvePos(file, query.end);
              srv.passes["typeAt"].forEach(function(hook) {
                type = hook(file, pos, expr, type);
              });
            }
            if (!type) throw ternError("No type found at the given position.");
            return type;
          };
        
          function findTypeAt(srv, query, file) {
            var expr = findExpr(file, query), exprName;
            var type = findExprType(srv, query, file, expr);
            if (query.preferFunction)
              type = type.getFunctionType() || type.getType();
            else
              type = type.getType();
        
            if (expr) {
              if (expr.node.type == "Identifier")
                exprName = expr.node.name;
              else if (expr.node.type == "MemberExpression" && !expr.node.computed)
                exprName = expr.node.property.name;
            }
        
            if (query.depth != null && typeof query.depth != "number")
              throw ternError(".query.depth must be a number");
        
            var result = {guess: infer.didGuess(),
                          type: infer.toString(type, query.depth),
                          name: type && type.name,
                          exprName: exprName};
            if (type) storeTypeDocs(type, result);
        
            return clean(result);
          }
        
          function findDocs(srv, query, file) {
            var expr = findExpr(file, query);
            var type = findExprType(srv, query, file, expr);
            var result = {url: type.url, doc: type.doc};
            var inner = type.getType();
            if (inner) storeTypeDocs(inner, result);
            return clean(result);
          }
        
          function storeTypeDocs(type, out) {
            if (!out.url) out.url = type.url;
            if (!out.doc) out.doc = type.doc;
            if (!out.origin) out.origin = type.origin;
            var ctor, boring = infer.cx().protos;
            if (!out.url && !out.doc && type.proto && (ctor = type.proto.hasCtor) &&
                type.proto != boring.Object && type.proto != boring.Function && type.proto != boring.Array) {
              out.url = ctor.url;
              out.doc = ctor.doc;
            }
          }
        
          var getSpan = exports.getSpan = function(obj) {
            if (!obj.origin) return;
            if (obj.originNode) {
              var node = obj.originNode;
              if (/^Function/.test(node.type) && node.id) node = node.id;
              return {origin: obj.origin, node: node};
            }
            if (obj.span) return {origin: obj.origin, span: obj.span};
          };
        
          var storeSpan = exports.storeSpan = function(srv, query, span, target) {
            target.origin = span.origin;
            if (span.span) {
              var m = /^(\d+)\[(\d+):(\d+)\]-(\d+)\[(\d+):(\d+)\]$/.exec(span.span);
              target.start = query.lineCharPositions ? {line: Number(m[2]), ch: Number(m[3])} : Number(m[1]);
              target.end = query.lineCharPositions ? {line: Number(m[5]), ch: Number(m[6])} : Number(m[4]);
            } else {
              var file = srv.findFile(span.origin);
              target.start = outputPos(query, file, span.node.start);
              target.end = outputPos(query, file, span.node.end);
            }
          };
        
          function findDef(srv, query, file) {
            var expr = findExpr(file, query);
            var type = findExprType(srv, query, file, expr);
            if (infer.didGuess()) return {};
        
            var span = getSpan(type);
            var result = {url: type.url, doc: type.doc, origin: type.origin};
        
            if (type.types) for (var i = type.types.length - 1; i >= 0; --i) {
              var tp = type.types[i];
              storeTypeDocs(tp, result);
              if (!span) span = getSpan(tp);
            }
        
            if (span && span.node) { // refers to a loaded file
              var spanFile = span.node.sourceFile || srv.findFile(span.origin);
              var start = outputPos(query, spanFile, span.node.start), end = outputPos(query, spanFile, span.node.end);
              result.start = start; result.end = end;
              result.file = span.origin;
              var cxStart = Math.max(0, span.node.start - 50);
              result.contextOffset = span.node.start - cxStart;
              result.context = spanFile.text.slice(cxStart, cxStart + 50);
            } else if (span) { // external
              result.file = span.origin;
              storeSpan(srv, query, span, result);
            }
            return clean(result);
          }
        
          function findRefsToVariable(srv, query, file, expr, checkShadowing) {
            var name = expr.node.name;
        
            for (var scope = expr.state; scope && !(name in scope.props); scope = scope.prev) {}
            if (!scope) throw ternError("Could not find a definition for " + name + " " + !!srv.cx.topScope.props.x);
        
            var type, refs = [];
            function storeRef(file) {
              return function(node, scopeHere) {
                if (checkShadowing) for (var s = scopeHere; s != scope; s = s.prev) {
                  var exists = s.hasProp(checkShadowing);
                  if (exists)
                    throw ternError("Renaming `" + name + "` to `" + checkShadowing + "` would make a variable at line " +
                                    (asLineChar(file, node.start).line + 1) + " point to the definition at line " +
                                    (asLineChar(file, exists.name.start).line + 1));
                }
                refs.push({file: file.name,
                           start: outputPos(query, file, node.start),
                           end: outputPos(query, file, node.end)});
              };
            }
        
            if (scope.originNode) {
              type = "local";
              if (checkShadowing) {
                for (var prev = scope.prev; prev; prev = prev.prev)
                  if (checkShadowing in prev.props) break;
                if (prev) infer.findRefs(scope.originNode, scope, checkShadowing, prev, function(node) {
                  throw ternError("Renaming `" + name + "` to `" + checkShadowing + "` would shadow the definition used at line " +
                                  (asLineChar(file, node.start).line + 1));
                });
              }
              infer.findRefs(scope.originNode, scope, name, scope, storeRef(file));
            } else {
              type = "global";
              for (var i = 0; i < srv.files.length; ++i) {
                var cur = srv.files[i];
                infer.findRefs(cur.ast, cur.scope, name, scope, storeRef(cur));
              }
            }
        
            return {refs: refs, type: type, name: name};
          }
        
          function findRefsToProperty(srv, query, expr, prop) {
            var objType = infer.expressionType(expr).getType();
            if (!objType) throw ternError("Couldn't determine type of base object.");
        
            var refs = [];
            function storeRef(file) {
              return function(node) {
                refs.push({file: file.name,
                           start: outputPos(query, file, node.start),
                           end: outputPos(query, file, node.end)});
              };
            }
            for (var i = 0; i < srv.files.length; ++i) {
              var cur = srv.files[i];
              infer.findPropRefs(cur.ast, cur.scope, objType, prop.name, storeRef(cur));
            }
        
            return {refs: refs, name: prop.name};
          }
        
          function findRefs(srv, query, file) {
            var expr = findExprOrThrow(file, query, true);
            if (expr && expr.node.type == "Identifier") {
              return findRefsToVariable(srv, query, file, expr);
            } else if (expr && expr.node.type == "MemberExpression" && !expr.node.computed) {
              var p = expr.node.property;
              expr.node = expr.node.object;
              return findRefsToProperty(srv, query, expr, p);
            } else if (expr && expr.node.type == "ObjectExpression") {
              var pos = resolvePos(file, query.end);
              for (var i = 0; i < expr.node.properties.length; ++i) {
                var k = expr.node.properties[i].key;
                if (k.start <= pos && k.end >= pos)
                  return findRefsToProperty(srv, query, expr, k);
              }
            }
            throw ternError("Not at a variable or property name.");
          }
        
          function buildRename(srv, query, file) {
            if (typeof query.newName != "string") throw ternError(".query.newName should be a string");
            var expr = findExprOrThrow(file, query);
            if (!expr || expr.node.type != "Identifier") throw ternError("Not at a variable.");
        
            var data = findRefsToVariable(srv, query, file, expr, query.newName), refs = data.refs;
            delete data.refs;
            data.files = srv.files.map(function(f){return f.name;});
        
            var changes = data.changes = [];
            for (var i = 0; i < refs.length; ++i) {
              var use = refs[i];
              use.text = query.newName;
              changes.push(use);
            }
        
            return data;
          }
        
          function listFiles(srv) {
            return {files: srv.files.map(function(f){return f.name;})};
          }
        
          exports.version = "0.7.1";
        });
        
    • typescript
      • lib.d.ts.text
        /*! *****************************************************************************
        Copyright (c) Microsoft Corporation. All rights reserved. 
        Licensed under the Apache License, Version 2.0 (the "License"); you may not use
        this file except in compliance with the License. You may obtain a copy of the
        License at http://www.apache.org/licenses/LICENSE-2.0  
         
        THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
        KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
        WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
        MERCHANTABLITY OR NON-INFRINGEMENT. 
         
        See the Apache Version 2.0 License for specific language governing permissions
        and limitations under the License.
        ***************************************************************************** */
        
        /// <reference no-default-lib="true"/>
        
        /////////////////////////////
        /// ECMAScript APIs
        /////////////////////////////
        
        declare var NaN: number;
        declare var Infinity: number;
        
        /**
          * Evaluates JavaScript code and executes it. 
          * @param x A String value that contains valid JavaScript code.
          */
        declare function eval(x: string): any;
        
        /**
          * Converts A string to an integer.
          * @param s A string to convert into a number.
          * @param radix A value between 2 and 36 that specifies the base of the number in numString. 
          * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.
          * All other strings are considered decimal.
          */
        declare function parseInt(s: string, radix?: number): number;
        
        /**
          * Converts a string to a floating-point number. 
          * @param string A string that contains a floating-point number. 
          */
        declare function parseFloat(string: string): number;
        
        /**
          * Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number). 
          * @param number A numeric value.
          */
        declare function isNaN(number: number): boolean;
        
        /** 
          * Determines whether a supplied number is finite.
          * @param number Any numeric value.
          */
        declare function isFinite(number: number): boolean;
        
        /**
          * Gets the unencoded version of an encoded Uniform Resource Identifier (URI).
          * @param encodedURI A value representing an encoded URI.
          */
        declare function decodeURI(encodedURI: string): string;
        
        /**
          * Gets the unencoded version of an encoded component of a Uniform Resource Identifier (URI).
          * @param encodedURIComponent A value representing an encoded URI component.
          */
        declare function decodeURIComponent(encodedURIComponent: string): string;
        
        /** 
          * Encodes a text string as a valid Uniform Resource Identifier (URI)
          * @param uri A value representing an encoded URI.
          */
        declare function encodeURI(uri: string): string;
        
        /**
          * Encodes a text string as a valid component of a Uniform Resource Identifier (URI).
          * @param uriComponent A value representing an encoded URI component.
          */
        declare function encodeURIComponent(uriComponent: string): string;
        
        interface PropertyDescriptor {
            configurable?: boolean;
            enumerable?: boolean;
            value?: any;
            writable?: boolean;
            get? (): any;
            set? (v: any): void;
        }
        
        interface PropertyDescriptorMap {
            [s: string]: PropertyDescriptor;
        }
        
        interface Object {
            /** The initial value of Object.prototype.constructor is the standard built-in Object constructor. */
            constructor: Function;
        
            /** Returns a string representation of an object. */
            toString(): string;
        
            /** Returns a date converted to a string using the current locale. */
            toLocaleString(): string;
        
            /** Returns the primitive value of the specified object. */
            valueOf(): Object;
        
            /**
              * Determines whether an object has a property with the specified name. 
              * @param v A property name.
              */
            hasOwnProperty(v: string): boolean;
        
            /**
              * Determines whether an object exists in another object's prototype chain. 
              * @param v Another object whose prototype chain is to be checked.
              */
            isPrototypeOf(v: Object): boolean;
        
            /** 
              * Determines whether a specified property is enumerable.
              * @param v A property name.
              */
            propertyIsEnumerable(v: string): boolean;
        }
        
        /**
          * Provides functionality common to all JavaScript objects.
          */
        declare var Object: {
            new (value?: any): Object;
            (): any;
            (value: any): any;
        
            /** A reference to the prototype for a class of objects. */
            prototype: Object;
        
            /** 
              * Returns the prototype of an object. 
              * @param o The object that references the prototype.
              */
            getPrototypeOf(o: any): any;
        
            /**
              * Gets the own property descriptor of the specified object. 
              * An own property descriptor is one that is defined directly on the object and is not inherited from the object's prototype. 
              * @param o Object that contains the property.
              * @param p Name of the property.
            */
            getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor;
        
            /** 
              * Returns the names of the own properties of an object. The own properties of an object are those that are defined directly 
              * on that object, and are not inherited from the object's prototype. The properties of an object include both fields (objects) and functions.
              * @param o Object that contains the own properties.
              */
            getOwnPropertyNames(o: any): string[];
        
            /** 
              * Creates an object that has the specified prototype, and that optionally contains specified properties.
              * @param o Object to use as a prototype. May be null
              * @param properties JavaScript object that contains one or more property descriptors. 
              */
            create(o: any, properties?: PropertyDescriptorMap): any;
        
            /**
              * Adds a property to an object, or modifies attributes of an existing property. 
              * @param o Object on which to add or modify the property. This can be a native JavaScript object (that is, a user-defined object or a built in object) or a DOM object.
              * @param p The property name.
              * @param attributes Descriptor for the property. It can be for a data property or an accessor property.
              */
            defineProperty(o: any, p: string, attributes: PropertyDescriptor): any;
        
            /**
              * Adds one or more properties to an object, and/or modifies attributes of existing properties. 
              * @param o Object on which to add or modify the properties. This can be a native JavaScript object or a DOM object.
              * @param properties JavaScript object that contains one or more descriptor objects. Each descriptor object describes a data property or an accessor property.
              */
            defineProperties(o: any, properties: PropertyDescriptorMap): any;
        
            /**
              * Prevents the modification of attributes of existing properties, and prevents the addition of new properties.
              * @param o Object on which to lock the attributes. 
              */
            seal(o: any): any;
        
            /**
              * Prevents the modification of existing property attributes and values, and prevents the addition of new properties.
              * @param o Object on which to lock the attributes.
              */
            freeze(o: any): any;
        
            /**
              * Prevents the addition of new properties to an object.
              * @param o Object to make non-extensible. 
              */
            preventExtensions(o: any): any;
        
            /**
              * Returns true if existing property attributes cannot be modified in an object and new properties cannot be added to the object.
              * @param o Object to test. 
              */
            isSealed(o: any): boolean;
        
            /**
              * Returns true if existing property attributes and values cannot be modified in an object, and new properties cannot be added to the object.
              * @param o Object to test.  
              */
            isFrozen(o: any): boolean;
        
            /**
              * Returns a value that indicates whether new properties can be added to an object.
              * @param o Object to test. 
              */
            isExtensible(o: any): boolean;
        
            /**
              * Returns the names of the enumerable properties and methods of an object.
              * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
              */
            keys(o: any): string[];
        }
        
        /**
          * Creates a new function.
          */
        interface Function {
            /**
              * Calls the function, substituting the specified object for the this value of the function, and the specified array for the arguments of the function.
              * @param thisArg The object to be used as the this object.
              * @param argArray A set of arguments to be passed to the function.
              */
            apply(thisArg: any, argArray?: any): any;
        
            /**
              * Calls a method of an object, substituting another object for the current object.
              * @param thisArg The object to be used as the current object.
              * @param argArray A list of arguments to be passed to the method.
              */
            call(thisArg: any, ...argArray: any[]): any;
        
            /**
              * For a given function, creates a bound function that has the same body as the original function. 
              * The this object of the bound function is associated with the specified object, and has the specified initial parameters.
              * @param thisArg An object to which the this keyword can refer inside the new function.
              * @param argArray A list of arguments to be passed to the new function.
              */
            bind(thisArg: any, ...argArray: any[]): any;
        
            prototype: any;
            length: number;
        
            // Non-standard extensions
            arguments: any;
            caller: Function;
        }
        
        declare var Function: {
            /** 
              * Creates a new function.
              * @param args A list of arguments the function accepts.
              */
            new (...args: string[]): Function;
            (...args: string[]): Function;
            prototype: Function;
        }
        
        interface IArguments {
            [index: number]: any;
            length: number;
            callee: Function;
        }
        
        interface String {
            /** Returns a string representation of a string. */
            toString(): string;
        
            /**
              * Returns the character at the specified index.
              * @param pos The zero-based index of the desired character.
              */
            charAt(pos: number): string;
        
            /** 
              * Returns the Unicode value of the character at the specified location.
              * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned.
              */
            charCodeAt(index: number): number;
        
            /**
              * Returns a string that contains the concatenation of two or more strings.
              * @param strings The strings to append to the end of the string.  
              */
            concat(...strings: string[]): string;
        
            /**
              * Returns the position of the first occurrence of a substring. 
              * @param searchString The substring to search for in the string
              * @param position The index at which to begin searching the String object. If omitted, search starts at the beginning of the string.
              */
            indexOf(searchString: string, position?: number): number;
        
            /**
              * Returns the last occurrence of a substring in the string.
              * @param searchString The substring to search for.
              * @param position The index at which to begin searching. If omitted, the search begins at the end of the string.
              */
            lastIndexOf(searchString: string, position?: number): number;
        
            /**
              * Determines whether two strings are equivalent in the current locale.
              * @param that String to compare to target string
              */
            localeCompare(that: string): number;
        
            /** 
              * Matches a string with a regular expression, and returns an array containing the results of that search.
              * @param regexp A variable name or string literal containing the regular expression pattern and flags.
              */
            match(regexp: string): RegExpMatchArray;
        
            /** 
              * Matches a string with a regular expression, and returns an array containing the results of that search.
              * @param regexp A regular expression object that contains the regular expression pattern and applicable flags. 
              */
            match(regexp: RegExp): RegExpMatchArray;
        
            /**
              * Replaces text in a string, using a regular expression or search string.
              * @param searchValue A String object or string literal that represents the regular expression
              * @param replaceValue A String object or string literal containing the text to replace for every successful match of rgExp in stringObj.
              */
            replace(searchValue: string, replaceValue: string): string;
        
            /**
              * Replaces text in a string, using a regular expression or search string.
              * @param searchValue A String object or string literal that represents the regular expression
              * @param replaceValue A function that returns the replacement text.
              */
            replace(searchValue: string, replaceValue: (substring: string, ...args: any[]) => string): string;
        
            /**
              * Replaces text in a string, using a regular expression or search string.
              * @param searchValue A Regular Expression object containing the regular expression pattern and applicable flags
              * @param replaceValue A String object or string literal containing the text to replace for every successful match of rgExp in stringObj.
              */
            replace(searchValue: RegExp, replaceValue: string): string;
        
            /**
              * Replaces text in a string, using a regular expression or search string.
              * @param searchValue A Regular Expression object containing the regular expression pattern and applicable flags
              * @param replaceValue A function that returns the replacement text.
              */
            replace(searchValue: RegExp, replaceValue: (substring: string, ...args: any[]) => string): string;
        
            /**
              * Finds the first substring match in a regular expression search.
              * @param regexp The regular expression pattern and applicable flags. 
              */
            search(regexp: string): number;
        
            /**
              * Finds the first substring match in a regular expression search.
              * @param regexp The regular expression pattern and applicable flags. 
              */
            search(regexp: RegExp): number;
        
            /**
              * Returns a section of a string.
              * @param start The index to the beginning of the specified portion of stringObj. 
              * @param end The index to the end of the specified portion of stringObj. The substring includes the characters up to, but not including, the character indicated by end. 
              * If this value is not specified, the substring continues to the end of stringObj.
              */
            slice(start?: number, end?: number): string;
        
            /**
              * Split a string into substrings using the specified separator and return them as an array.
              * @param separator A string that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned. 
              * @param limit A value used to limit the number of elements returned in the array.
              */
            split(separator: string, limit?: number): string[];
        
            /**
              * Split a string into substrings using the specified separator and return them as an array.
              * @param separator A Regular Express that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned. 
              * @param limit A value used to limit the number of elements returned in the array.
              */
            split(separator: RegExp, limit?: number): string[];
        
            /**
              * Returns the substring at the specified location within a String object. 
              * @param start The zero-based index number indicating the beginning of the substring.
              * @param end Zero-based index number indicating the end of the substring. The substring includes the characters up to, but not including, the character indicated by end.
              * If end is omitted, the characters from start through the end of the original string are returned.
              */
            substring(start: number, end?: number): string;
        
            /** Converts all the alphabetic characters in a string to lowercase. */
            toLowerCase(): string;
        
            /** Converts all alphabetic characters to lowercase, taking into account the host environment's current locale. */
            toLocaleLowerCase(): string;
        
            /** Converts all the alphabetic characters in a string to uppercase. */
            toUpperCase(): string;
        
            /** Returns a string where all alphabetic characters have been converted to uppercase, taking into account the host environment's current locale. */
            toLocaleUpperCase(): string;
        
            /** Removes the leading and trailing white space and line terminator characters from a string. */
            trim(): string;
        
            /** Returns the length of a String object. */
            length: number;
        
            // IE extensions
            /**
              * Gets a substring beginning at the specified location and having the specified length.
              * @param from The starting position of the desired substring. The index of the first character in the string is zero.
              * @param length The number of characters to include in the returned substring.
              */
            substr(from: number, length?: number): string;
        
            [index: number]: string;
        }
        
        /** 
          * Allows manipulation and formatting of text strings and determination and location of substrings within strings. 
          */
        declare var String: {
            new (value?: any): String;
            (value?: any): string;
            prototype: String;
            fromCharCode(...codes: number[]): string;
        }
        
        interface Boolean {
        }
        declare var Boolean: {
            new (value?: any): Boolean;
            (value?: any): boolean;
            prototype: Boolean;
        }
        
        interface Number {
            /**
              * Returns a string representation of an object.
              * @param radix Specifies a radix for converting numeric values to strings. This value is only used for numbers.
              */
            toString(radix?: number): string;
        
            /** 
              * Returns a string representing a number in fixed-point notation.
              * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.
              */
            toFixed(fractionDigits?: number): string;
        
            /**
              * Returns a string containing a number represented in exponential notation.
              * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.
              */
            toExponential(fractionDigits?: number): string;
        
            /**
              * Returns a string containing a number represented either in exponential or fixed-point notation with a specified number of digits.
              * @param precision Number of significant digits. Must be in the range 1 - 21, inclusive.
              */
            toPrecision(precision?: number): string;
        }
        
        /** An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers. */
        declare var Number: {
            new (value?: any): Number;
            (value?: any): number;
            prototype: Number;
        
            /** The largest number that can be represented in JavaScript. Equal to approximately 1.79E+308. */
            MAX_VALUE: number;
        
            /** The closest number to zero that can be represented in JavaScript. Equal to approximately 5.00E-324. */
            MIN_VALUE: number;
        
            /** 
              * A value that is not a number.
              * In equality comparisons, NaN does not equal any value, including itself. To test whether a value is equivalent to NaN, use the isNaN function.
              */
            NaN: number;
        
            /** 
              * A value that is less than the largest negative number that can be represented in JavaScript.
              * JavaScript displays NEGATIVE_INFINITY values as -infinity. 
              */
            NEGATIVE_INFINITY: number;
        
            /**
              * A value greater than the largest number that can be represented in JavaScript. 
              * JavaScript displays POSITIVE_INFINITY values as infinity. 
              */
            POSITIVE_INFINITY: number;
        }
        
        interface TemplateStringsArray extends Array<string> {
            raw: string[];
        }
        
        interface Math {
            /** The mathematical constant e. This is Euler's number, the base of natural logarithms. */
            E: number;
            /** The natural logarithm of 10. */
            LN10: number;
            /** The natural logarithm of 2. */
            LN2: number;
            /** The base-2 logarithm of e. */
            LOG2E: number;
            /** The base-10 logarithm of e. */
            LOG10E: number;
            /** Pi. This is the ratio of the circumference of a circle to its diameter. */
            PI: number;
            /** The square root of 0.5, or, equivalently, one divided by the square root of 2. */
            SQRT1_2: number;
            /** The square root of 2. */
            SQRT2: number;
            /**
              * Returns the absolute value of a number (the value without regard to whether it is positive or negative). 
              * For example, the absolute value of -5 is the same as the absolute value of 5.
              * @param x A numeric expression for which the absolute value is needed.
              */
            abs(x: number): number;
            /**
              * Returns the arc cosine (or inverse cosine) of a number. 
              * @param x A numeric expression.
              */
            acos(x: number): number;
            /** 
              * Returns the arcsine of a number. 
              * @param x A numeric expression.
              */
            asin(x: number): number;
            /**
              * Returns the arctangent of a number. 
              * @param x A numeric expression for which the arctangent is needed.
              */
            atan(x: number): number;
            /**
              * Returns the angle (in radians) from the X axis to a point (y,x).
              * @param y A numeric expression representing the cartesian y-coordinate.
              * @param x A numeric expression representing the cartesian x-coordinate.
              */
            atan2(y: number, x: number): number;
            /**
              * Returns the smallest number greater than or equal to its numeric argument. 
              * @param x A numeric expression.
              */
            ceil(x: number): number;
            /**
              * Returns the cosine of a number. 
              * @param x A numeric expression that contains an angle measured in radians.
              */
            cos(x: number): number;
            /**
              * Returns e (the base of natural logarithms) raised to a power. 
              * @param x A numeric expression representing the power of e.
              */
            exp(x: number): number;
            /**
              * Returns the greatest number less than or equal to its numeric argument. 
              * @param x A numeric expression.
              */
            floor(x: number): number;
            /**
              * Returns the natural logarithm (base e) of a number. 
              * @param x A numeric expression.
              */
            log(x: number): number;
            /**
              * Returns the larger of a set of supplied numeric expressions. 
              * @param values Numeric expressions to be evaluated.
              */
            max(...values: number[]): number;
            /**
              * Returns the smaller of a set of supplied numeric expressions. 
              * @param values Numeric expressions to be evaluated.
              */
            min(...values: number[]): number;
            /**
              * Returns the value of a base expression taken to a specified power. 
              * @param x The base value of the expression.
              * @param y The exponent value of the expression.
              */
            pow(x: number, y: number): number;
            /** Returns a pseudorandom number between 0 and 1. */
            random(): number;
            /** 
              * Returns a supplied numeric expression rounded to the nearest number.
              * @param x The value to be rounded to the nearest number.
              */
            round(x: number): number;
            /**
              * Returns the sine of a number.
              * @param x A numeric expression that contains an angle measured in radians.
              */
            sin(x: number): number;
            /**
              * Returns the square root of a number.
              * @param x A numeric expression.
              */
            sqrt(x: number): number;
            /**
              * Returns the tangent of a number.
              * @param x A numeric expression that contains an angle measured in radians.
              */
            tan(x: number): number;
        }
        /** An intrinsic object that provides basic mathematics functionality and constants. */
        declare var Math: Math;
        
        /** Enables basic storage and retrieval of dates and times. */
        interface Date {
            /** Returns a string representation of a date. The format of the string depends on the locale. */
            toString(): string;
            /** Returns a date as a string value. */
            toDateString(): string;
            /** Returns a time as a string value. */
            toTimeString(): string;
            /** Returns a value as a string value appropriate to the host environment's current locale. */
            toLocaleString(): string;
            /** Returns a date as a string value appropriate to the host environment's current locale. */
            toLocaleDateString(): string;
            /** Returns a time as a string value appropriate to the host environment's current locale. */
            toLocaleTimeString(): string;
            /** Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC. */
            valueOf(): number;
            /** Gets the time value in milliseconds. */
            getTime(): number;
            /** Gets the year, using local time. */
            getFullYear(): number;
            /** Gets the year using Universal Coordinated Time (UTC). */
            getUTCFullYear(): number;
            /** Gets the month, using local time. */
            getMonth(): number;
            /** Gets the month of a Date object using Universal Coordinated Time (UTC). */
            getUTCMonth(): number;
            /** Gets the day-of-the-month, using local time. */
            getDate(): number;
            /** Gets the day-of-the-month, using Universal Coordinated Time (UTC). */
            getUTCDate(): number;
            /** Gets the day of the week, using local time. */
            getDay(): number;
            /** Gets the day of the week using Universal Coordinated Time (UTC). */
            getUTCDay(): number;
            /** Gets the hours in a date, using local time. */
            getHours(): number;
            /** Gets the hours value in a Date object using Universal Coordinated Time (UTC). */
            getUTCHours(): number;
            /** Gets the minutes of a Date object, using local time. */
            getMinutes(): number;
            /** Gets the minutes of a Date object using Universal Coordinated Time (UTC). */
            getUTCMinutes(): number;
            /** Gets the seconds of a Date object, using local time. */
            getSeconds(): number;
            /** Gets the seconds of a Date object using Universal Coordinated Time (UTC). */
            getUTCSeconds(): number;
            /** Gets the milliseconds of a Date, using local time. */
            getMilliseconds(): number;
            /** Gets the milliseconds of a Date object using Universal Coordinated Time (UTC). */
            getUTCMilliseconds(): number;
            /** Gets the difference in minutes between the time on the local computer and Universal Coordinated Time (UTC). */
            getTimezoneOffset(): number;
            /** 
              * Sets the date and time value in the Date object.
              * @param time A numeric value representing the number of elapsed milliseconds since midnight, January 1, 1970 GMT. 
              */
            setTime(time: number): number;
            /**
              * Sets the milliseconds value in the Date object using local time. 
              * @param ms A numeric value equal to the millisecond value.
              */
            setMilliseconds(ms: number): number;
            /** 
              * Sets the milliseconds value in the Date object using Universal Coordinated Time (UTC).
              * @param ms A numeric value equal to the millisecond value. 
              */
            setUTCMilliseconds(ms: number): number;
        
            /**
              * Sets the seconds value in the Date object using local time. 
              * @param sec A numeric value equal to the seconds value.
              * @param ms A numeric value equal to the milliseconds value.
              */
            setSeconds(sec: number, ms?: number): number;
            /**
              * Sets the seconds value in the Date object using Universal Coordinated Time (UTC).
              * @param sec A numeric value equal to the seconds value.
              * @param ms A numeric value equal to the milliseconds value.
              */
            setUTCSeconds(sec: number, ms?: number): number;
            /**
              * Sets the minutes value in the Date object using local time. 
              * @param min A numeric value equal to the minutes value. 
              * @param sec A numeric value equal to the seconds value. 
              * @param ms A numeric value equal to the milliseconds value.
              */
            setMinutes(min: number, sec?: number, ms?: number): number;
            /**
              * Sets the minutes value in the Date object using Universal Coordinated Time (UTC).
              * @param min A numeric value equal to the minutes value. 
              * @param sec A numeric value equal to the seconds value. 
              * @param ms A numeric value equal to the milliseconds value.
              */
            setUTCMinutes(min: number, sec?: number, ms?: number): number;
            /**
              * Sets the hour value in the Date object using local time.
              * @param hours A numeric value equal to the hours value.
              * @param min A numeric value equal to the minutes value.
              * @param sec A numeric value equal to the seconds value. 
              * @param ms A numeric value equal to the milliseconds value.
              */
            setHours(hours: number, min?: number, sec?: number, ms?: number): number;
            /**
              * Sets the hours value in the Date object using Universal Coordinated Time (UTC).
              * @param hours A numeric value equal to the hours value.
              * @param min A numeric value equal to the minutes value.
              * @param sec A numeric value equal to the seconds value. 
              * @param ms A numeric value equal to the milliseconds value.
              */
            setUTCHours(hours: number, min?: number, sec?: number, ms?: number): number;
            /**
              * Sets the numeric day-of-the-month value of the Date object using local time. 
              * @param date A numeric value equal to the day of the month.
              */
            setDate(date: number): number;
            /** 
              * Sets the numeric day of the month in the Date object using Universal Coordinated Time (UTC).
              * @param date A numeric value equal to the day of the month. 
              */
            setUTCDate(date: number): number;
            /** 
              * Sets the month value in the Date object using local time. 
              * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. 
              * @param date A numeric value representing the day of the month. If this value is not supplied, the value from a call to the getDate method is used.
              */
            setMonth(month: number, date?: number): number;
            /**
              * Sets the month value in the Date object using Universal Coordinated Time (UTC).
              * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively.
              * @param date A numeric value representing the day of the month. If it is not supplied, the value from a call to the getUTCDate method is used.
              */
            setUTCMonth(month: number, date?: number): number;
            /**
              * Sets the year of the Date object using local time.
              * @param year A numeric value for the year.
              * @param month A zero-based numeric value for the month (0 for January, 11 for December). Must be specified if numDate is specified.
              * @param date A numeric value equal for the day of the month.
              */
            setFullYear(year: number, month?: number, date?: number): number;
            /**
              * Sets the year value in the Date object using Universal Coordinated Time (UTC).
              * @param year A numeric value equal to the year.
              * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. Must be supplied if numDate is supplied.
              * @param date A numeric value equal to the day of the month.
              */
            setUTCFullYear(year: number, month?: number, date?: number): number;
            /** Returns a date converted to a string using Universal Coordinated Time (UTC). */
            toUTCString(): string;
            /** Returns a date as a string value in ISO format. */
            toISOString(): string;
            /** Used by the JSON.stringify method to enable the transformation of an object's data for JavaScript Object Notation (JSON) serialization. */
            toJSON(key?: any): string;
        }
        
        declare var Date: {
            new (): Date;
            new (value: number): Date;
            new (value: string): Date;
            new (year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;
            (): string;
            prototype: Date;
            /**
              * Parses a string containing a date, and returns the number of milliseconds between that date and midnight, January 1, 1970.
              * @param s A date string
              */
            parse(s: string): number;
            /**
              * Returns the number of milliseconds between midnight, January 1, 1970 Universal Coordinated Time (UTC) (or GMT) and the specified date. 
              * @param year The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.
              * @param month The month as an number between 0 and 11 (January to December).
              * @param date The date as an number between 1 and 31.
              * @param hours Must be supplied if minutes is supplied. An number from 0 to 23 (midnight to 11pm) that specifies the hour.
              * @param minutes Must be supplied if seconds is supplied. An number from 0 to 59 that specifies the minutes.
              * @param seconds Must be supplied if milliseconds is supplied. An number from 0 to 59 that specifies the seconds.
              * @param ms An number from 0 to 999 that specifies the milliseconds.
              */
            UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;
            now(): number;
        }
        
        interface RegExpMatchArray extends Array<string> {
            index?: number;
            input?: string;
        }
        
        interface RegExpExecArray extends Array<string> {
            index: number;
            input: string;
        }
        
        interface RegExp {
            /** 
              * Executes a search on a string using a regular expression pattern, and returns an array containing the results of that search.
              * @param string The String object or string literal on which to perform the search.
              */
            exec(string: string): RegExpExecArray;
        
            /** 
              * Returns a Boolean value that indicates whether or not a pattern exists in a searched string.
              * @param string String on which to perform the search.
              */
            test(string: string): boolean;
        
            /** Returns a copy of the text of the regular expression pattern. Read-only. The rgExp argument is a Regular expression object. It can be a variable name or a literal. */
            source: string;
        
            /** Returns a Boolean value indicating the state of the global flag (g) used with a regular expression. Default is false. Read-only. */
            global: boolean;
        
            /** Returns a Boolean value indicating the state of the ignoreCase flag (i) used with a regular expression. Default is false. Read-only. */
            ignoreCase: boolean;
        
            /** Returns a Boolean value indicating the state of the multiline flag (m) used with a regular expression. Default is false. Read-only. */
            multiline: boolean;
        
            lastIndex: number;
        
            // Non-standard extensions
            compile(): RegExp;
        }
        declare var RegExp: {
            new (pattern: string, flags?: string): RegExp;
            (pattern: string, flags?: string): RegExp;
        
            // Non-standard extensions
            $1: string;
            $2: string;
            $3: string;
            $4: string;
            $5: string;
            $6: string;
            $7: string;
            $8: string;
            $9: string;
            lastMatch: string;
        }
        
        interface Error {
            name: string;
            message: string;
        }
        declare var Error: {
            new (message?: string): Error;
            (message?: string): Error;
            prototype: Error;
        }
        
        interface EvalError extends Error {
        }
        declare var EvalError: {
            new (message?: string): EvalError;
            (message?: string): EvalError;
            prototype: EvalError;
        }
        
        interface RangeError extends Error {
        }
        declare var RangeError: {
            new (message?: string): RangeError;
            (message?: string): RangeError;
            prototype: RangeError;
        }
        
        interface ReferenceError extends Error {
        }
        declare var ReferenceError: {
            new (message?: string): ReferenceError;
            (message?: string): ReferenceError;
            prototype: ReferenceError;
        }
        
        interface SyntaxError extends Error {
        }
        declare var SyntaxError: {
            new (message?: string): SyntaxError;
            (message?: string): SyntaxError;
            prototype: SyntaxError;
        }
        
        interface TypeError extends Error {
        }
        declare var TypeError: {
            new (message?: string): TypeError;
            (message?: string): TypeError;
            prototype: TypeError;
        }
        
        interface URIError extends Error {
        }
        declare var URIError: {
            new (message?: string): URIError;
            (message?: string): URIError;
            prototype: URIError;
        }
        
        interface JSON {
            /**
              * Converts a JavaScript Object Notation (JSON) string into an object.
              * @param text A valid JSON string.
              * @param reviver A function that transforms the results. This function is called for each member of the object. 
              * If a member contains nested objects, the nested objects are transformed before the parent object is. 
              */
            parse(text: string, reviver?: (key: any, value: any) => any): any;
            /**
              * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
              * @param value A JavaScript value, usually an object or array, to be converted.
              */
            stringify(value: any): string;
            /**
              * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
              * @param value A JavaScript value, usually an object or array, to be converted.
              * @param replacer A function that transforms the results.
              */
            stringify(value: any, replacer: (key: string, value: any) => any): string;
            /**
              * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
              * @param value A JavaScript value, usually an object or array, to be converted.
              * @param replacer Array that transforms the results.
              */
            stringify(value: any, replacer: any[]): string;
            /**
              * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
              * @param value A JavaScript value, usually an object or array, to be converted.
              * @param replacer A function that transforms the results.
              * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
              */
            stringify(value: any, replacer: (key: string, value: any) => any, space: any): string;
            /**
              * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
              * @param value A JavaScript value, usually an object or array, to be converted.
              * @param replacer Array that transforms the results.
              * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
              */
            stringify(value: any, replacer: any[], space: any): string;
        }
        /**
          * An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.
          */
        declare var JSON: JSON;
        
        
        /////////////////////////////
        /// ECMAScript Array API (specially handled by compiler)
        /////////////////////////////
        
        interface Array<T> {
            /**
              * Gets or sets the length of the array. This is a number one higher than the highest element defined in an array.
              */
            length: number;
            /**
              * Returns a string representation of an array.
              */
            toString(): string;
            toLocaleString(): string;
            /**
              * Appends new elements to an array, and returns the new length of the array.
              * @param items New elements of the Array.
              */
            push(...items: T[]): number;
            /**
              * Removes the last element from an array and returns it.
              */
            pop(): T;
            /**
              * Combines two or more arrays.
              * @param items Additional items to add to the end of array1.
              */
            concat<U extends T[]>(...items: U[]): T[];
            /**
              * Combines two or more arrays.
              * @param items Additional items to add to the end of array1.
              */
            concat(...items: T[]): T[];
            /**
              * Adds all the elements of an array separated by the specified separator string.
              * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
              */
            join(separator?: string): string;
            /**
              * Reverses the elements in an Array. 
              */
            reverse(): T[];
            /**
              * Removes the first element from an array and returns it.
              */
            shift(): T;
            /** 
              * Returns a section of an array.
              * @param start The beginning of the specified portion of the array.
              * @param end The end of the specified portion of the array.
              */
            slice(start?: number, end?: number): T[];
        
            /**
              * Sorts an array.
              * @param compareFn The name of the function used to determine the order of the elements. If omitted, the elements are sorted in ascending, ASCII character order.
              */
            sort(compareFn?: (a: T, b: T) => number): T[];
        
            /**
              * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
              * @param start The zero-based location in the array from which to start removing elements.
              */
            splice(start: number): T[];
        
            /**
              * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
              * @param start The zero-based location in the array from which to start removing elements.
              * @param deleteCount The number of elements to remove.
              * @param items Elements to insert into the array in place of the deleted elements.
              */
            splice(start: number, deleteCount: number, ...items: T[]): T[];
        
            /**
              * Inserts new elements at the start of an array.
              * @param items  Elements to insert at the start of the Array.
              */
            unshift(...items: T[]): number;
        
            /**
              * Returns the index of the first occurrence of a value in an array.
              * @param searchElement The value to locate in the array.
              * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.
              */
            indexOf(searchElement: T, fromIndex?: number): number;
        
            /**
              * Returns the index of the last occurrence of a specified value in an array.
              * @param searchElement The value to locate in the array.
              * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array.
              */
            lastIndexOf(searchElement: T, fromIndex?: number): number;
        
            /**
              * Determines whether all the members of an array satisfy the specified test.
              * @param callbackfn A function that accepts up to three arguments. The every method calls the callbackfn function for each element in array1 until the callbackfn returns false, or until the end of the array.
              * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
              */
            every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean;
        
            /**
              * Determines whether the specified callback function returns true for any element of an array.
              * @param callbackfn A function that accepts up to three arguments. The some method calls the callbackfn function for each element in array1 until the callbackfn returns true, or until the end of the array.
              * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
              */
            some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean;
        
            /**
              * Performs the specified action for each element in an array.
              * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array. 
              * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
              */
            forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
        
            /**
              * Calls a defined callback function on each element of an array, and returns an array that contains the results.
              * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array. 
              * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
              */
            map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
        
            /**
              * Returns the elements of an array that meet the condition specified in a callback function. 
              * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array. 
              * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
              */
            filter(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[];
        
            /**
              * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
              * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
              * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
              */
            reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T;
            /**
              * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
              * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
              * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
              */
            reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
        
            /** 
              * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
              * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. 
              * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
              */
            reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T;
            /** 
              * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
              * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. 
              * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
              */
            reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
        
            [n: number]: T;
        }
        declare var Array: {
            new (arrayLength?: number): any[];
            new <T>(arrayLength: number): T[];
            new <T>(...items: T[]): T[];
            (arrayLength?: number): any[];
            <T>(arrayLength: number): T[];
            <T>(...items: T[]): T[];
            isArray(arg: any): boolean;
            prototype: Array<any>;
        }
        
        /////////////////////////////
        /// IE10 ECMAScript Extensions
        /////////////////////////////
        
        /**
          * Represents a raw buffer of binary data, which is used to store data for the 
          * different typed arrays. ArrayBuffers cannot be read from or written to directly, 
          * but can be passed to a typed array or DataView Object to interpret the raw 
          * buffer as needed. 
          */
        interface ArrayBuffer {
            /**
              * Read-only. The length of the ArrayBuffer (in bytes).
              */
            byteLength: number;
        
            /**
              * Returns a section of an ArrayBuffer.
              */
            slice(begin:number, end?:number): ArrayBuffer;
        }
        
        declare var ArrayBuffer: {
            prototype: ArrayBuffer;
            new (byteLength: number): ArrayBuffer;
        }
        
        interface ArrayBufferView {
            buffer: ArrayBuffer;
            byteOffset: number;
            byteLength: number;
        }
        
        /**
          * A typed array of 8-bit integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
          */
        interface Int8Array extends ArrayBufferView {
            /**
              * The size in bytes of each element in the array. 
              */
            BYTES_PER_ELEMENT: number;
        
            /**
              * The length of the array.
              */
            length: number;
        
            [index: number]: number;
        
            /**
              * Gets the element at the specified index.
              * @param index The index at which to get the element of the array.
              */
            get(index: number): number;
        
            /**
              * Sets a value or an array of values.
              * @param index The index of the location to set.
              * @param value The value to set.
              */
            set(index: number, value: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: Int8Array, offset?: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: number[], offset?: number): void;
        
            /**
              * Gets a new Int8Array view of the ArrayBuffer store for this array, referencing the elements at begin, inclusive, up to end, exclusive. 
              * @param begin The index of the beginning of the array.
              * @param end The index of the end of the array.
              */
            subarray(begin: number, end?: number): Int8Array;
        }
        declare var Int8Array: {
            prototype: Int8Array;
            new (length: number): Int8Array;
            new (array: Int8Array): Int8Array;
            new (array: number[]): Int8Array;
            new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int8Array;
            BYTES_PER_ELEMENT: number;
        }
        
        /**
          * A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
          */
        interface Uint8Array extends ArrayBufferView {
            /**
              * The size in bytes of each element in the array. 
              */
            BYTES_PER_ELEMENT: number;
        
            /**
              * The length of the array.
              */
            length: number;
            [index: number]: number;
        
            /**
              * Gets the element at the specified index.
              * @param index The index at which to get the element of the array.
              */
            get(index: number): number;
        
            /**
              * Sets a value or an array of values.
              * @param index The index of the location to set.
              * @param value The value to set.
              */
            set(index: number, value: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: Uint8Array, offset?: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: number[], offset?: number): void;
        
            /**
              * Gets a new Uint8Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray. 
              * @param begin The index of the beginning of the array.
              * @param end The index of the end of the array.
              */
            subarray(begin: number, end?: number): Uint8Array;
        }
        declare var Uint8Array: {
            prototype: Uint8Array;
            new (length: number): Uint8Array;
            new (array: Uint8Array): Uint8Array;
            new (array: number[]): Uint8Array;
            new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint8Array;
            BYTES_PER_ELEMENT: number;
        }
        
        /**
          * A typed array of 16-bit integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
          */
        interface Int16Array extends ArrayBufferView {
            /**
              * The size in bytes of each element in the array. 
              */
            BYTES_PER_ELEMENT: number;
        
            /**
              * The length of the array.
              */
            length: number;
            [index: number]: number;
        
            /**
              * Gets the element at the specified index.
              * @param index The index at which to get the element of the array.
              */
            get(index: number): number;
        
            /**
              * Sets a value or an array of values.
              * @param index The index of the location to set.
              * @param value The value to set.
              */
            set(index: number, value: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: Int16Array, offset?: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: number[], offset?: number): void;
        
            /**
              * Gets a new Int16Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray. 
              * @param begin The index of the beginning of the array.
              * @param end The index of the end of the array.
              */
            subarray(begin: number, end?: number): Int16Array;
        }
        declare var Int16Array: {
            prototype: Int16Array;
            new (length: number): Int16Array;
            new (array: Int16Array): Int16Array;
            new (array: number[]): Int16Array;
            new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int16Array;
            BYTES_PER_ELEMENT: number;
        }
        
        /**
          * A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
          */
        interface Uint16Array extends ArrayBufferView {
            /**
              * The size in bytes of each element in the array. 
              */
            BYTES_PER_ELEMENT: number;
        
            /**
              * The length of the array.
              */
            length: number;
            [index: number]: number;
        
            /**
              * Gets the element at the specified index.
              * @param index The index at which to get the element of the array.
              */
            get(index: number): number;
        
            /**
              * Sets a value or an array of values.
              * @param index The index of the location to set.
              * @param value The value to set.
              */
            set(index: number, value: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: Uint16Array, offset?: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: number[], offset?: number): void;
        
            /**
              * Gets a new Uint16Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray.
              * @param begin The index of the beginning of the array.
              * @param end The index of the end of the array.
              */
            subarray(begin: number, end?: number): Uint16Array;
        }
        declare var Uint16Array: {
            prototype: Uint16Array;
            new (length: number): Uint16Array;
            new (array: Uint16Array): Uint16Array;
            new (array: number[]): Uint16Array;
            new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint16Array;
            BYTES_PER_ELEMENT: number;
        }
        
        /**
          * A typed array of 32-bit integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
          */
        interface Int32Array extends ArrayBufferView {
            /**
              * The size in bytes of each element in the array. 
              */
            BYTES_PER_ELEMENT: number;
        
            /**
              * The length of the array.
              */
            length: number;
            [index: number]: number;
        
            /**
              * Gets the element at the specified index.
              * @param index The index at which to get the element of the array.
              */
            get(index: number): number;
        
            /**
              * Sets a value or an array of values.
              * @param index The index of the location to set.
              * @param value The value to set.
              */
            set(index: number, value: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: Int32Array, offset?: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: number[], offset?: number): void;
        
            /**
              * Gets a new Int32Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray. 
              * @param begin The index of the beginning of the array.
              * @param end The index of the end of the array.
              */
            subarray(begin: number, end?: number): Int32Array;
        }
        declare var Int32Array: {
            prototype: Int32Array;
            new (length: number): Int32Array;
            new (array: Int32Array): Int32Array;
            new (array: number[]): Int32Array;
            new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int32Array;
            BYTES_PER_ELEMENT: number;
        }
        
        /**
          * A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
          */
        interface Uint32Array extends ArrayBufferView {
            /**
              * The size in bytes of each element in the array. 
              */
            BYTES_PER_ELEMENT: number;
        
            /**
              * The length of the array.
              */
            length: number;
            [index: number]: number;
        
            /**
              * Gets the element at the specified index.
              * @param index The index at which to get the element of the array.
              */
            get(index: number): number;
        
            /**
              * Sets a value or an array of values.
              * @param index The index of the location to set.
              * @param value The value to set.
              */
            set(index: number, value: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: Uint32Array, offset?: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: number[], offset?: number): void;
        
            /**
              * Gets a new Int8Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray. 
              * @param begin The index of the beginning of the array.
              * @param end The index of the end of the array.
              */
            subarray(begin: number, end?: number): Uint32Array;
        }
        declare var Uint32Array: {
            prototype: Uint32Array;
            new (length: number): Uint32Array;
            new (array: Uint32Array): Uint32Array;
            new (array: number[]): Uint32Array;
            new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint32Array;
            BYTES_PER_ELEMENT: number;
        }
        
        /**
          * A typed array of 32-bit float values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
          */
        interface Float32Array extends ArrayBufferView {
            /**
              * The size in bytes of each element in the array. 
              */
            BYTES_PER_ELEMENT: number;
        
            /**
              * The length of the array.
              */
            length: number;
            [index: number]: number;
        
            /**
              * Gets the element at the specified index.
              * @param index The index at which to get the element of the array.
              */
            get(index: number): number;
        
            /**
              * Sets a value or an array of values.
              * @param index The index of the location to set.
              * @param value The value to set.
              */
            set(index: number, value: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: Float32Array, offset?: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: number[], offset?: number): void;
        
            /**
              * Gets a new Float32Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray. 
              * @param begin The index of the beginning of the array.
              * @param end The index of the end of the array.
              */
            subarray(begin: number, end?: number): Float32Array;
        }
        declare var Float32Array: {
            prototype: Float32Array;
            new (length: number): Float32Array;
            new (array: Float32Array): Float32Array;
            new (array: number[]): Float32Array;
            new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float32Array;
            BYTES_PER_ELEMENT: number;
        }
        
        /**
          * A typed array of 64-bit float values. The contents are initialized to 0. If the requested number of bytes could not be allocated an exception is raised.
          */
        interface Float64Array extends ArrayBufferView {
            /**
              * The size in bytes of each element in the array. 
              */
            BYTES_PER_ELEMENT: number;
        
            /**
              * The length of the array.
              */
            length: number;
            [index: number]: number;
        
            /**
              * Gets the element at the specified index.
              * @param index The index at which to get the element of the array.
              */
            get(index: number): number;
        
            /**
              * Sets a value or an array of values.
              * @param index The index of the location to set.
              * @param value The value to set.
              */
            set(index: number, value: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: Float64Array, offset?: number): void;
        
            /**
              * Sets a value or an array of values.
              * @param array A typed or untyped array of values to set.
              * @param offset The index in the current array at which the values are to be written.
              */
            set(array: number[], offset?: number): void;
        
            /**
              * Gets a new Float64Array view of the ArrayBuffer Object store for this array, specifying the first and last members of the subarray. 
              * @param begin The index of the beginning of the array.
              * @param end The index of the end of the array.
              */
            subarray(begin: number, end?: number): Float64Array;
        }
        declare var Float64Array: {
            prototype: Float64Array;
            new (length: number): Float64Array;
            new (array: Float64Array): Float64Array;
            new (array: number[]): Float64Array;
            new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float64Array;
            BYTES_PER_ELEMENT: number;
        }
        
        /**
          * You can use a DataView object to read and write the different kinds of binary data to any location in the ArrayBuffer. 
          */
        interface DataView extends ArrayBufferView {
            /**
              * Gets the Int8 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset. 
              * @param byteOffset The place in the buffer at which the value should be retrieved.
              */
            getInt8(byteOffset: number): number;
        
            /**
              * Gets the Uint8 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset. 
              * @param byteOffset The place in the buffer at which the value should be retrieved.
              */
            getUint8(byteOffset: number): number;
        
            /**
              * Gets the Int16 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset. 
              * @param byteOffset The place in the buffer at which the value should be retrieved.
              */
            getInt16(byteOffset: number, littleEndian?: boolean): number;
        
            /**
              * Gets the Uint16 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset. 
              * @param byteOffset The place in the buffer at which the value should be retrieved.
              */
            getUint16(byteOffset: number, littleEndian?: boolean): number;
        
            /**
              * Gets the Int32 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset. 
              * @param byteOffset The place in the buffer at which the value should be retrieved.
              */
            getInt32(byteOffset: number, littleEndian?: boolean): number;
        
            /**
              * Gets the Uint32 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset. 
              * @param byteOffset The place in the buffer at which the value should be retrieved.
              */
            getUint32(byteOffset: number, littleEndian?: boolean): number;
        
            /**
              * Gets the Float32 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset. 
              * @param byteOffset The place in the buffer at which the value should be retrieved.
              */
            getFloat32(byteOffset: number, littleEndian?: boolean): number;
        
            /**
              * Gets the Float64 value at the specified byte offset from the start of the view. There is no alignment constraint; multi-byte values may be fetched from any offset. 
              * @param byteOffset The place in the buffer at which the value should be retrieved.
              */
            getFloat64(byteOffset: number, littleEndian?: boolean): number;
        
            /**
              * Stores an Int8 value at the specified byte offset from the start of the view. 
              * @param byteOffset The place in the buffer at which the value should be set.
              * @param value The value to set.
              */
            setInt8(byteOffset: number, value: number): void;
        
            /**
              * Stores an Uint8 value at the specified byte offset from the start of the view. 
              * @param byteOffset The place in the buffer at which the value should be set.
              * @param value The value to set.
              */
            setUint8(byteOffset: number, value: number): void;
        
            /**
              * Stores an Int16 value at the specified byte offset from the start of the view. 
              * @param byteOffset The place in the buffer at which the value should be set.
              * @param value The value to set.
              * @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
              */
            setInt16(byteOffset: number, value: number, littleEndian?: boolean): void;
        
            /**
              * Stores an Uint16 value at the specified byte offset from the start of the view. 
              * @param byteOffset The place in the buffer at which the value should be set.
              * @param value The value to set.
              * @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
              */
            setUint16(byteOffset: number, value: number, littleEndian?: boolean): void;
        
            /**
              * Stores an Int32 value at the specified byte offset from the start of the view. 
              * @param byteOffset The place in the buffer at which the value should be set.
              * @param value The value to set.
              * @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
              */
            setInt32(byteOffset: number, value: number, littleEndian?: boolean): void;
        
            /**
              * Stores an Uint32 value at the specified byte offset from the start of the view. 
              * @param byteOffset The place in the buffer at which the value should be set.
              * @param value The value to set.
              * @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
              */
            setUint32(byteOffset: number, value: number, littleEndian?: boolean): void;
        
            /**
              * Stores an Float32 value at the specified byte offset from the start of the view. 
              * @param byteOffset The place in the buffer at which the value should be set.
              * @param value The value to set.
              * @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
              */
            setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void;
        
            /**
              * Stores an Float64 value at the specified byte offset from the start of the view. 
              * @param byteOffset The place in the buffer at which the value should be set.
              * @param value The value to set.
              * @param littleEndian If false or undefined, a big-endian value should be written, otherwise a little-endian value should be written.
              */
            setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void;
        }
        declare var DataView: {
            prototype: DataView;
            new (buffer: ArrayBuffer, byteOffset?: number, length?: number): DataView;
        }
        
        /////////////////////////////
        /// IE11 ECMAScript Extensions
        /////////////////////////////
        
        interface Map<K, V> {
            clear(): void;
            delete(key: K): boolean;
            forEach(callbackfn: (value: V, index: K, map: Map<K, V>) => void, thisArg?: any): void;
            get(key: K): V;
            has(key: K): boolean;
            set(key: K, value: V): Map<K, V>;
            size: number;
        }
        declare var Map: {
            new <K, V>(): Map<K, V>;
        }
        
        interface WeakMap<K, V> {
            clear(): void;
            delete(key: K): boolean;
            get(key: K): V;
            has(key: K): boolean;
            set(key: K, value: V): WeakMap<K, V>;
        }
        declare var WeakMap: {
            new <K, V>(): WeakMap<K, V>;
        }
        
        interface Set<T> {
            add(value: T): Set<T>;
            clear(): void;
            delete(value: T): boolean;
            forEach(callbackfn: (value: T, index: T, set: Set<T>) => void, thisArg?: any): void;
            has(value: T): boolean;
            size: number;
        }
        declare var Set: {
            new <T>(): Set<T>;
        }
        
        declare module Intl {
        
            interface CollatorOptions {
                usage?: string;
                localeMatcher?: string;
                numeric?: boolean;
                caseFirst?: string;
                sensitivity?: string;
                ignorePunctuation?: boolean;
            }
        
            interface ResolvedCollatorOptions {
                locale: string;
                usage: string;
                sensitivity: string;
                ignorePunctuation: boolean;
                collation: string;
                caseFirst: string;
                numeric: boolean;
            }
        
            interface Collator {
                compare(x: string, y: string): number;
                resolvedOptions(): ResolvedCollatorOptions;
            }
            var Collator: {
                new (locales?: string[], options?: CollatorOptions): Collator;
                new (locale?: string, options?: CollatorOptions): Collator;
                (locales?: string[], options?: CollatorOptions): Collator;
                (locale?: string, options?: CollatorOptions): Collator;
                supportedLocalesOf(locales: string[], options?: CollatorOptions): string[];
                supportedLocalesOf(locale: string, options?: CollatorOptions): string[];
            }
        
            interface NumberFormatOptions {
                localeMatcher?: string;
                style?: string;
                currency?: string;
                currencyDisplay?: string;
                useGrouping?: boolean;
            }
        
            interface ResolvedNumberFormatOptions {
                locale: string;
                numberingSystem: string;
                style: string;
                currency?: string;
                currencyDisplay?: string;
                minimumintegerDigits: number;
                minimumFractionDigits: number;
                maximumFractionDigits: number;
                minimumSignificantDigits?: number;
                maximumSignificantDigits?: number;
                useGrouping: boolean;
            }
        
            interface NumberFormat {
                format(value: number): string;
                resolvedOptions(): ResolvedNumberFormatOptions;
            }
            var NumberFormat: {
                new (locales?: string[], options?: NumberFormatOptions): Collator;
                new (locale?: string, options?: NumberFormatOptions): Collator;
                (locales?: string[], options?: NumberFormatOptions): Collator;
                (locale?: string, options?: NumberFormatOptions): Collator;
                supportedLocalesOf(locales: string[], options?: NumberFormatOptions): string[];
                supportedLocalesOf(locale: string, options?: NumberFormatOptions): string[];
            }
        
            interface DateTimeFormatOptions {
                localeMatcher?: string;
                weekday?: string;
                era?: string;
                year?: string;
                month?: string;
                day?: string;
                hour?: string;
                minute?: string;
                second?: string;
                timeZoneName?: string;
                formatMatcher?: string;
                hour12: boolean;
            }
        
            interface ResolvedDateTimeFormatOptions {
                locale: string;
                calendar: string;
                numberingSystem: string;
                timeZone: string;
                hour12?: boolean;
                weekday?: string;
                era?: string;
                year?: string;
                month?: string;
                day?: string;
                hour?: string;
                minute?: string;
                second?: string;
                timeZoneName?: string;
            }
        
            interface DateTimeFormat {
                format(date: number): string;
                resolvedOptions(): ResolvedDateTimeFormatOptions;
            }
            var DateTimeFormat: {
                new (locales?: string[], options?: DateTimeFormatOptions): Collator;
                new (locale?: string, options?: DateTimeFormatOptions): Collator;
                (locales?: string[], options?: DateTimeFormatOptions): Collator;
                (locale?: string, options?: DateTimeFormatOptions): Collator;
                supportedLocalesOf(locales: string[], options?: DateTimeFormatOptions): string[];
                supportedLocalesOf(locale: string, options?: DateTimeFormatOptions): string[];
            }
        }
        
        interface String {
            /**
              * Determines whether two strings are equivalent in the current locale.
              * @param that String to compare to target string
              * @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. This parameter must conform to BCP 47 standards; see the Intl.Collator object for details.
              * @param options An object that contains one or more properties that specify comparison options. see the Intl.Collator object for details.
              */
            localeCompare(that: string, locales: string[], options?: Intl.CollatorOptions): number;
        
            /**
              * Determines whether two strings are equivalent in the current locale.
              * @param that String to compare to target string
              * @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used. This parameter must conform to BCP 47 standards; see the Intl.Collator object for details.
              * @param options An object that contains one or more properties that specify comparison options. see the Intl.Collator object for details.
              */
            localeCompare(that: string, locale: string, options?: Intl.CollatorOptions): number;
        }
        
        interface Number {
            /**
              * Converts a number to a string by using the current or specified locale. 
              * @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.
              * @param options An object that contains one or more properties that specify comparison options.
              */
            toLocaleString(locales?: string[], options?: Intl.NumberFormatOptions): string;
        
            /**
              * Converts a number to a string by using the current or specified locale. 
              * @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used.
              * @param options An object that contains one or more properties that specify comparison options.
              */
            toLocaleString(locale?: string, options?: Intl.NumberFormatOptions): string;
        }
        
        interface Date {
            /**
              * Converts a date to a string by using the current or specified locale.  
              * @param locales An array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.
              * @param options An object that contains one or more properties that specify comparison options.
              */
            toLocaleString(locales?: string[], options?: Intl.DateTimeFormatOptions): string;
        
            /**
              * Converts a date to a string by using the current or specified locale.  
              * @param locale Locale tag. If you omit this parameter, the default locale of the JavaScript runtime is used.
              * @param options An object that contains one or more properties that specify comparison options.
              */
            toLocaleString(locale?: string, options?: Intl.DateTimeFormatOptions): string;
        }
        
        /////////////////////////////
        /// IE DOM APIs
        /////////////////////////////
        
        
        interface PositionOptions {
            enableHighAccuracy?: boolean;
            timeout?: number;
            maximumAge?: number;
        }
        
        interface ObjectURLOptions {
            oneTimeOnly?: boolean;
        }
        
        interface StoreExceptionsInformation extends ExceptionInformation {
            siteName?: string;
            explanationString?: string;
            detailURI?: string;
        }
        
        interface StoreSiteSpecificExceptionsInformation extends StoreExceptionsInformation {
            arrayOfDomainStrings?: string[];
        }
        
        interface ConfirmSiteSpecificExceptionsInformation extends ExceptionInformation {
            arrayOfDomainStrings?: string[];
        }
        
        interface AlgorithmParameters {
        }
        
        interface MutationObserverInit {
            childList?: boolean;
            attributes?: boolean;
            characterData?: boolean;
            subtree?: boolean;
            attributeOldValue?: boolean;
            characterDataOldValue?: boolean;
            attributeFilter?: string[];
        }
        
        interface PointerEventInit extends MouseEventInit {
            pointerId?: number;
            width?: number;
            height?: number;
            pressure?: number;
            tiltX?: number;
            tiltY?: number;
            pointerType?: string;
            isPrimary?: boolean;
        }
        
        interface ExceptionInformation {
            domain?: string;
        }
        
        interface DeviceAccelerationDict {
            x?: number;
            y?: number;
            z?: number;
        }
        
        interface MsZoomToOptions {
            contentX?: number;
            contentY?: number;
            viewportX?: string;
            viewportY?: string;
            scaleFactor?: number;
            animate?: string;
        }
        
        interface DeviceRotationRateDict {
            alpha?: number;
            beta?: number;
            gamma?: number;
        }
        
        interface Algorithm {
            name?: string;
            params?: AlgorithmParameters;
        }
        
        interface MouseEventInit {
            bubbles?: boolean;
            cancelable?: boolean;
            view?: Window;
            detail?: number;
            screenX?: number;
            screenY?: number;
            clientX?: number;
            clientY?: number;
            ctrlKey?: boolean;
            shiftKey?: boolean;
            altKey?: boolean;
            metaKey?: boolean;
            button?: number;
            buttons?: number;
            relatedTarget?: EventTarget;
        }
        
        interface WebGLContextAttributes {
            alpha?: boolean;
            depth?: boolean;
            stencil?: boolean;
            antialias?: boolean;
            premultipliedAlpha?: boolean;
            preserveDrawingBuffer?: boolean;
        }
        
        interface NodeListOf<TNode extends Node> extends NodeList {
            length: number;
            item(index: number): TNode;
            [index: number]: TNode;
        }
        
        interface HTMLElement extends Element, ElementCSSInlineStyle, MSEventAttachmentTarget, MSNodeExtensions {
            hidden: any;
            readyState: any;
            onmouseleave: (ev: MouseEvent) => any;
            onbeforecut: (ev: DragEvent) => any;
            onkeydown: (ev: KeyboardEvent) => any;
            onmove: (ev: MSEventObj) => any;
            onkeyup: (ev: KeyboardEvent) => any;
            onreset: (ev: Event) => any;
            onhelp: (ev: Event) => any;
            ondragleave: (ev: DragEvent) => any;
            className: string;
            onfocusin: (ev: FocusEvent) => any;
            onseeked: (ev: Event) => any;
            recordNumber: any;
            title: string;
            parentTextEdit: Element;
            outerHTML: string;
            ondurationchange: (ev: Event) => any;
            offsetHeight: number;
            all: HTMLCollection;
            onblur: (ev: FocusEvent) => any;
            dir: string;
            onemptied: (ev: Event) => any;
            onseeking: (ev: Event) => any;
            oncanplay: (ev: Event) => any;
            ondeactivate: (ev: UIEvent) => any;
            ondatasetchanged: (ev: MSEventObj) => any;
            onrowsdelete: (ev: MSEventObj) => any;
            sourceIndex: number;
            onloadstart: (ev: Event) => any;
            onlosecapture: (ev: MSEventObj) => any;
            ondragenter: (ev: DragEvent) => any;
            oncontrolselect: (ev: MSEventObj) => any;
            onsubmit: (ev: Event) => any;
            behaviorUrns: MSBehaviorUrnsCollection;
            scopeName: string;
            onchange: (ev: Event) => any;
            id: string;
            onlayoutcomplete: (ev: MSEventObj) => any;
            uniqueID: string;
            onbeforeactivate: (ev: UIEvent) => any;
            oncanplaythrough: (ev: Event) => any;
            onbeforeupdate: (ev: MSEventObj) => any;
            onfilterchange: (ev: MSEventObj) => any;
            offsetParent: Element;
            ondatasetcomplete: (ev: MSEventObj) => any;
            onsuspend: (ev: Event) => any;
            onmouseenter: (ev: MouseEvent) => any;
            innerText: string;
            onerrorupdate: (ev: MSEventObj) => any;
            onmouseout: (ev: MouseEvent) => any;
            parentElement: HTMLElement;
            onmousewheel: (ev: MouseWheelEvent) => any;
            onvolumechange: (ev: Event) => any;
            oncellchange: (ev: MSEventObj) => any;
            onrowexit: (ev: MSEventObj) => any;
            onrowsinserted: (ev: MSEventObj) => any;
            onpropertychange: (ev: MSEventObj) => any;
            filters: any;
            children: HTMLCollection;
            ondragend: (ev: DragEvent) => any;
            onbeforepaste: (ev: DragEvent) => any;
            ondragover: (ev: DragEvent) => any;
            offsetTop: number;
            onmouseup: (ev: MouseEvent) => any;
            ondragstart: (ev: DragEvent) => any;
            onbeforecopy: (ev: DragEvent) => any;
            ondrag: (ev: DragEvent) => any;
            innerHTML: string;
            onmouseover: (ev: MouseEvent) => any;
            lang: string;
            uniqueNumber: number;
            onpause: (ev: Event) => any;
            tagUrn: string;
            onmousedown: (ev: MouseEvent) => any;
            onclick: (ev: MouseEvent) => any;
            onwaiting: (ev: Event) => any;
            onresizestart: (ev: MSEventObj) => any;
            offsetLeft: number;
            isTextEdit: boolean;
            isDisabled: boolean;
            onpaste: (ev: DragEvent) => any;
            canHaveHTML: boolean;
            onmoveend: (ev: MSEventObj) => any;
            language: string;
            onstalled: (ev: Event) => any;
            onmousemove: (ev: MouseEvent) => any;
            style: MSStyleCSSProperties;
            isContentEditable: boolean;
            onbeforeeditfocus: (ev: MSEventObj) => any;
            onratechange: (ev: Event) => any;
            contentEditable: string;
            tabIndex: number;
            document: Document;
            onprogress: (ev: ProgressEvent) => any;
            ondblclick: (ev: MouseEvent) => any;
            oncontextmenu: (ev: MouseEvent) => any;
            onloadedmetadata: (ev: Event) => any;
            onafterupdate: (ev: MSEventObj) => any;
            onerror: (ev: ErrorEvent) => any;
            onplay: (ev: Event) => any;
            onresizeend: (ev: MSEventObj) => any;
            onplaying: (ev: Event) => any;
            isMultiLine: boolean;
            onfocusout: (ev: FocusEvent) => any;
            onabort: (ev: UIEvent) => any;
            ondataavailable: (ev: MSEventObj) => any;
            hideFocus: boolean;
            onreadystatechange: (ev: Event) => any;
            onkeypress: (ev: KeyboardEvent) => any;
            onloadeddata: (ev: Event) => any;
            onbeforedeactivate: (ev: UIEvent) => any;
            outerText: string;
            disabled: boolean;
            onactivate: (ev: UIEvent) => any;
            accessKey: string;
            onmovestart: (ev: MSEventObj) => any;
            onselectstart: (ev: Event) => any;
            onfocus: (ev: FocusEvent) => any;
            ontimeupdate: (ev: Event) => any;
            onresize: (ev: UIEvent) => any;
            oncut: (ev: DragEvent) => any;
            onselect: (ev: UIEvent) => any;
            ondrop: (ev: DragEvent) => any;
            offsetWidth: number;
            oncopy: (ev: DragEvent) => any;
            onended: (ev: Event) => any;
            onscroll: (ev: UIEvent) => any;
            onrowenter: (ev: MSEventObj) => any;
            onload: (ev: Event) => any;
            canHaveChildren: boolean;
            oninput: (ev: Event) => any;
            onmscontentzoom: (ev: MSEventObj) => any;
            oncuechange: (ev: Event) => any;
            spellcheck: boolean;
            classList: DOMTokenList;
            onmsmanipulationstatechanged: (ev: any) => any;
            draggable: boolean;
            dataset: DOMStringMap;
            dragDrop(): boolean;
            scrollIntoView(top?: boolean): void;
            addFilter(filter: any): void;
            setCapture(containerCapture?: boolean): void;
            focus(): void;
            getAdjacentText(where: string): string;
            insertAdjacentText(where: string, text: string): void;
            getElementsByClassName(classNames: string): NodeList;
            setActive(): void;
            removeFilter(filter: any): void;
            blur(): void;
            clearAttributes(): void;
            releaseCapture(): void;
            createControlRange(): ControlRangeCollection;
            removeBehavior(cookie: number): boolean;
            contains(child: HTMLElement): boolean;
            click(): void;
            insertAdjacentElement(position: string, insertedElement: Element): Element;
            mergeAttributes(source: HTMLElement, preserveIdentity?: boolean): void;
            replaceAdjacentText(where: string, newText: string): string;
            applyElement(apply: Element, where?: string): Element;
            addBehavior(bstrUrl: string, factory?: any): number;
            insertAdjacentHTML(where: string, html: string): void;
            msGetInputContext(): MSInputMethodContext;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "move", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "deactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetchanged", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsdelete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "losecapture", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "controlselect", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "layoutcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "filterchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "errorupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "cellchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowexit", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsinserted", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "propertychange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforepaste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecopy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "paste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "moveend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeeditfocus", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "afterupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizeend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dataavailable", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforedeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "activate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "movestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "selectstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "cut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "copy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "rowenter", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mscontentzoom", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "cuechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "msmanipulationstatechanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var HTMLElement: {
            prototype: HTMLElement;
            new(): HTMLElement;
        }
        
        interface Document extends Node, NodeSelector, MSEventAttachmentTarget, DocumentEvent, MSResourceMetadata, MSNodeExtensions, MSDocumentExtensions, GlobalEventHandlers {
            /**
              * Gets a reference to the root node of the document. 
              */
            documentElement: HTMLElement;
            /**
              * Retrieves the collection of user agents and versions declared in the X-UA-Compatible
              */
            compatible: MSCompatibleInfoCollection;
            /**
              * Fires when the user presses a key.
              * @param ev The keyboard event
              */
            onkeydown: (ev: KeyboardEvent) => any;
            /**
              * Fires when the user releases a key.
              * @param ev The keyboard event
              */
            onkeyup: (ev: KeyboardEvent) => any;
            /**
              * Gets the implementation object of the current document. 
              */
            implementation: DOMImplementation;
            /**
              * Fires when the user resets a form. 
              * @param ev The event.
              */
            onreset: (ev: Event) => any;
            /**
              * Retrieves a collection of all script objects in the document.
              */
            scripts: HTMLCollection;
            /**
              * Fires when the user presses the F1 key while the browser is the active window. 
              * @param ev The event.
              */
            onhelp: (ev: Event) => any;
            /** 
              * Fires on the target object when the user moves the mouse out of a valid drop target during a drag operation.
              * @param ev The drag event.
              */
            ondragleave: (ev: DragEvent) => any;
            /**
              * Gets or sets the character set used to encode the object.
              */
            charset: string;
            /**
              * Fires for an element just prior to setting focus on that element.
              * @param ev The focus event
              */
            onfocusin: (ev: FocusEvent) => any;
            /** 
              * Sets or gets the color of the links that the user has visited.
              */
            vlinkColor: string;
            /**
              * Occurs when the seek operation ends. 
              * @param ev The event.
              */
            onseeked: (ev: Event) => any;
            security: string;
            /**
              * Contains the title of the document.
              */
            title: string;
            /**
              * Retrieves a collection of namespace objects.
              */
            namespaces: MSNamespaceInfoCollection;
            /**
              * Gets the default character set from the current regional language settings.
              */
            defaultCharset: string;
            /**
              * Retrieves a collection of all embed objects in the document.
              */
            embeds: HTMLCollection;
            /**
              * Retrieves a collection of styleSheet objects representing the style sheets that correspond to each instance of a link or style object in the document.
              */
            styleSheets: StyleSheetList;
            /**
              * Retrieves a collection of all window objects defined by the given document or defined by the document associated with the given window.
              */
            frames: Window;
            /**
              * Occurs when the duration attribute is updated. 
              * @param ev The event.
              */
            ondurationchange: (ev: Event) => any;
            /**
              * Returns a reference to the collection of elements contained by the object.
              */
            all: HTMLCollection;
            /**
              * Retrieves a collection, in source order, of all form objects in the document.
              */
            forms: HTMLCollection;
            /** 
              * Fires when the object loses the input focus. 
              * @param ev The focus event.
              */
            onblur: (ev: FocusEvent) => any;
            /**
              * Sets or retrieves a value that indicates the reading order of the object. 
              */
            dir: string;
            /**
              * Occurs when the media element is reset to its initial state. 
              * @param ev The event.
              */
            onemptied: (ev: Event) => any;
            /**
              * Sets or gets a value that indicates whether the document can be edited.
              */
            designMode: string;
            /**
              * Occurs when the current playback position is moved. 
              * @param ev The event.
              */
            onseeking: (ev: Event) => any;
            /**
              * Fires when the activeElement is changed from the current object to another object in the parent document.
              * @param ev The UI Event
              */
            ondeactivate: (ev: UIEvent) => any;
            /**
              * Occurs when playback is possible, but would require further buffering. 
              * @param ev The event.
              */
            oncanplay: (ev: Event) => any;
            /**
              * Fires when the data set exposed by a data source object changes. 
              * @param ev The event.
              */
            ondatasetchanged: (ev: MSEventObj) => any;
            /**
              * Fires when rows are about to be deleted from the recordset.
              * @param ev The event 
              */
            onrowsdelete: (ev: MSEventObj) => any;
            Script: MSScriptHost;
            /**
              * Occurs when Internet Explorer begins looking for media data. 
              * @param ev The event.
              */
            onloadstart: (ev: Event) => any;
            /**
              * Gets the URL for the document, stripped of any character encoding.
              */
            URLUnencoded: string;
            defaultView: Window;
            /**
              * Fires when the user is about to make a control selection of the object.
              * @param ev The event.
              */
            oncontrolselect: (ev: MSEventObj) => any;
            /** 
              * Fires on the target element when the user drags the object to a valid drop target.
              * @param ev The drag event.
              */
            ondragenter: (ev: DragEvent) => any;
            onsubmit: (ev: Event) => any;
            /**
              * Returns the character encoding used to create the webpage that is loaded into the document object.
              */
            inputEncoding: string;
            /**
              * Gets the object that has the focus when the parent document has focus.
              */
            activeElement: Element;
            /**
              * Fires when the contents of the object or selection have changed. 
              * @param ev The event.
              */
            onchange: (ev: Event) => any;
            /**
              * Retrieves a collection of all a objects that specify the href property and all area objects in the document.
              */
            links: HTMLCollection;
            /**
              * Retrieves an autogenerated, unique identifier for the object. 
              */
            uniqueID: string;
            /**
              * Sets or gets the URL for the current document. 
              */
            URL: string;
            /**
              * Fires immediately before the object is set as the active element.
              * @param ev The event.
              */
            onbeforeactivate: (ev: UIEvent) => any;
            head: HTMLHeadElement;
            cookie: string;
            xmlEncoding: string;
            oncanplaythrough: (ev: Event) => any;
            /** 
              * Retrieves the document compatibility mode of the document.
              */
            documentMode: number;
            characterSet: string;
            /**
              * Retrieves a collection of all a objects that have a name and/or id property. Objects in this collection are in HTML source order.
              */
            anchors: HTMLCollection;
            onbeforeupdate: (ev: MSEventObj) => any;
            /** 
              * Fires to indicate that all data is available from the data source object. 
              * @param ev The event.
              */
            ondatasetcomplete: (ev: MSEventObj) => any;
            plugins: HTMLCollection;
            /**
              * Occurs if the load operation has been intentionally halted. 
              * @param ev The event.
              */
            onsuspend: (ev: Event) => any;
            /**
              * Gets the root svg element in the document hierarchy.
              */
            rootElement: SVGSVGElement;
            /**
              * Retrieves a value that indicates the current state of the object.
              */
            readyState: string;
            /**
              * Gets the URL of the location that referred the user to the current page.
              */
            referrer: string;
            /**
              * Sets or gets the color of all active links in the document.
              */
            alinkColor: string;
            /**
              * Fires on a databound object when an error occurs while updating the associated data in the data source object. 
              * @param ev The event.
              */
            onerrorupdate: (ev: MSEventObj) => any;
            /**
              * Gets a reference to the container object of the window.
              */
            parentWindow: Window;
            /**
              * Fires when the user moves the mouse pointer outside the boundaries of the object. 
              * @param ev The mouse event.
              */
            onmouseout: (ev: MouseEvent) => any;
            /**
              * Occurs when a user clicks a button in a Thumbnail Toolbar of a webpage running in Site Mode.
              * @param ev The event.
              */
            onmsthumbnailclick: (ev: MSSiteModeEvent) => any;
            /**
              * Fires when the wheel button is rotated. 
              * @param ev The mouse event
              */
            onmousewheel: (ev: MouseWheelEvent) => any;
            /**
              * Occurs when the volume is changed, or playback is muted or unmuted.
              * @param ev The event.
              */
            onvolumechange: (ev: Event) => any;
            /** 
              * Fires when data changes in the data provider.
              * @param ev The event.
              */
            oncellchange: (ev: MSEventObj) => any;
            /**
              * Fires just before the data source control changes the current row in the object. 
              * @param ev The event.
              */
            onrowexit: (ev: MSEventObj) => any;
            /**
              * Fires just after new rows are inserted in the current recordset.
              * @param ev The event.
              */
            onrowsinserted: (ev: MSEventObj) => any;
            /**
              * Gets or sets the version attribute specified in the declaration of an XML document.
              */
            xmlVersion: string;
            msCapsLockWarningOff: boolean;
            /**
              * Fires when a property changes on the object.
              * @param ev The event.
              */
            onpropertychange: (ev: MSEventObj) => any;
            /**
              * Fires on the source object when the user releases the mouse at the close of a drag operation.
              * @param ev The event.
              */
            ondragend: (ev: DragEvent) => any;
            /**
              * Gets an object representing the document type declaration associated with the current document. 
              */
            doctype: DocumentType;
            /**
              * Fires on the target element continuously while the user drags the object over a valid drop target.
              * @param ev The event.
              */
            ondragover: (ev: DragEvent) => any;
            /**
              * Deprecated. Sets or retrieves a value that indicates the background color behind the object. 
              */
            bgColor: string;
            /**
              * Fires on the source object when the user starts to drag a text selection or selected object. 
              * @param ev The event.
              */
            ondragstart: (ev: DragEvent) => any;
            /**
              * Fires when the user releases a mouse button while the mouse is over the object. 
              * @param ev The mouse event.
              */
            onmouseup: (ev: MouseEvent) => any;
            /**
              * Fires on the source object continuously during a drag operation.
              * @param ev The event.
              */
            ondrag: (ev: DragEvent) => any;
            /**
              * Fires when the user moves the mouse pointer into the object.
              * @param ev The mouse event.
              */
            onmouseover: (ev: MouseEvent) => any;
            /**
              * Sets or gets the color of the document links. 
              */
            linkColor: string;
            /**
              * Occurs when playback is paused.
              * @param ev The event.
              */
            onpause: (ev: Event) => any;
            /**
              * Fires when the user clicks the object with either mouse button. 
              * @param ev The mouse event.
              */
            onmousedown: (ev: MouseEvent) => any;
            /**
              * Fires when the user clicks the left mouse button on the object
              * @param ev The mouse event.
              */
            onclick: (ev: MouseEvent) => any;
            /**
              * Occurs when playback stops because the next frame of a video resource is not available. 
              * @param ev The event.
              */
            onwaiting: (ev: Event) => any;
            /**
              * Fires when the user clicks the Stop button or leaves the Web page.
              * @param ev The event.
              */
            onstop: (ev: Event) => any;
            /**
              * Occurs when an item is removed from a Jump List of a webpage running in Site Mode. 
              * @param ev The event.
              */
            onmssitemodejumplistitemremoved: (ev: MSSiteModeEvent) => any;
            /**
              * Retrieves a collection of all applet objects in the document.
              */
            applets: HTMLCollection;
            /**
              * Specifies the beginning and end of the document body.
              */
            body: HTMLElement;
            /**
              * Sets or gets the security domain of the document. 
              */
            domain: string;
            xmlStandalone: boolean;
            /**
              * Represents the active selection, which is a highlighted block of text or other elements in the document that a user or a script can carry out some action on.
              */
            selection: MSSelection;
            /**
              * Occurs when the download has stopped. 
              * @param ev The event.
              */
            onstalled: (ev: Event) => any;
            /**
              * Fires when the user moves the mouse over the object. 
              * @param ev The mouse event.
              */
            onmousemove: (ev: MouseEvent) => any;
            /**
              * Fires before an object contained in an editable element enters a UI-activated state or when an editable container object is control selected.
              * @param ev The event.
              */
            onbeforeeditfocus: (ev: MSEventObj) => any;
            /**
              * Occurs when the playback rate is increased or decreased. 
              * @param ev The event.
              */
            onratechange: (ev: Event) => any;
            /**
              * Occurs to indicate progress while downloading media data. 
              * @param ev The event.
              */
            onprogress: (ev: ProgressEvent) => any;
            /**
              * Fires when the user double-clicks the object.
              * @param ev The mouse event.
              */
            ondblclick: (ev: MouseEvent) => any;
            /**
              * Fires when the user clicks the right mouse button in the client area, opening the context menu. 
              * @param ev The mouse event.
              */
            oncontextmenu: (ev: MouseEvent) => any;
            /**
              * Occurs when the duration and dimensions of the media have been determined.
              * @param ev The event.
              */
            onloadedmetadata: (ev: Event) => any;
            media: string;
            /**
              * Fires when an error occurs during object loading.
              * @param ev The event.
              */
            onerror: (ev: ErrorEvent) => any;
            /**
              * Occurs when the play method is requested. 
              * @param ev The event.
              */
            onplay: (ev: Event) => any;
            onafterupdate: (ev: MSEventObj) => any;
            /**
              * Occurs when the audio or video has started playing. 
              * @param ev The event.
              */
            onplaying: (ev: Event) => any;
            /**
              * Retrieves a collection, in source order, of img objects in the document.
              */
            images: HTMLCollection;
            /**
              * Contains information about the current URL. 
              */
            location: Location;
            /**
              * Fires when the user aborts the download.
              * @param ev The event.
              */
            onabort: (ev: UIEvent) => any;
            /**
              * Fires for the current element with focus immediately after moving focus to another element. 
              * @param ev The event.
              */
            onfocusout: (ev: FocusEvent) => any;
            /**
              * Fires when the selection state of a document changes.
              * @param ev The event.
              */
            onselectionchange: (ev: Event) => any;
            /**
              * Fires when a local DOM Storage area is written to disk.
              * @param ev The event.
              */
            onstoragecommit: (ev: StorageEvent) => any;
            /**
              * Fires periodically as data arrives from data source objects that asynchronously transmit their data. 
              * @param ev The event.
              */
            ondataavailable: (ev: MSEventObj) => any;
            /**
              * Fires when the state of the object has changed.
              * @param ev The event
              */
            onreadystatechange: (ev: Event) => any;
            /**
              * Gets the date that the page was last modified, if the page supplies one. 
              */
            lastModified: string;
            /**
              * Fires when the user presses an alphanumeric key.
              * @param ev The event.
              */
            onkeypress: (ev: KeyboardEvent) => any;
            /**
              * Occurs when media data is loaded at the current playback position. 
              * @param ev The event.
              */
            onloadeddata: (ev: Event) => any;
            /**
              * Fires immediately before the activeElement is changed from the current object to another object in the parent document.
              * @param ev The event.
              */
            onbeforedeactivate: (ev: UIEvent) => any;
            /**
              * Fires when the object is set as the active element.
              * @param ev The event.
              */
            onactivate: (ev: UIEvent) => any;
            onselectstart: (ev: Event) => any;
            /**
              * Fires when the object receives focus. 
              * @param ev The event.
              */
            onfocus: (ev: FocusEvent) => any;
            /**
              * Sets or gets the foreground (text) color of the document.
              */
            fgColor: string;
            /**
              * Occurs to indicate the current playback position.
              * @param ev The event.
              */
            ontimeupdate: (ev: Event) => any;
            /**
              * Fires when the current selection changes.
              * @param ev The event.
              */
            onselect: (ev: UIEvent) => any;
            ondrop: (ev: DragEvent) => any;
            /**
              * Occurs when the end of playback is reached. 
              * @param ev The event
              */
            onended: (ev: Event) => any;
            /**
              * Gets a value that indicates whether standards-compliant mode is switched on for the object.
              */
            compatMode: string;
            /**
              * Fires when the user repositions the scroll box in the scroll bar on the object. 
              * @param ev The event.
              */
            onscroll: (ev: UIEvent) => any;
            /**
              * Fires to indicate that the current row has changed in the data source and new data values are available on the object. 
              * @param ev The event.
              */
            onrowenter: (ev: MSEventObj) => any;
            /**
              * Fires immediately after the browser loads the object. 
              * @param ev The event.
              */
            onload: (ev: Event) => any;
            oninput: (ev: Event) => any;
            onmspointerdown: (ev: any) => any;
            msHidden: boolean;
            msVisibilityState: string;
            onmsgesturedoubletap: (ev: any) => any;
            visibilityState: string;
            onmsmanipulationstatechanged: (ev: any) => any;
            onmspointerhover: (ev: any) => any;
            onmscontentzoom: (ev: MSEventObj) => any;
            onmspointermove: (ev: any) => any;
            onmsgesturehold: (ev: any) => any;
            onmsgesturechange: (ev: any) => any;
            onmsgesturestart: (ev: any) => any;
            onmspointercancel: (ev: any) => any;
            onmsgestureend: (ev: any) => any;
            onmsgesturetap: (ev: any) => any;
            onmspointerout: (ev: any) => any;
            onmsinertiastart: (ev: any) => any;
            msCSSOMElementFloatMetrics: boolean;
            onmspointerover: (ev: any) => any;
            hidden: boolean;
            onmspointerup: (ev: any) => any;
            msFullscreenEnabled: boolean;
            onmsfullscreenerror: (ev: any) => any;
            onmspointerenter: (ev: any) => any;
            msFullscreenElement: Element;
            onmsfullscreenchange: (ev: any) => any;
            onmspointerleave: (ev: any) => any;
            /**
              * Returns a reference to the first object with the specified value of the ID or NAME attribute.
              * @param elementId String that specifies the ID value. Case-insensitive.
              */
            getElementById(elementId: string): HTMLElement;
            /**
              * Returns the current value of the document, range, or current selection for the given command.
              * @param commandId String that specifies a command identifier.
              */
            queryCommandValue(commandId: string): string;
            adoptNode(source: Node): Node;
            /**
              * Returns a Boolean value that indicates whether the specified command is in the indeterminate state.
              * @param commandId String that specifies a command identifier.
              */
            queryCommandIndeterm(commandId: string): boolean;
            getElementsByTagNameNS(namespaceURI: string, localName: string): NodeList;
            createProcessingInstruction(target: string, data: string): ProcessingInstruction;
            /**
              * Executes a command on the current document, current selection, or the given range.
              * @param commandId String that specifies the command to execute. This command can be any of the command identifiers that can be executed in script.
              * @param showUI Display the user interface, defaults to false.
              * @param value Value to assign.
              */
            execCommand(commandId: string, showUI?: boolean, value?: any): boolean;
            /**
              * Returns the element for the specified x coordinate and the specified y coordinate. 
              * @param x The x-offset
              * @param y The y-offset
              */
            elementFromPoint(x: number, y: number): Element;
            createCDATASection(data: string): CDATASection;
            /**
              * Retrieves the string associated with a command.
              * @param commandId String that contains the identifier of a command. This can be any command identifier given in the list of Command Identifiers. 
              */
            queryCommandText(commandId: string): string;
            /**
              * Writes one or more HTML expressions to a document in the specified window. 
              * @param content Specifies the text and HTML tags to write.
              */
            write(...content: string[]): void;
            /**
              * Allows updating the print settings for the page.
              */
            updateSettings(): void;
            /**
              * Creates an instance of the element for the specified tag.
              * @param tagName The name of an element.
              */
            createElement(tagName: "a"): HTMLAnchorElement;
            createElement(tagName: "abbr"): HTMLPhraseElement;
            createElement(tagName: "acronym"): HTMLPhraseElement;
            createElement(tagName: "address"): HTMLBlockElement;
            createElement(tagName: "applet"): HTMLAppletElement;
            createElement(tagName: "area"): HTMLAreaElement;
            createElement(tagName: "article"): HTMLElement;
            createElement(tagName: "aside"): HTMLElement;
            createElement(tagName: "audio"): HTMLAudioElement;
            createElement(tagName: "b"): HTMLPhraseElement;
            createElement(tagName: "base"): HTMLBaseElement;
            createElement(tagName: "basefont"): HTMLBaseFontElement;
            createElement(tagName: "bdo"): HTMLPhraseElement;
            createElement(tagName: "bgsound"): HTMLBGSoundElement;
            createElement(tagName: "big"): HTMLPhraseElement;
            createElement(tagName: "blockquote"): HTMLBlockElement;
            createElement(tagName: "body"): HTMLBodyElement;
            createElement(tagName: "br"): HTMLBRElement;
            createElement(tagName: "button"): HTMLButtonElement;
            createElement(tagName: "canvas"): HTMLCanvasElement;
            createElement(tagName: "caption"): HTMLTableCaptionElement;
            createElement(tagName: "center"): HTMLBlockElement;
            createElement(tagName: "cite"): HTMLPhraseElement;
            createElement(tagName: "code"): HTMLPhraseElement;
            createElement(tagName: "col"): HTMLTableColElement;
            createElement(tagName: "colgroup"): HTMLTableColElement;
            createElement(tagName: "datalist"): HTMLDataListElement;
            createElement(tagName: "dd"): HTMLDDElement;
            createElement(tagName: "del"): HTMLModElement;
            createElement(tagName: "dfn"): HTMLPhraseElement;
            createElement(tagName: "dir"): HTMLDirectoryElement;
            createElement(tagName: "div"): HTMLDivElement;
            createElement(tagName: "dl"): HTMLDListElement;
            createElement(tagName: "dt"): HTMLDTElement;
            createElement(tagName: "em"): HTMLPhraseElement;
            createElement(tagName: "embed"): HTMLEmbedElement;
            createElement(tagName: "fieldset"): HTMLFieldSetElement;
            createElement(tagName: "figcaption"): HTMLElement;
            createElement(tagName: "figure"): HTMLElement;
            createElement(tagName: "font"): HTMLFontElement;
            createElement(tagName: "footer"): HTMLElement;
            createElement(tagName: "form"): HTMLFormElement;
            createElement(tagName: "frame"): HTMLFrameElement;
            createElement(tagName: "frameset"): HTMLFrameSetElement;
            createElement(tagName: "h1"): HTMLHeadingElement;
            createElement(tagName: "h2"): HTMLHeadingElement;
            createElement(tagName: "h3"): HTMLHeadingElement;
            createElement(tagName: "h4"): HTMLHeadingElement;
            createElement(tagName: "h5"): HTMLHeadingElement;
            createElement(tagName: "h6"): HTMLHeadingElement;
            createElement(tagName: "head"): HTMLHeadElement;
            createElement(tagName: "header"): HTMLElement;
            createElement(tagName: "hgroup"): HTMLElement;
            createElement(tagName: "hr"): HTMLHRElement;
            createElement(tagName: "html"): HTMLHtmlElement;
            createElement(tagName: "i"): HTMLPhraseElement;
            createElement(tagName: "iframe"): HTMLIFrameElement;
            createElement(tagName: "img"): HTMLImageElement;
            createElement(tagName: "input"): HTMLInputElement;
            createElement(tagName: "ins"): HTMLModElement;
            createElement(tagName: "isindex"): HTMLIsIndexElement;
            createElement(tagName: "kbd"): HTMLPhraseElement;
            createElement(tagName: "keygen"): HTMLBlockElement;
            createElement(tagName: "label"): HTMLLabelElement;
            createElement(tagName: "legend"): HTMLLegendElement;
            createElement(tagName: "li"): HTMLLIElement;
            createElement(tagName: "link"): HTMLLinkElement;
            createElement(tagName: "listing"): HTMLBlockElement;
            createElement(tagName: "map"): HTMLMapElement;
            createElement(tagName: "mark"): HTMLElement;
            createElement(tagName: "marquee"): HTMLMarqueeElement;
            createElement(tagName: "menu"): HTMLMenuElement;
            createElement(tagName: "meta"): HTMLMetaElement;
            createElement(tagName: "nav"): HTMLElement;
            createElement(tagName: "nextid"): HTMLNextIdElement;
            createElement(tagName: "nobr"): HTMLPhraseElement;
            createElement(tagName: "noframes"): HTMLElement;
            createElement(tagName: "noscript"): HTMLElement;
            createElement(tagName: "object"): HTMLObjectElement;
            createElement(tagName: "ol"): HTMLOListElement;
            createElement(tagName: "optgroup"): HTMLOptGroupElement;
            createElement(tagName: "option"): HTMLOptionElement;
            createElement(tagName: "p"): HTMLParagraphElement;
            createElement(tagName: "param"): HTMLParamElement;
            createElement(tagName: "plaintext"): HTMLBlockElement;
            createElement(tagName: "pre"): HTMLPreElement;
            createElement(tagName: "progress"): HTMLProgressElement;
            createElement(tagName: "q"): HTMLQuoteElement;
            createElement(tagName: "rt"): HTMLPhraseElement;
            createElement(tagName: "ruby"): HTMLPhraseElement;
            createElement(tagName: "s"): HTMLPhraseElement;
            createElement(tagName: "samp"): HTMLPhraseElement;
            createElement(tagName: "script"): HTMLScriptElement;
            createElement(tagName: "section"): HTMLElement;
            createElement(tagName: "select"): HTMLSelectElement;
            createElement(tagName: "small"): HTMLPhraseElement;
            createElement(tagName: "SOURCE"): HTMLSourceElement;
            createElement(tagName: "span"): HTMLSpanElement;
            createElement(tagName: "strike"): HTMLPhraseElement;
            createElement(tagName: "strong"): HTMLPhraseElement;
            createElement(tagName: "style"): HTMLStyleElement;
            createElement(tagName: "sub"): HTMLPhraseElement;
            createElement(tagName: "sup"): HTMLPhraseElement;
            createElement(tagName: "table"): HTMLTableElement;
            createElement(tagName: "tbody"): HTMLTableSectionElement;
            createElement(tagName: "td"): HTMLTableDataCellElement;
            createElement(tagName: "textarea"): HTMLTextAreaElement;
            createElement(tagName: "tfoot"): HTMLTableSectionElement;
            createElement(tagName: "th"): HTMLTableHeaderCellElement;
            createElement(tagName: "thead"): HTMLTableSectionElement;
            createElement(tagName: "title"): HTMLTitleElement;
            createElement(tagName: "tr"): HTMLTableRowElement;
            createElement(tagName: "track"): HTMLTrackElement;
            createElement(tagName: "tt"): HTMLPhraseElement;
            createElement(tagName: "u"): HTMLPhraseElement;
            createElement(tagName: "ul"): HTMLUListElement;
            createElement(tagName: "var"): HTMLPhraseElement;
            createElement(tagName: "video"): HTMLVideoElement;
            createElement(tagName: "wbr"): HTMLElement;
            createElement(tagName: "x-ms-webview"): MSHTMLWebViewElement;
            createElement(tagName: "xmp"): HTMLBlockElement;
            createElement(tagName: string): HTMLElement;
            /**
              * Removes mouse capture from the object in the current document.
              */
            releaseCapture(): void;
            /**
              * Writes one or more HTML expressions, followed by a carriage return, to a document in the specified window. 
              * @param content The text and HTML tags to write.
              */
            writeln(...content: string[]): void;
            createElementNS(namespaceURI: string, qualifiedName: string): Element;
            /**
              * Opens a new window and loads a document specified by a given URL. Also, opens a new window that uses the url parameter and the name parameter to collect the output of the write method and the writeln method.
              * @param url Specifies a MIME type for the document.
              * @param name Specifies the name of the window. This name is used as the value for the TARGET attribute on a form or an anchor element.
              * @param features Contains a list of items separated by commas. Each item consists of an option and a value, separated by an equals sign (for example, "fullscreen=yes, toolbar=yes"). The following values are supported.
              * @param replace Specifies whether the existing entry for the document is replaced in the history list.
              */
            open(url?: string, name?: string, features?: string, replace?: boolean): any;
            /**
              * Returns a Boolean value that indicates whether the current command is supported on the current range.
              * @param commandId Specifies a command identifier.
              */
            queryCommandSupported(commandId: string): boolean;
            /**
              * Creates a TreeWalker object that you can use to traverse filtered lists of nodes or elements in a document.
              * @param root The root element or node to start traversing on.
              * @param whatToShow The type of nodes or elements to appear in the node list. For more information, see whatToShow.
              * @param filter A custom NodeFilter function to use.
              * @param entityReferenceExpansion A flag that specifies whether entity reference nodes are expanded.
              */
            createTreeWalker(root: Node, whatToShow: number, filter: NodeFilter, entityReferenceExpansion: boolean): TreeWalker;
            createAttributeNS(namespaceURI: string, qualifiedName: string): Attr;
            /** 
              * Returns a Boolean value that indicates whether a specified command can be successfully executed using execCommand, given the current state of the document.
              * @param commandId Specifies a command identifier.
              */
            queryCommandEnabled(commandId: string): boolean;
            /**
              * Causes the element to receive the focus and executes the code specified by the onfocus event.
              */
            focus(): void;
            /**
              * Closes an output stream and forces the sent data to display.
              */
            close(): void;
            getElementsByClassName(classNames: string): NodeList;
            importNode(importedNode: Node, deep: boolean): Node;
            /**
              *  Returns an empty range object that has both of its boundary points positioned at the beginning of the document. 
              */
            createRange(): Range;
            /**
              * Fires a specified event on the object.
              * @param eventName Specifies the name of the event to fire.
              * @param eventObj Object that specifies the event object from which to obtain event object properties.
              */
            fireEvent(eventName: string, eventObj?: any): boolean;
            /**
              * Creates a comment object with the specified data.
              * @param data Sets the comment object's data.
              */
            createComment(data: string): Comment;
            /**
              * Retrieves a collection of objects based on the specified element name.
              * @param name Specifies the name of an element.
              */
            getElementsByTagName(name: "a"): NodeListOf<HTMLAnchorElement>;
            getElementsByTagName(name: "abbr"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "acronym"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "address"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "applet"): NodeListOf<HTMLAppletElement>;
            getElementsByTagName(name: "area"): NodeListOf<HTMLAreaElement>;
            getElementsByTagName(name: "article"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "aside"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "audio"): NodeListOf<HTMLAudioElement>;
            getElementsByTagName(name: "b"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "base"): NodeListOf<HTMLBaseElement>;
            getElementsByTagName(name: "basefont"): NodeListOf<HTMLBaseFontElement>;
            getElementsByTagName(name: "bdo"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "bgsound"): NodeListOf<HTMLBGSoundElement>;
            getElementsByTagName(name: "big"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "blockquote"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "body"): NodeListOf<HTMLBodyElement>;
            getElementsByTagName(name: "br"): NodeListOf<HTMLBRElement>;
            getElementsByTagName(name: "button"): NodeListOf<HTMLButtonElement>;
            getElementsByTagName(name: "canvas"): NodeListOf<HTMLCanvasElement>;
            getElementsByTagName(name: "caption"): NodeListOf<HTMLTableCaptionElement>;
            getElementsByTagName(name: "center"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "cite"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "code"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "col"): NodeListOf<HTMLTableColElement>;
            getElementsByTagName(name: "colgroup"): NodeListOf<HTMLTableColElement>;
            getElementsByTagName(name: "datalist"): NodeListOf<HTMLDataListElement>;
            getElementsByTagName(name: "dd"): NodeListOf<HTMLDDElement>;
            getElementsByTagName(name: "del"): NodeListOf<HTMLModElement>;
            getElementsByTagName(name: "dfn"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "dir"): NodeListOf<HTMLDirectoryElement>;
            getElementsByTagName(name: "div"): NodeListOf<HTMLDivElement>;
            getElementsByTagName(name: "dl"): NodeListOf<HTMLDListElement>;
            getElementsByTagName(name: "dt"): NodeListOf<HTMLDTElement>;
            getElementsByTagName(name: "em"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "embed"): NodeListOf<HTMLEmbedElement>;
            getElementsByTagName(name: "fieldset"): NodeListOf<HTMLFieldSetElement>;
            getElementsByTagName(name: "figcaption"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "figure"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "font"): NodeListOf<HTMLFontElement>;
            getElementsByTagName(name: "footer"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "form"): NodeListOf<HTMLFormElement>;
            getElementsByTagName(name: "frame"): NodeListOf<HTMLFrameElement>;
            getElementsByTagName(name: "frameset"): NodeListOf<HTMLFrameSetElement>;
            getElementsByTagName(name: "h1"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "h2"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "h3"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "h4"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "h5"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "h6"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "head"): NodeListOf<HTMLHeadElement>;
            getElementsByTagName(name: "header"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "hgroup"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "hr"): NodeListOf<HTMLHRElement>;
            getElementsByTagName(name: "html"): NodeListOf<HTMLHtmlElement>;
            getElementsByTagName(name: "i"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "iframe"): NodeListOf<HTMLIFrameElement>;
            getElementsByTagName(name: "img"): NodeListOf<HTMLImageElement>;
            getElementsByTagName(name: "input"): NodeListOf<HTMLInputElement>;
            getElementsByTagName(name: "ins"): NodeListOf<HTMLModElement>;
            getElementsByTagName(name: "isindex"): NodeListOf<HTMLIsIndexElement>;
            getElementsByTagName(name: "kbd"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "keygen"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "label"): NodeListOf<HTMLLabelElement>;
            getElementsByTagName(name: "legend"): NodeListOf<HTMLLegendElement>;
            getElementsByTagName(name: "li"): NodeListOf<HTMLLIElement>;
            getElementsByTagName(name: "link"): NodeListOf<HTMLLinkElement>;
            getElementsByTagName(name: "listing"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "map"): NodeListOf<HTMLMapElement>;
            getElementsByTagName(name: "mark"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "marquee"): NodeListOf<HTMLMarqueeElement>;
            getElementsByTagName(name: "menu"): NodeListOf<HTMLMenuElement>;
            getElementsByTagName(name: "meta"): NodeListOf<HTMLMetaElement>;
            getElementsByTagName(name: "nav"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "nextid"): NodeListOf<HTMLNextIdElement>;
            getElementsByTagName(name: "nobr"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "noframes"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "noscript"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "object"): NodeListOf<HTMLObjectElement>;
            getElementsByTagName(name: "ol"): NodeListOf<HTMLOListElement>;
            getElementsByTagName(name: "optgroup"): NodeListOf<HTMLOptGroupElement>;
            getElementsByTagName(name: "option"): NodeListOf<HTMLOptionElement>;
            getElementsByTagName(name: "p"): NodeListOf<HTMLParagraphElement>;
            getElementsByTagName(name: "param"): NodeListOf<HTMLParamElement>;
            getElementsByTagName(name: "plaintext"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "pre"): NodeListOf<HTMLPreElement>;
            getElementsByTagName(name: "progress"): NodeListOf<HTMLProgressElement>;
            getElementsByTagName(name: "q"): NodeListOf<HTMLQuoteElement>;
            getElementsByTagName(name: "rt"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "ruby"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "s"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "samp"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "script"): NodeListOf<HTMLScriptElement>;
            getElementsByTagName(name: "section"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "select"): NodeListOf<HTMLSelectElement>;
            getElementsByTagName(name: "small"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "SOURCE"): NodeListOf<HTMLSourceElement>;
            getElementsByTagName(name: "span"): NodeListOf<HTMLSpanElement>;
            getElementsByTagName(name: "strike"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "strong"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "style"): NodeListOf<HTMLStyleElement>;
            getElementsByTagName(name: "sub"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "sup"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "table"): NodeListOf<HTMLTableElement>;
            getElementsByTagName(name: "tbody"): NodeListOf<HTMLTableSectionElement>;
            getElementsByTagName(name: "td"): NodeListOf<HTMLTableDataCellElement>;
            getElementsByTagName(name: "textarea"): NodeListOf<HTMLTextAreaElement>;
            getElementsByTagName(name: "tfoot"): NodeListOf<HTMLTableSectionElement>;
            getElementsByTagName(name: "th"): NodeListOf<HTMLTableHeaderCellElement>;
            getElementsByTagName(name: "thead"): NodeListOf<HTMLTableSectionElement>;
            getElementsByTagName(name: "title"): NodeListOf<HTMLTitleElement>;
            getElementsByTagName(name: "tr"): NodeListOf<HTMLTableRowElement>;
            getElementsByTagName(name: "track"): NodeListOf<HTMLTrackElement>;
            getElementsByTagName(name: "tt"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "u"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "ul"): NodeListOf<HTMLUListElement>;
            getElementsByTagName(name: "var"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "video"): NodeListOf<HTMLVideoElement>;
            getElementsByTagName(name: "wbr"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "x-ms-webview"): NodeListOf<MSHTMLWebViewElement>;
            getElementsByTagName(name: "xmp"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: string): NodeList;
            /**
              * Creates a new document.
              */
            createDocumentFragment(): DocumentFragment;
            /**
              * Creates a style sheet for the document. 
              * @param href Specifies how to add the style sheet to the document. If a file name is specified for the URL, the style information is added as a link object. If the URL contains style information, it is added to the style object.
              * @param index Specifies the index that indicates where the new style sheet is inserted in the styleSheets collection. The default is to insert the new style sheet at the end of the collection.
              */
            createStyleSheet(href?: string, index?: number): CSSStyleSheet;
            /**
              * Gets a collection of objects based on the value of the NAME or ID attribute.
              * @param elementName Gets a collection of objects based on the value of the NAME or ID attribute.
              */
            getElementsByName(elementName: string): NodeList;
            /**
              * Returns a Boolean value that indicates the current state of the command.
              * @param commandId String that specifies a command identifier.
              */
            queryCommandState(commandId: string): boolean;
            /**
              * Gets a value indicating whether the object currently has focus.
              */
            hasFocus(): boolean;
            /**
              * Displays help information for the given command identifier.
              * @param commandId Displays help information for the given command identifier.
              */
            execCommandShowHelp(commandId: string): boolean;
            /**
              * Creates an attribute object with a specified name.
              * @param name String that sets the attribute object's name.
              */
            createAttribute(name: string): Attr;
            /**
              * Creates a text string from the specified value. 
              * @param data String that specifies the nodeValue property of the text node.
              */
            createTextNode(data: string): Text;
            /**
              * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document. 
              * @param root The root element or node to start traversing on.
              * @param whatToShow The type of nodes or elements to appear in the node list
              * @param filter A custom NodeFilter function to use. For more information, see filter. Use null for no filter.
              * @param entityReferenceExpansion A flag that specifies whether entity reference nodes are expanded.
              */
            createNodeIterator(root: Node, whatToShow: number, filter: NodeFilter, entityReferenceExpansion: boolean): NodeIterator;
            /**
              * Generates an event object to pass event context information when you use the fireEvent method.
              * @param eventObj An object that specifies an existing event object on which to base the new object.
              */
            createEventObject(eventObj?: any): MSEventObj;
            /**
              * Returns an object representing the current selection of the document that is loaded into the object displaying a webpage.
              */
            getSelection(): Selection;
            msElementsFromPoint(x: number, y: number): NodeList;
            msElementsFromRect(left: number, top: number, width: number, height: number): NodeList;
            clear(): void;
            msExitFullscreen(): void;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "deactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetchanged", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsdelete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "controlselect", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "errorupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "msthumbnailclick", listener: (ev: MSSiteModeEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "cellchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowexit", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsinserted", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "propertychange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "stop", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mssitemodejumplistitemremoved", listener: (ev: MSSiteModeEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeeditfocus", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "afterupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "selectionchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "storagecommit", listener: (ev: StorageEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dataavailable", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforedeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "activate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "selectstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "rowenter", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msmanipulationstatechanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mscontentzoom", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msfullscreenerror", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msfullscreenchange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var Document: {
            prototype: Document;
            new(): Document;
        }
        
        interface Console {
            info(message?: any, ...optionalParams: any[]): void;
            warn(message?: any, ...optionalParams: any[]): void;
            error(message?: any, ...optionalParams: any[]): void;
            log(message?: any, ...optionalParams: any[]): void;
            profile(reportName?: string): void;
            assert(test?: boolean, message?: string, ...optionalParams: any[]): void;
            msIsIndependentlyComposed(element: Element): boolean;
            clear(): void;
            dir(value?: any, ...optionalParams: any[]): void;
            profileEnd(): void;
            count(countTitle?: string): void;
            groupEnd(): void;
            time(timerName?: string): void;
            timeEnd(timerName?: string): void;
            trace(): void;
            group(groupTitle?: string): void;
            dirxml(value: any): void;
            debug(message?: string, ...optionalParams: any[]): void;
            groupCollapsed(groupTitle?: string): void;
            select(element: Element): void;
        }
        declare var Console: {
            prototype: Console;
            new(): Console;
        }
        
        interface MSEventObj extends Event {
            nextPage: string;
            keyCode: number;
            toElement: Element;
            returnValue: any;
            dataFld: string;
            y: number;
            dataTransfer: DataTransfer;
            propertyName: string;
            url: string;
            offsetX: number;
            recordset: any;
            screenX: number;
            buttonID: number;
            wheelDelta: number;
            reason: number;
            origin: string;
            data: string;
            srcFilter: any;
            boundElements: HTMLCollection;
            cancelBubble: boolean;
            altLeft: boolean;
            behaviorCookie: number;
            bookmarks: BookmarkCollection;
            type: string;
            repeat: boolean;
            srcElement: Element;
            source: Window;
            fromElement: Element;
            offsetY: number;
            x: number;
            behaviorPart: number;
            qualifier: string;
            altKey: boolean;
            ctrlKey: boolean;
            clientY: number;
            shiftKey: boolean;
            shiftLeft: boolean;
            contentOverflow: boolean;
            screenY: number;
            ctrlLeft: boolean;
            button: number;
            srcUrn: string;
            clientX: number;
            actionURL: string;
            getAttribute(strAttributeName: string, lFlags?: number): any;
            setAttribute(strAttributeName: string, AttributeValue: any, lFlags?: number): void;
            removeAttribute(strAttributeName: string, lFlags?: number): boolean;
        }
        declare var MSEventObj: {
            prototype: MSEventObj;
            new(): MSEventObj;
        }
        
        interface HTMLCanvasElement extends HTMLElement {
            /**
              * Gets or sets the width of a canvas element on a document.
              */
            width: number;
            /**
              * Gets or sets the height of a canvas element on a document.
              */
            height: number;
            /**
              * Returns an object that provides methods and properties for drawing and manipulating images and graphics on a canvas element in a document. A context object includes information about colors, line widths, fonts, and other graphic parameters that can be drawn on a canvas.
              * @param contextId The identifier (ID) of the type of canvas to create. Internet Explorer 9 and Internet Explorer 10 support only a 2-D context using canvas.getContext("2d"); IE11 Preview also supports 3-D or WebGL context using canvas.getContext("experimental-webgl");
              */
            getContext(contextId: "2d"): CanvasRenderingContext2D;
            /**
              * Returns an object that provides methods and properties for drawing and manipulating images and graphics on a canvas element in a document. A context object includes information about colors, line widths, fonts, and other graphic parameters that can be drawn on a canvas.
              * @param contextId The identifier (ID) of the type of canvas to create. Internet Explorer 9 and Internet Explorer 10 support only a 2-D context using canvas.getContext("2d"); IE11 Preview also supports 3-D or WebGL context using canvas.getContext("experimental-webgl");
              */
            getContext(contextId: "experimental-webgl"): WebGLRenderingContext;
            /**
              * Returns an object that provides methods and properties for drawing and manipulating images and graphics on a canvas element in a document. A context object includes information about colors, line widths, fonts, and other graphic parameters that can be drawn on a canvas.
              * @param contextId The identifier (ID) of the type of canvas to create. Internet Explorer 9 and Internet Explorer 10 support only a 2-D context using canvas.getContext("2d"); IE11 Preview also supports 3-D or WebGL context using canvas.getContext("experimental-webgl");
              */
            getContext(contextId: string, ...args: any[]): any;
            /**
              * Returns the content of the current canvas as an image that you can use as a source for another canvas or an HTML element.
              * @param type The standard MIME type for the image format to return. If you do not specify this parameter, the default value is a PNG format image.
              */
            toDataURL(type?: string, ...args: any[]): string;
            /**
              * Returns a blob object encoded as a Portable Network Graphics (PNG) format from a canvas image or drawing.
              */
            msToBlob(): Blob;
        }
        declare var HTMLCanvasElement: {
            prototype: HTMLCanvasElement;
            new(): HTMLCanvasElement;
        }
        
        interface Window extends EventTarget, MSEventAttachmentTarget, WindowLocalStorage, MSWindowExtensions, WindowSessionStorage, WindowTimers, WindowBase64, IDBEnvironment, WindowConsole, GlobalEventHandlers {
            ondragend: (ev: DragEvent) => any;
            onkeydown: (ev: KeyboardEvent) => any;
            ondragover: (ev: DragEvent) => any;
            onkeyup: (ev: KeyboardEvent) => any;
            onreset: (ev: Event) => any;
            onmouseup: (ev: MouseEvent) => any;
            ondragstart: (ev: DragEvent) => any;
            ondrag: (ev: DragEvent) => any;
            screenX: number;
            onmouseover: (ev: MouseEvent) => any;
            ondragleave: (ev: DragEvent) => any;
            history: History;
            pageXOffset: number;
            name: string;
            onafterprint: (ev: Event) => any;
            onpause: (ev: Event) => any;
            onbeforeprint: (ev: Event) => any;
            top: Window;
            onmousedown: (ev: MouseEvent) => any;
            onseeked: (ev: Event) => any;
            opener: Window;
            onclick: (ev: MouseEvent) => any;
            innerHeight: number;
            onwaiting: (ev: Event) => any;
            ononline: (ev: Event) => any;
            ondurationchange: (ev: Event) => any;
            frames: Window;
            onblur: (ev: FocusEvent) => any;
            onemptied: (ev: Event) => any;
            onseeking: (ev: Event) => any;
            oncanplay: (ev: Event) => any;
            outerWidth: number;
            onstalled: (ev: Event) => any;
            onmousemove: (ev: MouseEvent) => any;
            innerWidth: number;
            onoffline: (ev: Event) => any;
            length: number;
            screen: Screen;
            onbeforeunload: (ev: BeforeUnloadEvent) => any;
            onratechange: (ev: Event) => any;
            onstorage: (ev: StorageEvent) => any;
            onloadstart: (ev: Event) => any;
            ondragenter: (ev: DragEvent) => any;
            onsubmit: (ev: Event) => any;
            self: Window;
            document: Document;
            onprogress: (ev: ProgressEvent) => any;
            ondblclick: (ev: MouseEvent) => any;
            pageYOffset: number;
            oncontextmenu: (ev: MouseEvent) => any;
            onchange: (ev: Event) => any;
            onloadedmetadata: (ev: Event) => any;
            onplay: (ev: Event) => any;
            onerror: ErrorEventHandler;
            onplaying: (ev: Event) => any;
            parent: Window;
            location: Location;
            oncanplaythrough: (ev: Event) => any;
            onabort: (ev: UIEvent) => any;
            onreadystatechange: (ev: Event) => any;
            outerHeight: number;
            onkeypress: (ev: KeyboardEvent) => any;
            frameElement: Element;
            onloadeddata: (ev: Event) => any;
            onsuspend: (ev: Event) => any;
            window: Window;
            onfocus: (ev: FocusEvent) => any;
            onmessage: (ev: MessageEvent) => any;
            ontimeupdate: (ev: Event) => any;
            onresize: (ev: UIEvent) => any;
            onselect: (ev: UIEvent) => any;
            navigator: Navigator;
            styleMedia: StyleMedia;
            ondrop: (ev: DragEvent) => any;
            onmouseout: (ev: MouseEvent) => any;
            onended: (ev: Event) => any;
            onhashchange: (ev: Event) => any;
            onunload: (ev: Event) => any;
            onscroll: (ev: UIEvent) => any;
            screenY: number;
            onmousewheel: (ev: MouseWheelEvent) => any;
            onload: (ev: Event) => any;
            onvolumechange: (ev: Event) => any;
            oninput: (ev: Event) => any;
            performance: Performance;
            onmspointerdown: (ev: any) => any;
            animationStartTime: number;
            onmsgesturedoubletap: (ev: any) => any;
            onmspointerhover: (ev: any) => any;
            onmsgesturehold: (ev: any) => any;
            onmspointermove: (ev: any) => any;
            onmsgesturechange: (ev: any) => any;
            onmsgesturestart: (ev: any) => any;
            onmspointercancel: (ev: any) => any;
            onmsgestureend: (ev: any) => any;
            onmsgesturetap: (ev: any) => any;
            onmspointerout: (ev: any) => any;
            msAnimationStartTime: number;
            applicationCache: ApplicationCache;
            onmsinertiastart: (ev: any) => any;
            onmspointerover: (ev: any) => any;
            onpopstate: (ev: PopStateEvent) => any;
            onmspointerup: (ev: any) => any;
            onpageshow: (ev: PageTransitionEvent) => any;
            ondevicemotion: (ev: DeviceMotionEvent) => any;
            devicePixelRatio: number;
            msCrypto: Crypto;
            ondeviceorientation: (ev: DeviceOrientationEvent) => any;
            doNotTrack: string;
            onmspointerenter: (ev: any) => any;
            onpagehide: (ev: PageTransitionEvent) => any;
            onmspointerleave: (ev: any) => any;
            alert(message?: any): void;
            scroll(x?: number, y?: number): void;
            focus(): void;
            scrollTo(x?: number, y?: number): void;
            print(): void;
            prompt(message?: string, _default?: string): string;
            toString(): string;
            open(url?: string, target?: string, features?: string, replace?: boolean): Window;
            scrollBy(x?: number, y?: number): void;
            confirm(message?: string): boolean;
            close(): void;
            postMessage(message: any, targetOrigin: string, ports?: any): void;
            showModalDialog(url?: string, argument?: any, options?: any): any;
            blur(): void;
            getSelection(): Selection;
            getComputedStyle(elt: Element, pseudoElt?: string): CSSStyleDeclaration;
            msCancelRequestAnimationFrame(handle: number): void;
            matchMedia(mediaQuery: string): MediaQueryList;
            cancelAnimationFrame(handle: number): void;
            msIsStaticHTML(html: string): boolean;
            msMatchMedia(mediaQuery: string): MediaQueryList;
            requestAnimationFrame(callback: FrameRequestCallback): number;
            msRequestAnimationFrame(callback: FrameRequestCallback): number;
            addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "afterprint", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeprint", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "online", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "offline", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeunload", listener: (ev: BeforeUnloadEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "storage", listener: (ev: StorageEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "hashchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "unload", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "popstate", listener: (ev: PopStateEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "pageshow", listener: (ev: PageTransitionEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "devicemotion", listener: (ev: DeviceMotionEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "deviceorientation", listener: (ev: DeviceOrientationEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "pagehide", listener: (ev: PageTransitionEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var Window: {
            prototype: Window;
            new(): Window;
        }
        
        interface HTMLCollection extends MSHTMLCollectionExtensions {
            /**
              * Sets or retrieves the number of objects in a collection.
              */
            length: number;
            /**
              * Retrieves an object from various collections.
              */
            item(nameOrIndex?: any, optionalIndex?: any): Element;
            /**
              * Retrieves a select object or an object from an options collection.
              */
            namedItem(name: string): Element;
            // [name: string]: Element;
            [index: number]: Element;
        }
        declare var HTMLCollection: {
            prototype: HTMLCollection;
            new(): HTMLCollection;
        }
        
        interface BlobPropertyBag {
            type?: string;
            endings?: string;
        }
        
        interface Blob {
            type: string;
            size: number;
            msDetachStream(): any;
            slice(start?: number, end?: number, contentType?: string): Blob;
            msClose(): void;
        }
        declare var Blob: {
            prototype: Blob;
            new (blobParts?: any[], options?: BlobPropertyBag): Blob;
        }
        
        interface NavigatorID {
            appVersion: string;
            appName: string;
            userAgent: string;
            platform: string;
            product: string;
            vendor: string;
        }
        
        interface HTMLTableElement extends HTMLElement, MSDataBindingTableExtensions, MSDataBindingExtensions, DOML2DeprecatedBackgroundStyle, DOML2DeprecatedBackgroundColorStyle {
            /**
              * Sets or retrieves the width of the object.
              */
            width: string;
            /**
              * Sets or retrieves the color for one of the two colors used to draw the 3-D border of the object.
              */
            borderColorLight: any;
            /**
              * Sets or retrieves the amount of space between cells in a table.
              */
            cellSpacing: string;
            /**
              * Retrieves the tFoot object of the table.
              */
            tFoot: HTMLTableSectionElement;
            /**
              * Sets or retrieves the way the border frame around the table is displayed.
              */
            frame: string;
            /**
              * Sets or retrieves the border color of the object. 
              */
            borderColor: any;
            /**
              * Sets or retrieves the number of horizontal rows contained in the object.
              */
            rows: HTMLCollection;
            /**
              * Sets or retrieves which dividing lines (inner borders) are displayed.
              */
            rules: string;
            /**
              * Sets or retrieves the number of columns in the table.
              */
            cols: number;
            /**
              * Sets or retrieves a description and/or structure of the object.
              */
            summary: string;
            /**
              * Retrieves the caption object of a table.
              */
            caption: HTMLTableCaptionElement;
            /**
              * Retrieves a collection of all tBody objects in the table. Objects in this collection are in source order.
              */
            tBodies: HTMLCollection;
            /**
              * Retrieves the tHead object of the table.
              */
            tHead: HTMLTableSectionElement;
            /**
              * Sets or retrieves a value that indicates the table alignment.
              */
            align: string;
            /**
              * Retrieves a collection of all cells in the table row or in the entire table.
              */
            cells: HTMLCollection;
            /**
              * Sets or retrieves the height of the object.
              */
            height: any;
            /**
              * Sets or retrieves the amount of space between the border of the cell and the content of the cell.
              */
            cellPadding: string;
            /**
              * Sets or retrieves the width of the border to draw around the object.
              */
            border: string;
            /**
              * Sets or retrieves the color for one of the two colors used to draw the 3-D border of the object.
              */
            borderColorDark: any;
            /**
              * Removes the specified row (tr) from the element and from the rows collection.
              * @param index Number that specifies the zero-based position in the rows collection of the row to remove.
              */
            deleteRow(index?: number): void;
            /**
              * Creates an empty tBody element in the table.
              */
            createTBody(): HTMLElement;
            /**
              * Deletes the caption element and its contents from the table.
              */
            deleteCaption(): void;
            /**
              * Creates a new row (tr) in the table, and adds the row to the rows collection.
              * @param index Number that specifies where to insert the row in the rows collection. The default value is -1, which appends the new row to the end of the rows collection.
              */
            insertRow(index?: number): HTMLElement;
            /**
              * Deletes the tFoot element and its contents from the table.
              */
            deleteTFoot(): void;
            /**
              * Returns the tHead element object if successful, or null otherwise.
              */
            createTHead(): HTMLElement;
            /**
              * Deletes the tHead element and its contents from the table.
              */
            deleteTHead(): void;
            /**
              * Creates an empty caption element in the table.
              */
            createCaption(): HTMLElement;
            /**
              * Moves a table row to a new position.
              * @param indexFrom Number that specifies the index in the rows collection of the table row that is moved.
              * @param indexTo Number that specifies where the row is moved within the rows collection.
              */
            moveRow(indexFrom?: number, indexTo?: number): any;
            /**
              * Creates an empty tFoot element in the table.
              */
            createTFoot(): HTMLElement;
        }
        declare var HTMLTableElement: {
            prototype: HTMLTableElement;
            new(): HTMLTableElement;
        }
        
        interface TreeWalker {
            whatToShow: number;
            filter: NodeFilter;
            root: Node;
            currentNode: Node;
            expandEntityReferences: boolean;
            previousSibling(): Node;
            lastChild(): Node;
            nextSibling(): Node;
            nextNode(): Node;
            parentNode(): Node;
            firstChild(): Node;
            previousNode(): Node;
        }
        declare var TreeWalker: {
            prototype: TreeWalker;
            new(): TreeWalker;
        }
        
        interface GetSVGDocument {
            getSVGDocument(): Document;
        }
        
        interface SVGPathSegCurvetoQuadraticRel extends SVGPathSeg {
            y: number;
            y1: number;
            x: number;
            x1: number;
        }
        declare var SVGPathSegCurvetoQuadraticRel: {
            prototype: SVGPathSegCurvetoQuadraticRel;
            new(): SVGPathSegCurvetoQuadraticRel;
        }
        
        interface Performance {
            navigation: PerformanceNavigation;
            timing: PerformanceTiming;
            getEntriesByType(entryType: string): any;
            toJSON(): any;
            getMeasures(measureName?: string): any;
            clearMarks(markName?: string): void;
            getMarks(markName?: string): any;
            clearResourceTimings(): void;
            mark(markName: string): void;
            measure(measureName: string, startMarkName?: string, endMarkName?: string): void;
            getEntriesByName(name: string, entryType?: string): any;
            getEntries(): any;
            clearMeasures(measureName?: string): void;
            setResourceTimingBufferSize(maxSize: number): void;
            now(): number;
        }
        declare var Performance: {
            prototype: Performance;
            new(): Performance;
        }
        
        interface MSDataBindingTableExtensions {
            dataPageSize: number;
            nextPage(): void;
            firstPage(): void;
            refresh(): void;
            previousPage(): void;
            lastPage(): void;
        }
        
        interface CompositionEvent extends UIEvent {
            data: string;
            locale: string;
            initCompositionEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, dataArg: string, locale: string): void;
        }
        declare var CompositionEvent: {
            prototype: CompositionEvent;
            new(): CompositionEvent;
        }
        
        interface WindowTimers extends WindowTimersExtension {
            clearTimeout(handle: number): void;
            setTimeout(handler: any, timeout?: any, ...args: any[]): number;
            clearInterval(handle: number): void;
            setInterval(handler: any, timeout?: any, ...args: any[]): number;
        }
        
        interface SVGMarkerElement extends SVGElement, SVGStylable, SVGLangSpace, SVGFitToViewBox, SVGExternalResourcesRequired {
            orientType: SVGAnimatedEnumeration;
            markerUnits: SVGAnimatedEnumeration;
            markerWidth: SVGAnimatedLength;
            markerHeight: SVGAnimatedLength;
            orientAngle: SVGAnimatedAngle;
            refY: SVGAnimatedLength;
            refX: SVGAnimatedLength;
            setOrientToAngle(angle: SVGAngle): void;
            setOrientToAuto(): void;
            SVG_MARKER_ORIENT_UNKNOWN: number;
            SVG_MARKER_ORIENT_ANGLE: number;
            SVG_MARKERUNITS_UNKNOWN: number;
            SVG_MARKERUNITS_STROKEWIDTH: number;
            SVG_MARKER_ORIENT_AUTO: number;
            SVG_MARKERUNITS_USERSPACEONUSE: number;
        }
        declare var SVGMarkerElement: {
            prototype: SVGMarkerElement;
            new(): SVGMarkerElement;
            SVG_MARKER_ORIENT_UNKNOWN: number;
            SVG_MARKER_ORIENT_ANGLE: number;
            SVG_MARKERUNITS_UNKNOWN: number;
            SVG_MARKERUNITS_STROKEWIDTH: number;
            SVG_MARKER_ORIENT_AUTO: number;
            SVG_MARKERUNITS_USERSPACEONUSE: number;
        }
        
        interface CSSStyleDeclaration {
            backgroundAttachment: string;
            visibility: string;
            textAlignLast: string;
            borderRightStyle: string;
            counterIncrement: string;
            orphans: string;
            cssText: string;
            borderStyle: string;
            pointerEvents: string;
            borderTopColor: string;
            markerEnd: string;
            textIndent: string;
            listStyleImage: string;
            cursor: string;
            listStylePosition: string;
            wordWrap: string;
            borderTopStyle: string;
            alignmentBaseline: string;
            opacity: string;
            direction: string;
            strokeMiterlimit: string;
            maxWidth: string;
            color: string;
            clip: string;
            borderRightWidth: string;
            verticalAlign: string;
            overflow: string;
            mask: string;
            borderLeftStyle: string;
            emptyCells: string;
            stopOpacity: string;
            paddingRight: string;
            parentRule: CSSRule;
            background: string;
            boxSizing: string;
            textJustify: string;
            height: string;
            paddingTop: string;
            length: number;
            right: string;
            baselineShift: string;
            borderLeft: string;
            widows: string;
            lineHeight: string;
            left: string;
            textUnderlinePosition: string;
            glyphOrientationHorizontal: string;
            display: string;
            textAnchor: string;
            cssFloat: string;
            strokeDasharray: string;
            rubyAlign: string;
            fontSizeAdjust: string;
            borderLeftColor: string;
            backgroundImage: string;
            listStyleType: string;
            strokeWidth: string;
            textOverflow: string;
            fillRule: string;
            borderBottomColor: string;
            zIndex: string;
            position: string;
            listStyle: string;
            msTransformOrigin: string;
            dominantBaseline: string;
            overflowY: string;
            fill: string;
            captionSide: string;
            borderCollapse: string;
            boxShadow: string;
            quotes: string;
            tableLayout: string;
            unicodeBidi: string;
            borderBottomWidth: string;
            backgroundSize: string;
            textDecoration: string;
            strokeDashoffset: string;
            fontSize: string;
            border: string;
            pageBreakBefore: string;
            borderTopRightRadius: string;
            msTransform: string;
            borderBottomLeftRadius: string;
            textTransform: string;
            rubyPosition: string;
            strokeLinejoin: string;
            clipPath: string;
            borderRightColor: string;
            fontFamily: string;
            clear: string;
            content: string;
            backgroundClip: string;
            marginBottom: string;
            counterReset: string;
            outlineWidth: string;
            marginRight: string;
            paddingLeft: string;
            borderBottom: string;
            wordBreak: string;
            marginTop: string;
            top: string;
            fontWeight: string;
            borderRight: string;
            width: string;
            kerning: string;
            pageBreakAfter: string;
            borderBottomStyle: string;
            fontStretch: string;
            padding: string;
            strokeOpacity: string;
            markerStart: string;
            bottom: string;
            borderLeftWidth: string;
            clipRule: string;
            backgroundPosition: string;
            backgroundColor: string;
            pageBreakInside: string;
            backgroundOrigin: string;
            strokeLinecap: string;
            borderTopWidth: string;
            outlineStyle: string;
            borderTop: string;
            outlineColor: string;
            paddingBottom: string;
            marginLeft: string;
            font: string;
            outline: string;
            wordSpacing: string;
            maxHeight: string;
            fillOpacity: string;
            letterSpacing: string;
            borderSpacing: string;
            backgroundRepeat: string;
            borderRadius: string;
            borderWidth: string;
            borderBottomRightRadius: string;
            whiteSpace: string;
            fontStyle: string;
            minWidth: string;
            stopColor: string;
            borderTopLeftRadius: string;
            borderColor: string;
            marker: string;
            glyphOrientationVertical: string;
            markerMid: string;
            fontVariant: string;
            minHeight: string;
            stroke: string;
            rubyOverhang: string;
            overflowX: string;
            textAlign: string;
            margin: string;
            animationFillMode: string;
            floodColor: string;
            animationIterationCount: string;
            textShadow: string;
            backfaceVisibility: string;
            msAnimationIterationCount: string;
            animationDelay: string;
            animationTimingFunction: string;
            columnWidth: any;
            msScrollSnapX: string;
            columnRuleColor: any;
            columnRuleWidth: any;
            transitionDelay: string;
            transition: string;
            msFlowFrom: string;
            msScrollSnapType: string;
            msContentZoomSnapType: string;
            msGridColumns: string;
            msAnimationName: string;
            msGridRowAlign: string;
            msContentZoomChaining: string;
            msGridColumn: any;
            msHyphenateLimitZone: any;
            msScrollRails: string;
            msAnimationDelay: string;
            enableBackground: string;
            msWrapThrough: string;
            columnRuleStyle: string;
            msAnimation: string;
            msFlexFlow: string;
            msScrollSnapY: string;
            msHyphenateLimitLines: any;
            msTouchAction: string;
            msScrollLimit: string;
            animation: string;
            transform: string;
            filter: string;
            colorInterpolationFilters: string;
            transitionTimingFunction: string;
            msBackfaceVisibility: string;
            animationPlayState: string;
            transformOrigin: string;
            msScrollLimitYMin: any;
            msFontFeatureSettings: string;
            msContentZoomLimitMin: any;
            columnGap: any;
            transitionProperty: string;
            msAnimationDuration: string;
            msAnimationFillMode: string;
            msFlexDirection: string;
            msTransitionDuration: string;
            fontFeatureSettings: string;
            breakBefore: string;
            msFlexWrap: string;
            perspective: string;
            msFlowInto: string;
            msTransformStyle: string;
            msScrollTranslation: string;
            msTransitionProperty: string;
            msUserSelect: string;
            msOverflowStyle: string;
            msScrollSnapPointsY: string;
            animationDirection: string;
            animationDuration: string;
            msFlex: string;
            msTransitionTimingFunction: string;
            animationName: string;
            columnRule: string;
            msGridColumnSpan: any;
            msFlexNegative: string;
            columnFill: string;
            msGridRow: any;
            msFlexOrder: string;
            msFlexItemAlign: string;
            msFlexPositive: string;
            msContentZoomLimitMax: any;
            msScrollLimitYMax: any;
            msGridColumnAlign: string;
            perspectiveOrigin: string;
            lightingColor: string;
            columns: string;
            msScrollChaining: string;
            msHyphenateLimitChars: string;
            msTouchSelect: string;
            floodOpacity: string;
            msAnimationDirection: string;
            msAnimationPlayState: string;
            columnSpan: string;
            msContentZooming: string;
            msPerspective: string;
            msFlexPack: string;
            msScrollSnapPointsX: string;
            msContentZoomSnapPoints: string;
            msGridRowSpan: any;
            msContentZoomSnap: string;
            msScrollLimitXMin: any;
            breakInside: string;
            msHighContrastAdjust: string;
            msFlexLinePack: string;
            msGridRows: string;
            transitionDuration: string;
            msHyphens: string;
            breakAfter: string;
            msTransition: string;
            msPerspectiveOrigin: string;
            msContentZoomLimit: string;
            msScrollLimitXMax: any;
            msFlexAlign: string;
            msWrapMargin: any;
            columnCount: any;
            msAnimationTimingFunction: string;
            msTransitionDelay: string;
            transformStyle: string;
            msWrapFlow: string;
            msFlexPreferredSize: string;
            alignItems: string;
            borderImageSource: string;
            flexBasis: string;
            borderImageWidth: string;
            borderImageRepeat: string;
            order: string;
            flex: string;
            alignContent: string;
            msImeAlign: string;
            flexShrink: string;
            flexGrow: string;
            borderImageSlice: string;
            flexWrap: string;
            borderImageOutset: string;
            flexDirection: string;
            touchAction: string;
            flexFlow: string;
            borderImage: string;
            justifyContent: string;
            alignSelf: string;
            msTextCombineHorizontal: string;
            getPropertyPriority(propertyName: string): string;
            getPropertyValue(propertyName: string): string;
            removeProperty(propertyName: string): string;
            item(index: number): string;
            [index: number]: string;
            setProperty(propertyName: string, value: string, priority?: string): void;
        }
        declare var CSSStyleDeclaration: {
            prototype: CSSStyleDeclaration;
            new(): CSSStyleDeclaration;
        }
        
        interface SVGGElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
        }
        declare var SVGGElement: {
            prototype: SVGGElement;
            new(): SVGGElement;
        }
        
        interface MSStyleCSSProperties extends MSCSSProperties {
            pixelWidth: number;
            posHeight: number;
            posLeft: number;
            pixelTop: number;
            pixelBottom: number;
            textDecorationNone: boolean;
            pixelLeft: number;
            posTop: number;
            posBottom: number;
            textDecorationOverline: boolean;
            posWidth: number;
            textDecorationLineThrough: boolean;
            pixelHeight: number;
            textDecorationBlink: boolean;
            posRight: number;
            pixelRight: number;
            textDecorationUnderline: boolean;
        }
        declare var MSStyleCSSProperties: {
            prototype: MSStyleCSSProperties;
            new(): MSStyleCSSProperties;
        }
        
        interface Navigator extends NavigatorID, NavigatorOnLine, NavigatorContentUtils, MSNavigatorExtensions, NavigatorGeolocation, MSNavigatorDoNotTrack, NavigatorStorageUtils, MSFileSaver {
            msMaxTouchPoints: number;
            msPointerEnabled: boolean;
            msManipulationViewsEnabled: boolean;
            pointerEnabled: boolean;
            maxTouchPoints: number;
            msLaunchUri(uri: string, successCallback?: MSLaunchUriCallback, noHandlerCallback?: MSLaunchUriCallback): void;
        }
        declare var Navigator: {
            prototype: Navigator;
            new(): Navigator;
        }
        
        interface SVGPathSegCurvetoCubicSmoothAbs extends SVGPathSeg {
            y: number;
            x2: number;
            x: number;
            y2: number;
        }
        declare var SVGPathSegCurvetoCubicSmoothAbs: {
            prototype: SVGPathSegCurvetoCubicSmoothAbs;
            new(): SVGPathSegCurvetoCubicSmoothAbs;
        }
        
        interface SVGZoomEvent extends UIEvent {
            zoomRectScreen: SVGRect;
            previousScale: number;
            newScale: number;
            previousTranslate: SVGPoint;
            newTranslate: SVGPoint;
        }
        declare var SVGZoomEvent: {
            prototype: SVGZoomEvent;
            new(): SVGZoomEvent;
        }
        
        interface NodeSelector {
            querySelectorAll(selectors: string): NodeList;
            querySelector(selectors: string): Element;
        }
        
        interface HTMLTableDataCellElement extends HTMLTableCellElement {
        }
        declare var HTMLTableDataCellElement: {
            prototype: HTMLTableDataCellElement;
            new(): HTMLTableDataCellElement;
        }
        
        interface HTMLBaseElement extends HTMLElement {
            /**
              * Sets or retrieves the window or frame at which to target content.
              */
            target: string;
            /**
              * Gets or sets the baseline URL on which relative links are based.
              */
            href: string;
        }
        declare var HTMLBaseElement: {
            prototype: HTMLBaseElement;
            new(): HTMLBaseElement;
        }
        
        interface ClientRect {
            left: number;
            width: number;
            right: number;
            top: number;
            bottom: number;
            height: number;
        }
        declare var ClientRect: {
            prototype: ClientRect;
            new(): ClientRect;
        }
        
        interface PositionErrorCallback {
            (error: PositionError): void;
        }
        
        interface DOMImplementation {
            createDocumentType(qualifiedName: string, publicId: string, systemId: string): DocumentType;
            createDocument(namespaceURI: string, qualifiedName: string, doctype: DocumentType): Document;
            hasFeature(feature: string, version?: string): boolean;
            createHTMLDocument(title: string): Document;
        }
        declare var DOMImplementation: {
            prototype: DOMImplementation;
            new(): DOMImplementation;
        }
        
        interface SVGUnitTypes {
            SVG_UNIT_TYPE_UNKNOWN: number;
            SVG_UNIT_TYPE_OBJECTBOUNDINGBOX: number;
            SVG_UNIT_TYPE_USERSPACEONUSE: number;
        }
        declare var SVGUnitTypes: SVGUnitTypes;
        
        interface Element extends Node, NodeSelector, ElementTraversal, GlobalEventHandlers {
            scrollTop: number;
            clientLeft: number;
            scrollLeft: number;
            tagName: string;
            clientWidth: number;
            scrollWidth: number;
            clientHeight: number;
            clientTop: number;
            scrollHeight: number;
            msRegionOverflow: string;
            onmspointerdown: (ev: any) => any;
            onmsgotpointercapture: (ev: any) => any;
            onmsgesturedoubletap: (ev: any) => any;
            onmspointerhover: (ev: any) => any;
            onmsgesturehold: (ev: any) => any;
            onmspointermove: (ev: any) => any;
            onmsgesturechange: (ev: any) => any;
            onmsgesturestart: (ev: any) => any;
            onmspointercancel: (ev: any) => any;
            onmsgestureend: (ev: any) => any;
            onmsgesturetap: (ev: any) => any;
            onmspointerout: (ev: any) => any;
            onmsinertiastart: (ev: any) => any;
            onmslostpointercapture: (ev: any) => any;
            onmspointerover: (ev: any) => any;
            msContentZoomFactor: number;
            onmspointerup: (ev: any) => any;
            onlostpointercapture: (ev: PointerEvent) => any;
            onmspointerenter: (ev: any) => any;
            ongotpointercapture: (ev: PointerEvent) => any;
            onmspointerleave: (ev: any) => any;
            getAttribute(name?: string): string;
            getElementsByTagNameNS(namespaceURI: string, localName: string): NodeList;
            hasAttributeNS(namespaceURI: string, localName: string): boolean;
            getBoundingClientRect(): ClientRect;
            getAttributeNS(namespaceURI: string, localName: string): string;
            getAttributeNodeNS(namespaceURI: string, localName: string): Attr;
            setAttributeNodeNS(newAttr: Attr): Attr;
            msMatchesSelector(selectors: string): boolean;
            hasAttribute(name: string): boolean;
            removeAttribute(name?: string): void;
            setAttributeNS(namespaceURI: string, qualifiedName: string, value: string): void;
            getAttributeNode(name: string): Attr;
            fireEvent(eventName: string, eventObj?: any): boolean;
            getElementsByTagName(name: "a"): NodeListOf<HTMLAnchorElement>;
            getElementsByTagName(name: "abbr"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "acronym"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "address"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "applet"): NodeListOf<HTMLAppletElement>;
            getElementsByTagName(name: "area"): NodeListOf<HTMLAreaElement>;
            getElementsByTagName(name: "article"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "aside"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "audio"): NodeListOf<HTMLAudioElement>;
            getElementsByTagName(name: "b"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "base"): NodeListOf<HTMLBaseElement>;
            getElementsByTagName(name: "basefont"): NodeListOf<HTMLBaseFontElement>;
            getElementsByTagName(name: "bdo"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "bgsound"): NodeListOf<HTMLBGSoundElement>;
            getElementsByTagName(name: "big"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "blockquote"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "body"): NodeListOf<HTMLBodyElement>;
            getElementsByTagName(name: "br"): NodeListOf<HTMLBRElement>;
            getElementsByTagName(name: "button"): NodeListOf<HTMLButtonElement>;
            getElementsByTagName(name: "canvas"): NodeListOf<HTMLCanvasElement>;
            getElementsByTagName(name: "caption"): NodeListOf<HTMLTableCaptionElement>;
            getElementsByTagName(name: "center"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "cite"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "code"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "col"): NodeListOf<HTMLTableColElement>;
            getElementsByTagName(name: "colgroup"): NodeListOf<HTMLTableColElement>;
            getElementsByTagName(name: "datalist"): NodeListOf<HTMLDataListElement>;
            getElementsByTagName(name: "dd"): NodeListOf<HTMLDDElement>;
            getElementsByTagName(name: "del"): NodeListOf<HTMLModElement>;
            getElementsByTagName(name: "dfn"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "dir"): NodeListOf<HTMLDirectoryElement>;
            getElementsByTagName(name: "div"): NodeListOf<HTMLDivElement>;
            getElementsByTagName(name: "dl"): NodeListOf<HTMLDListElement>;
            getElementsByTagName(name: "dt"): NodeListOf<HTMLDTElement>;
            getElementsByTagName(name: "em"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "embed"): NodeListOf<HTMLEmbedElement>;
            getElementsByTagName(name: "fieldset"): NodeListOf<HTMLFieldSetElement>;
            getElementsByTagName(name: "figcaption"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "figure"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "font"): NodeListOf<HTMLFontElement>;
            getElementsByTagName(name: "footer"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "form"): NodeListOf<HTMLFormElement>;
            getElementsByTagName(name: "frame"): NodeListOf<HTMLFrameElement>;
            getElementsByTagName(name: "frameset"): NodeListOf<HTMLFrameSetElement>;
            getElementsByTagName(name: "h1"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "h2"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "h3"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "h4"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "h5"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "h6"): NodeListOf<HTMLHeadingElement>;
            getElementsByTagName(name: "head"): NodeListOf<HTMLHeadElement>;
            getElementsByTagName(name: "header"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "hgroup"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "hr"): NodeListOf<HTMLHRElement>;
            getElementsByTagName(name: "html"): NodeListOf<HTMLHtmlElement>;
            getElementsByTagName(name: "i"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "iframe"): NodeListOf<HTMLIFrameElement>;
            getElementsByTagName(name: "img"): NodeListOf<HTMLImageElement>;
            getElementsByTagName(name: "input"): NodeListOf<HTMLInputElement>;
            getElementsByTagName(name: "ins"): NodeListOf<HTMLModElement>;
            getElementsByTagName(name: "isindex"): NodeListOf<HTMLIsIndexElement>;
            getElementsByTagName(name: "kbd"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "keygen"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "label"): NodeListOf<HTMLLabelElement>;
            getElementsByTagName(name: "legend"): NodeListOf<HTMLLegendElement>;
            getElementsByTagName(name: "li"): NodeListOf<HTMLLIElement>;
            getElementsByTagName(name: "link"): NodeListOf<HTMLLinkElement>;
            getElementsByTagName(name: "listing"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "map"): NodeListOf<HTMLMapElement>;
            getElementsByTagName(name: "mark"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "marquee"): NodeListOf<HTMLMarqueeElement>;
            getElementsByTagName(name: "menu"): NodeListOf<HTMLMenuElement>;
            getElementsByTagName(name: "meta"): NodeListOf<HTMLMetaElement>;
            getElementsByTagName(name: "nav"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "nextid"): NodeListOf<HTMLNextIdElement>;
            getElementsByTagName(name: "nobr"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "noframes"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "noscript"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "object"): NodeListOf<HTMLObjectElement>;
            getElementsByTagName(name: "ol"): NodeListOf<HTMLOListElement>;
            getElementsByTagName(name: "optgroup"): NodeListOf<HTMLOptGroupElement>;
            getElementsByTagName(name: "option"): NodeListOf<HTMLOptionElement>;
            getElementsByTagName(name: "p"): NodeListOf<HTMLParagraphElement>;
            getElementsByTagName(name: "param"): NodeListOf<HTMLParamElement>;
            getElementsByTagName(name: "plaintext"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: "pre"): NodeListOf<HTMLPreElement>;
            getElementsByTagName(name: "progress"): NodeListOf<HTMLProgressElement>;
            getElementsByTagName(name: "q"): NodeListOf<HTMLQuoteElement>;
            getElementsByTagName(name: "rt"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "ruby"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "s"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "samp"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "script"): NodeListOf<HTMLScriptElement>;
            getElementsByTagName(name: "section"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "select"): NodeListOf<HTMLSelectElement>;
            getElementsByTagName(name: "small"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "SOURCE"): NodeListOf<HTMLSourceElement>;
            getElementsByTagName(name: "span"): NodeListOf<HTMLSpanElement>;
            getElementsByTagName(name: "strike"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "strong"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "style"): NodeListOf<HTMLStyleElement>;
            getElementsByTagName(name: "sub"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "sup"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "table"): NodeListOf<HTMLTableElement>;
            getElementsByTagName(name: "tbody"): NodeListOf<HTMLTableSectionElement>;
            getElementsByTagName(name: "td"): NodeListOf<HTMLTableDataCellElement>;
            getElementsByTagName(name: "textarea"): NodeListOf<HTMLTextAreaElement>;
            getElementsByTagName(name: "tfoot"): NodeListOf<HTMLTableSectionElement>;
            getElementsByTagName(name: "th"): NodeListOf<HTMLTableHeaderCellElement>;
            getElementsByTagName(name: "thead"): NodeListOf<HTMLTableSectionElement>;
            getElementsByTagName(name: "title"): NodeListOf<HTMLTitleElement>;
            getElementsByTagName(name: "tr"): NodeListOf<HTMLTableRowElement>;
            getElementsByTagName(name: "track"): NodeListOf<HTMLTrackElement>;
            getElementsByTagName(name: "tt"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "u"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "ul"): NodeListOf<HTMLUListElement>;
            getElementsByTagName(name: "var"): NodeListOf<HTMLPhraseElement>;
            getElementsByTagName(name: "video"): NodeListOf<HTMLVideoElement>;
            getElementsByTagName(name: "wbr"): NodeListOf<HTMLElement>;
            getElementsByTagName(name: "x-ms-webview"): NodeListOf<MSHTMLWebViewElement>;
            getElementsByTagName(name: "xmp"): NodeListOf<HTMLBlockElement>;
            getElementsByTagName(name: string): NodeList;
            getClientRects(): ClientRectList;
            setAttributeNode(newAttr: Attr): Attr;
            removeAttributeNode(oldAttr: Attr): Attr;
            setAttribute(name?: string, value?: string): void;
            removeAttributeNS(namespaceURI: string, localName: string): void;
            msGetRegionContent(): MSRangeCollection;
            msReleasePointerCapture(pointerId: number): void;
            msSetPointerCapture(pointerId: number): void;
            msZoomTo(args: MsZoomToOptions): void;
            setPointerCapture(pointerId: number): void;
            msGetUntransformedBounds(): ClientRect;
            releasePointerCapture(pointerId: number): void;
            msRequestFullscreen(): void;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var Element: {
            prototype: Element;
            new(): Element;
        }
        
        interface HTMLNextIdElement extends HTMLElement {
            n: string;
        }
        declare var HTMLNextIdElement: {
            prototype: HTMLNextIdElement;
            new(): HTMLNextIdElement;
        }
        
        interface SVGPathSegMovetoRel extends SVGPathSeg {
            y: number;
            x: number;
        }
        declare var SVGPathSegMovetoRel: {
            prototype: SVGPathSegMovetoRel;
            new(): SVGPathSegMovetoRel;
        }
        
        interface SVGLineElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
            y1: SVGAnimatedLength;
            x2: SVGAnimatedLength;
            x1: SVGAnimatedLength;
            y2: SVGAnimatedLength;
        }
        declare var SVGLineElement: {
            prototype: SVGLineElement;
            new(): SVGLineElement;
        }
        
        interface HTMLParagraphElement extends HTMLElement, DOML2DeprecatedTextFlowControl {
            /**
              * Sets or retrieves how the object is aligned with adjacent text. 
              */
            align: string;
        }
        declare var HTMLParagraphElement: {
            prototype: HTMLParagraphElement;
            new(): HTMLParagraphElement;
        }
        
        interface HTMLAreasCollection extends HTMLCollection {
            /**
              * Removes an element from the collection.
              */
            remove(index?: number): void;
            /**
              * Adds an element to the areas, controlRange, or options collection.
              */
            add(element: HTMLElement, before?: any): void;
        }
        declare var HTMLAreasCollection: {
            prototype: HTMLAreasCollection;
            new(): HTMLAreasCollection;
        }
        
        interface SVGDescElement extends SVGElement, SVGStylable, SVGLangSpace {
        }
        declare var SVGDescElement: {
            prototype: SVGDescElement;
            new(): SVGDescElement;
        }
        
        interface Node extends EventTarget {
            nodeType: number;
            previousSibling: Node;
            localName: string;
            namespaceURI: string;
            textContent: string;
            parentNode: Node;
            nextSibling: Node;
            nodeValue: string;
            lastChild: Node;
            childNodes: NodeList;
            nodeName: string;
            ownerDocument: Document;
            attributes: NamedNodeMap;
            firstChild: Node;
            prefix: string;
            removeChild(oldChild: Node): Node;
            appendChild(newChild: Node): Node;
            isSupported(feature: string, version: string): boolean;
            isEqualNode(arg: Node): boolean;
            lookupPrefix(namespaceURI: string): string;
            isDefaultNamespace(namespaceURI: string): boolean;
            compareDocumentPosition(other: Node): number;
            normalize(): void;
            isSameNode(other: Node): boolean;
            hasAttributes(): boolean;
            lookupNamespaceURI(prefix: string): string;
            cloneNode(deep?: boolean): Node;
            hasChildNodes(): boolean;
            replaceChild(newChild: Node, oldChild: Node): Node;
            insertBefore(newChild: Node, refChild?: Node): Node;
            ENTITY_REFERENCE_NODE: number;
            ATTRIBUTE_NODE: number;
            DOCUMENT_FRAGMENT_NODE: number;
            TEXT_NODE: number;
            ELEMENT_NODE: number;
            COMMENT_NODE: number;
            DOCUMENT_POSITION_DISCONNECTED: number;
            DOCUMENT_POSITION_CONTAINED_BY: number;
            DOCUMENT_POSITION_CONTAINS: number;
            DOCUMENT_TYPE_NODE: number;
            DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: number;
            DOCUMENT_NODE: number;
            ENTITY_NODE: number;
            PROCESSING_INSTRUCTION_NODE: number;
            CDATA_SECTION_NODE: number;
            NOTATION_NODE: number;
            DOCUMENT_POSITION_FOLLOWING: number;
            DOCUMENT_POSITION_PRECEDING: number;
        }
        declare var Node: {
            prototype: Node;
            new(): Node;
            ENTITY_REFERENCE_NODE: number;
            ATTRIBUTE_NODE: number;
            DOCUMENT_FRAGMENT_NODE: number;
            TEXT_NODE: number;
            ELEMENT_NODE: number;
            COMMENT_NODE: number;
            DOCUMENT_POSITION_DISCONNECTED: number;
            DOCUMENT_POSITION_CONTAINED_BY: number;
            DOCUMENT_POSITION_CONTAINS: number;
            DOCUMENT_TYPE_NODE: number;
            DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: number;
            DOCUMENT_NODE: number;
            ENTITY_NODE: number;
            PROCESSING_INSTRUCTION_NODE: number;
            CDATA_SECTION_NODE: number;
            NOTATION_NODE: number;
            DOCUMENT_POSITION_FOLLOWING: number;
            DOCUMENT_POSITION_PRECEDING: number;
        }
        
        interface SVGPathSegCurvetoQuadraticSmoothRel extends SVGPathSeg {
            y: number;
            x: number;
        }
        declare var SVGPathSegCurvetoQuadraticSmoothRel: {
            prototype: SVGPathSegCurvetoQuadraticSmoothRel;
            new(): SVGPathSegCurvetoQuadraticSmoothRel;
        }
        
        interface DOML2DeprecatedListSpaceReduction {
            compact: boolean;
        }
        
        interface MSScriptHost {
        }
        declare var MSScriptHost: {
            prototype: MSScriptHost;
            new(): MSScriptHost;
        }
        
        interface SVGClipPathElement extends SVGElement, SVGUnitTypes, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
            clipPathUnits: SVGAnimatedEnumeration;
        }
        declare var SVGClipPathElement: {
            prototype: SVGClipPathElement;
            new(): SVGClipPathElement;
        }
        
        interface MouseEvent extends UIEvent {
            toElement: Element;
            layerY: number;
            fromElement: Element;
            which: number;
            pageX: number;
            offsetY: number;
            x: number;
            y: number;
            metaKey: boolean;
            altKey: boolean;
            ctrlKey: boolean;
            offsetX: number;
            screenX: number;
            clientY: number;
            shiftKey: boolean;
            layerX: number;
            screenY: number;
            relatedTarget: EventTarget;
            button: number;
            pageY: number;
            buttons: number;
            clientX: number;
            initMouseEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, ctrlKeyArg: boolean, altKeyArg: boolean, shiftKeyArg: boolean, metaKeyArg: boolean, buttonArg: number, relatedTargetArg: EventTarget): void;
            getModifierState(keyArg: string): boolean;
        }
        declare var MouseEvent: {
            prototype: MouseEvent;
            new(): MouseEvent;
        }
        
        interface RangeException {
            code: number;
            message: string;
            name: string;
            toString(): string;
            INVALID_NODE_TYPE_ERR: number;
            BAD_BOUNDARYPOINTS_ERR: number;
        }
        declare var RangeException: {
            prototype: RangeException;
            new(): RangeException;
            INVALID_NODE_TYPE_ERR: number;
            BAD_BOUNDARYPOINTS_ERR: number;
        }
        
        interface SVGTextPositioningElement extends SVGTextContentElement {
            y: SVGAnimatedLengthList;
            rotate: SVGAnimatedNumberList;
            dy: SVGAnimatedLengthList;
            x: SVGAnimatedLengthList;
            dx: SVGAnimatedLengthList;
        }
        declare var SVGTextPositioningElement: {
            prototype: SVGTextPositioningElement;
            new(): SVGTextPositioningElement;
        }
        
        interface HTMLAppletElement extends HTMLElement, DOML2DeprecatedMarginStyle, DOML2DeprecatedBorderStyle, DOML2DeprecatedAlignmentStyle, MSDataBindingExtensions, MSDataBindingRecordSetExtensions {
            width: number;
            /**
              * Sets or retrieves the Internet media type for the code associated with the object.
              */
            codeType: string;
            object: string;
            form: HTMLFormElement;
            code: string;
            /**
              * Sets or retrieves a character string that can be used to implement your own archive functionality for the object.
              */
            archive: string;
            /**
              * Sets or retrieves a text alternative to the graphic.
              */
            alt: string;
            /**
              * Sets or retrieves a message to be displayed while an object is loading.
              */
            standby: string;
            /**
              * Sets or retrieves the class identifier for the object.
              */
            classid: string;
            /**
              * Sets or retrieves the shape of the object.
              */
            name: string;
            /**
              * Sets or retrieves the URL, often with a bookmark extension (#name), to use as a client-side image map.
              */
            useMap: string;
            /**
              * Sets or retrieves the URL that references the data of the object.
              */
            data: string;
            /**
              * Sets or retrieves the height of the object.
              */
            height: string;
            /**
              * Gets or sets the optional alternative HTML script to execute if the object fails to load.
              */
            altHtml: string;
            /**
              * Address of a pointer to the document this page or frame contains. If there is no document, then null will be returned.
              */
            contentDocument: Document;
            /**
              * Sets or retrieves the URL of the component.
              */
            codeBase: string;
            /**
              * Sets or retrieves a character string that can be used to implement your own declare functionality for the object.
              */
            declare: boolean;
            /**
              * Returns the content type of the object.
              */
            type: string;
            /**
              * Retrieves a string of the URL where the object tag can be found. This is often the href of the document that the object is in, or the value set by a base element.
              */
            BaseHref: string;
        }
        declare var HTMLAppletElement: {
            prototype: HTMLAppletElement;
            new(): HTMLAppletElement;
        }
        
        interface TextMetrics {
            width: number;
        }
        declare var TextMetrics: {
            prototype: TextMetrics;
            new(): TextMetrics;
        }
        
        interface DocumentEvent {
            createEvent(eventInterface: "AnimationEvent"): AnimationEvent;
            createEvent(eventInterface: "CloseEvent"): CloseEvent;
            createEvent(eventInterface: "CompositionEvent"): CompositionEvent;
            createEvent(eventInterface: "CustomEvent"): CustomEvent;
            createEvent(eventInterface: "DeviceMotionEvent"): DeviceMotionEvent;
            createEvent(eventInterface: "DeviceOrientationEvent"): DeviceOrientationEvent;
            createEvent(eventInterface: "DragEvent"): DragEvent;
            createEvent(eventInterface: "ErrorEvent"): ErrorEvent;
            createEvent(eventInterface: "Event"): Event;
            createEvent(eventInterface: "Events"): Event;
            createEvent(eventInterface: "FocusEvent"): FocusEvent;
            createEvent(eventInterface: "HTMLEvents"): Event;
            createEvent(eventInterface: "IDBVersionChangeEvent"): IDBVersionChangeEvent;
            createEvent(eventInterface: "KeyboardEvent"): KeyboardEvent;
            createEvent(eventInterface: "LongRunningScriptDetectedEvent"): LongRunningScriptDetectedEvent;
            createEvent(eventInterface: "MessageEvent"): MessageEvent;
            createEvent(eventInterface: "MouseEvent"): MouseEvent;
            createEvent(eventInterface: "MouseEvents"): MouseEvent;
            createEvent(eventInterface: "MouseWheelEvent"): MouseWheelEvent;
            createEvent(eventInterface: "MSGestureEvent"): MSGestureEvent;
            createEvent(eventInterface: "MSPointerEvent"): MSPointerEvent;
            createEvent(eventInterface: "MutationEvent"): MutationEvent;
            createEvent(eventInterface: "MutationEvents"): MutationEvent;
            createEvent(eventInterface: "NavigationCompletedEvent"): NavigationCompletedEvent;
            createEvent(eventInterface: "NavigationEvent"): NavigationEvent;
            createEvent(eventInterface: "PageTransitionEvent"): PageTransitionEvent;
            createEvent(eventInterface: "PointerEvent"): MSPointerEvent;
            createEvent(eventInterface: "PopStateEvent"): PopStateEvent;
            createEvent(eventInterface: "ProgressEvent"): ProgressEvent;
            createEvent(eventInterface: "StorageEvent"): StorageEvent;
            createEvent(eventInterface: "SVGZoomEvents"): SVGZoomEvent;
            createEvent(eventInterface: "TextEvent"): TextEvent;
            createEvent(eventInterface: "TrackEvent"): TrackEvent;
            createEvent(eventInterface: "TransitionEvent"): TransitionEvent;
            createEvent(eventInterface: "UIEvent"): UIEvent;
            createEvent(eventInterface: "UIEvents"): UIEvent;
            createEvent(eventInterface: "UnviewableContentIdentifiedEvent"): UnviewableContentIdentifiedEvent;
            createEvent(eventInterface: "WebGLContextEvent"): WebGLContextEvent;
            createEvent(eventInterface: "WheelEvent"): WheelEvent;
            createEvent(eventInterface: string): Event;
        }
        
        interface HTMLOListElement extends HTMLElement, DOML2DeprecatedListSpaceReduction, DOML2DeprecatedListNumberingAndBulletStyle {
            /**
              * The starting number.
              */
            start: number;
        }
        declare var HTMLOListElement: {
            prototype: HTMLOListElement;
            new(): HTMLOListElement;
        }
        
        interface SVGPathSegLinetoVerticalRel extends SVGPathSeg {
            y: number;
        }
        declare var SVGPathSegLinetoVerticalRel: {
            prototype: SVGPathSegLinetoVerticalRel;
            new(): SVGPathSegLinetoVerticalRel;
        }
        
        interface SVGAnimatedString {
            animVal: string;
            baseVal: string;
        }
        declare var SVGAnimatedString: {
            prototype: SVGAnimatedString;
            new(): SVGAnimatedString;
        }
        
        interface CDATASection extends Text {
        }
        declare var CDATASection: {
            prototype: CDATASection;
            new(): CDATASection;
        }
        
        interface StyleMedia {
            type: string;
            matchMedium(mediaquery: string): boolean;
        }
        declare var StyleMedia: {
            prototype: StyleMedia;
            new(): StyleMedia;
        }
        
        interface HTMLSelectElement extends HTMLElement, MSHTMLCollectionExtensions, MSDataBindingExtensions {
            options: HTMLSelectElement;
            /**
              * Sets or retrieves the value which is returned to the server when the form control is submitted.
              */
            value: string;
            /**
              * Retrieves a reference to the form that the object is embedded in. 
              */
            form: HTMLFormElement;
            /**
              * Sets or retrieves the name of the object.
              */
            name: string;
            /**
              * Sets or retrieves the number of rows in the list box. 
              */
            size: number;
            /**
              * Sets or retrieves the number of objects in a collection.
              */
            length: number;
            /**
              * Sets or retrieves the index of the selected option in a select object.
              */
            selectedIndex: number;
            /**
              * Sets or retrieves the Boolean value indicating whether multiple items can be selected from a list.
              */
            multiple: boolean;
            /**
              * Retrieves the type of select control based on the value of the MULTIPLE attribute.
              */
            type: string;
            /**
              * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation messages without actually submitting.
              */
            validationMessage: string;
            /**
              * Provides a way to direct a user to a specific field when a document loads. This can provide both direction and convenience for a user, reducing the need to click or tab to a field when a page opens. This attribute is true when present on an element, and false when missing.
              */
            autofocus: boolean;
            /**
              * Returns a  ValidityState object that represents the validity states of an element.
              */
            validity: ValidityState;
            /**
              * When present, marks an element that can't be submitted without a value.
              */
            required: boolean;
            /**
              * Returns whether an element will successfully validate based on forms validation rules and constraints.
              */
            willValidate: boolean;
            /**
              * Removes an element from the collection.
              * @param index Number that specifies the zero-based index of the element to remove from the collection.
              */
            remove(index?: number): void;
            /**
              * Adds an element to the areas, controlRange, or options collection.
              * @param element Variant of type Number that specifies the index position in the collection where the element is placed. If no value is given, the method places the element at the end of the collection.
              * @param before Variant of type Object that specifies an element to insert before, or null to append the object to the collection. 
              */
            add(element: HTMLElement, before?: any): void;
            /**
              * Retrieves a select object or an object from an options collection.
              * @param name Variant of type Number or String that specifies the object or collection to retrieve. If this parameter is an integer, it is the zero-based index of the object. If this parameter is a string, all objects with matching name or id properties are retrieved, and a collection is returned if more than one match is made.
              * @param index Variant of type Number that specifies the zero-based index of the object to retrieve when a collection is returned.
              */
            item(name?: any, index?: any): any;
            /**
              * Retrieves a select object or an object from an options collection.
              * @param namedItem A String that specifies the name or id property of the object to retrieve. A collection is returned if more than one match is made.
              */
            namedItem(name: string): any;
            [name: string]: any;
            /**
              * Returns whether a form will validate when it is submitted, without having to submit it.
              */
            checkValidity(): boolean;
            /**
              * Sets a custom error message that is displayed when a form is submitted.
              * @param error Sets a custom error message that is displayed when a form is submitted.
              */
            setCustomValidity(error: string): void;
        }
        declare var HTMLSelectElement: {
            prototype: HTMLSelectElement;
            new(): HTMLSelectElement;
        }
        
        interface TextRange {
            boundingLeft: number;
            htmlText: string;
            offsetLeft: number;
            boundingWidth: number;
            boundingHeight: number;
            boundingTop: number;
            text: string;
            offsetTop: number;
            moveToPoint(x: number, y: number): void;
            queryCommandValue(cmdID: string): any;
            getBookmark(): string;
            move(unit: string, count?: number): number;
            queryCommandIndeterm(cmdID: string): boolean;
            scrollIntoView(fStart?: boolean): void;
            findText(string: string, count?: number, flags?: number): boolean;
            execCommand(cmdID: string, showUI?: boolean, value?: any): boolean;
            getBoundingClientRect(): ClientRect;
            moveToBookmark(bookmark: string): boolean;
            isEqual(range: TextRange): boolean;
            duplicate(): TextRange;
            collapse(start?: boolean): void;
            queryCommandText(cmdID: string): string;
            select(): void;
            pasteHTML(html: string): void;
            inRange(range: TextRange): boolean;
            moveEnd(unit: string, count?: number): number;
            getClientRects(): ClientRectList;
            moveStart(unit: string, count?: number): number;
            parentElement(): Element;
            queryCommandState(cmdID: string): boolean;
            compareEndPoints(how: string, sourceRange: TextRange): number;
            execCommandShowHelp(cmdID: string): boolean;
            moveToElementText(element: Element): void;
            expand(Unit: string): boolean;
            queryCommandSupported(cmdID: string): boolean;
            setEndPoint(how: string, SourceRange: TextRange): void;
            queryCommandEnabled(cmdID: string): boolean;
        }
        declare var TextRange: {
            prototype: TextRange;
            new(): TextRange;
        }
        
        interface SVGTests {
            requiredFeatures: SVGStringList;
            requiredExtensions: SVGStringList;
            systemLanguage: SVGStringList;
            hasExtension(extension: string): boolean;
        }
        
        interface HTMLBlockElement extends HTMLElement, DOML2DeprecatedTextFlowControl {
            /**
              * Sets or retrieves the width of the object.
              */
            width: number;
            /**
              * Sets or retrieves reference information about the object.
              */
            cite: string;
        }
        declare var HTMLBlockElement: {
            prototype: HTMLBlockElement;
            new(): HTMLBlockElement;
        }
        
        interface CSSStyleSheet extends StyleSheet {
            owningElement: Element;
            imports: StyleSheetList;
            isAlternate: boolean;
            rules: MSCSSRuleList;
            isPrefAlternate: boolean;
            readOnly: boolean;
            cssText: string;
            ownerRule: CSSRule;
            href: string;
            cssRules: CSSRuleList;
            id: string;
            pages: StyleSheetPageList;
            addImport(bstrURL: string, lIndex?: number): number;
            addPageRule(bstrSelector: string, bstrStyle: string, lIndex?: number): number;
            insertRule(rule: string, index?: number): number;
            removeRule(lIndex: number): void;
            deleteRule(index?: number): void;
            addRule(bstrSelector: string, bstrStyle?: string, lIndex?: number): number;
            removeImport(lIndex: number): void;
        }
        declare var CSSStyleSheet: {
            prototype: CSSStyleSheet;
            new(): CSSStyleSheet;
        }
        
        interface MSSelection {
            type: string;
            typeDetail: string;
            createRange(): TextRange;
            clear(): void;
            createRangeCollection(): TextRangeCollection;
            empty(): void;
        }
        declare var MSSelection: {
            prototype: MSSelection;
            new(): MSSelection;
        }
        
        interface HTMLMetaElement extends HTMLElement {
            /**
              * Gets or sets information used to bind the value of a content attribute of a meta element to an HTTP response header.
              */
            httpEquiv: string;
            /**
              * Sets or retrieves the value specified in the content attribute of the meta object.
              */
            name: string;
            /**
              * Gets or sets meta-information to associate with httpEquiv or name.
              */
            content: string;
            /**
              * Sets or retrieves the URL property that will be loaded after the specified time has elapsed. 
              */
            url: string;
            /**
              * Sets or retrieves a scheme to be used in interpreting the value of a property specified for the object.
              */
            scheme: string;
            /**
              * Sets or retrieves the character set used to encode the object.
              */
            charset: string;
        }
        declare var HTMLMetaElement: {
            prototype: HTMLMetaElement;
            new(): HTMLMetaElement;
        }
        
        interface SVGPatternElement extends SVGElement, SVGUnitTypes, SVGStylable, SVGLangSpace, SVGTests, SVGFitToViewBox, SVGExternalResourcesRequired, SVGURIReference {
            patternUnits: SVGAnimatedEnumeration;
            y: SVGAnimatedLength;
            width: SVGAnimatedLength;
            x: SVGAnimatedLength;
            patternContentUnits: SVGAnimatedEnumeration;
            patternTransform: SVGAnimatedTransformList;
            height: SVGAnimatedLength;
        }
        declare var SVGPatternElement: {
            prototype: SVGPatternElement;
            new(): SVGPatternElement;
        }
        
        interface SVGAnimatedAngle {
            animVal: SVGAngle;
            baseVal: SVGAngle;
        }
        declare var SVGAnimatedAngle: {
            prototype: SVGAnimatedAngle;
            new(): SVGAnimatedAngle;
        }
        
        interface Selection {
            isCollapsed: boolean;
            anchorNode: Node;
            focusNode: Node;
            anchorOffset: number;
            focusOffset: number;
            rangeCount: number;
            addRange(range: Range): void;
            collapseToEnd(): void;
            toString(): string;
            selectAllChildren(parentNode: Node): void;
            getRangeAt(index: number): Range;
            collapse(parentNode: Node, offset: number): void;
            removeAllRanges(): void;
            collapseToStart(): void;
            deleteFromDocument(): void;
            removeRange(range: Range): void;
        }
        declare var Selection: {
            prototype: Selection;
            new(): Selection;
        }
        
        interface SVGScriptElement extends SVGElement, SVGExternalResourcesRequired, SVGURIReference {
            type: string;
        }
        declare var SVGScriptElement: {
            prototype: SVGScriptElement;
            new(): SVGScriptElement;
        }
        
        interface HTMLDDElement extends HTMLElement {
            /**
              * Sets or retrieves whether the browser automatically performs wordwrap.
              */
            noWrap: boolean;
        }
        declare var HTMLDDElement: {
            prototype: HTMLDDElement;
            new(): HTMLDDElement;
        }
        
        interface MSDataBindingRecordSetReadonlyExtensions {
            recordset: any;
            namedRecordset(dataMember: string, hierarchy?: any): any;
        }
        
        interface CSSStyleRule extends CSSRule {
            selectorText: string;
            style: MSStyleCSSProperties;
            readOnly: boolean;
        }
        declare var CSSStyleRule: {
            prototype: CSSStyleRule;
            new(): CSSStyleRule;
        }
        
        interface NodeIterator {
            whatToShow: number;
            filter: NodeFilter;
            root: Node;
            expandEntityReferences: boolean;
            nextNode(): Node;
            detach(): void;
            previousNode(): Node;
        }
        declare var NodeIterator: {
            prototype: NodeIterator;
            new(): NodeIterator;
        }
        
        interface SVGViewElement extends SVGElement, SVGZoomAndPan, SVGFitToViewBox, SVGExternalResourcesRequired {
            viewTarget: SVGStringList;
        }
        declare var SVGViewElement: {
            prototype: SVGViewElement;
            new(): SVGViewElement;
        }
        
        interface HTMLLinkElement extends HTMLElement, LinkStyle {
            /**
              * Sets or retrieves the relationship between the object and the destination of the link.
              */
            rel: string;
            /**
              * Sets or retrieves the window or frame at which to target content.
              */
            target: string;
            /**
              * Sets or retrieves a destination URL or an anchor point.
              */
            href: string;
            /**
              * Sets or retrieves the media type.
              */
            media: string;
            /**
              * Sets or retrieves the relationship between the object and the destination of the link.
              */
            rev: string;
            /**
              * Sets or retrieves the MIME type of the object.
              */
            type: string;
            /**
              * Sets or retrieves the character set used to encode the object.
              */
            charset: string;
            /**
              * Sets or retrieves the language code of the object.
              */
            hreflang: string;
        }
        declare var HTMLLinkElement: {
            prototype: HTMLLinkElement;
            new(): HTMLLinkElement;
        }
        
        interface SVGLocatable {
            farthestViewportElement: SVGElement;
            nearestViewportElement: SVGElement;
            getBBox(): SVGRect;
            getTransformToElement(element: SVGElement): SVGMatrix;
            getCTM(): SVGMatrix;
            getScreenCTM(): SVGMatrix;
        }
        
        interface HTMLFontElement extends HTMLElement, DOML2DeprecatedColorProperty, DOML2DeprecatedSizeProperty {
            /**
              * Sets or retrieves the current typeface family.
              */
            face: string;
        }
        declare var HTMLFontElement: {
            prototype: HTMLFontElement;
            new(): HTMLFontElement;
        }
        
        interface SVGTitleElement extends SVGElement, SVGStylable, SVGLangSpace {
        }
        declare var SVGTitleElement: {
            prototype: SVGTitleElement;
            new(): SVGTitleElement;
        }
        
        interface ControlRangeCollection {
            length: number;
            queryCommandValue(cmdID: string): any;
            remove(index: number): void;
            add(item: Element): void;
            queryCommandIndeterm(cmdID: string): boolean;
            scrollIntoView(varargStart?: any): void;
            item(index: number): Element;
            [index: number]: Element;
            execCommand(cmdID: string, showUI?: boolean, value?: any): boolean;
            addElement(item: Element): void;
            queryCommandState(cmdID: string): boolean;
            queryCommandSupported(cmdID: string): boolean;
            queryCommandEnabled(cmdID: string): boolean;
            queryCommandText(cmdID: string): string;
            select(): void;
        }
        declare var ControlRangeCollection: {
            prototype: ControlRangeCollection;
            new(): ControlRangeCollection;
        }
        
        interface MSNamespaceInfo extends MSEventAttachmentTarget {
            urn: string;
            onreadystatechange: (ev: Event) => any;
            name: string;
            readyState: string;
            doImport(implementationUrl: string): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var MSNamespaceInfo: {
            prototype: MSNamespaceInfo;
            new(): MSNamespaceInfo;
        }
        
        interface WindowSessionStorage {
            sessionStorage: Storage;
        }
        
        interface SVGAnimatedTransformList {
            animVal: SVGTransformList;
            baseVal: SVGTransformList;
        }
        declare var SVGAnimatedTransformList: {
            prototype: SVGAnimatedTransformList;
            new(): SVGAnimatedTransformList;
        }
        
        interface HTMLTableCaptionElement extends HTMLElement {
            /**
              * Sets or retrieves the alignment of the caption or legend.
              */
            align: string;
            /**
              * Sets or retrieves whether the caption appears at the top or bottom of the table.
              */
            vAlign: string;
        }
        declare var HTMLTableCaptionElement: {
            prototype: HTMLTableCaptionElement;
            new(): HTMLTableCaptionElement;
        }
        
        interface HTMLOptionElement extends HTMLElement, MSDataBindingExtensions {
            /**
              * Sets or retrieves the ordinal position of an option in a list box.
              */
            index: number;
            /**
              * Sets or retrieves the status of an option.
              */
            defaultSelected: boolean;
            /**
              * Sets or retrieves the value which is returned to the server when the form control is submitted.
              */
            value: string;
            /**
              * Sets or retrieves the text string specified by the option tag.
              */
            text: string;
            /**
              * Retrieves a reference to the form that the object is embedded in.
              */
            form: HTMLFormElement;
            /**
              * Sets or retrieves a value that you can use to implement your own label functionality for the object.
              */
            label: string;
            /**
              * Sets or retrieves whether the option in the list box is the default item.
              */
            selected: boolean;
        }
        declare var HTMLOptionElement: {
            prototype: HTMLOptionElement;
            new(): HTMLOptionElement;
            create(): HTMLOptionElement;
        }
        
        interface HTMLMapElement extends HTMLElement {
            /**
              * Sets or retrieves the name of the object.
              */
            name: string;
            /**
              * Retrieves a collection of the area objects defined for the given map object.
              */
            areas: HTMLAreasCollection;
        }
        declare var HTMLMapElement: {
            prototype: HTMLMapElement;
            new(): HTMLMapElement;
        }
        
        interface HTMLMenuElement extends HTMLElement, DOML2DeprecatedListSpaceReduction {
            type: string;
        }
        declare var HTMLMenuElement: {
            prototype: HTMLMenuElement;
            new(): HTMLMenuElement;
        }
        
        interface MouseWheelEvent extends MouseEvent {
            wheelDelta: number;
            initMouseWheelEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, buttonArg: number, relatedTargetArg: EventTarget, modifiersListArg: string, wheelDeltaArg: number): void;
        }
        declare var MouseWheelEvent: {
            prototype: MouseWheelEvent;
            new(): MouseWheelEvent;
        }
        
        interface SVGFitToViewBox {
            viewBox: SVGAnimatedRect;
            preserveAspectRatio: SVGAnimatedPreserveAspectRatio;
        }
        
        interface SVGPointList {
            numberOfItems: number;
            replaceItem(newItem: SVGPoint, index: number): SVGPoint;
            getItem(index: number): SVGPoint;
            clear(): void;
            appendItem(newItem: SVGPoint): SVGPoint;
            initialize(newItem: SVGPoint): SVGPoint;
            removeItem(index: number): SVGPoint;
            insertItemBefore(newItem: SVGPoint, index: number): SVGPoint;
        }
        declare var SVGPointList: {
            prototype: SVGPointList;
            new(): SVGPointList;
        }
        
        interface SVGAnimatedLengthList {
            animVal: SVGLengthList;
            baseVal: SVGLengthList;
        }
        declare var SVGAnimatedLengthList: {
            prototype: SVGAnimatedLengthList;
            new(): SVGAnimatedLengthList;
        }
        
        interface SVGAnimatedPreserveAspectRatio {
            animVal: SVGPreserveAspectRatio;
            baseVal: SVGPreserveAspectRatio;
        }
        declare var SVGAnimatedPreserveAspectRatio: {
            prototype: SVGAnimatedPreserveAspectRatio;
            new(): SVGAnimatedPreserveAspectRatio;
        }
        
        interface MSSiteModeEvent extends Event {
            buttonID: number;
            actionURL: string;
        }
        declare var MSSiteModeEvent: {
            prototype: MSSiteModeEvent;
            new(): MSSiteModeEvent;
        }
        
        interface DOML2DeprecatedTextFlowControl {
            clear: string;
        }
        
        interface StyleSheetPageList {
            length: number;
            item(index: number): CSSPageRule;
            [index: number]: CSSPageRule;
        }
        declare var StyleSheetPageList: {
            prototype: StyleSheetPageList;
            new(): StyleSheetPageList;
        }
        
        interface MSCSSProperties extends CSSStyleDeclaration {
            scrollbarShadowColor: string;
            scrollbarHighlightColor: string;
            layoutGridChar: string;
            layoutGridType: string;
            textAutospace: string;
            textKashidaSpace: string;
            writingMode: string;
            scrollbarFaceColor: string;
            backgroundPositionY: string;
            lineBreak: string;
            imeMode: string;
            msBlockProgression: string;
            layoutGridLine: string;
            scrollbarBaseColor: string;
            layoutGrid: string;
            layoutFlow: string;
            textKashida: string;
            filter: string;
            zoom: string;
            scrollbarArrowColor: string;
            behavior: string;
            backgroundPositionX: string;
            accelerator: string;
            layoutGridMode: string;
            textJustifyTrim: string;
            scrollbar3dLightColor: string;
            msInterpolationMode: string;
            scrollbarTrackColor: string;
            scrollbarDarkShadowColor: string;
            styleFloat: string;
            getAttribute(attributeName: string, flags?: number): any;
            setAttribute(attributeName: string, AttributeValue: any, flags?: number): void;
            removeAttribute(attributeName: string, flags?: number): boolean;
        }
        declare var MSCSSProperties: {
            prototype: MSCSSProperties;
            new(): MSCSSProperties;
        }
        
        interface SVGExternalResourcesRequired {
            externalResourcesRequired: SVGAnimatedBoolean;
        }
        
        interface HTMLImageElement extends HTMLElement, MSImageResourceExtensions, MSDataBindingExtensions, MSResourceMetadata {
            /**
              * Sets or retrieves the width of the object.
              */
            width: number;
            /**
              * Sets or retrieves the vertical margin for the object.
              */
            vspace: number;
            /**
              * The original height of the image resource before sizing.
              */
            naturalHeight: number;
            /**
              * Sets or retrieves a text alternative to the graphic.
              */
            alt: string;
            /**
              * Sets or retrieves how the object is aligned with adjacent text.
              */
            align: string;
            /**
              * The address or URL of the a media resource that is to be considered.
              */
            src: string;
            /**
              * Sets or retrieves the URL, often with a bookmark extension (#name), to use as a client-side image map.
              */
            useMap: string;
            /**
              * The original width of the image resource before sizing.
              */
            naturalWidth: number;
            /**
              * Sets or retrieves the name of the object.
              */
            name: string;
            /**
              * Sets or retrieves the height of the object.
              */
            height: number;
            /**
              * Specifies the properties of a border drawn around an object.
              */
            border: string;
            /**
              * Sets or retrieves the width of the border to draw around the object.
              */
            hspace: number;
            /**
              * Sets or retrieves a Uniform Resource Identifier (URI) to a long description of the object.
              */
            longDesc: string;
            /**
              * Contains the hypertext reference (HREF) of the URL.
              */
            href: string;
            /**
              * Sets or retrieves whether the image is a server-side image map.
              */
            isMap: boolean;
            /**
              * Retrieves whether the object is fully loaded.
              */
            complete: boolean;
            /**
              * Gets or sets the primary DLNA PlayTo device.
              */
            msPlayToPrimary: boolean;
            /**
              * Gets or sets whether the DLNA PlayTo device is available.
              */
            msPlayToDisabled: boolean;
            /**
              * Gets the source associated with the media element for use by the PlayToManager.
              */
            msPlayToSource: any;
            crossOrigin: string;
            msPlayToPreferredSourceUri: string;
        }
        declare var HTMLImageElement: {
            prototype: HTMLImageElement;
            new(): HTMLImageElement;
            create(): HTMLImageElement;
        }
        
        interface HTMLAreaElement extends HTMLElement {
            /**
              * Sets or retrieves the protocol portion of a URL.
              */
            protocol: string;
            /**
              * Sets or retrieves the substring of the href property that follows the question mark.
              */
            search: string;
            /**
              * Sets or retrieves a text alternative to the graphic.
              */
            alt: string;
            /**
              * Sets or retrieves the coordinates of the object.
              */
            coords: string;
            /**
              * Sets or retrieves the host name part of the location or URL. 
              */
            hostname: string;
            /**
              * Sets or retrieves the port number associated with a URL.
              */
            port: string;
            /**
              * Sets or retrieves the file name or path specified by the object.
              */
            pathname: string;
            /**
              * Sets or retrieves the hostname and port number of the location or URL.
              */
            host: string;
            /**
              * Sets or retrieves the subsection of the href property that follows the number sign (#).
              */
            hash: string;
            /**
              * Sets or retrieves the window or frame at which to target content.
              */
            target: string;
            /**
              * Sets or retrieves a destination URL or an anchor point.
              */
            href: string;
            /**
              * Sets or gets whether clicks in this region cause action.
              */
            noHref: boolean;
            /**
              * Sets or retrieves the shape of the object.
              */
            shape: string;
            /** 
              * Returns a string representation of an object.
              */
            toString(): string;
        }
        declare var HTMLAreaElement: {
            prototype: HTMLAreaElement;
            new(): HTMLAreaElement;
        }
        
        interface EventTarget {
            removeEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
            dispatchEvent(evt: Event): boolean;
        }
        
        interface SVGAngle {
            valueAsString: string;
            valueInSpecifiedUnits: number;
            value: number;
            unitType: number;
            newValueSpecifiedUnits(unitType: number, valueInSpecifiedUnits: number): void;
            convertToSpecifiedUnits(unitType: number): void;
            SVG_ANGLETYPE_RAD: number;
            SVG_ANGLETYPE_UNKNOWN: number;
            SVG_ANGLETYPE_UNSPECIFIED: number;
            SVG_ANGLETYPE_DEG: number;
            SVG_ANGLETYPE_GRAD: number;
        }
        declare var SVGAngle: {
            prototype: SVGAngle;
            new(): SVGAngle;
            SVG_ANGLETYPE_RAD: number;
            SVG_ANGLETYPE_UNKNOWN: number;
            SVG_ANGLETYPE_UNSPECIFIED: number;
            SVG_ANGLETYPE_DEG: number;
            SVG_ANGLETYPE_GRAD: number;
        }
        
        interface HTMLButtonElement extends HTMLElement, MSDataBindingExtensions {
            /** 
              * Sets or retrieves the default or selected value of the control.
              */
            value: string;
            status: any;
            /**
              * Retrieves a reference to the form that the object is embedded in.
              */
            form: HTMLFormElement;
            /** 
              * Sets or retrieves the name of the object.
              */
            name: string;
            /**
              * Gets the classification and default behavior of the button.
              */
            type: string;
            /**
              * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation messages without actually submitting.
              */
            validationMessage: string;
            /**
              * Overrides the target attribute on a form element.
              */
            formTarget: string;
            /**
              * Returns whether an element will successfully validate based on forms validation rules and constraints.
              */
            willValidate: boolean;
            /**
              * Overrides the action attribute (where the data on a form is sent) on the parent form element.
              */
            formAction: string;
            /**
              * Provides a way to direct a user to a specific field when a document loads. This can provide both direction and convenience for a user, reducing the need to click or tab to a field when a page opens. This attribute is true when present on an element, and false when missing.
              */
            autofocus: boolean;
            /**
              * Returns a  ValidityState object that represents the validity states of an element.
              */
            validity: ValidityState;
            /**
              * Overrides any validation or required attributes on a form or form elements to allow it to be submitted without validation. This can be used to create a "save draft"-type submit option.
              */
            formNoValidate: string;
            /**
              * Used to override the encoding (formEnctype attribute) specified on the form element.
              */
            formEnctype: string;
            /**
              * Overrides the submit method attribute previously specified on a form element.
              */
            formMethod: string;
            /**
              * Creates a TextRange object for the element.
              */
            createTextRange(): TextRange;
            /**
              * Returns whether a form will validate when it is submitted, without having to submit it.
              */
            checkValidity(): boolean;
            /**
              * Sets a custom error message that is displayed when a form is submitted.
              * @param error Sets a custom error message that is displayed when a form is submitted.
              */
            setCustomValidity(error: string): void;
        }
        declare var HTMLButtonElement: {
            prototype: HTMLButtonElement;
            new(): HTMLButtonElement;
        }
        
        interface HTMLSourceElement extends HTMLElement {
            /**
              * The address or URL of the a media resource that is to be considered.
              */
            src: string;
            /**
              * Gets or sets the intended media type of the media source.
             */
            media: string;
            /**
             * Gets or sets the MIME type of a media resource.
             */
            type: string;
            msKeySystem: string;
        }
        declare var HTMLSourceElement: {
            prototype: HTMLSourceElement;
            new(): HTMLSourceElement;
        }
        
        interface CanvasGradient {
            addColorStop(offset: number, color: string): void;
        }
        declare var CanvasGradient: {
            prototype: CanvasGradient;
            new(): CanvasGradient;
        }
        
        interface KeyboardEvent extends UIEvent {
            location: number;
            keyCode: number;
            shiftKey: boolean;
            which: number;
            locale: string;
            key: string;
            altKey: boolean;
            metaKey: boolean;
            char: string;
            ctrlKey: boolean;
            repeat: boolean;
            charCode: number;
            getModifierState(keyArg: string): boolean;
            initKeyboardEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, keyArg: string, locationArg: number, modifiersListArg: string, repeat: boolean, locale: string): void;
            DOM_KEY_LOCATION_RIGHT: number;
            DOM_KEY_LOCATION_STANDARD: number;
            DOM_KEY_LOCATION_LEFT: number;
            DOM_KEY_LOCATION_NUMPAD: number;
            DOM_KEY_LOCATION_JOYSTICK: number;
            DOM_KEY_LOCATION_MOBILE: number;
        }
        declare var KeyboardEvent: {
            prototype: KeyboardEvent;
            new(): KeyboardEvent;
            DOM_KEY_LOCATION_RIGHT: number;
            DOM_KEY_LOCATION_STANDARD: number;
            DOM_KEY_LOCATION_LEFT: number;
            DOM_KEY_LOCATION_NUMPAD: number;
            DOM_KEY_LOCATION_JOYSTICK: number;
            DOM_KEY_LOCATION_MOBILE: number;
        }
        
        interface MessageEvent extends Event {
            source: Window;
            origin: string;
            data: any;
            ports: any;
            initMessageEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, dataArg: any, originArg: string, lastEventIdArg: string, sourceArg: Window): void;
        }
        declare var MessageEvent: {
            prototype: MessageEvent;
            new(): MessageEvent;
        }
        
        interface SVGElement extends Element {
            onmouseover: (ev: MouseEvent) => any;
            viewportElement: SVGElement;
            onmousemove: (ev: MouseEvent) => any;
            onmouseout: (ev: MouseEvent) => any;
            ondblclick: (ev: MouseEvent) => any;
            onfocusout: (ev: FocusEvent) => any;
            onfocusin: (ev: FocusEvent) => any;
            xmlbase: string;
            onmousedown: (ev: MouseEvent) => any;
            onload: (ev: Event) => any;
            onmouseup: (ev: MouseEvent) => any;
            onclick: (ev: MouseEvent) => any;
            ownerSVGElement: SVGSVGElement;
            id: string;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var SVGElement: {
            prototype: SVGElement;
            new(): SVGElement;
        }
        
        interface HTMLScriptElement extends HTMLElement {
            /**
              * Sets or retrieves the status of the script.
              */
            defer: boolean;
            /**
              * Retrieves or sets the text of the object as a string. 
              */
            text: string;
            /**
              * Retrieves the URL to an external file that contains the source code or data.
              */
            src: string;
            /** 
              * Sets or retrieves the object that is bound to the event script.
              */
            htmlFor: string;
            /**
              * Sets or retrieves the character set used to encode the object.
              */
            charset: string;
            /**
              * Sets or retrieves the MIME type for the associated scripting engine.
              */
            type: string;
            /**
              * Sets or retrieves the event for which the script is written. 
              */
            event: string;
            async: boolean;
        }
        declare var HTMLScriptElement: {
            prototype: HTMLScriptElement;
            new(): HTMLScriptElement;
        }
        
        interface HTMLTableRowElement extends HTMLElement, HTMLTableAlignment, DOML2DeprecatedBackgroundColorStyle {
            /**
              * Retrieves the position of the object in the rows collection for the table.
              */
            rowIndex: number;
            /**
              * Retrieves a collection of all cells in the table row.
              */
            cells: HTMLCollection;
            /**
              * Sets or retrieves how the object is aligned with adjacent text.
              */
            align: string;
            /**
              * Sets or retrieves the color for one of the two colors used to draw the 3-D border of the object.
              */
            borderColorLight: any;
            /**
              * Retrieves the position of the object in the collection.
              */
            sectionRowIndex: number;
            /**
              * Sets or retrieves the border color of the object.
              */
            borderColor: any;
            /**
              * Sets or retrieves the height of the object.
              */
            height: any;
            /**
              * Sets or retrieves the color for one of the two colors used to draw the 3-D border of the object.
              */
            borderColorDark: any;
            /**
              * Removes the specified cell from the table row, as well as from the cells collection.
              * @param index Number that specifies the zero-based position of the cell to remove from the table row. If no value is provided, the last cell in the cells collection is deleted.
              */
            deleteCell(index?: number): void;
            /**
              * Creates a new cell in the table row, and adds the cell to the cells collection.
              * @param index Number that specifies where to insert the cell in the tr. The default value is -1, which appends the new cell to the end of the cells collection.
              */
            insertCell(index?: number): HTMLElement;
        }
        declare var HTMLTableRowElement: {
            prototype: HTMLTableRowElement;
            new(): HTMLTableRowElement;
        }
        
        interface CanvasRenderingContext2D {
            miterLimit: number;
            font: string;
            globalCompositeOperation: string;
            msFillRule: string;
            lineCap: string;
            msImageSmoothingEnabled: boolean;
            lineDashOffset: number;
            shadowColor: string;
            lineJoin: string;
            shadowOffsetX: number;
            lineWidth: number;
            canvas: HTMLCanvasElement;
            strokeStyle: any;
            globalAlpha: number;
            shadowOffsetY: number;
            fillStyle: any;
            shadowBlur: number;
            textAlign: string;
            textBaseline: string;
            restore(): void;
            setTransform(m11: number, m12: number, m21: number, m22: number, dx: number, dy: number): void;
            save(): void;
            arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): void;
            measureText(text: string): TextMetrics;
            isPointInPath(x: number, y: number, fillRule?: string): boolean;
            quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;
            putImageData(imagedata: ImageData, dx: number, dy: number, dirtyX?: number, dirtyY?: number, dirtyWidth?: number, dirtyHeight?: number): void;
            rotate(angle: number): void;
            fillText(text: string, x: number, y: number, maxWidth?: number): void;
            translate(x: number, y: number): void;
            scale(x: number, y: number): void;
            createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;
            lineTo(x: number, y: number): void;
            getLineDash(): number[];
            fill(fillRule?: string): void;
            createImageData(imageDataOrSw: any, sh?: number): ImageData;
            createPattern(image: HTMLElement, repetition: string): CanvasPattern;
            closePath(): void;
            rect(x: number, y: number, w: number, h: number): void;
            clip(fillRule?: string): void;
            clearRect(x: number, y: number, w: number, h: number): void;
            moveTo(x: number, y: number): void;
            getImageData(sx: number, sy: number, sw: number, sh: number): ImageData;
            fillRect(x: number, y: number, w: number, h: number): void;
            bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;
            drawImage(image: HTMLElement, offsetX: number, offsetY: number, width?: number, height?: number, canvasOffsetX?: number, canvasOffsetY?: number, canvasImageWidth?: number, canvasImageHeight?: number): void;
            transform(m11: number, m12: number, m21: number, m22: number, dx: number, dy: number): void;
            stroke(): void;
            strokeRect(x: number, y: number, w: number, h: number): void;
            setLineDash(segments: number[]): void;
            strokeText(text: string, x: number, y: number, maxWidth?: number): void;
            beginPath(): void;
            arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;
            createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;
        }
        declare var CanvasRenderingContext2D: {
            prototype: CanvasRenderingContext2D;
            new(): CanvasRenderingContext2D;
        }
        
        interface MSCSSRuleList {
            length: number;
            item(index?: number): CSSStyleRule;
            [index: number]: CSSStyleRule;
        }
        declare var MSCSSRuleList: {
            prototype: MSCSSRuleList;
            new(): MSCSSRuleList;
        }
        
        interface SVGPathSegLinetoHorizontalAbs extends SVGPathSeg {
            x: number;
        }
        declare var SVGPathSegLinetoHorizontalAbs: {
            prototype: SVGPathSegLinetoHorizontalAbs;
            new(): SVGPathSegLinetoHorizontalAbs;
        }
        
        interface SVGPathSegArcAbs extends SVGPathSeg {
            y: number;
            sweepFlag: boolean;
            r2: number;
            x: number;
            angle: number;
            r1: number;
            largeArcFlag: boolean;
        }
        declare var SVGPathSegArcAbs: {
            prototype: SVGPathSegArcAbs;
            new(): SVGPathSegArcAbs;
        }
        
        interface SVGTransformList {
            numberOfItems: number;
            getItem(index: number): SVGTransform;
            consolidate(): SVGTransform;
            clear(): void;
            appendItem(newItem: SVGTransform): SVGTransform;
            initialize(newItem: SVGTransform): SVGTransform;
            removeItem(index: number): SVGTransform;
            insertItemBefore(newItem: SVGTransform, index: number): SVGTransform;
            replaceItem(newItem: SVGTransform, index: number): SVGTransform;
            createSVGTransformFromMatrix(matrix: SVGMatrix): SVGTransform;
        }
        declare var SVGTransformList: {
            prototype: SVGTransformList;
            new(): SVGTransformList;
        }
        
        interface HTMLHtmlElement extends HTMLElement {
            /**
              * Sets or retrieves the DTD version that governs the current document.
              */
            version: string;
        }
        declare var HTMLHtmlElement: {
            prototype: HTMLHtmlElement;
            new(): HTMLHtmlElement;
        }
        
        interface SVGPathSegClosePath extends SVGPathSeg {
        }
        declare var SVGPathSegClosePath: {
            prototype: SVGPathSegClosePath;
            new(): SVGPathSegClosePath;
        }
        
        interface HTMLFrameElement extends HTMLElement, GetSVGDocument, MSDataBindingExtensions {
            /**
              * Sets or retrieves the width of the object.
              */
            width: any;
            /**
              * Sets or retrieves whether the frame can be scrolled.
              */
            scrolling: string;
            /**
              * Sets or retrieves the top and bottom margin heights before displaying the text in a frame.
              */
            marginHeight: string;
            /**
              * Sets or retrieves the left and right margin widths before displaying the text in a frame.
              */
            marginWidth: string;
            /**
              * Sets or retrieves the border color of the object.
              */
            borderColor: any;
            /**
              * Sets or retrieves the amount of additional space between the frames.
              */
            frameSpacing: any;
            /**
              * Sets or retrieves whether to display a border for the frame.
              */
            frameBorder: string;
            /**
              * Sets or retrieves whether the user can resize the frame.
              */
            noResize: boolean;
            /**
              * Retrieves the object of the specified.
              */
            contentWindow: Window;
            /**
              * Sets or retrieves a URL to be loaded by the object.
              */
            src: string;
            /**
              * Sets or retrieves the frame name.
              */
            name: string;
            /**
              * Sets or retrieves the height of the object.
              */
            height: any;
            /**
              * Retrieves the document object of the page or frame.
              */
            contentDocument: Document;
            /**
              * Specifies the properties of a border drawn around an object.
              */
            border: string;
            /**
              * Sets or retrieves a URI to a long description of the object.
              */
            longDesc: string;
            /**
              * Raised when the object has been completely received from the server.
              */
            onload: (ev: Event) => any;
            /**
              * Sets the value indicating whether the source file of a frame or iframe has specific security restrictions applied.
              */
            security: any;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "move", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "deactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetchanged", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsdelete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "losecapture", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "controlselect", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "layoutcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "filterchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "errorupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "cellchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowexit", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsinserted", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "propertychange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforepaste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecopy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "paste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "moveend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeeditfocus", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "afterupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizeend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dataavailable", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforedeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "activate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "movestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "selectstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "cut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "copy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "rowenter", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mscontentzoom", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "cuechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "msmanipulationstatechanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var HTMLFrameElement: {
            prototype: HTMLFrameElement;
            new(): HTMLFrameElement;
        }
        
        interface SVGAnimatedLength {
            animVal: SVGLength;
            baseVal: SVGLength;
        }
        declare var SVGAnimatedLength: {
            prototype: SVGAnimatedLength;
            new(): SVGAnimatedLength;
        }
        
        interface SVGAnimatedPoints {
            points: SVGPointList;
            animatedPoints: SVGPointList;
        }
        
        interface SVGDefsElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
        }
        declare var SVGDefsElement: {
            prototype: SVGDefsElement;
            new(): SVGDefsElement;
        }
        
        interface HTMLQuoteElement extends HTMLElement {
            /**
              * Sets or retrieves the date and time of a modification to the object.
              */
            dateTime: string;
            /**
              * Sets or retrieves reference information about the object.
              */
            cite: string;
        }
        declare var HTMLQuoteElement: {
            prototype: HTMLQuoteElement;
            new(): HTMLQuoteElement;
        }
        
        interface CSSMediaRule extends CSSRule {
            media: MediaList;
            cssRules: CSSRuleList;
            insertRule(rule: string, index?: number): number;
            deleteRule(index?: number): void;
        }
        declare var CSSMediaRule: {
            prototype: CSSMediaRule;
            new(): CSSMediaRule;
        }
        
        interface WindowModal {
            dialogArguments: any;
            returnValue: any;
        }
        
        interface XMLHttpRequest extends EventTarget {
            responseBody: any;
            status: number;
            readyState: number;
            responseText: string;
            responseXML: any;
            ontimeout: (ev: Event) => any;
            statusText: string;
            onreadystatechange: (ev: Event) => any;
            timeout: number;
            onload: (ev: Event) => any;
            response: any;
            withCredentials: boolean;
            onprogress: (ev: ProgressEvent) => any;
            onabort: (ev: UIEvent) => any;
            responseType: string;
            onloadend: (ev: ProgressEvent) => any;
            upload: XMLHttpRequestEventTarget;
            onerror: (ev: ErrorEvent) => any;
            onloadstart: (ev: Event) => any;
            msCaching: string;
            open(method: string, url: string, async?: boolean, user?: string, password?: string): void;
            send(data?: any): void;
            abort(): void;
            getAllResponseHeaders(): string;
            setRequestHeader(header: string, value: string): void;
            getResponseHeader(header: string): string;
            msCachingEnabled(): boolean;
            overrideMimeType(mime: string): void;
            LOADING: number;
            DONE: number;
            UNSENT: number;
            OPENED: number;
            HEADERS_RECEIVED: number;
            addEventListener(type: "timeout", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadend", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var XMLHttpRequest: {
            prototype: XMLHttpRequest;
            new(): XMLHttpRequest;
            LOADING: number;
            DONE: number;
            UNSENT: number;
            OPENED: number;
            HEADERS_RECEIVED: number;
            create(): XMLHttpRequest;
        }
        
        interface HTMLTableHeaderCellElement extends HTMLTableCellElement {
            /**
              * Sets or retrieves the group of cells in a table to which the object's information applies.
              */
            scope: string;
        }
        declare var HTMLTableHeaderCellElement: {
            prototype: HTMLTableHeaderCellElement;
            new(): HTMLTableHeaderCellElement;
        }
        
        interface HTMLDListElement extends HTMLElement, DOML2DeprecatedListSpaceReduction {
        }
        declare var HTMLDListElement: {
            prototype: HTMLDListElement;
            new(): HTMLDListElement;
        }
        
        interface MSDataBindingExtensions {
            dataSrc: string;
            dataFormatAs: string;
            dataFld: string;
        }
        
        interface SVGPathSegLinetoHorizontalRel extends SVGPathSeg {
            x: number;
        }
        declare var SVGPathSegLinetoHorizontalRel: {
            prototype: SVGPathSegLinetoHorizontalRel;
            new(): SVGPathSegLinetoHorizontalRel;
        }
        
        interface SVGEllipseElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
            ry: SVGAnimatedLength;
            cx: SVGAnimatedLength;
            rx: SVGAnimatedLength;
            cy: SVGAnimatedLength;
        }
        declare var SVGEllipseElement: {
            prototype: SVGEllipseElement;
            new(): SVGEllipseElement;
        }
        
        interface SVGAElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired, SVGURIReference {
            target: SVGAnimatedString;
        }
        declare var SVGAElement: {
            prototype: SVGAElement;
            new(): SVGAElement;
        }
        
        interface SVGStylable {
            className: SVGAnimatedString;
            style: CSSStyleDeclaration;
        }
        
        interface SVGTransformable extends SVGLocatable {
            transform: SVGAnimatedTransformList;
        }
        
        interface HTMLFrameSetElement extends HTMLElement {
            ononline: (ev: Event) => any;
            /**
              * Sets or retrieves the border color of the object.
              */
            borderColor: any;
            /**
              * Sets or retrieves the frame heights of the object.
              */
            rows: string;
            /**
              * Sets or retrieves the frame widths of the object.
              */
            cols: string;
            /**
              * Fires when the object loses the input focus.
              */
            onblur: (ev: FocusEvent) => any;
            /**
              * Sets or retrieves the amount of additional space between the frames.
              */
            frameSpacing: any;
            /**
              * Fires when the object receives focus.
              */
            onfocus: (ev: FocusEvent) => any;
            onmessage: (ev: MessageEvent) => any;
            onerror: (ev: ErrorEvent) => any;
            /**
              * Sets or retrieves whether to display a border for the frame.
              */
            frameBorder: string;
            onresize: (ev: UIEvent) => any;
            name: string;
            onafterprint: (ev: Event) => any;
            onbeforeprint: (ev: Event) => any;
            onoffline: (ev: Event) => any;
            border: string;
            onunload: (ev: Event) => any;
            onhashchange: (ev: Event) => any;
            onload: (ev: Event) => any;
            onbeforeunload: (ev: BeforeUnloadEvent) => any;
            onstorage: (ev: StorageEvent) => any;
            onpageshow: (ev: PageTransitionEvent) => any;
            onpagehide: (ev: PageTransitionEvent) => any;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "move", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "deactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetchanged", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsdelete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "losecapture", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "controlselect", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "layoutcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "filterchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "errorupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "cellchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowexit", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsinserted", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "propertychange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforepaste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecopy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "paste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "moveend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeeditfocus", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "afterupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizeend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dataavailable", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforedeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "activate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "movestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "selectstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "cut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "copy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "rowenter", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mscontentzoom", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "cuechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "msmanipulationstatechanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "online", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "afterprint", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeprint", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "offline", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "unload", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "hashchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeunload", listener: (ev: BeforeUnloadEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "storage", listener: (ev: StorageEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pageshow", listener: (ev: PageTransitionEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pagehide", listener: (ev: PageTransitionEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var HTMLFrameSetElement: {
            prototype: HTMLFrameSetElement;
            new(): HTMLFrameSetElement;
        }
        
        interface Screen extends EventTarget {
            width: number;
            deviceXDPI: number;
            fontSmoothingEnabled: boolean;
            bufferDepth: number;
            logicalXDPI: number;
            systemXDPI: number;
            availHeight: number;
            height: number;
            logicalYDPI: number;
            systemYDPI: number;
            updateInterval: number;
            colorDepth: number;
            availWidth: number;
            deviceYDPI: number;
            pixelDepth: number;
            msOrientation: string;
            onmsorientationchange: (ev: any) => any;
            msLockOrientation(orientation: string): boolean;
            msLockOrientation(orientations: string[]): boolean;
            msUnlockOrientation(): void;
            addEventListener(type: "msorientationchange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var Screen: {
            prototype: Screen;
            new(): Screen;
        }
        
        interface Coordinates {
            altitudeAccuracy: number;
            longitude: number;
            latitude: number;
            speed: number;
            heading: number;
            altitude: number;
            accuracy: number;
        }
        declare var Coordinates: {
            prototype: Coordinates;
            new(): Coordinates;
        }
        
        interface NavigatorGeolocation {
            geolocation: Geolocation;
        }
        
        interface NavigatorContentUtils {
        }
        
        interface EventListener {
            (evt: Event): void;
        }
        
        interface SVGLangSpace {
            xmllang: string;
            xmlspace: string;
        }
        
        interface DataTransfer {
            effectAllowed: string;
            dropEffect: string;
            types: DOMStringList;
            files: FileList;
            clearData(format?: string): boolean;
            setData(format: string, data: string): boolean;
            getData(format: string): string;
        }
        declare var DataTransfer: {
            prototype: DataTransfer;
            new(): DataTransfer;
        }
        
        interface FocusEvent extends UIEvent {
            relatedTarget: EventTarget;
            initFocusEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, relatedTargetArg: EventTarget): void;
        }
        declare var FocusEvent: {
            prototype: FocusEvent;
            new(): FocusEvent;
        }
        
        interface Range {
            startOffset: number;
            collapsed: boolean;
            endOffset: number;
            startContainer: Node;
            endContainer: Node;
            commonAncestorContainer: Node;
            setStart(refNode: Node, offset: number): void;
            setEndBefore(refNode: Node): void;
            setStartBefore(refNode: Node): void;
            selectNode(refNode: Node): void;
            detach(): void;
            getBoundingClientRect(): ClientRect;
            toString(): string;
            compareBoundaryPoints(how: number, sourceRange: Range): number;
            insertNode(newNode: Node): void;
            collapse(toStart: boolean): void;
            selectNodeContents(refNode: Node): void;
            cloneContents(): DocumentFragment;
            setEnd(refNode: Node, offset: number): void;
            cloneRange(): Range;
            getClientRects(): ClientRectList;
            surroundContents(newParent: Node): void;
            deleteContents(): void;
            setStartAfter(refNode: Node): void;
            extractContents(): DocumentFragment;
            setEndAfter(refNode: Node): void;
            createContextualFragment(fragment: string): DocumentFragment;
            END_TO_END: number;
            START_TO_START: number;
            START_TO_END: number;
            END_TO_START: number;
        }
        declare var Range: {
            prototype: Range;
            new(): Range;
            END_TO_END: number;
            START_TO_START: number;
            START_TO_END: number;
            END_TO_START: number;
        }
        
        interface SVGPoint {
            y: number;
            x: number;
            matrixTransform(matrix: SVGMatrix): SVGPoint;
        }
        declare var SVGPoint: {
            prototype: SVGPoint;
            new(): SVGPoint;
        }
        
        interface MSPluginsCollection {
            length: number;
            refresh(reload?: boolean): void;
        }
        declare var MSPluginsCollection: {
            prototype: MSPluginsCollection;
            new(): MSPluginsCollection;
        }
        
        interface SVGAnimatedNumberList {
            animVal: SVGNumberList;
            baseVal: SVGNumberList;
        }
        declare var SVGAnimatedNumberList: {
            prototype: SVGAnimatedNumberList;
            new(): SVGAnimatedNumberList;
        }
        
        interface SVGSVGElement extends SVGElement, SVGStylable, SVGZoomAndPan, DocumentEvent, SVGLangSpace, SVGLocatable, SVGTests, SVGFitToViewBox, SVGExternalResourcesRequired {
            width: SVGAnimatedLength;
            x: SVGAnimatedLength;
            contentStyleType: string;
            onzoom: (ev: any) => any;
            y: SVGAnimatedLength;
            viewport: SVGRect;
            onerror: (ev: ErrorEvent) => any;
            pixelUnitToMillimeterY: number;
            onresize: (ev: UIEvent) => any;
            screenPixelToMillimeterY: number;
            height: SVGAnimatedLength;
            onabort: (ev: UIEvent) => any;
            contentScriptType: string;
            pixelUnitToMillimeterX: number;
            currentTranslate: SVGPoint;
            onunload: (ev: Event) => any;
            currentScale: number;
            onscroll: (ev: UIEvent) => any;
            screenPixelToMillimeterX: number;
            setCurrentTime(seconds: number): void;
            createSVGLength(): SVGLength;
            getIntersectionList(rect: SVGRect, referenceElement: SVGElement): NodeList;
            unpauseAnimations(): void;
            createSVGRect(): SVGRect;
            checkIntersection(element: SVGElement, rect: SVGRect): boolean;
            unsuspendRedrawAll(): void;
            pauseAnimations(): void;
            suspendRedraw(maxWaitMilliseconds: number): number;
            deselectAll(): void;
            createSVGAngle(): SVGAngle;
            getEnclosureList(rect: SVGRect, referenceElement: SVGElement): NodeList;
            createSVGTransform(): SVGTransform;
            unsuspendRedraw(suspendHandleID: number): void;
            forceRedraw(): void;
            getCurrentTime(): number;
            checkEnclosure(element: SVGElement, rect: SVGRect): boolean;
            createSVGMatrix(): SVGMatrix;
            createSVGPoint(): SVGPoint;
            createSVGNumber(): SVGNumber;
            createSVGTransformFromMatrix(matrix: SVGMatrix): SVGTransform;
            getComputedStyle(elt: Element, pseudoElt?: string): CSSStyleDeclaration;
            getElementById(elementId: string): Element;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "zoom", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "unload", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var SVGSVGElement: {
            prototype: SVGSVGElement;
            new(): SVGSVGElement;
        }
        
        interface HTMLLabelElement extends HTMLElement, MSDataBindingExtensions {
            /**
              * Sets or retrieves the object to which the given label object is assigned.
              */
            htmlFor: string;
            /**
              * Retrieves a reference to the form that the object is embedded in.
              */
            form: HTMLFormElement;
        }
        declare var HTMLLabelElement: {
            prototype: HTMLLabelElement;
            new(): HTMLLabelElement;
        }
        
        interface MSResourceMetadata {
            protocol: string;
            fileSize: string;
            fileUpdatedDate: string;
            nameProp: string;
            fileCreatedDate: string;
            fileModifiedDate: string;
            mimeType: string;
        }
        
        interface HTMLLegendElement extends HTMLElement, MSDataBindingExtensions {
            /**
              * Retrieves a reference to the form that the object is embedded in.
              */
            align: string;
            /**
              * Retrieves a reference to the form that the object is embedded in.
              */
            form: HTMLFormElement;
        }
        declare var HTMLLegendElement: {
            prototype: HTMLLegendElement;
            new(): HTMLLegendElement;
        }
        
        interface HTMLDirectoryElement extends HTMLElement, DOML2DeprecatedListSpaceReduction, DOML2DeprecatedListNumberingAndBulletStyle {
        }
        declare var HTMLDirectoryElement: {
            prototype: HTMLDirectoryElement;
            new(): HTMLDirectoryElement;
        }
        
        interface SVGAnimatedInteger {
            animVal: number;
            baseVal: number;
        }
        declare var SVGAnimatedInteger: {
            prototype: SVGAnimatedInteger;
            new(): SVGAnimatedInteger;
        }
        
        interface SVGTextElement extends SVGTextPositioningElement, SVGTransformable {
        }
        declare var SVGTextElement: {
            prototype: SVGTextElement;
            new(): SVGTextElement;
        }
        
        interface SVGTSpanElement extends SVGTextPositioningElement {
        }
        declare var SVGTSpanElement: {
            prototype: SVGTSpanElement;
            new(): SVGTSpanElement;
        }
        
        interface HTMLLIElement extends HTMLElement, DOML2DeprecatedListNumberingAndBulletStyle {
            /**
              * Sets or retrieves the value of a list item.
              */
            value: number;
        }
        declare var HTMLLIElement: {
            prototype: HTMLLIElement;
            new(): HTMLLIElement;
        }
        
        interface SVGPathSegLinetoVerticalAbs extends SVGPathSeg {
            y: number;
        }
        declare var SVGPathSegLinetoVerticalAbs: {
            prototype: SVGPathSegLinetoVerticalAbs;
            new(): SVGPathSegLinetoVerticalAbs;
        }
        
        interface MSStorageExtensions {
            remainingSpace: number;
        }
        
        interface SVGStyleElement extends SVGElement, SVGLangSpace {
            media: string;
            type: string;
            title: string;
        }
        declare var SVGStyleElement: {
            prototype: SVGStyleElement;
            new(): SVGStyleElement;
        }
        
        interface MSCurrentStyleCSSProperties extends MSCSSProperties {
            blockDirection: string;
            clipBottom: string;
            clipLeft: string;
            clipRight: string;
            clipTop: string;
            hasLayout: string;
        }
        declare var MSCurrentStyleCSSProperties: {
            prototype: MSCurrentStyleCSSProperties;
            new(): MSCurrentStyleCSSProperties;
        }
        
        interface MSHTMLCollectionExtensions {
            urns(urn: any): any;
            tags(tagName: any): any;
        }
        
        interface Storage extends MSStorageExtensions {
            length: number;
            getItem(key: string): any;
            [key: string]: any;
            setItem(key: string, data: string): void;
            clear(): void;
            removeItem(key: string): void;
            key(index: number): string;
            [index: number]: string;
        }
        declare var Storage: {
            prototype: Storage;
            new(): Storage;
        }
        
        interface HTMLIFrameElement extends HTMLElement, GetSVGDocument, MSDataBindingExtensions {
            /**
              * Sets or retrieves the width of the object.
              */
            width: string;
            /**
              * Sets or retrieves whether the frame can be scrolled.
              */
            scrolling: string;
            /**
              * Sets or retrieves the top and bottom margin heights before displaying the text in a frame.
              */
            marginHeight: string;
            /**
              * Sets or retrieves the left and right margin widths before displaying the text in a frame.
              */
            marginWidth: string;
            /**
              * Sets or retrieves the amount of additional space between the frames.
              */
            frameSpacing: any;
            /**
              * Sets or retrieves whether to display a border for the frame.
              */
            frameBorder: string;
            /**
              * Sets or retrieves whether the user can resize the frame.
              */
            noResize: boolean;
            /**
              * Sets or retrieves the vertical margin for the object.
              */
            vspace: number;
            /**
              * Retrieves the object of the specified.
              */
            contentWindow: Window;
            /**
              * Sets or retrieves how the object is aligned with adjacent text.
              */
            align: string;
            /**
              * Sets or retrieves a URL to be loaded by the object.
              */
            src: string;
            /**
              * Sets or retrieves the frame name.
              */
            name: string;
            /**
              * Sets or retrieves the height of the object.
              */
            height: string;
            /**
              * Specifies the properties of a border drawn around an object.
              */
            border: string;
            /**
              * Retrieves the document object of the page or frame.
              */
            contentDocument: Document;
            /**
              * Sets or retrieves the horizontal margin for the object.
              */
            hspace: number;
            /**
              * Sets or retrieves a URI to a long description of the object.
              */
            longDesc: string;
            /**
              * Sets the value indicating whether the source file of a frame or iframe has specific security restrictions applied.
              */
            security: any;
            /**
              * Raised when the object has been completely received from the server.
              */
            onload: (ev: Event) => any;
            sandbox: DOMSettableTokenList;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "move", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "deactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetchanged", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsdelete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "losecapture", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "controlselect", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "layoutcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "filterchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "errorupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "cellchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowexit", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsinserted", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "propertychange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforepaste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecopy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "paste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "moveend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeeditfocus", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "afterupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizeend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dataavailable", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforedeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "activate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "movestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "selectstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "cut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "copy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "rowenter", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mscontentzoom", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "cuechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "msmanipulationstatechanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var HTMLIFrameElement: {
            prototype: HTMLIFrameElement;
            new(): HTMLIFrameElement;
        }
        
        interface TextRangeCollection {
            length: number;
            item(index: number): TextRange;
            [index: number]: TextRange;
        }
        declare var TextRangeCollection: {
            prototype: TextRangeCollection;
            new(): TextRangeCollection;
        }
        
        interface HTMLBodyElement extends HTMLElement, DOML2DeprecatedBackgroundStyle, DOML2DeprecatedBackgroundColorStyle {
            scroll: string;
            ononline: (ev: Event) => any;
            onblur: (ev: FocusEvent) => any;
            noWrap: boolean;
            onfocus: (ev: FocusEvent) => any;
            onmessage: (ev: MessageEvent) => any;
            text: any;
            onerror: (ev: ErrorEvent) => any;
            bgProperties: string;
            onresize: (ev: UIEvent) => any;
            link: any;
            aLink: any;
            bottomMargin: any;
            topMargin: any;
            onafterprint: (ev: Event) => any;
            vLink: any;
            onbeforeprint: (ev: Event) => any;
            onoffline: (ev: Event) => any;
            onunload: (ev: Event) => any;
            onhashchange: (ev: Event) => any;
            onload: (ev: Event) => any;
            rightMargin: any;
            onbeforeunload: (ev: BeforeUnloadEvent) => any;
            leftMargin: any;
            onstorage: (ev: StorageEvent) => any;
            onpopstate: (ev: PopStateEvent) => any;
            onpageshow: (ev: PageTransitionEvent) => any;
            onpagehide: (ev: PageTransitionEvent) => any;
            createTextRange(): TextRange;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "move", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "deactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetchanged", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsdelete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "losecapture", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "controlselect", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "layoutcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "filterchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "errorupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "cellchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowexit", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsinserted", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "propertychange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforepaste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecopy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "paste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "moveend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeeditfocus", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "afterupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizeend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dataavailable", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforedeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "activate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "movestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "selectstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "cut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "copy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "rowenter", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mscontentzoom", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "cuechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "msmanipulationstatechanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "online", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "afterprint", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeprint", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "offline", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "unload", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "hashchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeunload", listener: (ev: BeforeUnloadEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "storage", listener: (ev: StorageEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "popstate", listener: (ev: PopStateEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pageshow", listener: (ev: PageTransitionEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pagehide", listener: (ev: PageTransitionEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var HTMLBodyElement: {
            prototype: HTMLBodyElement;
            new(): HTMLBodyElement;
        }
        
        interface DocumentType extends Node {
            name: string;
            notations: NamedNodeMap;
            systemId: string;
            internalSubset: string;
            entities: NamedNodeMap;
            publicId: string;
        }
        declare var DocumentType: {
            prototype: DocumentType;
            new(): DocumentType;
        }
        
        interface SVGRadialGradientElement extends SVGGradientElement {
            cx: SVGAnimatedLength;
            r: SVGAnimatedLength;
            cy: SVGAnimatedLength;
            fx: SVGAnimatedLength;
            fy: SVGAnimatedLength;
        }
        declare var SVGRadialGradientElement: {
            prototype: SVGRadialGradientElement;
            new(): SVGRadialGradientElement;
        }
        
        interface MutationEvent extends Event {
            newValue: string;
            attrChange: number;
            attrName: string;
            prevValue: string;
            relatedNode: Node;
            initMutationEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, relatedNodeArg: Node, prevValueArg: string, newValueArg: string, attrNameArg: string, attrChangeArg: number): void;
            MODIFICATION: number;
            REMOVAL: number;
            ADDITION: number;
        }
        declare var MutationEvent: {
            prototype: MutationEvent;
            new(): MutationEvent;
            MODIFICATION: number;
            REMOVAL: number;
            ADDITION: number;
        }
        
        interface DragEvent extends MouseEvent {
            dataTransfer: DataTransfer;
            initDragEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, ctrlKeyArg: boolean, altKeyArg: boolean, shiftKeyArg: boolean, metaKeyArg: boolean, buttonArg: number, relatedTargetArg: EventTarget, dataTransferArg: DataTransfer): void;
            msConvertURL(file: File, targetType: string, targetURL?: string): void;
        }
        declare var DragEvent: {
            prototype: DragEvent;
            new(): DragEvent;
        }
        
        interface HTMLTableSectionElement extends HTMLElement, HTMLTableAlignment, DOML2DeprecatedBackgroundColorStyle {
            /**
              * Sets or retrieves a value that indicates the table alignment.
              */
            align: string;
            /**
              * Sets or retrieves the number of horizontal rows contained in the object.
              */
            rows: HTMLCollection;
            /**
              * Removes the specified row (tr) from the element and from the rows collection.
              * @param index Number that specifies the zero-based position in the rows collection of the row to remove.
              */
            deleteRow(index?: number): void;
            /**
              * Moves a table row to a new position.
              * @param indexFrom Number that specifies the index in the rows collection of the table row that is moved.
              * @param indexTo Number that specifies where the row is moved within the rows collection.
              */
            moveRow(indexFrom?: number, indexTo?: number): any;
            /**
              * Creates a new row (tr) in the table, and adds the row to the rows collection.
              * @param index Number that specifies where to insert the row in the rows collection. The default value is -1, which appends the new row to the end of the rows collection.
              */
            insertRow(index?: number): HTMLElement;
        }
        declare var HTMLTableSectionElement: {
            prototype: HTMLTableSectionElement;
            new(): HTMLTableSectionElement;
        }
        
        interface DOML2DeprecatedListNumberingAndBulletStyle {
            type: string;
        }
        
        interface HTMLInputElement extends HTMLElement, MSDataBindingExtensions {
            /**
              * Sets or retrieves the width of the object.
              */
            width: string;
            status: boolean;
            /**
              * Retrieves a reference to the form that the object is embedded in. 
              */
            form: HTMLFormElement;
            /**
              * Gets or sets the starting position or offset of a text selection.
              */
            selectionStart: number;
            indeterminate: boolean;
            readOnly: boolean;
            size: number;
            loop: number;
            /**
              * Gets or sets the end position or offset of a text selection.
              */
            selectionEnd: number;
            /**
              * Sets or retrieves the URL of the virtual reality modeling language (VRML) world to be displayed in the window.
              */
            vrml: string;
            /**
              * Sets or retrieves a lower resolution image to display.
              */
            lowsrc: string;
            /**
              * Sets or retrieves the vertical margin for the object.
              */
            vspace: number;
            /**
              * Sets or retrieves a comma-separated list of content types.
              */
            accept: string;
            /**
              * Sets or retrieves a text alternative to the graphic.
              */
            alt: string;
            /**
              * Sets or retrieves the state of the check box or radio button.
              */
            defaultChecked: boolean;
            /**
              * Sets or retrieves how the object is aligned with adjacent text.
              */
            align: string;
            /**
              * Returns the value of the data at the cursor's current position.
              */
            value: string;
            /**
              * The address or URL of the a media resource that is to be considered.
              */
            src: string;
            /**
              * Sets or retrieves the name of the object.
              */
            name: string;
            /**
              * Sets or retrieves the URL, often with a bookmark extension (#name), to use as a client-side image map.
              */
            useMap: string;
            /**
              * Sets or retrieves the height of the object.
              */
            height: string;
            /**
              * Sets or retrieves the width of the border to draw around the object.
              */
            border: string;
            dynsrc: string;
            /**
              * Sets or retrieves the state of the check box or radio button.
              */
            checked: boolean;
            /**
              * Sets or retrieves the width of the border to draw around the object.
              */
            hspace: number;
            /**
              * Sets or retrieves the maximum number of characters that the user can enter in a text control.
              */
            maxLength: number;
            /**
              * Returns the content type of the object.
              */
            type: string;
            /**
              * Sets or retrieves the initial contents of the object.
              */
            defaultValue: string;
            /**
              * Retrieves whether the object is fully loaded.
              */
            complete: boolean;
            start: string;
            /**
              * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation messages without actually submitting.
              */
            validationMessage: string;
            /**
              * Returns a FileList object on a file type input object.
              */
            files: FileList;
            /**
              * Defines the maximum acceptable value for an input element with type="number".When used with the min and step attributes, lets you control the range and increment (such as only even numbers) that the user can enter into an input field.
              */
            max: string;
            /**
              * Overrides the target attribute on a form element.
              */
            formTarget: string;
            /**
              * Returns whether an element will successfully validate based on forms validation rules and constraints.
              */
            willValidate: boolean;
            /**
              * Defines an increment or jump between values that you want to allow the user to enter. When used with the max and min attributes, lets you control the range and increment (for example, allow only even numbers) that the user can enter into an input field.
              */
            step: string;
            /**
              * Provides a way to direct a user to a specific field when a document loads. This can provide both direction and convenience for a user, reducing the need to click or tab to a field when a page opens. This attribute is true when present on an element, and false when missing.
              */
            autofocus: boolean;
            /**
              * When present, marks an element that can't be submitted without a value.
              */
            required: boolean;
            /**
              * Used to override the encoding (formEnctype attribute) specified on the form element.
              */
            formEnctype: string;
            /**
              * Returns the input field value as a number.
              */
            valueAsNumber: number;
            /**
              * Gets or sets a text string that is displayed in an input field as a hint or prompt to users as the format or type of information they need to enter.The text appears in an input field until the user puts focus on the field.
              */
            placeholder: string;
            /**
              * Overrides the submit method attribute previously specified on a form element.
              */
            formMethod: string;
            /**
              * Specifies the ID of a pre-defined datalist of options for an input element.
              */
            list: HTMLElement;
            /**
              * Specifies whether autocomplete is applied to an editable text field.
              */
            autocomplete: string;
            /**
              * Defines the minimum acceptable value for an input element with type="number". When used with the max and step attributes, lets you control the range and increment (such as even numbers only) that the user can enter into an input field.
              */
            min: string;
            /**
              * Overrides the action attribute (where the data on a form is sent) on the parent form element.
              */
            formAction: string;
            /**
              * Gets or sets a string containing a regular expression that the user's input must match.
              */
            pattern: string;
            /**
              * Returns a  ValidityState object that represents the validity states of an element.
              */
            validity: ValidityState;
            /**
              * Overrides any validation or required attributes on a form or form elements to allow it to be submitted without validation. This can be used to create a "save draft"-type submit option.
              */
            formNoValidate: string;
            /**
              * Sets or retrieves the Boolean value indicating whether multiple items can be selected from a list.
              */
            multiple: boolean;
            /**
              * Creates a TextRange object for the element.
              */
            createTextRange(): TextRange;
            /**
              * Sets the start and end positions of a selection in a text field.
              * @param start The offset into the text field for the start of the selection.
              * @param end The offset into the text field for the end of the selection.
              */
            setSelectionRange(start: number, end: number): void;
            /**
              * Makes the selection equal to the current object.
              */
            select(): void;
            /**
              * Returns whether a form will validate when it is submitted, without having to submit it.
              */
            checkValidity(): boolean;
            /**
              * Decrements a range input control's value by the value given by the Step attribute. If the optional parameter is used, it will decrement the input control's step value multiplied by the parameter's value.
              * @param n Value to decrement the value by.
              */
            stepDown(n?: number): void;
            /**
              * Increments a range input control's value by the value given by the Step attribute. If the optional parameter is used, will increment the input control's value by that value.
              * @param n Value to increment the value by.
              */
            stepUp(n?: number): void;
            /**
              * Sets a custom error message that is displayed when a form is submitted.
              * @param error Sets a custom error message that is displayed when a form is submitted.
              */
            setCustomValidity(error: string): void;
        }
        declare var HTMLInputElement: {
            prototype: HTMLInputElement;
            new(): HTMLInputElement;
        }
        
        interface HTMLAnchorElement extends HTMLElement, MSDataBindingExtensions {
            /**
              * Sets or retrieves the relationship between the object and the destination of the link.
              */
            rel: string;
            /**
              * Contains the protocol of the URL.
              */
            protocol: string;
            /**
              * Sets or retrieves the substring of the href property that follows the question mark.
              */
            search: string;
            /**
              * Sets or retrieves the coordinates of the object.
              */
            coords: string;
            /**
              * Contains the hostname of a URL.
              */
            hostname: string;
            /**
              * Contains the pathname of the URL.
              */
            pathname: string;
            Methods: string;
            /**
              * Sets or retrieves the window or frame at which to target content.
              */
            target: string;
            protocolLong: string;
            /**
              * Sets or retrieves a destination URL or an anchor point.
              */
            href: string;
            /**
              * Sets or retrieves the shape of the object.
              */
            name: string;
            /**
              * Sets or retrieves the character set used to encode the object.
              */
            charset: string;
            /**
              * Sets or retrieves the language code of the object.
              */
            hreflang: string;
            /**
              * Sets or retrieves the port number associated with a URL.
              */
            port: string;
            /**
              * Contains the hostname and port values of the URL.
              */
            host: string;
            /**
              * Contains the anchor portion of the URL including the hash sign (#).
              */
            hash: string;
            nameProp: string;
            urn: string;
            /**
              * Sets or retrieves the relationship between the object and the destination of the link.
              */
            rev: string;
            /**
              * Sets or retrieves the shape of the object.
              */
            shape: string;
            type: string;
            mimeType: string;
            /**
              * Retrieves or sets the text of the object as a string. 
              */
            text: string;
            /** 
              * Returns a string representation of an object.
              */
            toString(): string;
        }
        declare var HTMLAnchorElement: {
            prototype: HTMLAnchorElement;
            new(): HTMLAnchorElement;
        }
        
        interface HTMLParamElement extends HTMLElement {
            /**
              * Sets or retrieves the value of an input parameter for an element.
              */
            value: string;
            /**
              * Sets or retrieves the name of an input parameter for an element.
              */
            name: string;
            /**
              * Sets or retrieves the content type of the resource designated by the value attribute.
              */
            type: string;
            /**
              * Sets or retrieves the data type of the value attribute.
              */
            valueType: string;
        }
        declare var HTMLParamElement: {
            prototype: HTMLParamElement;
            new(): HTMLParamElement;
        }
        
        interface SVGImageElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired, SVGURIReference {
            y: SVGAnimatedLength;
            width: SVGAnimatedLength;
            preserveAspectRatio: SVGAnimatedPreserveAspectRatio;
            x: SVGAnimatedLength;
            height: SVGAnimatedLength;
        }
        declare var SVGImageElement: {
            prototype: SVGImageElement;
            new(): SVGImageElement;
        }
        
        interface SVGAnimatedNumber {
            animVal: number;
            baseVal: number;
        }
        declare var SVGAnimatedNumber: {
            prototype: SVGAnimatedNumber;
            new(): SVGAnimatedNumber;
        }
        
        interface PerformanceTiming {
            redirectStart: number;
            domainLookupEnd: number;
            responseStart: number;
            domComplete: number;
            domainLookupStart: number;
            loadEventStart: number;
            msFirstPaint: number;
            unloadEventEnd: number;
            fetchStart: number;
            requestStart: number;
            domInteractive: number;
            navigationStart: number;
            connectEnd: number;
            loadEventEnd: number;
            connectStart: number;
            responseEnd: number;
            domLoading: number;
            redirectEnd: number;
            unloadEventStart: number;
            domContentLoadedEventStart: number;
            domContentLoadedEventEnd: number;
            toJSON(): any;
        }
        declare var PerformanceTiming: {
            prototype: PerformanceTiming;
            new(): PerformanceTiming;
        }
        
        interface HTMLPreElement extends HTMLElement, DOML2DeprecatedTextFlowControl {
            /**
              * Sets or gets a value that you can use to implement your own width functionality for the object.
              */
            width: number;
            /**
              * Indicates a citation by rendering text in italic type.
              */
            cite: string;
        }
        declare var HTMLPreElement: {
            prototype: HTMLPreElement;
            new(): HTMLPreElement;
        }
        
        interface EventException {
            code: number;
            message: string;
            name: string;
            toString(): string;
            DISPATCH_REQUEST_ERR: number;
            UNSPECIFIED_EVENT_TYPE_ERR: number;
        }
        declare var EventException: {
            prototype: EventException;
            new(): EventException;
            DISPATCH_REQUEST_ERR: number;
            UNSPECIFIED_EVENT_TYPE_ERR: number;
        }
        
        interface MSNavigatorDoNotTrack {
            msDoNotTrack: string;
            removeSiteSpecificTrackingException(args: ExceptionInformation): void;
            removeWebWideTrackingException(args: ExceptionInformation): void;
            storeWebWideTrackingException(args: StoreExceptionsInformation): void;
            storeSiteSpecificTrackingException(args: StoreSiteSpecificExceptionsInformation): void;
            confirmSiteSpecificTrackingException(args: ConfirmSiteSpecificExceptionsInformation): boolean;
            confirmWebWideTrackingException(args: ExceptionInformation): boolean;
        }
        
        interface NavigatorOnLine {
            onLine: boolean;
        }
        
        interface WindowLocalStorage {
            localStorage: Storage;
        }
        
        interface SVGMetadataElement extends SVGElement {
        }
        declare var SVGMetadataElement: {
            prototype: SVGMetadataElement;
            new(): SVGMetadataElement;
        }
        
        interface SVGPathSegArcRel extends SVGPathSeg {
            y: number;
            sweepFlag: boolean;
            r2: number;
            x: number;
            angle: number;
            r1: number;
            largeArcFlag: boolean;
        }
        declare var SVGPathSegArcRel: {
            prototype: SVGPathSegArcRel;
            new(): SVGPathSegArcRel;
        }
        
        interface SVGPathSegMovetoAbs extends SVGPathSeg {
            y: number;
            x: number;
        }
        declare var SVGPathSegMovetoAbs: {
            prototype: SVGPathSegMovetoAbs;
            new(): SVGPathSegMovetoAbs;
        }
        
        interface SVGStringList {
            numberOfItems: number;
            replaceItem(newItem: string, index: number): string;
            getItem(index: number): string;
            clear(): void;
            appendItem(newItem: string): string;
            initialize(newItem: string): string;
            removeItem(index: number): string;
            insertItemBefore(newItem: string, index: number): string;
        }
        declare var SVGStringList: {
            prototype: SVGStringList;
            new(): SVGStringList;
        }
        
        interface XDomainRequest {
            timeout: number;
            onerror: (ev: ErrorEvent) => any;
            onload: (ev: Event) => any;
            onprogress: (ev: ProgressEvent) => any;
            ontimeout: (ev: Event) => any;
            responseText: string;
            contentType: string;
            open(method: string, url: string): void;
            abort(): void;
            send(data?: any): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeout", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var XDomainRequest: {
            prototype: XDomainRequest;
            new(): XDomainRequest;
            create(): XDomainRequest;
        }
        
        interface DOML2DeprecatedBackgroundColorStyle {
            bgColor: any;
        }
        
        interface ElementTraversal {
            childElementCount: number;
            previousElementSibling: Element;
            lastElementChild: Element;
            nextElementSibling: Element;
            firstElementChild: Element;
        }
        
        interface SVGLength {
            valueAsString: string;
            valueInSpecifiedUnits: number;
            value: number;
            unitType: number;
            newValueSpecifiedUnits(unitType: number, valueInSpecifiedUnits: number): void;
            convertToSpecifiedUnits(unitType: number): void;
            SVG_LENGTHTYPE_NUMBER: number;
            SVG_LENGTHTYPE_CM: number;
            SVG_LENGTHTYPE_PC: number;
            SVG_LENGTHTYPE_PERCENTAGE: number;
            SVG_LENGTHTYPE_MM: number;
            SVG_LENGTHTYPE_PT: number;
            SVG_LENGTHTYPE_IN: number;
            SVG_LENGTHTYPE_EMS: number;
            SVG_LENGTHTYPE_PX: number;
            SVG_LENGTHTYPE_UNKNOWN: number;
            SVG_LENGTHTYPE_EXS: number;
        }
        declare var SVGLength: {
            prototype: SVGLength;
            new(): SVGLength;
            SVG_LENGTHTYPE_NUMBER: number;
            SVG_LENGTHTYPE_CM: number;
            SVG_LENGTHTYPE_PC: number;
            SVG_LENGTHTYPE_PERCENTAGE: number;
            SVG_LENGTHTYPE_MM: number;
            SVG_LENGTHTYPE_PT: number;
            SVG_LENGTHTYPE_IN: number;
            SVG_LENGTHTYPE_EMS: number;
            SVG_LENGTHTYPE_PX: number;
            SVG_LENGTHTYPE_UNKNOWN: number;
            SVG_LENGTHTYPE_EXS: number;
        }
        
        interface SVGPolygonElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGAnimatedPoints, SVGTests, SVGExternalResourcesRequired {
        }
        declare var SVGPolygonElement: {
            prototype: SVGPolygonElement;
            new(): SVGPolygonElement;
        }
        
        interface HTMLPhraseElement extends HTMLElement {
            /**
              * Sets or retrieves the date and time of a modification to the object.
              */
            dateTime: string;
            /**
              * Sets or retrieves reference information about the object.
              */
            cite: string;
        }
        declare var HTMLPhraseElement: {
            prototype: HTMLPhraseElement;
            new(): HTMLPhraseElement;
        }
        
        interface NavigatorStorageUtils {
        }
        
        interface SVGPathSegCurvetoCubicRel extends SVGPathSeg {
            y: number;
            y1: number;
            x2: number;
            x: number;
            x1: number;
            y2: number;
        }
        declare var SVGPathSegCurvetoCubicRel: {
            prototype: SVGPathSegCurvetoCubicRel;
            new(): SVGPathSegCurvetoCubicRel;
        }
        
        interface SVGTextContentElement extends SVGElement, SVGStylable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
            textLength: SVGAnimatedLength;
            lengthAdjust: SVGAnimatedEnumeration;
            getCharNumAtPosition(point: SVGPoint): number;
            getStartPositionOfChar(charnum: number): SVGPoint;
            getExtentOfChar(charnum: number): SVGRect;
            getComputedTextLength(): number;
            getSubStringLength(charnum: number, nchars: number): number;
            selectSubString(charnum: number, nchars: number): void;
            getNumberOfChars(): number;
            getRotationOfChar(charnum: number): number;
            getEndPositionOfChar(charnum: number): SVGPoint;
            LENGTHADJUST_SPACING: number;
            LENGTHADJUST_SPACINGANDGLYPHS: number;
            LENGTHADJUST_UNKNOWN: number;
        }
        declare var SVGTextContentElement: {
            prototype: SVGTextContentElement;
            new(): SVGTextContentElement;
            LENGTHADJUST_SPACING: number;
            LENGTHADJUST_SPACINGANDGLYPHS: number;
            LENGTHADJUST_UNKNOWN: number;
        }
        
        interface DOML2DeprecatedColorProperty {
            color: string;
        }
        
        interface Location {
            hash: string;
            protocol: string;
            search: string;
            href: string;
            hostname: string;
            port: string;
            pathname: string;
            host: string;
            reload(flag?: boolean): void;
            replace(url: string): void;
            assign(url: string): void;
            toString(): string;
        }
        declare var Location: {
            prototype: Location;
            new(): Location;
        }
        
        interface HTMLTitleElement extends HTMLElement {
            /**
              * Retrieves or sets the text of the object as a string. 
              */
            text: string;
        }
        declare var HTMLTitleElement: {
            prototype: HTMLTitleElement;
            new(): HTMLTitleElement;
        }
        
        interface HTMLStyleElement extends HTMLElement, LinkStyle {
            /**
              * Sets or retrieves the media type.
              */
            media: string;
            /**
              * Retrieves the CSS language in which the style sheet is written.
              */
            type: string;
        }
        declare var HTMLStyleElement: {
            prototype: HTMLStyleElement;
            new(): HTMLStyleElement;
        }
        
        interface PerformanceEntry {
            name: string;
            startTime: number;
            duration: number;
            entryType: string;
        }
        declare var PerformanceEntry: {
            prototype: PerformanceEntry;
            new(): PerformanceEntry;
        }
        
        interface SVGTransform {
            type: number;
            angle: number;
            matrix: SVGMatrix;
            setTranslate(tx: number, ty: number): void;
            setScale(sx: number, sy: number): void;
            setMatrix(matrix: SVGMatrix): void;
            setSkewY(angle: number): void;
            setRotate(angle: number, cx: number, cy: number): void;
            setSkewX(angle: number): void;
            SVG_TRANSFORM_SKEWX: number;
            SVG_TRANSFORM_UNKNOWN: number;
            SVG_TRANSFORM_SCALE: number;
            SVG_TRANSFORM_TRANSLATE: number;
            SVG_TRANSFORM_MATRIX: number;
            SVG_TRANSFORM_ROTATE: number;
            SVG_TRANSFORM_SKEWY: number;
        }
        declare var SVGTransform: {
            prototype: SVGTransform;
            new(): SVGTransform;
            SVG_TRANSFORM_SKEWX: number;
            SVG_TRANSFORM_UNKNOWN: number;
            SVG_TRANSFORM_SCALE: number;
            SVG_TRANSFORM_TRANSLATE: number;
            SVG_TRANSFORM_MATRIX: number;
            SVG_TRANSFORM_ROTATE: number;
            SVG_TRANSFORM_SKEWY: number;
        }
        
        interface UIEvent extends Event {
            detail: number;
            view: Window;
            initUIEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number): void;
        }
        declare var UIEvent: {
            prototype: UIEvent;
            new(): UIEvent;
        }
        
        interface SVGURIReference {
            href: SVGAnimatedString;
        }
        
        interface SVGPathSeg {
            pathSegType: number;
            pathSegTypeAsLetter: string;
            PATHSEG_MOVETO_REL: number;
            PATHSEG_LINETO_VERTICAL_REL: number;
            PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: number;
            PATHSEG_CURVETO_QUADRATIC_REL: number;
            PATHSEG_CURVETO_CUBIC_ABS: number;
            PATHSEG_LINETO_HORIZONTAL_ABS: number;
            PATHSEG_CURVETO_QUADRATIC_ABS: number;
            PATHSEG_LINETO_ABS: number;
            PATHSEG_CLOSEPATH: number;
            PATHSEG_LINETO_HORIZONTAL_REL: number;
            PATHSEG_CURVETO_CUBIC_SMOOTH_REL: number;
            PATHSEG_LINETO_REL: number;
            PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: number;
            PATHSEG_ARC_REL: number;
            PATHSEG_CURVETO_CUBIC_REL: number;
            PATHSEG_UNKNOWN: number;
            PATHSEG_LINETO_VERTICAL_ABS: number;
            PATHSEG_ARC_ABS: number;
            PATHSEG_MOVETO_ABS: number;
            PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: number;
        }
        declare var SVGPathSeg: {
            prototype: SVGPathSeg;
            new(): SVGPathSeg;
            PATHSEG_MOVETO_REL: number;
            PATHSEG_LINETO_VERTICAL_REL: number;
            PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: number;
            PATHSEG_CURVETO_QUADRATIC_REL: number;
            PATHSEG_CURVETO_CUBIC_ABS: number;
            PATHSEG_LINETO_HORIZONTAL_ABS: number;
            PATHSEG_CURVETO_QUADRATIC_ABS: number;
            PATHSEG_LINETO_ABS: number;
            PATHSEG_CLOSEPATH: number;
            PATHSEG_LINETO_HORIZONTAL_REL: number;
            PATHSEG_CURVETO_CUBIC_SMOOTH_REL: number;
            PATHSEG_LINETO_REL: number;
            PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: number;
            PATHSEG_ARC_REL: number;
            PATHSEG_CURVETO_CUBIC_REL: number;
            PATHSEG_UNKNOWN: number;
            PATHSEG_LINETO_VERTICAL_ABS: number;
            PATHSEG_ARC_ABS: number;
            PATHSEG_MOVETO_ABS: number;
            PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: number;
        }
        
        interface WheelEvent extends MouseEvent {
            deltaZ: number;
            deltaX: number;
            deltaMode: number;
            deltaY: number;
            initWheelEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, buttonArg: number, relatedTargetArg: EventTarget, modifiersListArg: string, deltaXArg: number, deltaYArg: number, deltaZArg: number, deltaMode: number): void;
            getCurrentPoint(element: Element): void;
            DOM_DELTA_PIXEL: number;
            DOM_DELTA_LINE: number;
            DOM_DELTA_PAGE: number;
        }
        declare var WheelEvent: {
            prototype: WheelEvent;
            new(): WheelEvent;
            DOM_DELTA_PIXEL: number;
            DOM_DELTA_LINE: number;
            DOM_DELTA_PAGE: number;
        }
        
        interface MSEventAttachmentTarget {
            attachEvent(event: string, listener: EventListener): boolean;
            detachEvent(event: string, listener: EventListener): void;
        }
        
        interface SVGNumber {
            value: number;
        }
        declare var SVGNumber: {
            prototype: SVGNumber;
            new(): SVGNumber;
        }
        
        interface SVGPathElement extends SVGElement, SVGStylable, SVGAnimatedPathData, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
            getPathSegAtLength(distance: number): number;
            getPointAtLength(distance: number): SVGPoint;
            createSVGPathSegCurvetoQuadraticAbs(x: number, y: number, x1: number, y1: number): SVGPathSegCurvetoQuadraticAbs;
            createSVGPathSegLinetoRel(x: number, y: number): SVGPathSegLinetoRel;
            createSVGPathSegCurvetoQuadraticRel(x: number, y: number, x1: number, y1: number): SVGPathSegCurvetoQuadraticRel;
            createSVGPathSegCurvetoCubicAbs(x: number, y: number, x1: number, y1: number, x2: number, y2: number): SVGPathSegCurvetoCubicAbs;
            createSVGPathSegLinetoAbs(x: number, y: number): SVGPathSegLinetoAbs;
            createSVGPathSegClosePath(): SVGPathSegClosePath;
            createSVGPathSegCurvetoCubicRel(x: number, y: number, x1: number, y1: number, x2: number, y2: number): SVGPathSegCurvetoCubicRel;
            createSVGPathSegCurvetoQuadraticSmoothRel(x: number, y: number): SVGPathSegCurvetoQuadraticSmoothRel;
            createSVGPathSegMovetoRel(x: number, y: number): SVGPathSegMovetoRel;
            createSVGPathSegCurvetoCubicSmoothAbs(x: number, y: number, x2: number, y2: number): SVGPathSegCurvetoCubicSmoothAbs;
            createSVGPathSegMovetoAbs(x: number, y: number): SVGPathSegMovetoAbs;
            createSVGPathSegLinetoVerticalRel(y: number): SVGPathSegLinetoVerticalRel;
            createSVGPathSegArcRel(x: number, y: number, r1: number, r2: number, angle: number, largeArcFlag: boolean, sweepFlag: boolean): SVGPathSegArcRel;
            createSVGPathSegCurvetoQuadraticSmoothAbs(x: number, y: number): SVGPathSegCurvetoQuadraticSmoothAbs;
            createSVGPathSegLinetoHorizontalRel(x: number): SVGPathSegLinetoHorizontalRel;
            getTotalLength(): number;
            createSVGPathSegCurvetoCubicSmoothRel(x: number, y: number, x2: number, y2: number): SVGPathSegCurvetoCubicSmoothRel;
            createSVGPathSegLinetoHorizontalAbs(x: number): SVGPathSegLinetoHorizontalAbs;
            createSVGPathSegLinetoVerticalAbs(y: number): SVGPathSegLinetoVerticalAbs;
            createSVGPathSegArcAbs(x: number, y: number, r1: number, r2: number, angle: number, largeArcFlag: boolean, sweepFlag: boolean): SVGPathSegArcAbs;
        }
        declare var SVGPathElement: {
            prototype: SVGPathElement;
            new(): SVGPathElement;
        }
        
        interface MSCompatibleInfo {
            version: string;
            userAgent: string;
        }
        declare var MSCompatibleInfo: {
            prototype: MSCompatibleInfo;
            new(): MSCompatibleInfo;
        }
        
        interface Text extends CharacterData, MSNodeExtensions {
            wholeText: string;
            splitText(offset: number): Text;
            replaceWholeText(content: string): Text;
        }
        declare var Text: {
            prototype: Text;
            new(): Text;
        }
        
        interface SVGAnimatedRect {
            animVal: SVGRect;
            baseVal: SVGRect;
        }
        declare var SVGAnimatedRect: {
            prototype: SVGAnimatedRect;
            new(): SVGAnimatedRect;
        }
        
        interface CSSNamespaceRule extends CSSRule {
            namespaceURI: string;
            prefix: string;
        }
        declare var CSSNamespaceRule: {
            prototype: CSSNamespaceRule;
            new(): CSSNamespaceRule;
        }
        
        interface SVGPathSegList {
            numberOfItems: number;
            replaceItem(newItem: SVGPathSeg, index: number): SVGPathSeg;
            getItem(index: number): SVGPathSeg;
            clear(): void;
            appendItem(newItem: SVGPathSeg): SVGPathSeg;
            initialize(newItem: SVGPathSeg): SVGPathSeg;
            removeItem(index: number): SVGPathSeg;
            insertItemBefore(newItem: SVGPathSeg, index: number): SVGPathSeg;
        }
        declare var SVGPathSegList: {
            prototype: SVGPathSegList;
            new(): SVGPathSegList;
        }
        
        interface HTMLUnknownElement extends HTMLElement, MSDataBindingRecordSetReadonlyExtensions {
        }
        declare var HTMLUnknownElement: {
            prototype: HTMLUnknownElement;
            new(): HTMLUnknownElement;
        }
        
        interface HTMLAudioElement extends HTMLMediaElement {
        }
        declare var HTMLAudioElement: {
            prototype: HTMLAudioElement;
            new(): HTMLAudioElement;
        }
        
        interface MSImageResourceExtensions {
            dynsrc: string;
            vrml: string;
            lowsrc: string;
            start: string;
            loop: number;
        }
        
        interface PositionError {
            code: number;
            message: string;
            toString(): string;
            POSITION_UNAVAILABLE: number;
            PERMISSION_DENIED: number;
            TIMEOUT: number;
        }
        declare var PositionError: {
            prototype: PositionError;
            new(): PositionError;
            POSITION_UNAVAILABLE: number;
            PERMISSION_DENIED: number;
            TIMEOUT: number;
        }
        
        interface HTMLTableCellElement extends HTMLElement, HTMLTableAlignment, DOML2DeprecatedBackgroundStyle, DOML2DeprecatedBackgroundColorStyle {
            /**
              * Sets or retrieves the width of the object.
              */
            width: number;
            /**
              * Sets or retrieves a list of header cells that provide information for the object.
              */
            headers: string;
            /**
              * Retrieves the position of the object in the cells collection of a row.
              */
            cellIndex: number;
            /**
              * Sets or retrieves how the object is aligned with adjacent text.
              */
            align: string;
            /**
              * Sets or retrieves the color for one of the two colors used to draw the 3-D border of the object.
              */
            borderColorLight: any;
            /**
              * Sets or retrieves the number columns in the table that the object should span.
              */
            colSpan: number;
            /**
              * Sets or retrieves the border color of the object. 
              */
            borderColor: any;
            /**
              * Sets or retrieves a comma-delimited list of conceptual categories associated with the object.
              */
            axis: string;
            /**
              * Sets or retrieves the height of the object.
              */
            height: any;
            /**
              * Sets or retrieves whether the browser automatically performs wordwrap.
              */
            noWrap: boolean;
            /**
              * Sets or retrieves abbreviated text for the object.
              */
            abbr: string;
            /**
              * Sets or retrieves how many rows in a table the cell should span.
              */
            rowSpan: number;
            /**
              * Sets or retrieves the group of cells in a table to which the object's information applies.
              */
            scope: string;
            /**
              * Sets or retrieves the color for one of the two colors used to draw the 3-D border of the object.
              */
            borderColorDark: any;
        }
        declare var HTMLTableCellElement: {
            prototype: HTMLTableCellElement;
            new(): HTMLTableCellElement;
        }
        
        interface SVGElementInstance extends EventTarget {
            previousSibling: SVGElementInstance;
            parentNode: SVGElementInstance;
            lastChild: SVGElementInstance;
            nextSibling: SVGElementInstance;
            childNodes: SVGElementInstanceList;
            correspondingUseElement: SVGUseElement;
            correspondingElement: SVGElement;
            firstChild: SVGElementInstance;
        }
        declare var SVGElementInstance: {
            prototype: SVGElementInstance;
            new(): SVGElementInstance;
        }
        
        interface MSNamespaceInfoCollection {
            length: number;
            add(namespace?: string, urn?: string, implementationUrl?: any): any;
            item(index: any): any;
            // [index: any]: any;
        }
        declare var MSNamespaceInfoCollection: {
            prototype: MSNamespaceInfoCollection;
            new(): MSNamespaceInfoCollection;
        }
        
        interface SVGCircleElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
            cx: SVGAnimatedLength;
            r: SVGAnimatedLength;
            cy: SVGAnimatedLength;
        }
        declare var SVGCircleElement: {
            prototype: SVGCircleElement;
            new(): SVGCircleElement;
        }
        
        interface StyleSheetList {
            length: number;
            item(index?: number): StyleSheet;
            [index: number]: StyleSheet;
        }
        declare var StyleSheetList: {
            prototype: StyleSheetList;
            new(): StyleSheetList;
        }
        
        interface CSSImportRule extends CSSRule {
            styleSheet: CSSStyleSheet;
            href: string;
            media: MediaList;
        }
        declare var CSSImportRule: {
            prototype: CSSImportRule;
            new(): CSSImportRule;
        }
        
        interface CustomEvent extends Event {
            detail: any;
            initCustomEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, detailArg: any): void;
        }
        declare var CustomEvent: {
            prototype: CustomEvent;
            new(): CustomEvent;
        }
        
        interface HTMLBaseFontElement extends HTMLElement, DOML2DeprecatedColorProperty {
            /**
              * Sets or retrieves the current typeface family.
              */
            face: string;
            /**
              * Sets or retrieves the font size of the object.
              */
            size: number;
        }
        declare var HTMLBaseFontElement: {
            prototype: HTMLBaseFontElement;
            new(): HTMLBaseFontElement;
        }
        
        interface HTMLTextAreaElement extends HTMLElement, MSDataBindingExtensions {
            /**
              * Retrieves or sets the text in the entry field of the textArea element.
              */
            value: string;
            /**
              * Sets or retrieves the value indicating whether the control is selected.
              */
            status: any;
            /**
              * Retrieves a reference to the form that the object is embedded in.
              */
            form: HTMLFormElement;
            /**
              * Sets or retrieves the name of the object.
              */
            name: string;
            /**
              * Gets or sets the starting position or offset of a text selection.
              */
            selectionStart: number;
            /**
              * Sets or retrieves the number of horizontal rows contained in the object.
              */
            rows: number;
            /**
              * Sets or retrieves the width of the object.
              */
            cols: number;
            /**
              * Sets or retrieves the value indicated whether the content of the object is read-only.
              */
            readOnly: boolean;
            /**
              * Sets or retrieves how to handle wordwrapping in the object.
              */
            wrap: string;
            /**
              * Gets or sets the end position or offset of a text selection.
              */
            selectionEnd: number;
            /**
              * Retrieves the type of control.
              */
            type: string;
            /**
              * Sets or retrieves the initial contents of the object.
              */
            defaultValue: string;
            /**
              * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation messages without actually submitting.
              */
            validationMessage: string;
            /**
              * Provides a way to direct a user to a specific field when a document loads. This can provide both direction and convenience for a user, reducing the need to click or tab to a field when a page opens. This attribute is true when present on an element, and false when missing.
              */
            autofocus: boolean;
            /**
              * Returns a  ValidityState object that represents the validity states of an element.
              */
            validity: ValidityState;
            /**
              * When present, marks an element that can't be submitted without a value.
              */
            required: boolean;
            /**
              * Sets or retrieves the maximum number of characters that the user can enter in a text control.
              */
            maxLength: number;
            /**
              * Returns whether an element will successfully validate based on forms validation rules and constraints.
              */
            willValidate: boolean;
            /**
              * Gets or sets a text string that is displayed in an input field as a hint or prompt to users as the format or type of information they need to enter.The text appears in an input field until the user puts focus on the field.
              */
            placeholder: string;
            /**
              * Creates a TextRange object for the element.
              */
            createTextRange(): TextRange;
            /**
              * Sets the start and end positions of a selection in a text field.
              * @param start The offset into the text field for the start of the selection.
              * @param end The offset into the text field for the end of the selection.
              */
            setSelectionRange(start: number, end: number): void;
            /**
              * Highlights the input area of a form element.
              */
            select(): void;
            /**
              * Returns whether a form will validate when it is submitted, without having to submit it.
              */
            checkValidity(): boolean;
            /**
              * Sets a custom error message that is displayed when a form is submitted.
              * @param error Sets a custom error message that is displayed when a form is submitted.
              */
            setCustomValidity(error: string): void;
        }
        declare var HTMLTextAreaElement: {
            prototype: HTMLTextAreaElement;
            new(): HTMLTextAreaElement;
        }
        
        interface Geolocation {
            clearWatch(watchId: number): void;
            getCurrentPosition(successCallback: PositionCallback, errorCallback?: PositionErrorCallback, options?: PositionOptions): void;
            watchPosition(successCallback: PositionCallback, errorCallback?: PositionErrorCallback, options?: PositionOptions): number;
        }
        declare var Geolocation: {
            prototype: Geolocation;
            new(): Geolocation;
        }
        
        interface DOML2DeprecatedMarginStyle {
            vspace: number;
            hspace: number;
        }
        
        interface MSWindowModeless {
            dialogTop: any;
            dialogLeft: any;
            dialogWidth: any;
            dialogHeight: any;
            menuArguments: any;
        }
        
        interface DOML2DeprecatedAlignmentStyle {
            align: string;
        }
        
        interface HTMLMarqueeElement extends HTMLElement, MSDataBindingExtensions, DOML2DeprecatedBackgroundColorStyle {
            width: string;
            onbounce: (ev: Event) => any;
            vspace: number;
            trueSpeed: boolean;
            scrollAmount: number;
            scrollDelay: number;
            behavior: string;
            height: string;
            loop: number;
            direction: string;
            hspace: number;
            onstart: (ev: Event) => any;
            onfinish: (ev: Event) => any;
            stop(): void;
            start(): void;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "move", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "deactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetchanged", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsdelete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "losecapture", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "controlselect", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "layoutcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "filterchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "errorupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "cellchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowexit", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsinserted", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "propertychange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforepaste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecopy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "paste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "moveend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeeditfocus", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "afterupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizeend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dataavailable", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforedeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "activate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "movestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "selectstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "cut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "copy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "rowenter", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mscontentzoom", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "cuechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "msmanipulationstatechanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "bounce", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "start", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "finish", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var HTMLMarqueeElement: {
            prototype: HTMLMarqueeElement;
            new(): HTMLMarqueeElement;
        }
        
        interface SVGRect {
            y: number;
            width: number;
            x: number;
            height: number;
        }
        declare var SVGRect: {
            prototype: SVGRect;
            new(): SVGRect;
        }
        
        interface MSNodeExtensions {
            swapNode(otherNode: Node): Node;
            removeNode(deep?: boolean): Node;
            replaceNode(replacement: Node): Node;
        }
        
        interface History {
            length: number;
            state: any;
            back(distance?: any): void;
            forward(distance?: any): void;
            go(delta?: any): void;
            replaceState(statedata: any, title: string, url?: string): void;
            pushState(statedata: any, title: string, url?: string): void;
        }
        declare var History: {
            prototype: History;
            new(): History;
        }
        
        interface SVGPathSegCurvetoCubicAbs extends SVGPathSeg {
            y: number;
            y1: number;
            x2: number;
            x: number;
            x1: number;
            y2: number;
        }
        declare var SVGPathSegCurvetoCubicAbs: {
            prototype: SVGPathSegCurvetoCubicAbs;
            new(): SVGPathSegCurvetoCubicAbs;
        }
        
        interface SVGPathSegCurvetoQuadraticAbs extends SVGPathSeg {
            y: number;
            y1: number;
            x: number;
            x1: number;
        }
        declare var SVGPathSegCurvetoQuadraticAbs: {
            prototype: SVGPathSegCurvetoQuadraticAbs;
            new(): SVGPathSegCurvetoQuadraticAbs;
        }
        
        interface TimeRanges {
            length: number;
            start(index: number): number;
            end(index: number): number;
        }
        declare var TimeRanges: {
            prototype: TimeRanges;
            new(): TimeRanges;
        }
        
        interface CSSRule {
            cssText: string;
            parentStyleSheet: CSSStyleSheet;
            parentRule: CSSRule;
            type: number;
            IMPORT_RULE: number;
            MEDIA_RULE: number;
            STYLE_RULE: number;
            NAMESPACE_RULE: number;
            PAGE_RULE: number;
            UNKNOWN_RULE: number;
            FONT_FACE_RULE: number;
            CHARSET_RULE: number;
            KEYFRAMES_RULE: number;
            KEYFRAME_RULE: number;
            VIEWPORT_RULE: number;
        }
        declare var CSSRule: {
            prototype: CSSRule;
            new(): CSSRule;
            IMPORT_RULE: number;
            MEDIA_RULE: number;
            STYLE_RULE: number;
            NAMESPACE_RULE: number;
            PAGE_RULE: number;
            UNKNOWN_RULE: number;
            FONT_FACE_RULE: number;
            CHARSET_RULE: number;
            KEYFRAMES_RULE: number;
            KEYFRAME_RULE: number;
            VIEWPORT_RULE: number;
        }
        
        interface SVGPathSegLinetoAbs extends SVGPathSeg {
            y: number;
            x: number;
        }
        declare var SVGPathSegLinetoAbs: {
            prototype: SVGPathSegLinetoAbs;
            new(): SVGPathSegLinetoAbs;
        }
        
        interface HTMLModElement extends HTMLElement {
            /**
              * Sets or retrieves the date and time of a modification to the object.
              */
            dateTime: string;
            /**
              * Sets or retrieves reference information about the object.
              */
            cite: string;
        }
        declare var HTMLModElement: {
            prototype: HTMLModElement;
            new(): HTMLModElement;
        }
        
        interface SVGMatrix {
            e: number;
            c: number;
            a: number;
            b: number;
            d: number;
            f: number;
            multiply(secondMatrix: SVGMatrix): SVGMatrix;
            flipY(): SVGMatrix;
            skewY(angle: number): SVGMatrix;
            inverse(): SVGMatrix;
            scaleNonUniform(scaleFactorX: number, scaleFactorY: number): SVGMatrix;
            rotate(angle: number): SVGMatrix;
            flipX(): SVGMatrix;
            translate(x: number, y: number): SVGMatrix;
            scale(scaleFactor: number): SVGMatrix;
            rotateFromVector(x: number, y: number): SVGMatrix;
            skewX(angle: number): SVGMatrix;
        }
        declare var SVGMatrix: {
            prototype: SVGMatrix;
            new(): SVGMatrix;
        }
        
        interface MSPopupWindow {
            document: Document;
            isOpen: boolean;
            show(x: number, y: number, w: number, h: number, element?: any): void;
            hide(): void;
        }
        declare var MSPopupWindow: {
            prototype: MSPopupWindow;
            new(): MSPopupWindow;
        }
        
        interface BeforeUnloadEvent extends Event {
            returnValue: string;
        }
        declare var BeforeUnloadEvent: {
            prototype: BeforeUnloadEvent;
            new(): BeforeUnloadEvent;
        }
        
        interface SVGUseElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired, SVGURIReference {
            y: SVGAnimatedLength;
            width: SVGAnimatedLength;
            animatedInstanceRoot: SVGElementInstance;
            instanceRoot: SVGElementInstance;
            x: SVGAnimatedLength;
            height: SVGAnimatedLength;
        }
        declare var SVGUseElement: {
            prototype: SVGUseElement;
            new(): SVGUseElement;
        }
        
        interface Event {
            timeStamp: number;
            defaultPrevented: boolean;
            isTrusted: boolean;
            currentTarget: EventTarget;
            cancelBubble: boolean;
            target: EventTarget;
            eventPhase: number;
            cancelable: boolean;
            type: string;
            srcElement: Element;
            bubbles: boolean;
            initEvent(eventTypeArg: string, canBubbleArg: boolean, cancelableArg: boolean): void;
            stopPropagation(): void;
            stopImmediatePropagation(): void;
            preventDefault(): void;
            CAPTURING_PHASE: number;
            AT_TARGET: number;
            BUBBLING_PHASE: number;
        }
        declare var Event: {
            prototype: Event;
            new(): Event;
            CAPTURING_PHASE: number;
            AT_TARGET: number;
            BUBBLING_PHASE: number;
        }
        
        interface ImageData {
            width: number;
            data: number[];
            height: number;
        }
        declare var ImageData: {
            prototype: ImageData;
            new(): ImageData;
        }
        
        interface HTMLTableColElement extends HTMLElement, HTMLTableAlignment {
            /**
              * Sets or retrieves the width of the object.
              */
            width: any;
            /**
              * Sets or retrieves the alignment of the object relative to the display or table.
              */
            align: string;
            /**
              * Sets or retrieves the number of columns in the group.
              */
            span: number;
        }
        declare var HTMLTableColElement: {
            prototype: HTMLTableColElement;
            new(): HTMLTableColElement;
        }
        
        interface SVGException {
            code: number;
            message: string;
            name: string;
            toString(): string;
            SVG_MATRIX_NOT_INVERTABLE: number;
            SVG_WRONG_TYPE_ERR: number;
            SVG_INVALID_VALUE_ERR: number;
        }
        declare var SVGException: {
            prototype: SVGException;
            new(): SVGException;
            SVG_MATRIX_NOT_INVERTABLE: number;
            SVG_WRONG_TYPE_ERR: number;
            SVG_INVALID_VALUE_ERR: number;
        }
        
        interface SVGLinearGradientElement extends SVGGradientElement {
            y1: SVGAnimatedLength;
            x2: SVGAnimatedLength;
            x1: SVGAnimatedLength;
            y2: SVGAnimatedLength;
        }
        declare var SVGLinearGradientElement: {
            prototype: SVGLinearGradientElement;
            new(): SVGLinearGradientElement;
        }
        
        interface HTMLTableAlignment {
            /**
              * Sets or retrieves a value that you can use to implement your own ch functionality for the object.
              */
            ch: string;
            /**
              * Sets or retrieves how text and other content are vertically aligned within the object that contains them.
              */
            vAlign: string;
            /**
              * Sets or retrieves a value that you can use to implement your own chOff functionality for the object.
              */
            chOff: string;
        }
        
        interface SVGAnimatedEnumeration {
            animVal: number;
            baseVal: number;
        }
        declare var SVGAnimatedEnumeration: {
            prototype: SVGAnimatedEnumeration;
            new(): SVGAnimatedEnumeration;
        }
        
        interface DOML2DeprecatedSizeProperty {
            size: number;
        }
        
        interface HTMLUListElement extends HTMLElement, DOML2DeprecatedListSpaceReduction, DOML2DeprecatedListNumberingAndBulletStyle {
        }
        declare var HTMLUListElement: {
            prototype: HTMLUListElement;
            new(): HTMLUListElement;
        }
        
        interface SVGRectElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
            y: SVGAnimatedLength;
            width: SVGAnimatedLength;
            ry: SVGAnimatedLength;
            rx: SVGAnimatedLength;
            x: SVGAnimatedLength;
            height: SVGAnimatedLength;
        }
        declare var SVGRectElement: {
            prototype: SVGRectElement;
            new(): SVGRectElement;
        }
        
        interface ErrorEventHandler {
            (event: Event, source: string, fileno: number, columnNumber: number): void;
        }
        
        interface HTMLDivElement extends HTMLElement, MSDataBindingExtensions {
            /**
              * Sets or retrieves how the object is aligned with adjacent text. 
              */
            align: string;
            /**
              * Sets or retrieves whether the browser automatically performs wordwrap.
              */
            noWrap: boolean;
        }
        declare var HTMLDivElement: {
            prototype: HTMLDivElement;
            new(): HTMLDivElement;
        }
        
        interface DOML2DeprecatedBorderStyle {
            border: string;
        }
        
        interface NamedNodeMap {
            length: number;
            removeNamedItemNS(namespaceURI: string, localName: string): Attr;
            item(index: number): Attr;
            [index: number]: Attr;
            removeNamedItem(name: string): Attr;
            getNamedItem(name: string): Attr;
            // [name: string]: Attr;
            setNamedItem(arg: Attr): Attr;
            getNamedItemNS(namespaceURI: string, localName: string): Attr;
            setNamedItemNS(arg: Attr): Attr;
        }
        declare var NamedNodeMap: {
            prototype: NamedNodeMap;
            new(): NamedNodeMap;
        }
        
        interface MediaList {
            length: number;
            mediaText: string;
            deleteMedium(oldMedium: string): void;
            appendMedium(newMedium: string): void;
            item(index: number): string;
            [index: number]: string;
            toString(): string;
        }
        declare var MediaList: {
            prototype: MediaList;
            new(): MediaList;
        }
        
        interface SVGPathSegCurvetoQuadraticSmoothAbs extends SVGPathSeg {
            y: number;
            x: number;
        }
        declare var SVGPathSegCurvetoQuadraticSmoothAbs: {
            prototype: SVGPathSegCurvetoQuadraticSmoothAbs;
            new(): SVGPathSegCurvetoQuadraticSmoothAbs;
        }
        
        interface SVGPathSegCurvetoCubicSmoothRel extends SVGPathSeg {
            y: number;
            x2: number;
            x: number;
            y2: number;
        }
        declare var SVGPathSegCurvetoCubicSmoothRel: {
            prototype: SVGPathSegCurvetoCubicSmoothRel;
            new(): SVGPathSegCurvetoCubicSmoothRel;
        }
        
        interface SVGLengthList {
            numberOfItems: number;
            replaceItem(newItem: SVGLength, index: number): SVGLength;
            getItem(index: number): SVGLength;
            clear(): void;
            appendItem(newItem: SVGLength): SVGLength;
            initialize(newItem: SVGLength): SVGLength;
            removeItem(index: number): SVGLength;
            insertItemBefore(newItem: SVGLength, index: number): SVGLength;
        }
        declare var SVGLengthList: {
            prototype: SVGLengthList;
            new(): SVGLengthList;
        }
        
        interface ProcessingInstruction extends Node {
            target: string;
            data: string;
        }
        declare var ProcessingInstruction: {
            prototype: ProcessingInstruction;
            new(): ProcessingInstruction;
        }
        
        interface MSWindowExtensions {
            status: string;
            onmouseleave: (ev: MouseEvent) => any;
            screenLeft: number;
            offscreenBuffering: any;
            maxConnectionsPerServer: number;
            onmouseenter: (ev: MouseEvent) => any;
            clipboardData: DataTransfer;
            defaultStatus: string;
            clientInformation: Navigator;
            closed: boolean;
            onhelp: (ev: Event) => any;
            external: External;
            event: MSEventObj;
            onfocusout: (ev: FocusEvent) => any;
            screenTop: number;
            onfocusin: (ev: FocusEvent) => any;
            showModelessDialog(url?: string, argument?: any, options?: any): Window;
            navigate(url: string): void;
            resizeBy(x?: number, y?: number): void;
            item(index: any): any;
            resizeTo(x?: number, y?: number): void;
            createPopup(arguments?: any): MSPopupWindow;
            toStaticHTML(html: string): string;
            execScript(code: string, language?: string): any;
            msWriteProfilerMark(profilerMarkName: string): void;
            moveTo(x?: number, y?: number): void;
            moveBy(x?: number, y?: number): void;
            showHelp(url: string, helpArg?: any, features?: string): void;
            captureEvents(): void;
            releaseEvents(): void;
            addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        
        interface MSBehaviorUrnsCollection {
            length: number;
            item(index: number): string;
        }
        declare var MSBehaviorUrnsCollection: {
            prototype: MSBehaviorUrnsCollection;
            new(): MSBehaviorUrnsCollection;
        }
        
        interface CSSFontFaceRule extends CSSRule {
            style: CSSStyleDeclaration;
        }
        declare var CSSFontFaceRule: {
            prototype: CSSFontFaceRule;
            new(): CSSFontFaceRule;
        }
        
        interface DOML2DeprecatedBackgroundStyle {
            background: string;
        }
        
        interface TextEvent extends UIEvent {
            inputMethod: number;
            data: string;
            locale: string;
            initTextEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, dataArg: string, inputMethod: number, locale: string): void;
            DOM_INPUT_METHOD_KEYBOARD: number;
            DOM_INPUT_METHOD_DROP: number;
            DOM_INPUT_METHOD_IME: number;
            DOM_INPUT_METHOD_SCRIPT: number;
            DOM_INPUT_METHOD_VOICE: number;
            DOM_INPUT_METHOD_UNKNOWN: number;
            DOM_INPUT_METHOD_PASTE: number;
            DOM_INPUT_METHOD_HANDWRITING: number;
            DOM_INPUT_METHOD_OPTION: number;
            DOM_INPUT_METHOD_MULTIMODAL: number;
        }
        declare var TextEvent: {
            prototype: TextEvent;
            new(): TextEvent;
            DOM_INPUT_METHOD_KEYBOARD: number;
            DOM_INPUT_METHOD_DROP: number;
            DOM_INPUT_METHOD_IME: number;
            DOM_INPUT_METHOD_SCRIPT: number;
            DOM_INPUT_METHOD_VOICE: number;
            DOM_INPUT_METHOD_UNKNOWN: number;
            DOM_INPUT_METHOD_PASTE: number;
            DOM_INPUT_METHOD_HANDWRITING: number;
            DOM_INPUT_METHOD_OPTION: number;
            DOM_INPUT_METHOD_MULTIMODAL: number;
        }
        
        interface DocumentFragment extends Node, NodeSelector, MSEventAttachmentTarget, MSNodeExtensions {
        }
        declare var DocumentFragment: {
            prototype: DocumentFragment;
            new(): DocumentFragment;
        }
        
        interface SVGPolylineElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGAnimatedPoints, SVGTests, SVGExternalResourcesRequired {
        }
        declare var SVGPolylineElement: {
            prototype: SVGPolylineElement;
            new(): SVGPolylineElement;
        }
        
        interface SVGAnimatedPathData {
            pathSegList: SVGPathSegList;
        }
        
        interface Position {
            timestamp: Date;
            coords: Coordinates;
        }
        declare var Position: {
            prototype: Position;
            new(): Position;
        }
        
        interface BookmarkCollection {
            length: number;
            item(index: number): any;
            [index: number]: any;
        }
        declare var BookmarkCollection: {
            prototype: BookmarkCollection;
            new(): BookmarkCollection;
        }
        
        interface PerformanceMark extends PerformanceEntry {
        }
        declare var PerformanceMark: {
            prototype: PerformanceMark;
            new(): PerformanceMark;
        }
        
        interface CSSPageRule extends CSSRule {
            pseudoClass: string;
            selectorText: string;
            selector: string;
            style: CSSStyleDeclaration;
        }
        declare var CSSPageRule: {
            prototype: CSSPageRule;
            new(): CSSPageRule;
        }
        
        interface HTMLBRElement extends HTMLElement {
            /**
              * Sets or retrieves the side on which floating objects are not to be positioned when any IHTMLBlockElement is inserted into the document.
              */
            clear: string;
        }
        declare var HTMLBRElement: {
            prototype: HTMLBRElement;
            new(): HTMLBRElement;
        }
        
        interface MSNavigatorExtensions {
            userLanguage: string;
            plugins: MSPluginsCollection;
            cookieEnabled: boolean;
            appCodeName: string;
            cpuClass: string;
            appMinorVersion: string;
            connectionSpeed: number;
            browserLanguage: string;
            mimeTypes: MSMimeTypesCollection;
            systemLanguage: string;
            language: string;
            javaEnabled(): boolean;
            taintEnabled(): boolean;
        }
        
        interface HTMLSpanElement extends HTMLElement, MSDataBindingExtensions {
        }
        declare var HTMLSpanElement: {
            prototype: HTMLSpanElement;
            new(): HTMLSpanElement;
        }
        
        interface HTMLHeadElement extends HTMLElement {
            profile: string;
        }
        declare var HTMLHeadElement: {
            prototype: HTMLHeadElement;
            new(): HTMLHeadElement;
        }
        
        interface HTMLHeadingElement extends HTMLElement, DOML2DeprecatedTextFlowControl {
            /**
              * Sets or retrieves a value that indicates the table alignment.
              */
            align: string;
        }
        declare var HTMLHeadingElement: {
            prototype: HTMLHeadingElement;
            new(): HTMLHeadingElement;
        }
        
        interface HTMLFormElement extends HTMLElement, MSHTMLCollectionExtensions {
            /**
              * Sets or retrieves the number of objects in a collection.
              */
            length: number;
            /**
              * Sets or retrieves the window or frame at which to target content.
              */
            target: string;
            /**
              * Sets or retrieves a list of character encodings for input data that must be accepted by the server processing the form.
              */
            acceptCharset: string;
            /**
              * Sets or retrieves the encoding type for the form.
              */
            enctype: string;
            /**
              * Retrieves a collection, in source order, of all controls in a given form.
              */
            elements: HTMLCollection;
            /**
              * Sets or retrieves the URL to which the form content is sent for processing.
              */
            action: string;
            /**
              * Sets or retrieves the name of the object.
              */
            name: string;
            /**
              * Sets or retrieves how to send the form data to the server.
              */
            method: string;
            /**
              * Sets or retrieves the MIME encoding for the form.
              */
            encoding: string;
            /**
              * Specifies whether autocomplete is applied to an editable text field.
              */
            autocomplete: string;
            /**
              * Designates a form that is not validated when submitted.
              */
            noValidate: boolean;
            /**
              * Fires when the user resets a form.
              */
            reset(): void;
            /**
              * Retrieves a form object or an object from an elements collection.
              * @param name Variant of type Number or String that specifies the object or collection to retrieve. If this parameter is a Number, it is the zero-based index of the object. If this parameter is a string, all objects with matching name or id properties are retrieved, and a collection is returned if more than one match is made.
              * @param index Variant of type Number that specifies the zero-based index of the object to retrieve when a collection is returned.
              */
            item(name?: any, index?: any): any;
            /**
              * Fires when a FORM is about to be submitted.
              */
            submit(): void;
            /**
              * Retrieves a form object or an object from an elements collection.
              */
            namedItem(name: string): any;
            [name: string]: any;
            /**
              * Returns whether a form will validate when it is submitted, without having to submit it.
              */
            checkValidity(): boolean;
        }
        declare var HTMLFormElement: {
            prototype: HTMLFormElement;
            new(): HTMLFormElement;
        }
        
        interface SVGZoomAndPan {
            zoomAndPan: number;
            SVG_ZOOMANDPAN_MAGNIFY: number;
            SVG_ZOOMANDPAN_UNKNOWN: number;
            SVG_ZOOMANDPAN_DISABLE: number;
        }
        declare var SVGZoomAndPan: SVGZoomAndPan;
        
        interface HTMLMediaElement extends HTMLElement {
            /**
              * Gets the earliest possible position, in seconds, that the playback can begin.
              */
            initialTime: number;
            /**
              * Gets TimeRanges for the current media resource that has been played.
              */
            played: TimeRanges;
            /**
              * Gets the address or URL of the current media resource that is selected by IHTMLMediaElement.
              */
            currentSrc: string;
            readyState: any;
            /**
              * The autobuffer element is not supported by Internet Explorer 9. Use the preload element instead.
              */
            autobuffer: boolean;
            /**
              * Gets or sets a flag to specify whether playback should restart after it completes.
              */
            loop: boolean;
            /**
              * Gets information about whether the playback has ended or not.
              */
            ended: boolean;
            /**
              * Gets a collection of buffered time ranges.
              */
            buffered: TimeRanges;
            /**
              * Returns an object representing the current error state of the audio or video element.
              */
            error: MediaError;
            /**
              * Returns a TimeRanges object that represents the ranges of the current media resource that can be seeked.
              */
            seekable: TimeRanges;
            /**
              * Gets or sets a value that indicates whether to start playing the media automatically.
              */
            autoplay: boolean;
            /**
              * Gets or sets a flag that indicates whether the client provides a set of controls for the media (in case the developer does not include controls for the player).
              */
            controls: boolean;
            /**
              * Gets or sets the volume level for audio portions of the media element.
              */
            volume: number;
            /**
              * The address or URL of the a media resource that is to be considered.
              */
            src: string;
            /**
              * Gets or sets the current rate of speed for the media resource to play. This speed is expressed as a multiple of the normal speed of the media resource.
              */
            playbackRate: number;
            /**
              * Returns the duration in seconds of the current media resource. A NaN value is returned if duration is not available, or Infinity if the media resource is streaming.
              */
            duration: number;
            /**
              * Gets or sets a flag that indicates whether the audio (either audio or the audio track on video media) is muted.
              */
            muted: boolean;
            /**
              * Gets or sets the default playback rate when the user is not using fast forward or reverse for a video or audio resource.
              */
            defaultPlaybackRate: number;
            /**
              * Gets a flag that specifies whether playback is paused.
              */
            paused: boolean;
            /**
              * Gets a flag that indicates whether the the client is currently moving to a new playback position in the media resource.
              */
            seeking: boolean;
            /**
              * Gets or sets the current playback position, in seconds.
              */
            currentTime: number;
            /**
              * Gets or sets the current playback position, in seconds.
              */
            preload: string;
            /**
              * Gets the current network activity for the element.
              */
            networkState: number;
            /**
              * Specifies the purpose of the audio or video media, such as background audio or alerts.
              */
            msAudioCategory: string;
            /**
              * Specifies whether or not to enable low-latency playback on the media element.
              */
            msRealTime: boolean;
            /**
              * Gets or sets the primary DLNA PlayTo device.
              */
            msPlayToPrimary: boolean;
            textTracks: TextTrackList;
            /**
              * Gets or sets whether the DLNA PlayTo device is available.
              */
            msPlayToDisabled: boolean;
            /**
              * Returns an AudioTrackList object with the audio tracks for a given video element.
              */
            audioTracks: AudioTrackList;
            /**
              * Gets the source associated with the media element for use by the PlayToManager.
              */
            msPlayToSource: any;
            /**
              * Specifies the output device id that the audio will be sent to.
              */
            msAudioDeviceType: string;
            /**
              * Gets or sets the path to the preferred media source. This enables the Play To target device to stream the media content, which can be DRM protected, from a different location, such as a cloud media server.
              */
            msPlayToPreferredSourceUri: string;
            onmsneedkey: (ev: MSMediaKeyNeededEvent) => any;
            /**
              * Gets the MSMediaKeys object, which is used for decrypting media data, that is associated with this media element.
              */
            msKeys: MSMediaKeys;
            msGraphicsTrustStatus: MSGraphicsTrust;
            /**
              * Pauses the current playback and sets paused to TRUE. This can be used to test whether the media is playing or paused. You can also use the pause or play events to tell whether the media is playing or not.
              */
            pause(): void;
            /**
              * Loads and starts playback of a media resource.
              */
            play(): void;
            /**
              * Fires immediately after the client loads the object.
              */
            load(): void;
            /**
              * Returns a string that specifies whether the client can play a given media resource type.
              */
            canPlayType(type: string): string;
            /**
              * Clears all effects from the media pipeline.
              */
            msClearEffects(): void;
            /**
              * Specifies the media protection manager for a given media pipeline.
              */
            msSetMediaProtectionManager(mediaProtectionManager?: any): void;
            /**
              * Inserts the specified audio effect into media pipeline.
              */
            msInsertAudioEffect(activatableClassId: string, effectRequired: boolean, config?: any): void;
            msSetMediaKeys(mediaKeys: MSMediaKeys): void;
            addTextTrack(kind: string, label?: string, language?: string): TextTrack;
            HAVE_METADATA: number;
            HAVE_CURRENT_DATA: number;
            HAVE_NOTHING: number;
            NETWORK_NO_SOURCE: number;
            HAVE_ENOUGH_DATA: number;
            NETWORK_EMPTY: number;
            NETWORK_LOADING: number;
            NETWORK_IDLE: number;
            HAVE_FUTURE_DATA: number;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "move", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "deactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetchanged", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsdelete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "losecapture", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "controlselect", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "layoutcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "filterchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "errorupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "cellchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowexit", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsinserted", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "propertychange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforepaste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecopy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "paste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "moveend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeeditfocus", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "afterupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizeend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dataavailable", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforedeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "activate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "movestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "selectstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "cut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "copy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "rowenter", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mscontentzoom", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "cuechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "msmanipulationstatechanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msneedkey", listener: (ev: MSMediaKeyNeededEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var HTMLMediaElement: {
            prototype: HTMLMediaElement;
            new(): HTMLMediaElement;
            HAVE_METADATA: number;
            HAVE_CURRENT_DATA: number;
            HAVE_NOTHING: number;
            NETWORK_NO_SOURCE: number;
            HAVE_ENOUGH_DATA: number;
            NETWORK_EMPTY: number;
            NETWORK_LOADING: number;
            NETWORK_IDLE: number;
            HAVE_FUTURE_DATA: number;
        }
        
        interface ElementCSSInlineStyle {
            runtimeStyle: MSStyleCSSProperties;
            currentStyle: MSCurrentStyleCSSProperties;
            doScroll(component?: any): void;
            componentFromPoint(x: number, y: number): string;
        }
        
        interface DOMParser {
            parseFromString(source: string, mimeType: string): Document;
        }
        declare var DOMParser: {
            prototype: DOMParser;
            new(): DOMParser;
        }
        
        interface MSMimeTypesCollection {
            length: number;
        }
        declare var MSMimeTypesCollection: {
            prototype: MSMimeTypesCollection;
            new(): MSMimeTypesCollection;
        }
        
        interface StyleSheet {
            disabled: boolean;
            ownerNode: Node;
            parentStyleSheet: StyleSheet;
            href: string;
            media: MediaList;
            type: string;
            title: string;
        }
        declare var StyleSheet: {
            prototype: StyleSheet;
            new(): StyleSheet;
        }
        
        interface SVGTextPathElement extends SVGTextContentElement, SVGURIReference {
            startOffset: SVGAnimatedLength;
            method: SVGAnimatedEnumeration;
            spacing: SVGAnimatedEnumeration;
            TEXTPATH_SPACINGTYPE_EXACT: number;
            TEXTPATH_METHODTYPE_STRETCH: number;
            TEXTPATH_SPACINGTYPE_AUTO: number;
            TEXTPATH_SPACINGTYPE_UNKNOWN: number;
            TEXTPATH_METHODTYPE_UNKNOWN: number;
            TEXTPATH_METHODTYPE_ALIGN: number;
        }
        declare var SVGTextPathElement: {
            prototype: SVGTextPathElement;
            new(): SVGTextPathElement;
            TEXTPATH_SPACINGTYPE_EXACT: number;
            TEXTPATH_METHODTYPE_STRETCH: number;
            TEXTPATH_SPACINGTYPE_AUTO: number;
            TEXTPATH_SPACINGTYPE_UNKNOWN: number;
            TEXTPATH_METHODTYPE_UNKNOWN: number;
            TEXTPATH_METHODTYPE_ALIGN: number;
        }
        
        interface HTMLDTElement extends HTMLElement {
            /**
              * Sets or retrieves whether the browser automatically performs wordwrap.
              */
            noWrap: boolean;
        }
        declare var HTMLDTElement: {
            prototype: HTMLDTElement;
            new(): HTMLDTElement;
        }
        
        interface NodeList {
            length: number;
            item(index: number): Node;
            [index: number]: Node;
        }
        declare var NodeList: {
            prototype: NodeList;
            new(): NodeList;
        }
        
        interface XMLSerializer {
            serializeToString(target: Node): string;
        }
        declare var XMLSerializer: {
            prototype: XMLSerializer;
            new(): XMLSerializer;
        }
        
        interface PerformanceMeasure extends PerformanceEntry {
        }
        declare var PerformanceMeasure: {
            prototype: PerformanceMeasure;
            new(): PerformanceMeasure;
        }
        
        interface SVGGradientElement extends SVGElement, SVGUnitTypes, SVGStylable, SVGExternalResourcesRequired, SVGURIReference {
            spreadMethod: SVGAnimatedEnumeration;
            gradientTransform: SVGAnimatedTransformList;
            gradientUnits: SVGAnimatedEnumeration;
            SVG_SPREADMETHOD_REFLECT: number;
            SVG_SPREADMETHOD_PAD: number;
            SVG_SPREADMETHOD_UNKNOWN: number;
            SVG_SPREADMETHOD_REPEAT: number;
        }
        declare var SVGGradientElement: {
            prototype: SVGGradientElement;
            new(): SVGGradientElement;
            SVG_SPREADMETHOD_REFLECT: number;
            SVG_SPREADMETHOD_PAD: number;
            SVG_SPREADMETHOD_UNKNOWN: number;
            SVG_SPREADMETHOD_REPEAT: number;
        }
        
        interface NodeFilter {
            acceptNode(n: Node): number;
            SHOW_ENTITY_REFERENCE: number;
            SHOW_NOTATION: number;
            SHOW_ENTITY: number;
            SHOW_DOCUMENT: number;
            SHOW_PROCESSING_INSTRUCTION: number;
            FILTER_REJECT: number;
            SHOW_CDATA_SECTION: number;
            FILTER_ACCEPT: number;
            SHOW_ALL: number;
            SHOW_DOCUMENT_TYPE: number;
            SHOW_TEXT: number;
            SHOW_ELEMENT: number;
            SHOW_COMMENT: number;
            FILTER_SKIP: number;
            SHOW_ATTRIBUTE: number;
            SHOW_DOCUMENT_FRAGMENT: number;
        }
        declare var NodeFilter: NodeFilter;
        
        interface SVGNumberList {
            numberOfItems: number;
            replaceItem(newItem: SVGNumber, index: number): SVGNumber;
            getItem(index: number): SVGNumber;
            clear(): void;
            appendItem(newItem: SVGNumber): SVGNumber;
            initialize(newItem: SVGNumber): SVGNumber;
            removeItem(index: number): SVGNumber;
            insertItemBefore(newItem: SVGNumber, index: number): SVGNumber;
        }
        declare var SVGNumberList: {
            prototype: SVGNumberList;
            new(): SVGNumberList;
        }
        
        interface MediaError {
            code: number;
            msExtendedCode: number;
            MEDIA_ERR_ABORTED: number;
            MEDIA_ERR_NETWORK: number;
            MEDIA_ERR_SRC_NOT_SUPPORTED: number;
            MEDIA_ERR_DECODE: number;
            MS_MEDIA_ERR_ENCRYPTED: number;
        }
        declare var MediaError: {
            prototype: MediaError;
            new(): MediaError;
            MEDIA_ERR_ABORTED: number;
            MEDIA_ERR_NETWORK: number;
            MEDIA_ERR_SRC_NOT_SUPPORTED: number;
            MEDIA_ERR_DECODE: number;
            MS_MEDIA_ERR_ENCRYPTED: number;
        }
        
        interface HTMLFieldSetElement extends HTMLElement {
            /**
              * Sets or retrieves how the object is aligned with adjacent text.
              */
            align: string;
            /**
              * Retrieves a reference to the form that the object is embedded in.
              */
            form: HTMLFormElement;
            /**
              * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation messages without actually submitting.
              */
            validationMessage: string;
            /**
              * Returns a  ValidityState object that represents the validity states of an element.
              */
            validity: ValidityState;
            /**
              * Returns whether an element will successfully validate based on forms validation rules and constraints.
              */
            willValidate: boolean;
            /**
              * Returns whether a form will validate when it is submitted, without having to submit it.
              */
            checkValidity(): boolean;
            /**
              * Sets a custom error message that is displayed when a form is submitted.
              * @param error Sets a custom error message that is displayed when a form is submitted.
              */
            setCustomValidity(error: string): void;
        }
        declare var HTMLFieldSetElement: {
            prototype: HTMLFieldSetElement;
            new(): HTMLFieldSetElement;
        }
        
        interface HTMLBGSoundElement extends HTMLElement {
            /**
              * Sets or gets the value indicating how the volume of the background sound is divided between the left speaker and the right speaker.
              */
            balance: any;
            /**
              * Sets or gets the volume setting for the sound. 
              */
            volume: any;
            /**
              * Sets or gets the URL of a sound to play.
              */
            src: string;
            /**
              * Sets or retrieves the number of times a sound or video clip will loop when activated.
              */
            loop: number;
        }
        declare var HTMLBGSoundElement: {
            prototype: HTMLBGSoundElement;
            new(): HTMLBGSoundElement;
        }
        
        interface Comment extends CharacterData {
            text: string;
        }
        declare var Comment: {
            prototype: Comment;
            new(): Comment;
        }
        
        interface PerformanceResourceTiming extends PerformanceEntry {
            redirectStart: number;
            redirectEnd: number;
            domainLookupEnd: number;
            responseStart: number;
            domainLookupStart: number;
            fetchStart: number;
            requestStart: number;
            connectEnd: number;
            connectStart: number;
            initiatorType: string;
            responseEnd: number;
        }
        declare var PerformanceResourceTiming: {
            prototype: PerformanceResourceTiming;
            new(): PerformanceResourceTiming;
        }
        
        interface CanvasPattern {
        }
        declare var CanvasPattern: {
            prototype: CanvasPattern;
            new(): CanvasPattern;
        }
        
        interface HTMLHRElement extends HTMLElement, DOML2DeprecatedColorProperty, DOML2DeprecatedSizeProperty {
            /**
              * Sets or retrieves the width of the object.
              */
            width: number;
            /**
              * Sets or retrieves how the object is aligned with adjacent text.
              */
            align: string;
            /**
              * Sets or retrieves whether the horizontal rule is drawn with 3-D shading.
              */
            noShade: boolean;
        }
        declare var HTMLHRElement: {
            prototype: HTMLHRElement;
            new(): HTMLHRElement;
        }
        
        interface HTMLObjectElement extends HTMLElement, GetSVGDocument, DOML2DeprecatedMarginStyle, DOML2DeprecatedBorderStyle, DOML2DeprecatedAlignmentStyle, MSDataBindingExtensions, MSDataBindingRecordSetExtensions {
            /**
              * Sets or retrieves the width of the object.
              */
            width: string;
            /**
              * Sets or retrieves the Internet media type for the code associated with the object.
              */
            codeType: string;
            /**
              * Retrieves the contained object.
              */
            object: any;
            /**
              * Retrieves a reference to the form that the object is embedded in.
              */
            form: HTMLFormElement;
            /**
              * Sets or retrieves the URL of the file containing the compiled Java class.
              */
            code: string;
            /**
              * Sets or retrieves a character string that can be used to implement your own archive functionality for the object.
              */
            archive: string;
            /**
              * Sets or retrieves a message to be displayed while an object is loading.
              */
            standby: string;
            /**
              * Sets or retrieves a text alternative to the graphic.
              */
            alt: string;
            /**
              * Sets or retrieves the class identifier for the object.
              */
            classid: string;
            /**
              * Sets or retrieves the name of the object.
              */
            name: string;
            /**
              * Sets or retrieves the URL, often with a bookmark extension (#name), to use as a client-side image map.
              */
            useMap: string;
            /**
              * Sets or retrieves the URL that references the data of the object.
              */
            data: string;
            /**
              * Sets or retrieves the height of the object.
              */
            height: string;
            /**
              * Retrieves the document object of the page or frame.
              */
            contentDocument: Document;
            /**
              * Gets or sets the optional alternative HTML script to execute if the object fails to load.
              */
            altHtml: string;
            /**
              * Sets or retrieves the URL of the component.
              */
            codeBase: string;
            declare: boolean;
            /**
              * Sets or retrieves the MIME type of the object.
              */
            type: string;
            /**
              * Retrieves a string of the URL where the object tag can be found. This is often the href of the document that the object is in, or the value set by a base element.
              */
            BaseHref: string;
            /**
              * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation messages without actually submitting.
              */
            validationMessage: string;
            /**
              * Returns a  ValidityState object that represents the validity states of an element.
              */
            validity: ValidityState;
            /**
              * Returns whether an element will successfully validate based on forms validation rules and constraints.
              */
            willValidate: boolean;
            /**
              * Gets or sets the path to the preferred media source. This enables the Play To target device to stream the media content, which can be DRM protected, from a different location, such as a cloud media server.
              */
            msPlayToPreferredSourceUri: string;
            /**
              * Gets or sets the primary DLNA PlayTo device.
              */
            msPlayToPrimary: boolean;
            /**
              * Gets or sets whether the DLNA PlayTo device is available.
              */
            msPlayToDisabled: boolean;
            readyState: number;
            /**
              * Gets the source associated with the media element for use by the PlayToManager.
              */
            msPlayToSource: any;
            /**
              * Returns whether a form will validate when it is submitted, without having to submit it.
              */
            checkValidity(): boolean;
            /**
              * Sets a custom error message that is displayed when a form is submitted.
              * @param error Sets a custom error message that is displayed when a form is submitted.
              */
            setCustomValidity(error: string): void;
        }
        declare var HTMLObjectElement: {
            prototype: HTMLObjectElement;
            new(): HTMLObjectElement;
        }
        
        interface HTMLEmbedElement extends HTMLElement, GetSVGDocument {
            /**
              * Sets or retrieves the width of the object.
              */
            width: string;
            /**
              * Retrieves the palette used for the embedded document.
              */
            palette: string;
            /**
              * Sets or retrieves a URL to be loaded by the object.
              */
            src: string;
            /**
              * Sets or retrieves the name of the object.
              */
            name: string;
            hidden: string;
            /**
              * Retrieves the URL of the plug-in used to view an embedded document.
              */
            pluginspage: string;
            /**
              * Sets or retrieves the height of the object.
              */
            height: string;
            /**
              * Sets or retrieves the height and width units of the embed object.
              */
            units: string;
            /**
              * Gets or sets the path to the preferred media source. This enables the Play To target device to stream the media content, which can be DRM protected, from a different location, such as a cloud media server.
              */
            msPlayToPreferredSourceUri: string;
            /**
              * Gets or sets the primary DLNA PlayTo device.
              */
            msPlayToPrimary: boolean;
            /**
              * Gets or sets whether the DLNA PlayTo device is available.
              */
            msPlayToDisabled: boolean;
            readyState: string;
            /**
              * Gets the source associated with the media element for use by the PlayToManager.
              */
            msPlayToSource: any;
        }
        declare var HTMLEmbedElement: {
            prototype: HTMLEmbedElement;
            new(): HTMLEmbedElement;
        }
        
        interface StorageEvent extends Event {
            oldValue: any;
            newValue: any;
            url: string;
            storageArea: Storage;
            key: string;
            initStorageEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, keyArg: string, oldValueArg: any, newValueArg: any, urlArg: string, storageAreaArg: Storage): void;
        }
        declare var StorageEvent: {
            prototype: StorageEvent;
            new(): StorageEvent;
        }
        
        interface CharacterData extends Node {
            length: number;
            data: string;
            deleteData(offset: number, count: number): void;
            replaceData(offset: number, count: number, arg: string): void;
            appendData(arg: string): void;
            insertData(offset: number, arg: string): void;
            substringData(offset: number, count: number): string;
        }
        declare var CharacterData: {
            prototype: CharacterData;
            new(): CharacterData;
        }
        
        interface HTMLOptGroupElement extends HTMLElement, MSDataBindingExtensions {
            /**
              * Sets or retrieves the ordinal position of an option in a list box.
              */
            index: number;
            /**
              * Sets or retrieves the status of an option.
              */
            defaultSelected: boolean;
            /**
              * Sets or retrieves the text string specified by the option tag.
              */
            text: string;
            /**
              * Sets or retrieves the value which is returned to the server when the form control is submitted.
              */
            value: string;
            /**
              * Retrieves a reference to the form that the object is embedded in.
              */
            form: HTMLFormElement;
            /**
              * Sets or retrieves a value that you can use to implement your own label functionality for the object.
              */
            label: string;
            /**
              * Sets or retrieves whether the option in the list box is the default item.
              */
            selected: boolean;
        }
        declare var HTMLOptGroupElement: {
            prototype: HTMLOptGroupElement;
            new(): HTMLOptGroupElement;
        }
        
        interface HTMLIsIndexElement extends HTMLElement {
            /**
              * Retrieves a reference to the form that the object is embedded in. 
              */
            form: HTMLFormElement;
            /**
              * Sets or retrieves the URL to which the form content is sent for processing.
              */
            action: string;
            prompt: string;
        }
        declare var HTMLIsIndexElement: {
            prototype: HTMLIsIndexElement;
            new(): HTMLIsIndexElement;
        }
        
        interface SVGPathSegLinetoRel extends SVGPathSeg {
            y: number;
            x: number;
        }
        declare var SVGPathSegLinetoRel: {
            prototype: SVGPathSegLinetoRel;
            new(): SVGPathSegLinetoRel;
        }
        
        interface DOMException {
            code: number;
            message: string;
            name: string;
            toString(): string;
            HIERARCHY_REQUEST_ERR: number;
            NO_MODIFICATION_ALLOWED_ERR: number;
            INVALID_MODIFICATION_ERR: number;
            NAMESPACE_ERR: number;
            INVALID_CHARACTER_ERR: number;
            TYPE_MISMATCH_ERR: number;
            ABORT_ERR: number;
            INVALID_STATE_ERR: number;
            SECURITY_ERR: number;
            NETWORK_ERR: number;
            WRONG_DOCUMENT_ERR: number;
            QUOTA_EXCEEDED_ERR: number;
            INDEX_SIZE_ERR: number;
            DOMSTRING_SIZE_ERR: number;
            SYNTAX_ERR: number;
            SERIALIZE_ERR: number;
            VALIDATION_ERR: number;
            NOT_FOUND_ERR: number;
            URL_MISMATCH_ERR: number;
            PARSE_ERR: number;
            NO_DATA_ALLOWED_ERR: number;
            NOT_SUPPORTED_ERR: number;
            INVALID_ACCESS_ERR: number;
            INUSE_ATTRIBUTE_ERR: number;
            INVALID_NODE_TYPE_ERR: number;
            DATA_CLONE_ERR: number;
            TIMEOUT_ERR: number;
        }
        declare var DOMException: {
            prototype: DOMException;
            new(): DOMException;
            HIERARCHY_REQUEST_ERR: number;
            NO_MODIFICATION_ALLOWED_ERR: number;
            INVALID_MODIFICATION_ERR: number;
            NAMESPACE_ERR: number;
            INVALID_CHARACTER_ERR: number;
            TYPE_MISMATCH_ERR: number;
            ABORT_ERR: number;
            INVALID_STATE_ERR: number;
            SECURITY_ERR: number;
            NETWORK_ERR: number;
            WRONG_DOCUMENT_ERR: number;
            QUOTA_EXCEEDED_ERR: number;
            INDEX_SIZE_ERR: number;
            DOMSTRING_SIZE_ERR: number;
            SYNTAX_ERR: number;
            SERIALIZE_ERR: number;
            VALIDATION_ERR: number;
            NOT_FOUND_ERR: number;
            URL_MISMATCH_ERR: number;
            PARSE_ERR: number;
            NO_DATA_ALLOWED_ERR: number;
            NOT_SUPPORTED_ERR: number;
            INVALID_ACCESS_ERR: number;
            INUSE_ATTRIBUTE_ERR: number;
            INVALID_NODE_TYPE_ERR: number;
            DATA_CLONE_ERR: number;
            TIMEOUT_ERR: number;
        }
        
        interface SVGAnimatedBoolean {
            animVal: boolean;
            baseVal: boolean;
        }
        declare var SVGAnimatedBoolean: {
            prototype: SVGAnimatedBoolean;
            new(): SVGAnimatedBoolean;
        }
        
        interface MSCompatibleInfoCollection {
            length: number;
            item(index: number): MSCompatibleInfo;
        }
        declare var MSCompatibleInfoCollection: {
            prototype: MSCompatibleInfoCollection;
            new(): MSCompatibleInfoCollection;
        }
        
        interface SVGSwitchElement extends SVGElement, SVGStylable, SVGTransformable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
        }
        declare var SVGSwitchElement: {
            prototype: SVGSwitchElement;
            new(): SVGSwitchElement;
        }
        
        interface SVGPreserveAspectRatio {
            align: number;
            meetOrSlice: number;
            SVG_PRESERVEASPECTRATIO_NONE: number;
            SVG_PRESERVEASPECTRATIO_XMINYMID: number;
            SVG_PRESERVEASPECTRATIO_XMAXYMIN: number;
            SVG_PRESERVEASPECTRATIO_XMINYMAX: number;
            SVG_PRESERVEASPECTRATIO_XMAXYMAX: number;
            SVG_MEETORSLICE_UNKNOWN: number;
            SVG_PRESERVEASPECTRATIO_XMAXYMID: number;
            SVG_PRESERVEASPECTRATIO_XMIDYMAX: number;
            SVG_PRESERVEASPECTRATIO_XMINYMIN: number;
            SVG_MEETORSLICE_MEET: number;
            SVG_PRESERVEASPECTRATIO_XMIDYMID: number;
            SVG_PRESERVEASPECTRATIO_XMIDYMIN: number;
            SVG_MEETORSLICE_SLICE: number;
            SVG_PRESERVEASPECTRATIO_UNKNOWN: number;
        }
        declare var SVGPreserveAspectRatio: {
            prototype: SVGPreserveAspectRatio;
            new(): SVGPreserveAspectRatio;
            SVG_PRESERVEASPECTRATIO_NONE: number;
            SVG_PRESERVEASPECTRATIO_XMINYMID: number;
            SVG_PRESERVEASPECTRATIO_XMAXYMIN: number;
            SVG_PRESERVEASPECTRATIO_XMINYMAX: number;
            SVG_PRESERVEASPECTRATIO_XMAXYMAX: number;
            SVG_MEETORSLICE_UNKNOWN: number;
            SVG_PRESERVEASPECTRATIO_XMAXYMID: number;
            SVG_PRESERVEASPECTRATIO_XMIDYMAX: number;
            SVG_PRESERVEASPECTRATIO_XMINYMIN: number;
            SVG_MEETORSLICE_MEET: number;
            SVG_PRESERVEASPECTRATIO_XMIDYMID: number;
            SVG_PRESERVEASPECTRATIO_XMIDYMIN: number;
            SVG_MEETORSLICE_SLICE: number;
            SVG_PRESERVEASPECTRATIO_UNKNOWN: number;
        }
        
        interface Attr extends Node {
            expando: boolean;
            specified: boolean;
            ownerElement: Element;
            value: string;
            name: string;
        }
        declare var Attr: {
            prototype: Attr;
            new(): Attr;
        }
        
        interface PerformanceNavigation {
            redirectCount: number;
            type: number;
            toJSON(): any;
            TYPE_RELOAD: number;
            TYPE_RESERVED: number;
            TYPE_BACK_FORWARD: number;
            TYPE_NAVIGATE: number;
        }
        declare var PerformanceNavigation: {
            prototype: PerformanceNavigation;
            new(): PerformanceNavigation;
            TYPE_RELOAD: number;
            TYPE_RESERVED: number;
            TYPE_BACK_FORWARD: number;
            TYPE_NAVIGATE: number;
        }
        
        interface SVGStopElement extends SVGElement, SVGStylable {
            offset: SVGAnimatedNumber;
        }
        declare var SVGStopElement: {
            prototype: SVGStopElement;
            new(): SVGStopElement;
        }
        
        interface PositionCallback {
            (position: Position): void;
        }
        
        interface SVGSymbolElement extends SVGElement, SVGStylable, SVGLangSpace, SVGFitToViewBox, SVGExternalResourcesRequired {
        }
        declare var SVGSymbolElement: {
            prototype: SVGSymbolElement;
            new(): SVGSymbolElement;
        }
        
        interface SVGElementInstanceList {
            length: number;
            item(index: number): SVGElementInstance;
        }
        declare var SVGElementInstanceList: {
            prototype: SVGElementInstanceList;
            new(): SVGElementInstanceList;
        }
        
        interface CSSRuleList {
            length: number;
            item(index: number): CSSRule;
            [index: number]: CSSRule;
        }
        declare var CSSRuleList: {
            prototype: CSSRuleList;
            new(): CSSRuleList;
        }
        
        interface MSDataBindingRecordSetExtensions {
            recordset: any;
            namedRecordset(dataMember: string, hierarchy?: any): any;
        }
        
        interface LinkStyle {
            styleSheet: StyleSheet;
            sheet: StyleSheet;
        }
        
        interface HTMLVideoElement extends HTMLMediaElement {
            /**
              * Gets or sets the width of the video element.
              */
            width: number;
            /**
              * Gets the intrinsic width of a video in CSS pixels, or zero if the dimensions are not known.
              */
            videoWidth: number;
            /**
              * Gets the intrinsic height of a video in CSS pixels, or zero if the dimensions are not known.
              */
            videoHeight: number;
            /**
              * Gets or sets the height of the video element.
              */
            height: number;
            /**
              * Gets or sets a URL of an image to display, for example, like a movie poster. This can be a still frame from the video, or another image if no video data is available.
              */
            poster: string;
            msIsStereo3D: boolean;
            msStereo3DPackingMode: string;
            onMSVideoOptimalLayoutChanged: (ev: any) => any;
            onMSVideoFrameStepCompleted: (ev: any) => any;
            msStereo3DRenderMode: string;
            msIsLayoutOptimalForPlayback: boolean;
            msHorizontalMirror: boolean;
            onMSVideoFormatChanged: (ev: any) => any;
            msZoom: boolean;
            msInsertVideoEffect(activatableClassId: string, effectRequired: boolean, config?: any): void;
            msSetVideoRectangle(left: number, top: number, right: number, bottom: number): void;
            msFrameStep(forward: boolean): void;
            getVideoPlaybackQuality(): VideoPlaybackQuality;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgotpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mslostpointercapture", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "lostpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "gotpointercapture", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "move", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "deactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetchanged", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsdelete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "losecapture", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "controlselect", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "layoutcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "filterchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "datasetcomplete", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "errorupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "cellchange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowexit", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "rowsinserted", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "propertychange", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforepaste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforecopy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "paste", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "moveend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "beforeeditfocus", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "afterupdate", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resizeend", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "dataavailable", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "beforedeactivate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "activate", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "movestart", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "selectstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "cut", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "copy", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "rowenter", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "mscontentzoom", listener: (ev: MSEventObj) => any, useCapture?: boolean): void;
            addEventListener(type: "cuechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "msmanipulationstatechanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "msneedkey", listener: (ev: MSMediaKeyNeededEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "MSVideoOptimalLayoutChanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "MSVideoFrameStepCompleted", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "MSVideoFormatChanged", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var HTMLVideoElement: {
            prototype: HTMLVideoElement;
            new(): HTMLVideoElement;
        }
        
        interface ClientRectList {
            length: number;
            item(index: number): ClientRect;
            [index: number]: ClientRect;
        }
        declare var ClientRectList: {
            prototype: ClientRectList;
            new(): ClientRectList;
        }
        
        interface SVGMaskElement extends SVGElement, SVGUnitTypes, SVGStylable, SVGLangSpace, SVGTests, SVGExternalResourcesRequired {
            y: SVGAnimatedLength;
            width: SVGAnimatedLength;
            maskUnits: SVGAnimatedEnumeration;
            maskContentUnits: SVGAnimatedEnumeration;
            x: SVGAnimatedLength;
            height: SVGAnimatedLength;
        }
        declare var SVGMaskElement: {
            prototype: SVGMaskElement;
            new(): SVGMaskElement;
        }
        
        interface External {
        }
        declare var External: {
            prototype: External;
            new(): External;
        }
        
        interface MSGestureEvent extends UIEvent {
            offsetY: number;
            translationY: number;
            velocityExpansion: number;
            velocityY: number;
            velocityAngular: number;
            translationX: number;
            velocityX: number;
            hwTimestamp: number;
            offsetX: number;
            screenX: number;
            rotation: number;
            expansion: number;
            clientY: number;
            screenY: number;
            scale: number;
            gestureObject: any;
            clientX: number;
            initGestureEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, offsetXArg: number, offsetYArg: number, translationXArg: number, translationYArg: number, scaleArg: number, expansionArg: number, rotationArg: number, velocityXArg: number, velocityYArg: number, velocityExpansionArg: number, velocityAngularArg: number, hwTimestampArg: number): void;
            MSGESTURE_FLAG_BEGIN: number;
            MSGESTURE_FLAG_END: number;
            MSGESTURE_FLAG_CANCEL: number;
            MSGESTURE_FLAG_INERTIA: number;
            MSGESTURE_FLAG_NONE: number;
        }
        declare var MSGestureEvent: {
            prototype: MSGestureEvent;
            new(): MSGestureEvent;
            MSGESTURE_FLAG_BEGIN: number;
            MSGESTURE_FLAG_END: number;
            MSGESTURE_FLAG_CANCEL: number;
            MSGESTURE_FLAG_INERTIA: number;
            MSGESTURE_FLAG_NONE: number;
        }
        
        interface ErrorEvent extends Event {
            colno: number;
            filename: string;
            error: any;
            lineno: number;
            message: string;
            initErrorEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, messageArg: string, filenameArg: string, linenoArg: number): void;
        }
        declare var ErrorEvent: {
            prototype: ErrorEvent;
            new(): ErrorEvent;
        }
        
        interface SVGFilterElement extends SVGElement, SVGUnitTypes, SVGStylable, SVGLangSpace, SVGURIReference, SVGExternalResourcesRequired {
            y: SVGAnimatedLength;
            width: SVGAnimatedLength;
            filterResX: SVGAnimatedInteger;
            filterUnits: SVGAnimatedEnumeration;
            primitiveUnits: SVGAnimatedEnumeration;
            x: SVGAnimatedLength;
            height: SVGAnimatedLength;
            filterResY: SVGAnimatedInteger;
            setFilterRes(filterResX: number, filterResY: number): void;
        }
        declare var SVGFilterElement: {
            prototype: SVGFilterElement;
            new(): SVGFilterElement;
        }
        
        interface TrackEvent extends Event {
            track: any;
        }
        declare var TrackEvent: {
            prototype: TrackEvent;
            new(): TrackEvent;
        }
        
        interface SVGFEMergeNodeElement extends SVGElement {
            in1: SVGAnimatedString;
        }
        declare var SVGFEMergeNodeElement: {
            prototype: SVGFEMergeNodeElement;
            new(): SVGFEMergeNodeElement;
        }
        
        interface SVGFEFloodElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
        }
        declare var SVGFEFloodElement: {
            prototype: SVGFEFloodElement;
            new(): SVGFEFloodElement;
        }
        
        interface MSGesture {
            target: Element;
            addPointer(pointerId: number): void;
            stop(): void;
        }
        declare var MSGesture: {
            prototype: MSGesture;
            new(): MSGesture;
        }
        
        interface TextTrackCue extends EventTarget {
            onenter: (ev: Event) => any;
            track: TextTrack;
            endTime: number;
            text: string;
            pauseOnExit: boolean;
            id: string;
            startTime: number;
            onexit: (ev: Event) => any;
            getCueAsHTML(): DocumentFragment;
            addEventListener(type: "enter", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "exit", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var TextTrackCue: {
            prototype: TextTrackCue;
            new(startTime: number, endTime: number, text: string): TextTrackCue;
        }
        
        interface MSStreamReader extends MSBaseReader {
            error: DOMError;
            readAsArrayBuffer(stream: MSStream, size?: number): void;
            readAsBlob(stream: MSStream, size?: number): void;
            readAsDataURL(stream: MSStream, size?: number): void;
            readAsText(stream: MSStream, encoding?: string, size?: number): void;
        }
        declare var MSStreamReader: {
            prototype: MSStreamReader;
            new(): MSStreamReader;
        }
        
        interface DOMTokenList {
            length: number;
            contains(token: string): boolean;
            remove(token: string): void;
            toggle(token: string): boolean;
            add(token: string): void;
            item(index: number): string;
            [index: number]: string;
            toString(): string;
        }
        declare var DOMTokenList: {
            prototype: DOMTokenList;
            new(): DOMTokenList;
        }
        
        interface SVGFEFuncAElement extends SVGComponentTransferFunctionElement {
        }
        declare var SVGFEFuncAElement: {
            prototype: SVGFEFuncAElement;
            new(): SVGFEFuncAElement;
        }
        
        interface SVGFETileElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            in1: SVGAnimatedString;
        }
        declare var SVGFETileElement: {
            prototype: SVGFETileElement;
            new(): SVGFETileElement;
        }
        
        interface SVGFEBlendElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            in2: SVGAnimatedString;
            mode: SVGAnimatedEnumeration;
            in1: SVGAnimatedString;
            SVG_FEBLEND_MODE_DARKEN: number;
            SVG_FEBLEND_MODE_UNKNOWN: number;
            SVG_FEBLEND_MODE_MULTIPLY: number;
            SVG_FEBLEND_MODE_NORMAL: number;
            SVG_FEBLEND_MODE_SCREEN: number;
            SVG_FEBLEND_MODE_LIGHTEN: number;
        }
        declare var SVGFEBlendElement: {
            prototype: SVGFEBlendElement;
            new(): SVGFEBlendElement;
            SVG_FEBLEND_MODE_DARKEN: number;
            SVG_FEBLEND_MODE_UNKNOWN: number;
            SVG_FEBLEND_MODE_MULTIPLY: number;
            SVG_FEBLEND_MODE_NORMAL: number;
            SVG_FEBLEND_MODE_SCREEN: number;
            SVG_FEBLEND_MODE_LIGHTEN: number;
        }
        
        interface MessageChannel {
            port2: MessagePort;
            port1: MessagePort;
        }
        declare var MessageChannel: {
            prototype: MessageChannel;
            new(): MessageChannel;
        }
        
        interface SVGFEMergeElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
        }
        declare var SVGFEMergeElement: {
            prototype: SVGFEMergeElement;
            new(): SVGFEMergeElement;
        }
        
        interface TransitionEvent extends Event {
            propertyName: string;
            elapsedTime: number;
            initTransitionEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, propertyNameArg: string, elapsedTimeArg: number): void;
        }
        declare var TransitionEvent: {
            prototype: TransitionEvent;
            new(): TransitionEvent;
        }
        
        interface MediaQueryList {
            matches: boolean;
            media: string;
            addListener(listener: MediaQueryListListener): void;
            removeListener(listener: MediaQueryListListener): void;
        }
        declare var MediaQueryList: {
            prototype: MediaQueryList;
            new(): MediaQueryList;
        }
        
        interface DOMError {
            name: string;
            toString(): string;
        }
        declare var DOMError: {
            prototype: DOMError;
            new(): DOMError;
        }
        
        interface CloseEvent extends Event {
            wasClean: boolean;
            reason: string;
            code: number;
            initCloseEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, wasCleanArg: boolean, codeArg: number, reasonArg: string): void;
        }
        declare var CloseEvent: {
            prototype: CloseEvent;
            new(): CloseEvent;
        }
        
        interface WebSocket extends EventTarget {
            protocol: string;
            readyState: number;
            bufferedAmount: number;
            onopen: (ev: Event) => any;
            extensions: string;
            onmessage: (ev: MessageEvent) => any;
            onclose: (ev: CloseEvent) => any;
            onerror: (ev: ErrorEvent) => any;
            binaryType: string;
            url: string;
            close(code?: number, reason?: string): void;
            send(data: any): void;
            OPEN: number;
            CLOSING: number;
            CONNECTING: number;
            CLOSED: number;
            addEventListener(type: "open", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "close", listener: (ev: CloseEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var WebSocket: {
            prototype: WebSocket;
            new(url: string, protocols?: string): WebSocket;
            new(url: string, protocols?: string[]): WebSocket;
            OPEN: number;
            CLOSING: number;
            CONNECTING: number;
            CLOSED: number;
        }
        
        interface SVGFEPointLightElement extends SVGElement {
            y: SVGAnimatedNumber;
            x: SVGAnimatedNumber;
            z: SVGAnimatedNumber;
        }
        declare var SVGFEPointLightElement: {
            prototype: SVGFEPointLightElement;
            new(): SVGFEPointLightElement;
        }
        
        interface ProgressEvent extends Event {
            loaded: number;
            lengthComputable: boolean;
            total: number;
            initProgressEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, lengthComputableArg: boolean, loadedArg: number, totalArg: number): void;
        }
        declare var ProgressEvent: {
            prototype: ProgressEvent;
            new(): ProgressEvent;
        }
        
        interface IDBObjectStore {
            indexNames: DOMStringList;
            name: string;
            transaction: IDBTransaction;
            keyPath: string;
            count(key?: any): IDBRequest;
            add(value: any, key?: any): IDBRequest;
            clear(): IDBRequest;
            createIndex(name: string, keyPath: string, optionalParameters?: any): IDBIndex;
            put(value: any, key?: any): IDBRequest;
            openCursor(range?: any, direction?: string): IDBRequest;
            deleteIndex(indexName: string): void;
            index(name: string): IDBIndex;
            get(key: any): IDBRequest;
            delete(key: any): IDBRequest;
        }
        declare var IDBObjectStore: {
            prototype: IDBObjectStore;
            new(): IDBObjectStore;
        }
        
        interface SVGFEGaussianBlurElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            stdDeviationX: SVGAnimatedNumber;
            in1: SVGAnimatedString;
            stdDeviationY: SVGAnimatedNumber;
            setStdDeviation(stdDeviationX: number, stdDeviationY: number): void;
        }
        declare var SVGFEGaussianBlurElement: {
            prototype: SVGFEGaussianBlurElement;
            new(): SVGFEGaussianBlurElement;
        }
        
        interface SVGFilterPrimitiveStandardAttributes extends SVGStylable {
            y: SVGAnimatedLength;
            width: SVGAnimatedLength;
            x: SVGAnimatedLength;
            height: SVGAnimatedLength;
            result: SVGAnimatedString;
        }
        
        interface IDBVersionChangeEvent extends Event {
            newVersion: number;
            oldVersion: number;
        }
        declare var IDBVersionChangeEvent: {
            prototype: IDBVersionChangeEvent;
            new(): IDBVersionChangeEvent;
        }
        
        interface IDBIndex {
            unique: boolean;
            name: string;
            keyPath: string;
            objectStore: IDBObjectStore;
            count(key?: any): IDBRequest;
            getKey(key: any): IDBRequest;
            openKeyCursor(range?: IDBKeyRange, direction?: string): IDBRequest;
            get(key: any): IDBRequest;
            openCursor(range?: IDBKeyRange, direction?: string): IDBRequest;
        }
        declare var IDBIndex: {
            prototype: IDBIndex;
            new(): IDBIndex;
        }
        
        interface FileList {
            length: number;
            item(index: number): File;
            [index: number]: File;
        }
        declare var FileList: {
            prototype: FileList;
            new(): FileList;
        }
        
        interface IDBCursor {
            source: any;
            direction: string;
            key: any;
            primaryKey: any;
            advance(count: number): void;
            delete(): IDBRequest;
            continue(key?: any): void;
            update(value: any): IDBRequest;
            PREV: string;
            PREV_NO_DUPLICATE: string;
            NEXT: string;
            NEXT_NO_DUPLICATE: string;
        }
        declare var IDBCursor: {
            prototype: IDBCursor;
            new(): IDBCursor;
            PREV: string;
            PREV_NO_DUPLICATE: string;
            NEXT: string;
            NEXT_NO_DUPLICATE: string;
        }
        
        interface SVGFESpecularLightingElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            kernelUnitLengthY: SVGAnimatedNumber;
            surfaceScale: SVGAnimatedNumber;
            specularExponent: SVGAnimatedNumber;
            in1: SVGAnimatedString;
            kernelUnitLengthX: SVGAnimatedNumber;
            specularConstant: SVGAnimatedNumber;
        }
        declare var SVGFESpecularLightingElement: {
            prototype: SVGFESpecularLightingElement;
            new(): SVGFESpecularLightingElement;
        }
        
        interface File extends Blob {
            lastModifiedDate: any;
            name: string;
        }
        declare var File: {
            prototype: File;
            new(): File;
        }
        
        interface URL {
            revokeObjectURL(url: string): void;
            createObjectURL(object: any, options?: ObjectURLOptions): string;
        }
        declare var URL: URL;
        
        interface IDBCursorWithValue extends IDBCursor {
            value: any;
        }
        declare var IDBCursorWithValue: {
            prototype: IDBCursorWithValue;
            new(): IDBCursorWithValue;
        }
        
        interface XMLHttpRequestEventTarget extends EventTarget {
            onprogress: (ev: ProgressEvent) => any;
            onerror: (ev: ErrorEvent) => any;
            onload: (ev: Event) => any;
            ontimeout: (ev: Event) => any;
            onabort: (ev: UIEvent) => any;
            onloadstart: (ev: Event) => any;
            onloadend: (ev: ProgressEvent) => any;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "timeout", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "loadend", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var XMLHttpRequestEventTarget: {
            prototype: XMLHttpRequestEventTarget;
            new(): XMLHttpRequestEventTarget;
        }
        
        interface IDBEnvironment {
            msIndexedDB: IDBFactory;
            indexedDB: IDBFactory;
        }
        
        interface AudioTrackList extends EventTarget {
            length: number;
            onchange: (ev: Event) => any;
            onaddtrack: (ev: TrackEvent) => any;
            onremovetrack: (ev: any /*PluginArray*/) => any;
            getTrackById(id: string): AudioTrack;
            item(index: number): AudioTrack;
            [index: number]: AudioTrack;
            addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "addtrack", listener: (ev: TrackEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "removetrack", listener: (ev: any /*PluginArray*/) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var AudioTrackList: {
            prototype: AudioTrackList;
            new(): AudioTrackList;
        }
        
        interface MSBaseReader extends EventTarget {
            onprogress: (ev: ProgressEvent) => any;
            readyState: number;
            onabort: (ev: UIEvent) => any;
            onloadend: (ev: ProgressEvent) => any;
            onerror: (ev: ErrorEvent) => any;
            onload: (ev: Event) => any;
            onloadstart: (ev: Event) => any;
            result: any;
            abort(): void;
            LOADING: number;
            EMPTY: number;
            DONE: number;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "loadend", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        
        interface SVGFEMorphologyElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            operator: SVGAnimatedEnumeration;
            radiusX: SVGAnimatedNumber;
            radiusY: SVGAnimatedNumber;
            in1: SVGAnimatedString;
            SVG_MORPHOLOGY_OPERATOR_UNKNOWN: number;
            SVG_MORPHOLOGY_OPERATOR_ERODE: number;
            SVG_MORPHOLOGY_OPERATOR_DILATE: number;
        }
        declare var SVGFEMorphologyElement: {
            prototype: SVGFEMorphologyElement;
            new(): SVGFEMorphologyElement;
            SVG_MORPHOLOGY_OPERATOR_UNKNOWN: number;
            SVG_MORPHOLOGY_OPERATOR_ERODE: number;
            SVG_MORPHOLOGY_OPERATOR_DILATE: number;
        }
        
        interface SVGFEFuncRElement extends SVGComponentTransferFunctionElement {
        }
        declare var SVGFEFuncRElement: {
            prototype: SVGFEFuncRElement;
            new(): SVGFEFuncRElement;
        }
        
        interface WindowTimersExtension {
            msSetImmediate(expression: any, ...args: any[]): number;
            clearImmediate(handle: number): void;
            msClearImmediate(handle: number): void;
            setImmediate(expression: any, ...args: any[]): number;
        }
        
        interface SVGFEDisplacementMapElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            in2: SVGAnimatedString;
            xChannelSelector: SVGAnimatedEnumeration;
            yChannelSelector: SVGAnimatedEnumeration;
            scale: SVGAnimatedNumber;
            in1: SVGAnimatedString;
            SVG_CHANNEL_B: number;
            SVG_CHANNEL_R: number;
            SVG_CHANNEL_G: number;
            SVG_CHANNEL_UNKNOWN: number;
            SVG_CHANNEL_A: number;
        }
        declare var SVGFEDisplacementMapElement: {
            prototype: SVGFEDisplacementMapElement;
            new(): SVGFEDisplacementMapElement;
            SVG_CHANNEL_B: number;
            SVG_CHANNEL_R: number;
            SVG_CHANNEL_G: number;
            SVG_CHANNEL_UNKNOWN: number;
            SVG_CHANNEL_A: number;
        }
        
        interface AnimationEvent extends Event {
            animationName: string;
            elapsedTime: number;
            initAnimationEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, animationNameArg: string, elapsedTimeArg: number): void;
        }
        declare var AnimationEvent: {
            prototype: AnimationEvent;
            new(): AnimationEvent;
        }
        
        interface SVGComponentTransferFunctionElement extends SVGElement {
            tableValues: SVGAnimatedNumberList;
            slope: SVGAnimatedNumber;
            type: SVGAnimatedEnumeration;
            exponent: SVGAnimatedNumber;
            amplitude: SVGAnimatedNumber;
            intercept: SVGAnimatedNumber;
            offset: SVGAnimatedNumber;
            SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: number;
            SVG_FECOMPONENTTRANSFER_TYPE_TABLE: number;
            SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY: number;
            SVG_FECOMPONENTTRANSFER_TYPE_GAMMA: number;
            SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE: number;
            SVG_FECOMPONENTTRANSFER_TYPE_LINEAR: number;
        }
        declare var SVGComponentTransferFunctionElement: {
            prototype: SVGComponentTransferFunctionElement;
            new(): SVGComponentTransferFunctionElement;
            SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: number;
            SVG_FECOMPONENTTRANSFER_TYPE_TABLE: number;
            SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY: number;
            SVG_FECOMPONENTTRANSFER_TYPE_GAMMA: number;
            SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE: number;
            SVG_FECOMPONENTTRANSFER_TYPE_LINEAR: number;
        }
        
        interface MSRangeCollection {
            length: number;
            item(index: number): Range;
            [index: number]: Range;
        }
        declare var MSRangeCollection: {
            prototype: MSRangeCollection;
            new(): MSRangeCollection;
        }
        
        interface SVGFEDistantLightElement extends SVGElement {
            azimuth: SVGAnimatedNumber;
            elevation: SVGAnimatedNumber;
        }
        declare var SVGFEDistantLightElement: {
            prototype: SVGFEDistantLightElement;
            new(): SVGFEDistantLightElement;
        }
        
        interface SVGFEFuncBElement extends SVGComponentTransferFunctionElement {
        }
        declare var SVGFEFuncBElement: {
            prototype: SVGFEFuncBElement;
            new(): SVGFEFuncBElement;
        }
        
        interface IDBKeyRange {
            upper: any;
            upperOpen: boolean;
            lower: any;
            lowerOpen: boolean;
        }
        declare var IDBKeyRange: {
            prototype: IDBKeyRange;
            new(): IDBKeyRange;
            bound(lower: any, upper: any, lowerOpen?: boolean, upperOpen?: boolean): IDBKeyRange;
            only(value: any): IDBKeyRange;
            lowerBound(bound: any, open?: boolean): IDBKeyRange;
            upperBound(bound: any, open?: boolean): IDBKeyRange;
        }
        
        interface WindowConsole {
            console: Console;
        }
        
        interface IDBTransaction extends EventTarget {
            oncomplete: (ev: Event) => any;
            db: IDBDatabase;
            mode: string;
            error: DOMError;
            onerror: (ev: ErrorEvent) => any;
            onabort: (ev: UIEvent) => any;
            abort(): void;
            objectStore(name: string): IDBObjectStore;
            READ_ONLY: string;
            VERSION_CHANGE: string;
            READ_WRITE: string;
            addEventListener(type: "complete", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var IDBTransaction: {
            prototype: IDBTransaction;
            new(): IDBTransaction;
            READ_ONLY: string;
            VERSION_CHANGE: string;
            READ_WRITE: string;
        }
        
        interface AudioTrack {
            kind: string;
            language: string;
            id: string;
            label: string;
            enabled: boolean;
            sourceBuffer: SourceBuffer;
        }
        declare var AudioTrack: {
            prototype: AudioTrack;
            new(): AudioTrack;
        }
        
        interface SVGFEConvolveMatrixElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            orderY: SVGAnimatedInteger;
            kernelUnitLengthY: SVGAnimatedNumber;
            orderX: SVGAnimatedInteger;
            preserveAlpha: SVGAnimatedBoolean;
            kernelMatrix: SVGAnimatedNumberList;
            edgeMode: SVGAnimatedEnumeration;
            kernelUnitLengthX: SVGAnimatedNumber;
            bias: SVGAnimatedNumber;
            targetX: SVGAnimatedInteger;
            targetY: SVGAnimatedInteger;
            divisor: SVGAnimatedNumber;
            in1: SVGAnimatedString;
            SVG_EDGEMODE_WRAP: number;
            SVG_EDGEMODE_DUPLICATE: number;
            SVG_EDGEMODE_UNKNOWN: number;
            SVG_EDGEMODE_NONE: number;
        }
        declare var SVGFEConvolveMatrixElement: {
            prototype: SVGFEConvolveMatrixElement;
            new(): SVGFEConvolveMatrixElement;
            SVG_EDGEMODE_WRAP: number;
            SVG_EDGEMODE_DUPLICATE: number;
            SVG_EDGEMODE_UNKNOWN: number;
            SVG_EDGEMODE_NONE: number;
        }
        
        interface TextTrackCueList {
            length: number;
            item(index: number): TextTrackCue;
            [index: number]: TextTrackCue;
            getCueById(id: string): TextTrackCue;
        }
        declare var TextTrackCueList: {
            prototype: TextTrackCueList;
            new(): TextTrackCueList;
        }
        
        interface CSSKeyframesRule extends CSSRule {
            name: string;
            cssRules: CSSRuleList;
            findRule(rule: string): CSSKeyframeRule;
            deleteRule(rule: string): void;
            appendRule(rule: string): void;
        }
        declare var CSSKeyframesRule: {
            prototype: CSSKeyframesRule;
            new(): CSSKeyframesRule;
        }
        
        interface SVGFETurbulenceElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            baseFrequencyX: SVGAnimatedNumber;
            numOctaves: SVGAnimatedInteger;
            type: SVGAnimatedEnumeration;
            baseFrequencyY: SVGAnimatedNumber;
            stitchTiles: SVGAnimatedEnumeration;
            seed: SVGAnimatedNumber;
            SVG_STITCHTYPE_UNKNOWN: number;
            SVG_STITCHTYPE_NOSTITCH: number;
            SVG_TURBULENCE_TYPE_UNKNOWN: number;
            SVG_TURBULENCE_TYPE_TURBULENCE: number;
            SVG_TURBULENCE_TYPE_FRACTALNOISE: number;
            SVG_STITCHTYPE_STITCH: number;
        }
        declare var SVGFETurbulenceElement: {
            prototype: SVGFETurbulenceElement;
            new(): SVGFETurbulenceElement;
            SVG_STITCHTYPE_UNKNOWN: number;
            SVG_STITCHTYPE_NOSTITCH: number;
            SVG_TURBULENCE_TYPE_UNKNOWN: number;
            SVG_TURBULENCE_TYPE_TURBULENCE: number;
            SVG_TURBULENCE_TYPE_FRACTALNOISE: number;
            SVG_STITCHTYPE_STITCH: number;
        }
        
        interface TextTrackList extends EventTarget {
            length: number;
            onaddtrack: (ev: TrackEvent) => any;
            item(index: number): TextTrack;
            [index: number]: TextTrack;
            addEventListener(type: "addtrack", listener: (ev: TrackEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var TextTrackList: {
            prototype: TextTrackList;
            new(): TextTrackList;
        }
        
        interface SVGFEFuncGElement extends SVGComponentTransferFunctionElement {
        }
        declare var SVGFEFuncGElement: {
            prototype: SVGFEFuncGElement;
            new(): SVGFEFuncGElement;
        }
        
        interface SVGFEColorMatrixElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            in1: SVGAnimatedString;
            type: SVGAnimatedEnumeration;
            values: SVGAnimatedNumberList;
            SVG_FECOLORMATRIX_TYPE_SATURATE: number;
            SVG_FECOLORMATRIX_TYPE_UNKNOWN: number;
            SVG_FECOLORMATRIX_TYPE_MATRIX: number;
            SVG_FECOLORMATRIX_TYPE_HUEROTATE: number;
            SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA: number;
        }
        declare var SVGFEColorMatrixElement: {
            prototype: SVGFEColorMatrixElement;
            new(): SVGFEColorMatrixElement;
            SVG_FECOLORMATRIX_TYPE_SATURATE: number;
            SVG_FECOLORMATRIX_TYPE_UNKNOWN: number;
            SVG_FECOLORMATRIX_TYPE_MATRIX: number;
            SVG_FECOLORMATRIX_TYPE_HUEROTATE: number;
            SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA: number;
        }
        
        interface SVGFESpotLightElement extends SVGElement {
            pointsAtY: SVGAnimatedNumber;
            y: SVGAnimatedNumber;
            limitingConeAngle: SVGAnimatedNumber;
            specularExponent: SVGAnimatedNumber;
            x: SVGAnimatedNumber;
            pointsAtZ: SVGAnimatedNumber;
            z: SVGAnimatedNumber;
            pointsAtX: SVGAnimatedNumber;
        }
        declare var SVGFESpotLightElement: {
            prototype: SVGFESpotLightElement;
            new(): SVGFESpotLightElement;
        }
        
        interface WindowBase64 {
            btoa(rawString: string): string;
            atob(encodedString: string): string;
        }
        
        interface IDBDatabase extends EventTarget {
            version: string;
            name: string;
            objectStoreNames: DOMStringList;
            onerror: (ev: ErrorEvent) => any;
            onabort: (ev: UIEvent) => any;
            createObjectStore(name: string, optionalParameters?: any): IDBObjectStore;
            close(): void;
            transaction(storeNames: any, mode?: string): IDBTransaction;
            deleteObjectStore(name: string): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var IDBDatabase: {
            prototype: IDBDatabase;
            new(): IDBDatabase;
        }
        
        interface DOMStringList {
            length: number;
            contains(str: string): boolean;
            item(index: number): string;
            [index: number]: string;
        }
        declare var DOMStringList: {
            prototype: DOMStringList;
            new(): DOMStringList;
        }
        
        interface IDBOpenDBRequest extends IDBRequest {
            onupgradeneeded: (ev: IDBVersionChangeEvent) => any;
            onblocked: (ev: Event) => any;
            addEventListener(type: "success", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "upgradeneeded", listener: (ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "blocked", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var IDBOpenDBRequest: {
            prototype: IDBOpenDBRequest;
            new(): IDBOpenDBRequest;
        }
        
        interface HTMLProgressElement extends HTMLElement {
            /**
              * Sets or gets the current value of a progress element. The value must be a non-negative number between 0 and the max value.
              */
            value: number;
            /**
              * Defines the maximum, or "done" value for a progress element.
              */
            max: number;
            /**
              * Returns the quotient of value/max when the value attribute is set (determinate progress bar), or -1 when the value attribute is missing (indeterminate progress bar).
              */
            position: number;
            /**
              * Retrieves a reference to the form that the object is embedded in.
              */
            form: HTMLFormElement;
        }
        declare var HTMLProgressElement: {
            prototype: HTMLProgressElement;
            new(): HTMLProgressElement;
        }
        
        interface MSLaunchUriCallback {
            (): void;
        }
        
        interface SVGFEOffsetElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            dy: SVGAnimatedNumber;
            in1: SVGAnimatedString;
            dx: SVGAnimatedNumber;
        }
        declare var SVGFEOffsetElement: {
            prototype: SVGFEOffsetElement;
            new(): SVGFEOffsetElement;
        }
        
        interface MSUnsafeFunctionCallback {
            (): any;
        }
        
        interface TextTrack extends EventTarget {
            language: string;
            mode: any;
            readyState: number;
            activeCues: TextTrackCueList;
            cues: TextTrackCueList;
            oncuechange: (ev: Event) => any;
            kind: string;
            onload: (ev: Event) => any;
            onerror: (ev: ErrorEvent) => any;
            label: string;
            addCue(cue: TextTrackCue): void;
            removeCue(cue: TextTrackCue): void;
            ERROR: number;
            SHOWING: number;
            LOADING: number;
            LOADED: number;
            NONE: number;
            HIDDEN: number;
            DISABLED: number;
            addEventListener(type: "cuechange", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var TextTrack: {
            prototype: TextTrack;
            new(): TextTrack;
            ERROR: number;
            SHOWING: number;
            LOADING: number;
            LOADED: number;
            NONE: number;
            HIDDEN: number;
            DISABLED: number;
        }
        
        interface MediaQueryListListener {
            (mql: MediaQueryList): void;
        }
        
        interface IDBRequest extends EventTarget {
            source: any;
            onsuccess: (ev: Event) => any;
            error: DOMError;
            transaction: IDBTransaction;
            onerror: (ev: ErrorEvent) => any;
            readyState: string;
            result: any;
            addEventListener(type: "success", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var IDBRequest: {
            prototype: IDBRequest;
            new(): IDBRequest;
        }
        
        interface MessagePort extends EventTarget {
            onmessage: (ev: MessageEvent) => any;
            close(): void;
            postMessage(message?: any, ports?: any): void;
            start(): void;
            addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var MessagePort: {
            prototype: MessagePort;
            new(): MessagePort;
        }
        
        interface FileReader extends MSBaseReader {
            error: DOMError;
            readAsArrayBuffer(blob: Blob): void;
            readAsDataURL(blob: Blob): void;
            readAsText(blob: Blob, encoding?: string): void;
        }
        declare var FileReader: {
            prototype: FileReader;
            new(): FileReader;
        }
        
        interface ApplicationCache extends EventTarget {
            status: number;
            ondownloading: (ev: Event) => any;
            onprogress: (ev: ProgressEvent) => any;
            onupdateready: (ev: Event) => any;
            oncached: (ev: Event) => any;
            onobsolete: (ev: Event) => any;
            onerror: (ev: ErrorEvent) => any;
            onchecking: (ev: Event) => any;
            onnoupdate: (ev: Event) => any;
            swapCache(): void;
            abort(): void;
            update(): void;
            CHECKING: number;
            UNCACHED: number;
            UPDATEREADY: number;
            DOWNLOADING: number;
            IDLE: number;
            OBSOLETE: number;
            addEventListener(type: "downloading", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "updateready", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "cached", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "obsolete", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "checking", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "noupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var ApplicationCache: {
            prototype: ApplicationCache;
            new(): ApplicationCache;
            CHECKING: number;
            UNCACHED: number;
            UPDATEREADY: number;
            DOWNLOADING: number;
            IDLE: number;
            OBSOLETE: number;
        }
        
        interface FrameRequestCallback {
            (time: number): void;
        }
        
        interface PopStateEvent extends Event {
            state: any;
            initPopStateEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, stateArg: any): void;
        }
        declare var PopStateEvent: {
            prototype: PopStateEvent;
            new(): PopStateEvent;
        }
        
        interface CSSKeyframeRule extends CSSRule {
            keyText: string;
            style: CSSStyleDeclaration;
        }
        declare var CSSKeyframeRule: {
            prototype: CSSKeyframeRule;
            new(): CSSKeyframeRule;
        }
        
        interface MSFileSaver {
            msSaveBlob(blob: any, defaultName?: string): boolean;
            msSaveOrOpenBlob(blob: any, defaultName?: string): boolean;
        }
        
        interface MSStream {
            type: string;
            msDetachStream(): any;
            msClose(): void;
        }
        declare var MSStream: {
            prototype: MSStream;
            new(): MSStream;
        }
        
        interface MSBlobBuilder {
            append(data: any, endings?: string): void;
            getBlob(contentType?: string): Blob;
        }
        declare var MSBlobBuilder: {
            prototype: MSBlobBuilder;
            new(): MSBlobBuilder;
        }
        
        interface DOMSettableTokenList extends DOMTokenList {
            value: string;
        }
        declare var DOMSettableTokenList: {
            prototype: DOMSettableTokenList;
            new(): DOMSettableTokenList;
        }
        
        interface IDBFactory {
            open(name: string, version?: number): IDBOpenDBRequest;
            cmp(first: any, second: any): number;
            deleteDatabase(name: string): IDBOpenDBRequest;
        }
        declare var IDBFactory: {
            prototype: IDBFactory;
            new(): IDBFactory;
        }
        
        interface MSPointerEvent extends MouseEvent {
            width: number;
            rotation: number;
            pressure: number;
            pointerType: any;
            isPrimary: boolean;
            tiltY: number;
            height: number;
            intermediatePoints: any;
            currentPoint: any;
            tiltX: number;
            hwTimestamp: number;
            pointerId: number;
            initPointerEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, ctrlKeyArg: boolean, altKeyArg: boolean, shiftKeyArg: boolean, metaKeyArg: boolean, buttonArg: number, relatedTargetArg: EventTarget, offsetXArg: number, offsetYArg: number, widthArg: number, heightArg: number, pressure: number, rotation: number, tiltX: number, tiltY: number, pointerIdArg: number, pointerType: any, hwTimestampArg: number, isPrimary: boolean): void;
            getCurrentPoint(element: Element): void;
            getIntermediatePoints(element: Element): void;
            MSPOINTER_TYPE_PEN: number;
            MSPOINTER_TYPE_MOUSE: number;
            MSPOINTER_TYPE_TOUCH: number;
        }
        declare var MSPointerEvent: {
            prototype: MSPointerEvent;
            new(): MSPointerEvent;
            MSPOINTER_TYPE_PEN: number;
            MSPOINTER_TYPE_MOUSE: number;
            MSPOINTER_TYPE_TOUCH: number;
        }
        
        interface MSManipulationEvent extends UIEvent {
            lastState: number;
            currentState: number;
            initMSManipulationEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, lastState: number, currentState: number): void;
            MS_MANIPULATION_STATE_STOPPED: number;
            MS_MANIPULATION_STATE_ACTIVE: number;
            MS_MANIPULATION_STATE_INERTIA: number;
            MS_MANIPULATION_STATE_SELECTING: number;
            MS_MANIPULATION_STATE_COMMITTED: number;
            MS_MANIPULATION_STATE_PRESELECT: number;
            MS_MANIPULATION_STATE_DRAGGING: number;
            MS_MANIPULATION_STATE_CANCELLED: number;
        }
        declare var MSManipulationEvent: {
            prototype: MSManipulationEvent;
            new(): MSManipulationEvent;
            MS_MANIPULATION_STATE_STOPPED: number;
            MS_MANIPULATION_STATE_ACTIVE: number;
            MS_MANIPULATION_STATE_INERTIA: number;
            MS_MANIPULATION_STATE_SELECTING: number;
            MS_MANIPULATION_STATE_COMMITTED: number;
            MS_MANIPULATION_STATE_PRESELECT: number;
            MS_MANIPULATION_STATE_DRAGGING: number;
            MS_MANIPULATION_STATE_CANCELLED: number;
        }
        
        interface FormData {
            append(name: any, value: any, blobName?: string): void;
        }
        declare var FormData: {
            prototype: FormData;
            new(): FormData;
        }
        
        interface HTMLDataListElement extends HTMLElement {
            options: HTMLCollection;
        }
        declare var HTMLDataListElement: {
            prototype: HTMLDataListElement;
            new(): HTMLDataListElement;
        }
        
        interface SVGFEImageElement extends SVGElement, SVGLangSpace, SVGFilterPrimitiveStandardAttributes, SVGURIReference, SVGExternalResourcesRequired {
            preserveAspectRatio: SVGAnimatedPreserveAspectRatio;
        }
        declare var SVGFEImageElement: {
            prototype: SVGFEImageElement;
            new(): SVGFEImageElement;
        }
        
        interface AbstractWorker extends EventTarget {
            onerror: (ev: ErrorEvent) => any;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        
        interface SVGFECompositeElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            operator: SVGAnimatedEnumeration;
            in2: SVGAnimatedString;
            k2: SVGAnimatedNumber;
            k1: SVGAnimatedNumber;
            k3: SVGAnimatedNumber;
            in1: SVGAnimatedString;
            k4: SVGAnimatedNumber;
            SVG_FECOMPOSITE_OPERATOR_OUT: number;
            SVG_FECOMPOSITE_OPERATOR_OVER: number;
            SVG_FECOMPOSITE_OPERATOR_XOR: number;
            SVG_FECOMPOSITE_OPERATOR_ARITHMETIC: number;
            SVG_FECOMPOSITE_OPERATOR_UNKNOWN: number;
            SVG_FECOMPOSITE_OPERATOR_IN: number;
            SVG_FECOMPOSITE_OPERATOR_ATOP: number;
        }
        declare var SVGFECompositeElement: {
            prototype: SVGFECompositeElement;
            new(): SVGFECompositeElement;
            SVG_FECOMPOSITE_OPERATOR_OUT: number;
            SVG_FECOMPOSITE_OPERATOR_OVER: number;
            SVG_FECOMPOSITE_OPERATOR_XOR: number;
            SVG_FECOMPOSITE_OPERATOR_ARITHMETIC: number;
            SVG_FECOMPOSITE_OPERATOR_UNKNOWN: number;
            SVG_FECOMPOSITE_OPERATOR_IN: number;
            SVG_FECOMPOSITE_OPERATOR_ATOP: number;
        }
        
        interface ValidityState {
            customError: boolean;
            valueMissing: boolean;
            stepMismatch: boolean;
            rangeUnderflow: boolean;
            rangeOverflow: boolean;
            typeMismatch: boolean;
            patternMismatch: boolean;
            tooLong: boolean;
            valid: boolean;
        }
        declare var ValidityState: {
            prototype: ValidityState;
            new(): ValidityState;
        }
        
        interface HTMLTrackElement extends HTMLElement {
            kind: string;
            src: string;
            srclang: string;
            track: TextTrack;
            label: string;
            default: boolean;
            readyState: number;
            ERROR: number;
            LOADING: number;
            LOADED: number;
            NONE: number;
        }
        declare var HTMLTrackElement: {
            prototype: HTMLTrackElement;
            new(): HTMLTrackElement;
            ERROR: number;
            LOADING: number;
            LOADED: number;
            NONE: number;
        }
        
        interface MSApp {
            createFileFromStorageFile(storageFile: any): File;
            createBlobFromRandomAccessStream(type: string, seeker: any): Blob;
            createStreamFromInputStream(type: string, inputStream: any): MSStream;
            terminateApp(exceptionObject: any): void;
            createDataPackage(object: any): any;
            execUnsafeLocalFunction(unsafeFunction: MSUnsafeFunctionCallback): any;
            getHtmlPrintDocumentSource(htmlDoc: any): any;
            addPublicLocalApplicationUri(uri: string): void;
            createDataPackageFromSelection(): any;
            getViewOpener(): MSAppView;
            suppressSubdownloadCredentialPrompts(suppress: boolean): void;
            execAsyncAtPriority(asynchronousCallback: MSExecAtPriorityFunctionCallback, priority: string, ...args: any[]): void;
            isTaskScheduledAtPriorityOrHigher(priority: string): boolean;
            execAtPriority(synchronousCallback: MSExecAtPriorityFunctionCallback, priority: string, ...args: any[]): any;
            createNewView(uri: string): MSAppView;
            getCurrentPriority(): string;
            NORMAL: string;
            HIGH: string;
            IDLE: string;
            CURRENT: string;
        }
        declare var MSApp: MSApp;
        
        interface SVGFEComponentTransferElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            in1: SVGAnimatedString;
        }
        declare var SVGFEComponentTransferElement: {
            prototype: SVGFEComponentTransferElement;
            new(): SVGFEComponentTransferElement;
        }
        
        interface SVGFEDiffuseLightingElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {
            kernelUnitLengthY: SVGAnimatedNumber;
            surfaceScale: SVGAnimatedNumber;
            in1: SVGAnimatedString;
            kernelUnitLengthX: SVGAnimatedNumber;
            diffuseConstant: SVGAnimatedNumber;
        }
        declare var SVGFEDiffuseLightingElement: {
            prototype: SVGFEDiffuseLightingElement;
            new(): SVGFEDiffuseLightingElement;
        }
        
        interface MSCSSMatrix {
            m24: number;
            m34: number;
            a: number;
            d: number;
            m32: number;
            m41: number;
            m11: number;
            f: number;
            e: number;
            m23: number;
            m14: number;
            m33: number;
            m22: number;
            m21: number;
            c: number;
            m12: number;
            b: number;
            m42: number;
            m31: number;
            m43: number;
            m13: number;
            m44: number;
            multiply(secondMatrix: MSCSSMatrix): MSCSSMatrix;
            skewY(angle: number): MSCSSMatrix;
            setMatrixValue(value: string): void;
            inverse(): MSCSSMatrix;
            rotateAxisAngle(x: number, y: number, z: number, angle: number): MSCSSMatrix;
            toString(): string;
            rotate(angleX: number, angleY?: number, angleZ?: number): MSCSSMatrix;
            translate(x: number, y: number, z?: number): MSCSSMatrix;
            scale(scaleX: number, scaleY?: number, scaleZ?: number): MSCSSMatrix;
            skewX(angle: number): MSCSSMatrix;
        }
        declare var MSCSSMatrix: {
            prototype: MSCSSMatrix;
            new(text?: string): MSCSSMatrix;
        }
        
        interface Worker extends AbstractWorker {
            onmessage: (ev: MessageEvent) => any;
            postMessage(message: any, ports?: any): void;
            terminate(): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var Worker: {
            prototype: Worker;
            new(stringUrl: string): Worker;
        }
        
        interface MSExecAtPriorityFunctionCallback {
            (...args: any[]): any;
        }
        
        interface MSGraphicsTrust {
            status: string;
            constrictionActive: boolean;
        }
        declare var MSGraphicsTrust: {
            prototype: MSGraphicsTrust;
            new(): MSGraphicsTrust;
        }
        
        interface SubtleCrypto {
            unwrapKey(wrappedKey: ArrayBufferView, keyAlgorithm: any, keyEncryptionKey: Key, extractable?: boolean, keyUsages?: string[]): KeyOperation;
            encrypt(algorithm: any, key: Key, buffer?: ArrayBufferView): CryptoOperation;
            importKey(format: string, keyData: ArrayBufferView, algorithm: any, extractable?: boolean, keyUsages?: string[]): KeyOperation;
            wrapKey(key: Key, keyEncryptionKey: Key, keyWrappingAlgorithm: any): KeyOperation;
            verify(algorithm: any, key: Key, signature: ArrayBufferView, buffer?: ArrayBufferView): CryptoOperation;
            deriveKey(algorithm: any, baseKey: Key, derivedKeyType: any, extractable?: boolean, keyUsages?: string[]): KeyOperation;
            digest(algorithm: any, buffer?: ArrayBufferView): CryptoOperation;
            exportKey(format: string, key: Key): KeyOperation;
            generateKey(algorithm: any, extractable?: boolean, keyUsages?: string[]): KeyOperation;
            sign(algorithm: any, key: Key, buffer?: ArrayBufferView): CryptoOperation;
            decrypt(algorithm: any, key: Key, buffer?: ArrayBufferView): CryptoOperation;
        }
        declare var SubtleCrypto: {
            prototype: SubtleCrypto;
            new(): SubtleCrypto;
        }
        
        interface Crypto extends RandomSource {
            subtle: SubtleCrypto;
        }
        declare var Crypto: {
            prototype: Crypto;
            new(): Crypto;
        }
        
        interface VideoPlaybackQuality {
            totalFrameDelay: number;
            creationTime: number;
            totalVideoFrames: number;
            droppedVideoFrames: number;
        }
        declare var VideoPlaybackQuality: {
            prototype: VideoPlaybackQuality;
            new(): VideoPlaybackQuality;
        }
        
        interface GlobalEventHandlers {
            onpointerenter: (ev: PointerEvent) => any;
            onpointerout: (ev: PointerEvent) => any;
            onpointerdown: (ev: PointerEvent) => any;
            onpointerup: (ev: PointerEvent) => any;
            onpointercancel: (ev: PointerEvent) => any;
            onpointerover: (ev: PointerEvent) => any;
            onpointermove: (ev: PointerEvent) => any;
            onpointerleave: (ev: PointerEvent) => any;
            addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        
        interface Key {
            algorithm: Algorithm;
            type: string;
            extractable: boolean;
            keyUsage: string[];
        }
        declare var Key: {
            prototype: Key;
            new(): Key;
        }
        
        interface DeviceAcceleration {
            y: number;
            x: number;
            z: number;
        }
        declare var DeviceAcceleration: {
            prototype: DeviceAcceleration;
            new(): DeviceAcceleration;
        }
        
        interface HTMLAllCollection extends HTMLCollection {
            namedItem(name: string): Element;
            // [name: string]: Element;
        }
        declare var HTMLAllCollection: {
            prototype: HTMLAllCollection;
            new(): HTMLAllCollection;
        }
        
        interface AesGcmEncryptResult {
            ciphertext: ArrayBuffer;
            tag: ArrayBuffer;
        }
        declare var AesGcmEncryptResult: {
            prototype: AesGcmEncryptResult;
            new(): AesGcmEncryptResult;
        }
        
        interface NavigationCompletedEvent extends NavigationEvent {
            webErrorStatus: number;
            isSuccess: boolean;
        }
        declare var NavigationCompletedEvent: {
            prototype: NavigationCompletedEvent;
            new(): NavigationCompletedEvent;
        }
        
        interface MutationRecord {
            oldValue: string;
            previousSibling: Node;
            addedNodes: NodeList;
            attributeName: string;
            removedNodes: NodeList;
            target: Node;
            nextSibling: Node;
            attributeNamespace: string;
            type: string;
        }
        declare var MutationRecord: {
            prototype: MutationRecord;
            new(): MutationRecord;
        }
        
        interface MimeTypeArray {
            length: number;
            item(index: number): Plugin;
            [index: number]: Plugin;
            namedItem(type: string): Plugin;
            // [type: string]: Plugin;
        }
        declare var MimeTypeArray: {
            prototype: MimeTypeArray;
            new(): MimeTypeArray;
        }
        
        interface KeyOperation extends EventTarget {
            oncomplete: (ev: Event) => any;
            onerror: (ev: ErrorEvent) => any;
            result: any;
            addEventListener(type: "complete", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var KeyOperation: {
            prototype: KeyOperation;
            new(): KeyOperation;
        }
        
        interface DOMStringMap {
        }
        declare var DOMStringMap: {
            prototype: DOMStringMap;
            new(): DOMStringMap;
        }
        
        interface DeviceOrientationEvent extends Event {
            gamma: number;
            alpha: number;
            absolute: boolean;
            beta: number;
            initDeviceOrientationEvent(type: string, bubbles: boolean, cancelable: boolean, alpha: number, beta: number, gamma: number, absolute: boolean): void;
        }
        declare var DeviceOrientationEvent: {
            prototype: DeviceOrientationEvent;
            new(): DeviceOrientationEvent;
        }
        
        interface MSMediaKeys {
            keySystem: string;
            createSession(type: string, initData: Uint8Array, cdmData?: Uint8Array): MSMediaKeySession;
        }
        declare var MSMediaKeys: {
            prototype: MSMediaKeys;
            new(keySystem: string): MSMediaKeys;
            isTypeSupported(keySystem: string, type?: string): boolean;
        }
        
        interface MSMediaKeyMessageEvent extends Event {
            destinationURL: string;
            message: Uint8Array;
        }
        declare var MSMediaKeyMessageEvent: {
            prototype: MSMediaKeyMessageEvent;
            new(): MSMediaKeyMessageEvent;
        }
        
        interface MSHTMLWebViewElement extends HTMLElement {
            documentTitle: string;
            width: number;
            src: string;
            canGoForward: boolean;
            height: number;
            canGoBack: boolean;
            navigateWithHttpRequestMessage(requestMessage: any): void;
            goBack(): void;
            navigate(uri: string): void;
            stop(): void;
            navigateToString(contents: string): void;
            captureSelectedContentToDataPackageAsync(): MSWebViewAsyncOperation;
            capturePreviewToBlobAsync(): MSWebViewAsyncOperation;
            refresh(): void;
            goForward(): void;
            navigateToLocalStreamUri(source: string, streamResolver: any): void;
            invokeScriptAsync(scriptName: string, ...args: any[]): MSWebViewAsyncOperation;
            buildLocalStreamUri(contentIdentifier: string, relativePath: string): string;
        }
        declare var MSHTMLWebViewElement: {
            prototype: MSHTMLWebViewElement;
            new(): MSHTMLWebViewElement;
        }
        
        interface NavigationEvent extends Event {
            uri: string;
        }
        declare var NavigationEvent: {
            prototype: NavigationEvent;
            new(): NavigationEvent;
        }
        
        interface RandomSource {
            getRandomValues(array: ArrayBufferView): ArrayBufferView;
        }
        
        interface SourceBuffer extends EventTarget {
            updating: boolean;
            appendWindowStart: number;
            appendWindowEnd: number;
            buffered: TimeRanges;
            timestampOffset: number;
            audioTracks: AudioTrackList;
            appendBuffer(data: ArrayBuffer): void;
            remove(start: number, end: number): void;
            abort(): void;
            appendStream(stream: MSStream, maxSize?: number): void;
        }
        declare var SourceBuffer: {
            prototype: SourceBuffer;
            new(): SourceBuffer;
        }
        
        interface MSInputMethodContext extends EventTarget {
            oncandidatewindowshow: (ev: any) => any;
            target: HTMLElement;
            compositionStartOffset: number;
            oncandidatewindowhide: (ev: any) => any;
            oncandidatewindowupdate: (ev: any) => any;
            compositionEndOffset: number;
            getCompositionAlternatives(): string[];
            getCandidateWindowClientRect(): ClientRect;
            hasComposition(): boolean;
            isCandidateWindowVisible(): boolean;
            addEventListener(type: "candidatewindowshow", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "candidatewindowhide", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: "candidatewindowupdate", listener: (ev: any) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var MSInputMethodContext: {
            prototype: MSInputMethodContext;
            new(): MSInputMethodContext;
        }
        
        interface DeviceRotationRate {
            gamma: number;
            alpha: number;
            beta: number;
        }
        declare var DeviceRotationRate: {
            prototype: DeviceRotationRate;
            new(): DeviceRotationRate;
        }
        
        interface PluginArray {
            length: number;
            refresh(reload?: boolean): void;
            item(index: number): Plugin;
            [index: number]: Plugin;
            namedItem(name: string): Plugin;
            // [name: string]: Plugin;
        }
        declare var PluginArray: {
            prototype: PluginArray;
            new(): PluginArray;
        }
        
        interface MSMediaKeyError {
            systemCode: number;
            code: number;
            MS_MEDIA_KEYERR_SERVICE: number;
            MS_MEDIA_KEYERR_HARDWARECHANGE: number;
            MS_MEDIA_KEYERR_OUTPUT: number;
            MS_MEDIA_KEYERR_DOMAIN: number;
            MS_MEDIA_KEYERR_UNKNOWN: number;
            MS_MEDIA_KEYERR_CLIENT: number;
        }
        declare var MSMediaKeyError: {
            prototype: MSMediaKeyError;
            new(): MSMediaKeyError;
            MS_MEDIA_KEYERR_SERVICE: number;
            MS_MEDIA_KEYERR_HARDWARECHANGE: number;
            MS_MEDIA_KEYERR_OUTPUT: number;
            MS_MEDIA_KEYERR_DOMAIN: number;
            MS_MEDIA_KEYERR_UNKNOWN: number;
            MS_MEDIA_KEYERR_CLIENT: number;
        }
        
        interface Plugin {
            length: number;
            filename: string;
            version: string;
            name: string;
            description: string;
            item(index: number): MimeType;
            [index: number]: MimeType;
            namedItem(type: string): MimeType;
            // [type: string]: MimeType;
        }
        declare var Plugin: {
            prototype: Plugin;
            new(): Plugin;
        }
        
        interface MediaSource extends EventTarget {
            sourceBuffers: SourceBufferList;
            duration: number;
            readyState: string;
            activeSourceBuffers: SourceBufferList;
            addSourceBuffer(type: string): SourceBuffer;
            endOfStream(error?: string): void;
            removeSourceBuffer(sourceBuffer: SourceBuffer): void;
        }
        declare var MediaSource: {
            prototype: MediaSource;
            new(): MediaSource;
            isTypeSupported(type: string): boolean;
        }
        
        interface SourceBufferList extends EventTarget {
            length: number;
            item(index: number): SourceBuffer;
            [index: number]: SourceBuffer;
        }
        declare var SourceBufferList: {
            prototype: SourceBufferList;
            new(): SourceBufferList;
        }
        
        interface XMLDocument extends Document {
        }
        declare var XMLDocument: {
            prototype: XMLDocument;
            new(): XMLDocument;
        }
        
        interface DeviceMotionEvent extends Event {
            rotationRate: DeviceRotationRate;
            acceleration: DeviceAcceleration;
            interval: number;
            accelerationIncludingGravity: DeviceAcceleration;
            initDeviceMotionEvent(type: string, bubbles: boolean, cancelable: boolean, acceleration: DeviceAccelerationDict, accelerationIncludingGravity: DeviceAccelerationDict, rotationRate: DeviceRotationRateDict, interval: number): void;
        }
        declare var DeviceMotionEvent: {
            prototype: DeviceMotionEvent;
            new(): DeviceMotionEvent;
        }
        
        interface MimeType {
            enabledPlugin: Plugin;
            suffixes: string;
            type: string;
            description: string;
        }
        declare var MimeType: {
            prototype: MimeType;
            new(): MimeType;
        }
        
        interface PointerEvent extends MouseEvent {
            width: number;
            rotation: number;
            pressure: number;
            pointerType: any;
            isPrimary: boolean;
            tiltY: number;
            height: number;
            intermediatePoints: any;
            currentPoint: any;
            tiltX: number;
            hwTimestamp: number;
            pointerId: number;
            initPointerEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, ctrlKeyArg: boolean, altKeyArg: boolean, shiftKeyArg: boolean, metaKeyArg: boolean, buttonArg: number, relatedTargetArg: EventTarget, offsetXArg: number, offsetYArg: number, widthArg: number, heightArg: number, pressure: number, rotation: number, tiltX: number, tiltY: number, pointerIdArg: number, pointerType: any, hwTimestampArg: number, isPrimary: boolean): void;
            getCurrentPoint(element: Element): void;
            getIntermediatePoints(element: Element): void;
        }
        declare var PointerEvent: {
            prototype: PointerEvent;
            new(): PointerEvent;
        }
        
        interface MSDocumentExtensions {
            captureEvents(): void;
            releaseEvents(): void;
        }
        
        interface MutationObserver {
            observe(target: Node, options: MutationObserverInit): void;
            takeRecords(): MutationRecord[];
            disconnect(): void;
        }
        declare var MutationObserver: {
            prototype: MutationObserver;
            new (callback: (arr: MutationRecord[], observer: MutationObserver)=>any): MutationObserver;
        }
        
        interface MSWebViewAsyncOperation extends EventTarget {
            target: MSHTMLWebViewElement;
            oncomplete: (ev: Event) => any;
            error: DOMError;
            onerror: (ev: ErrorEvent) => any;
            readyState: number;
            type: number;
            result: any;
            start(): void;
            ERROR: number;
            TYPE_CREATE_DATA_PACKAGE_FROM_SELECTION: number;
            TYPE_INVOKE_SCRIPT: number;
            COMPLETED: number;
            TYPE_CAPTURE_PREVIEW_TO_RANDOM_ACCESS_STREAM: number;
            STARTED: number;
            addEventListener(type: "complete", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var MSWebViewAsyncOperation: {
            prototype: MSWebViewAsyncOperation;
            new(): MSWebViewAsyncOperation;
            ERROR: number;
            TYPE_CREATE_DATA_PACKAGE_FROM_SELECTION: number;
            TYPE_INVOKE_SCRIPT: number;
            COMPLETED: number;
            TYPE_CAPTURE_PREVIEW_TO_RANDOM_ACCESS_STREAM: number;
            STARTED: number;
        }
        
        interface ScriptNotifyEvent extends Event {
            value: string;
            callingUri: string;
        }
        declare var ScriptNotifyEvent: {
            prototype: ScriptNotifyEvent;
            new(): ScriptNotifyEvent;
        }
        
        interface PerformanceNavigationTiming extends PerformanceEntry {
            redirectStart: number;
            domainLookupEnd: number;
            responseStart: number;
            domComplete: number;
            domainLookupStart: number;
            loadEventStart: number;
            unloadEventEnd: number;
            fetchStart: number;
            requestStart: number;
            domInteractive: number;
            navigationStart: number;
            connectEnd: number;
            loadEventEnd: number;
            connectStart: number;
            responseEnd: number;
            domLoading: number;
            redirectEnd: number;
            redirectCount: number;
            unloadEventStart: number;
            domContentLoadedEventStart: number;
            domContentLoadedEventEnd: number;
            type: string;
        }
        declare var PerformanceNavigationTiming: {
            prototype: PerformanceNavigationTiming;
            new(): PerformanceNavigationTiming;
        }
        
        interface MSMediaKeyNeededEvent extends Event {
            initData: Uint8Array;
        }
        declare var MSMediaKeyNeededEvent: {
            prototype: MSMediaKeyNeededEvent;
            new(): MSMediaKeyNeededEvent;
        }
        
        interface LongRunningScriptDetectedEvent extends Event {
            stopPageScriptExecution: boolean;
            executionTime: number;
        }
        declare var LongRunningScriptDetectedEvent: {
            prototype: LongRunningScriptDetectedEvent;
            new(): LongRunningScriptDetectedEvent;
        }
        
        interface MSAppView {
            viewId: number;
            close(): void;
            postMessage(message: any, targetOrigin: string, ports?: any): void;
        }
        declare var MSAppView: {
            prototype: MSAppView;
            new(): MSAppView;
        }
        
        interface PerfWidgetExternal {
            maxCpuSpeed: number;
            independentRenderingEnabled: boolean;
            irDisablingContentString: string;
            irStatusAvailable: boolean;
            performanceCounter: number;
            averagePaintTime: number;
            activeNetworkRequestCount: number;
            paintRequestsPerSecond: number;
            extraInformationEnabled: boolean;
            performanceCounterFrequency: number;
            averageFrameTime: number;
            repositionWindow(x: number, y: number): void;
            getRecentMemoryUsage(last: number): any;
            getMemoryUsage(): number;
            resizeWindow(width: number, height: number): void;
            getProcessCpuUsage(): number;
            removeEventListener(eventType: string, callback: (ev: any) => any): void;
            getRecentCpuUsage(last: number): any;
            addEventListener(eventType: string, callback: (ev: any) => any): void;
            getRecentFrames(last: number): any;
            getRecentPaintRequests(last: number): any;
        }
        declare var PerfWidgetExternal: {
            prototype: PerfWidgetExternal;
            new(): PerfWidgetExternal;
        }
        
        interface PageTransitionEvent extends Event {
            persisted: boolean;
        }
        declare var PageTransitionEvent: {
            prototype: PageTransitionEvent;
            new(): PageTransitionEvent;
        }
        
        interface MutationCallback {
            (mutations: MutationRecord[], observer: MutationObserver): void;
        }
        
        interface HTMLDocument extends Document {
        }
        declare var HTMLDocument: {
            prototype: HTMLDocument;
            new(): HTMLDocument;
        }
        
        interface KeyPair {
            privateKey: Key;
            publicKey: Key;
        }
        declare var KeyPair: {
            prototype: KeyPair;
            new(): KeyPair;
        }
        
        interface MSMediaKeySession extends EventTarget {
            sessionId: string;
            error: MSMediaKeyError;
            keySystem: string;
            close(): void;
            update(key: Uint8Array): void;
        }
        declare var MSMediaKeySession: {
            prototype: MSMediaKeySession;
            new(): MSMediaKeySession;
        }
        
        interface UnviewableContentIdentifiedEvent extends NavigationEvent {
            referrer: string;
        }
        declare var UnviewableContentIdentifiedEvent: {
            prototype: UnviewableContentIdentifiedEvent;
            new(): UnviewableContentIdentifiedEvent;
        }
        
        interface CryptoOperation extends EventTarget {
            algorithm: Algorithm;
            oncomplete: (ev: Event) => any;
            onerror: (ev: ErrorEvent) => any;
            onprogress: (ev: ProgressEvent) => any;
            onabort: (ev: UIEvent) => any;
            key: Key;
            result: any;
            abort(): void;
            finish(): void;
            process(buffer: ArrayBufferView): void;
            addEventListener(type: "complete", listener: (ev: Event) => any, useCapture?: boolean): void;
            addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
            addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
            addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        }
        declare var CryptoOperation: {
            prototype: CryptoOperation;
            new(): CryptoOperation;
        }
        
        interface WebGLTexture extends WebGLObject {
        }
        declare var WebGLTexture: {
            prototype: WebGLTexture;
            new(): WebGLTexture;
        }
        
        interface OES_texture_float {
        }
        declare var OES_texture_float: {
            prototype: OES_texture_float;
            new(): OES_texture_float;
        }
        
        interface WebGLContextEvent extends Event {
            statusMessage: string;
        }
        declare var WebGLContextEvent: {
            prototype: WebGLContextEvent;
            new(): WebGLContextEvent;
        }
        
        interface WebGLRenderbuffer extends WebGLObject {
        }
        declare var WebGLRenderbuffer: {
            prototype: WebGLRenderbuffer;
            new(): WebGLRenderbuffer;
        }
        
        interface WebGLUniformLocation {
        }
        declare var WebGLUniformLocation: {
            prototype: WebGLUniformLocation;
            new(): WebGLUniformLocation;
        }
        
        interface WebGLActiveInfo {
            name: string;
            type: number;
            size: number;
        }
        declare var WebGLActiveInfo: {
            prototype: WebGLActiveInfo;
            new(): WebGLActiveInfo;
        }
        
        interface WEBGL_compressed_texture_s3tc {
            COMPRESSED_RGBA_S3TC_DXT1_EXT: number;
            COMPRESSED_RGBA_S3TC_DXT5_EXT: number;
            COMPRESSED_RGBA_S3TC_DXT3_EXT: number;
            COMPRESSED_RGB_S3TC_DXT1_EXT: number;
        }
        declare var WEBGL_compressed_texture_s3tc: {
            prototype: WEBGL_compressed_texture_s3tc;
            new(): WEBGL_compressed_texture_s3tc;
            COMPRESSED_RGBA_S3TC_DXT1_EXT: number;
            COMPRESSED_RGBA_S3TC_DXT5_EXT: number;
            COMPRESSED_RGBA_S3TC_DXT3_EXT: number;
            COMPRESSED_RGB_S3TC_DXT1_EXT: number;
        }
        
        interface WebGLRenderingContext {
            drawingBufferWidth: number;
            drawingBufferHeight: number;
            canvas: HTMLCanvasElement;
            getUniformLocation(program: WebGLProgram, name: string): WebGLUniformLocation;
            bindTexture(target: number, texture: WebGLTexture): void;
            bufferData(target: number, data: ArrayBufferView, usage: number): void;
            bufferData(target: number, data: ArrayBuffer, usage: number): void;
            bufferData(target: number, size: number, usage: number): void;
            depthMask(flag: boolean): void;
            getUniform(program: WebGLProgram, location: WebGLUniformLocation): any;
            vertexAttrib3fv(indx: number, values: number[]): void;
            vertexAttrib3fv(indx: number, values: Float32Array): void;
            linkProgram(program: WebGLProgram): void;
            getSupportedExtensions(): string[];
            bufferSubData(target: number, offset: number, data: ArrayBuffer): void;
            bufferSubData(target: number, offset: number, data: ArrayBufferView): void;
            vertexAttribPointer(indx: number, size: number, type: number, normalized: boolean, stride: number, offset: number): void;
            polygonOffset(factor: number, units: number): void;
            blendColor(red: number, green: number, blue: number, alpha: number): void;
            createTexture(): WebGLTexture;
            hint(target: number, mode: number): void;
            getVertexAttrib(index: number, pname: number): any;
            enableVertexAttribArray(index: number): void;
            depthRange(zNear: number, zFar: number): void;
            cullFace(mode: number): void;
            createFramebuffer(): WebGLFramebuffer;
            uniformMatrix4fv(location: WebGLUniformLocation, transpose: boolean, value: number[]): void;
            uniformMatrix4fv(location: WebGLUniformLocation, transpose: boolean, value: Float32Array): void;
            framebufferTexture2D(target: number, attachment: number, textarget: number, texture: WebGLTexture, level: number): void;
            deleteFramebuffer(framebuffer: WebGLFramebuffer): void;
            colorMask(red: boolean, green: boolean, blue: boolean, alpha: boolean): void;
            compressedTexImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, data: ArrayBufferView): void;
            uniformMatrix2fv(location: WebGLUniformLocation, transpose: boolean, value: number[]): void;
            uniformMatrix2fv(location: WebGLUniformLocation, transpose: boolean, value: Float32Array): void;
            getExtension(name: string): any;
            createProgram(): WebGLProgram;
            deleteShader(shader: WebGLShader): void;
            getAttachedShaders(program: WebGLProgram): WebGLShader[];
            enable(cap: number): void;
            blendEquation(mode: number): void;
            texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels: ArrayBufferView): void;
            texImage2D(target: number, level: number, internalformat: number, format: number, type: number, image: HTMLImageElement): void;
            texImage2D(target: number, level: number, internalformat: number, format: number, type: number, canvas: HTMLCanvasElement): void;
            texImage2D(target: number, level: number, internalformat: number, format: number, type: number, video: HTMLVideoElement): void;
            texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels: ImageData): void;
            createBuffer(): WebGLBuffer;
            deleteTexture(texture: WebGLTexture): void;
            useProgram(program: WebGLProgram): void;
            vertexAttrib2fv(indx: number, values: number[]): void;
            vertexAttrib2fv(indx: number, values: Float32Array): void;
            checkFramebufferStatus(target: number): number;
            frontFace(mode: number): void;
            getBufferParameter(target: number, pname: number): any;
            texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView): void;
            texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, image: HTMLImageElement): void;
            texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, canvas: HTMLCanvasElement): void;
            texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, video: HTMLVideoElement): void;
            texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels: ImageData): void;
            copyTexImage2D(target: number, level: number, internalformat: number, x: number, y: number, width: number, height: number, border: number): void;
            getVertexAttribOffset(index: number, pname: number): number;
            disableVertexAttribArray(index: number): void;
            blendFunc(sfactor: number, dfactor: number): void;
            drawElements(mode: number, count: number, type: number, offset: number): void;
            isFramebuffer(framebuffer: WebGLFramebuffer): boolean;
            uniform3iv(location: WebGLUniformLocation, v: number[]): void;
            uniform3iv(location: WebGLUniformLocation, v: Int32Array): void;
            lineWidth(width: number): void;
            getShaderInfoLog(shader: WebGLShader): string;
            getTexParameter(target: number, pname: number): any;
            getParameter(pname: number): any;
            getShaderPrecisionFormat(shadertype: number, precisiontype: number): WebGLShaderPrecisionFormat;
            getContextAttributes(): WebGLContextAttributes;
            vertexAttrib1f(indx: number, x: number): void;
            bindFramebuffer(target: number, framebuffer: WebGLFramebuffer): void;
            compressedTexSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, data: ArrayBufferView): void;
            isContextLost(): boolean;
            uniform1iv(location: WebGLUniformLocation, v: number[]): void;
            uniform1iv(location: WebGLUniformLocation, v: Int32Array): void;
            getRenderbufferParameter(target: number, pname: number): any;
            uniform2fv(location: WebGLUniformLocation, v: number[]): void;
            uniform2fv(location: WebGLUniformLocation, v: Float32Array): void;
            isTexture(texture: WebGLTexture): boolean;
            getError(): number;
            shaderSource(shader: WebGLShader, source: string): void;
            deleteRenderbuffer(renderbuffer: WebGLRenderbuffer): void;
            stencilMask(mask: number): void;
            bindBuffer(target: number, buffer: WebGLBuffer): void;
            getAttribLocation(program: WebGLProgram, name: string): number;
            uniform3i(location: WebGLUniformLocation, x: number, y: number, z: number): void;
            blendEquationSeparate(modeRGB: number, modeAlpha: number): void;
            clear(mask: number): void;
            blendFuncSeparate(srcRGB: number, dstRGB: number, srcAlpha: number, dstAlpha: number): void;
            stencilFuncSeparate(face: number, func: number, ref: number, mask: number): void;
            readPixels(x: number, y: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView): void;
            scissor(x: number, y: number, width: number, height: number): void;
            uniform2i(location: WebGLUniformLocation, x: number, y: number): void;
            getActiveAttrib(program: WebGLProgram, index: number): WebGLActiveInfo;
            getShaderSource(shader: WebGLShader): string;
            generateMipmap(target: number): void;
            bindAttribLocation(program: WebGLProgram, index: number, name: string): void;
            uniform1fv(location: WebGLUniformLocation, v: number[]): void;
            uniform1fv(location: WebGLUniformLocation, v: Float32Array): void;
            uniform2iv(location: WebGLUniformLocation, v: number[]): void;
            uniform2iv(location: WebGLUniformLocation, v: Int32Array): void;
            stencilOp(fail: number, zfail: number, zpass: number): void;
            uniform4fv(location: WebGLUniformLocation, v: number[]): void;
            uniform4fv(location: WebGLUniformLocation, v: Float32Array): void;
            vertexAttrib1fv(indx: number, values: number[]): void;
            vertexAttrib1fv(indx: number, values: Float32Array): void;
            flush(): void;
            uniform4f(location: WebGLUniformLocation, x: number, y: number, z: number, w: number): void;
            deleteProgram(program: WebGLProgram): void;
            isRenderbuffer(renderbuffer: WebGLRenderbuffer): boolean;
            uniform1i(location: WebGLUniformLocation, x: number): void;
            getProgramParameter(program: WebGLProgram, pname: number): any;
            getActiveUniform(program: WebGLProgram, index: number): WebGLActiveInfo;
            stencilFunc(func: number, ref: number, mask: number): void;
            pixelStorei(pname: number, param: number): void;
            disable(cap: number): void;
            vertexAttrib4fv(indx: number, values: number[]): void;
            vertexAttrib4fv(indx: number, values: Float32Array): void;
            createRenderbuffer(): WebGLRenderbuffer;
            isBuffer(buffer: WebGLBuffer): boolean;
            stencilOpSeparate(face: number, fail: number, zfail: number, zpass: number): void;
            getFramebufferAttachmentParameter(target: number, attachment: number, pname: number): any;
            uniform4i(location: WebGLUniformLocation, x: number, y: number, z: number, w: number): void;
            sampleCoverage(value: number, invert: boolean): void;
            depthFunc(func: number): void;
            texParameterf(target: number, pname: number, param: number): void;
            vertexAttrib3f(indx: number, x: number, y: number, z: number): void;
            drawArrays(mode: number, first: number, count: number): void;
            texParameteri(target: number, pname: number, param: number): void;
            vertexAttrib4f(indx: number, x: number, y: number, z: number, w: number): void;
            getShaderParameter(shader: WebGLShader, pname: number): any;
            clearDepth(depth: number): void;
            activeTexture(texture: number): void;
            viewport(x: number, y: number, width: number, height: number): void;
            detachShader(program: WebGLProgram, shader: WebGLShader): void;
            uniform1f(location: WebGLUniformLocation, x: number): void;
            uniformMatrix3fv(location: WebGLUniformLocation, transpose: boolean, value: number[]): void;
            uniformMatrix3fv(location: WebGLUniformLocation, transpose: boolean, value: Float32Array): void;
            deleteBuffer(buffer: WebGLBuffer): void;
            copyTexSubImage2D(target: number, level: number, xoffset: number, yoffset: number, x: number, y: number, width: number, height: number): void;
            uniform3fv(location: WebGLUniformLocation, v: number[]): void;
            uniform3fv(location: WebGLUniformLocation, v: Float32Array): void;
            stencilMaskSeparate(face: number, mask: number): void;
            attachShader(program: WebGLProgram, shader: WebGLShader): void;
            compileShader(shader: WebGLShader): void;
            clearColor(red: number, green: number, blue: number, alpha: number): void;
            isShader(shader: WebGLShader): boolean;
            clearStencil(s: number): void;
            framebufferRenderbuffer(target: number, attachment: number, renderbuffertarget: number, renderbuffer: WebGLRenderbuffer): void;
            finish(): void;
            uniform2f(location: WebGLUniformLocation, x: number, y: number): void;
            renderbufferStorage(target: number, internalformat: number, width: number, height: number): void;
            uniform3f(location: WebGLUniformLocation, x: number, y: number, z: number): void;
            getProgramInfoLog(program: WebGLProgram): string;
            validateProgram(program: WebGLProgram): void;
            isEnabled(cap: number): boolean;
            vertexAttrib2f(indx: number, x: number, y: number): void;
            isProgram(program: WebGLProgram): boolean;
            createShader(type: number): WebGLShader;
            bindRenderbuffer(target: number, renderbuffer: WebGLRenderbuffer): void;
            uniform4iv(location: WebGLUniformLocation, v: number[]): void;
            uniform4iv(location: WebGLUniformLocation, v: Int32Array): void;
            DEPTH_FUNC: number;
            DEPTH_COMPONENT16: number;
            REPLACE: number;
            REPEAT: number;
            VERTEX_ATTRIB_ARRAY_ENABLED: number;
            FRAMEBUFFER_INCOMPLETE_DIMENSIONS: number;
            STENCIL_BUFFER_BIT: number;
            RENDERER: number;
            STENCIL_BACK_REF: number;
            TEXTURE26: number;
            RGB565: number;
            DITHER: number;
            CONSTANT_COLOR: number;
            GENERATE_MIPMAP_HINT: number;
            POINTS: number;
            DECR: number;
            INT_VEC3: number;
            TEXTURE28: number;
            ONE_MINUS_CONSTANT_ALPHA: number;
            BACK: number;
            RENDERBUFFER_STENCIL_SIZE: number;
            UNPACK_FLIP_Y_WEBGL: number;
            BLEND: number;
            TEXTURE9: number;
            ARRAY_BUFFER_BINDING: number;
            MAX_VIEWPORT_DIMS: number;
            INVALID_FRAMEBUFFER_OPERATION: number;
            TEXTURE: number;
            TEXTURE0: number;
            TEXTURE31: number;
            TEXTURE24: number;
            HIGH_INT: number;
            RENDERBUFFER_BINDING: number;
            BLEND_COLOR: number;
            FASTEST: number;
            STENCIL_WRITEMASK: number;
            ALIASED_POINT_SIZE_RANGE: number;
            TEXTURE12: number;
            DST_ALPHA: number;
            BLEND_EQUATION_RGB: number;
            FRAMEBUFFER_COMPLETE: number;
            NEAREST_MIPMAP_NEAREST: number;
            VERTEX_ATTRIB_ARRAY_SIZE: number;
            TEXTURE3: number;
            DEPTH_WRITEMASK: number;
            CONTEXT_LOST_WEBGL: number;
            INVALID_VALUE: number;
            TEXTURE_MAG_FILTER: number;
            ONE_MINUS_CONSTANT_COLOR: number;
            ONE_MINUS_SRC_ALPHA: number;
            TEXTURE_CUBE_MAP_POSITIVE_Z: number;
            NOTEQUAL: number;
            ALPHA: number;
            DEPTH_STENCIL: number;
            MAX_VERTEX_UNIFORM_VECTORS: number;
            DEPTH_COMPONENT: number;
            RENDERBUFFER_RED_SIZE: number;
            TEXTURE20: number;
            RED_BITS: number;
            RENDERBUFFER_BLUE_SIZE: number;
            SCISSOR_BOX: number;
            VENDOR: number;
            FRONT_AND_BACK: number;
            CONSTANT_ALPHA: number;
            VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: number;
            NEAREST: number;
            CULL_FACE: number;
            ALIASED_LINE_WIDTH_RANGE: number;
            TEXTURE19: number;
            FRONT: number;
            DEPTH_CLEAR_VALUE: number;
            GREEN_BITS: number;
            TEXTURE29: number;
            TEXTURE23: number;
            MAX_RENDERBUFFER_SIZE: number;
            STENCIL_ATTACHMENT: number;
            TEXTURE27: number;
            BOOL_VEC2: number;
            OUT_OF_MEMORY: number;
            MIRRORED_REPEAT: number;
            POLYGON_OFFSET_UNITS: number;
            TEXTURE_MIN_FILTER: number;
            STENCIL_BACK_PASS_DEPTH_PASS: number;
            LINE_LOOP: number;
            FLOAT_MAT3: number;
            TEXTURE14: number;
            LINEAR: number;
            RGB5_A1: number;
            ONE_MINUS_SRC_COLOR: number;
            SAMPLE_COVERAGE_INVERT: number;
            DONT_CARE: number;
            FRAMEBUFFER_BINDING: number;
            RENDERBUFFER_ALPHA_SIZE: number;
            STENCIL_REF: number;
            ZERO: number;
            DECR_WRAP: number;
            SAMPLE_COVERAGE: number;
            STENCIL_BACK_FUNC: number;
            TEXTURE30: number;
            VIEWPORT: number;
            STENCIL_BITS: number;
            FLOAT: number;
            COLOR_WRITEMASK: number;
            SAMPLE_COVERAGE_VALUE: number;
            TEXTURE_CUBE_MAP_NEGATIVE_Y: number;
            STENCIL_BACK_FAIL: number;
            FLOAT_MAT4: number;
            UNSIGNED_SHORT_4_4_4_4: number;
            TEXTURE6: number;
            RENDERBUFFER_WIDTH: number;
            RGBA4: number;
            ALWAYS: number;
            BLEND_EQUATION_ALPHA: number;
            COLOR_BUFFER_BIT: number;
            TEXTURE_CUBE_MAP: number;
            DEPTH_BUFFER_BIT: number;
            STENCIL_CLEAR_VALUE: number;
            BLEND_EQUATION: number;
            RENDERBUFFER_GREEN_SIZE: number;
            NEAREST_MIPMAP_LINEAR: number;
            VERTEX_ATTRIB_ARRAY_TYPE: number;
            INCR_WRAP: number;
            ONE_MINUS_DST_COLOR: number;
            HIGH_FLOAT: number;
            BYTE: number;
            FRONT_FACE: number;
            SAMPLE_ALPHA_TO_COVERAGE: number;
            CCW: number;
            TEXTURE13: number;
            MAX_VERTEX_ATTRIBS: number;
            MAX_VERTEX_TEXTURE_IMAGE_UNITS: number;
            TEXTURE_WRAP_T: number;
            UNPACK_PREMULTIPLY_ALPHA_WEBGL: number;
            FLOAT_VEC2: number;
            LUMINANCE: number;
            GREATER: number;
            INT_VEC2: number;
            VALIDATE_STATUS: number;
            FRAMEBUFFER: number;
            FRAMEBUFFER_UNSUPPORTED: number;
            TEXTURE5: number;
            FUNC_SUBTRACT: number;
            BLEND_DST_ALPHA: number;
            SAMPLER_CUBE: number;
            ONE_MINUS_DST_ALPHA: number;
            LESS: number;
            TEXTURE_CUBE_MAP_POSITIVE_X: number;
            BLUE_BITS: number;
            DEPTH_TEST: number;
            VERTEX_ATTRIB_ARRAY_STRIDE: number;
            DELETE_STATUS: number;
            TEXTURE18: number;
            POLYGON_OFFSET_FACTOR: number;
            UNSIGNED_INT: number;
            TEXTURE_2D: number;
            DST_COLOR: number;
            FLOAT_MAT2: number;
            COMPRESSED_TEXTURE_FORMATS: number;
            MAX_FRAGMENT_UNIFORM_VECTORS: number;
            DEPTH_STENCIL_ATTACHMENT: number;
            LUMINANCE_ALPHA: number;
            CW: number;
            VERTEX_ATTRIB_ARRAY_NORMALIZED: number;
            TEXTURE_CUBE_MAP_NEGATIVE_Z: number;
            LINEAR_MIPMAP_LINEAR: number;
            BUFFER_SIZE: number;
            SAMPLE_BUFFERS: number;
            TEXTURE15: number;
            ACTIVE_TEXTURE: number;
            VERTEX_SHADER: number;
            TEXTURE22: number;
            VERTEX_ATTRIB_ARRAY_POINTER: number;
            INCR: number;
            COMPILE_STATUS: number;
            MAX_COMBINED_TEXTURE_IMAGE_UNITS: number;
            TEXTURE7: number;
            UNSIGNED_SHORT_5_5_5_1: number;
            DEPTH_BITS: number;
            RGBA: number;
            TRIANGLE_STRIP: number;
            COLOR_CLEAR_VALUE: number;
            BROWSER_DEFAULT_WEBGL: number;
            INVALID_ENUM: number;
            SCISSOR_TEST: number;
            LINE_STRIP: number;
            FRAMEBUFFER_INCOMPLETE_ATTACHMENT: number;
            STENCIL_FUNC: number;
            FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: number;
            RENDERBUFFER_HEIGHT: number;
            TEXTURE8: number;
            TRIANGLES: number;
            FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: number;
            STENCIL_BACK_VALUE_MASK: number;
            TEXTURE25: number;
            RENDERBUFFER: number;
            LEQUAL: number;
            TEXTURE1: number;
            STENCIL_INDEX8: number;
            FUNC_ADD: number;
            STENCIL_FAIL: number;
            BLEND_SRC_ALPHA: number;
            BOOL: number;
            ALPHA_BITS: number;
            LOW_INT: number;
            TEXTURE10: number;
            SRC_COLOR: number;
            MAX_VARYING_VECTORS: number;
            BLEND_DST_RGB: number;
            TEXTURE_BINDING_CUBE_MAP: number;
            STENCIL_INDEX: number;
            TEXTURE_BINDING_2D: number;
            MEDIUM_INT: number;
            SHADER_TYPE: number;
            POLYGON_OFFSET_FILL: number;
            DYNAMIC_DRAW: number;
            TEXTURE4: number;
            STENCIL_BACK_PASS_DEPTH_FAIL: number;
            STREAM_DRAW: number;
            MAX_CUBE_MAP_TEXTURE_SIZE: number;
            TEXTURE17: number;
            TRIANGLE_FAN: number;
            UNPACK_ALIGNMENT: number;
            CURRENT_PROGRAM: number;
            LINES: number;
            INVALID_OPERATION: number;
            FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: number;
            LINEAR_MIPMAP_NEAREST: number;
            CLAMP_TO_EDGE: number;
            RENDERBUFFER_DEPTH_SIZE: number;
            TEXTURE_WRAP_S: number;
            ELEMENT_ARRAY_BUFFER: number;
            UNSIGNED_SHORT_5_6_5: number;
            ACTIVE_UNIFORMS: number;
            FLOAT_VEC3: number;
            NO_ERROR: number;
            ATTACHED_SHADERS: number;
            DEPTH_ATTACHMENT: number;
            TEXTURE11: number;
            STENCIL_TEST: number;
            ONE: number;
            FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: number;
            STATIC_DRAW: number;
            GEQUAL: number;
            BOOL_VEC4: number;
            COLOR_ATTACHMENT0: number;
            PACK_ALIGNMENT: number;
            MAX_TEXTURE_SIZE: number;
            STENCIL_PASS_DEPTH_FAIL: number;
            CULL_FACE_MODE: number;
            TEXTURE16: number;
            STENCIL_BACK_WRITEMASK: number;
            SRC_ALPHA: number;
            UNSIGNED_SHORT: number;
            TEXTURE21: number;
            FUNC_REVERSE_SUBTRACT: number;
            SHADING_LANGUAGE_VERSION: number;
            EQUAL: number;
            FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: number;
            BOOL_VEC3: number;
            SAMPLER_2D: number;
            TEXTURE_CUBE_MAP_NEGATIVE_X: number;
            MAX_TEXTURE_IMAGE_UNITS: number;
            TEXTURE_CUBE_MAP_POSITIVE_Y: number;
            RENDERBUFFER_INTERNAL_FORMAT: number;
            STENCIL_VALUE_MASK: number;
            ELEMENT_ARRAY_BUFFER_BINDING: number;
            ARRAY_BUFFER: number;
            DEPTH_RANGE: number;
            NICEST: number;
            ACTIVE_ATTRIBUTES: number;
            NEVER: number;
            FLOAT_VEC4: number;
            CURRENT_VERTEX_ATTRIB: number;
            STENCIL_PASS_DEPTH_PASS: number;
            INVERT: number;
            LINK_STATUS: number;
            RGB: number;
            INT_VEC4: number;
            TEXTURE2: number;
            UNPACK_COLORSPACE_CONVERSION_WEBGL: number;
            MEDIUM_FLOAT: number;
            SRC_ALPHA_SATURATE: number;
            BUFFER_USAGE: number;
            SHORT: number;
            NONE: number;
            UNSIGNED_BYTE: number;
            INT: number;
            SUBPIXEL_BITS: number;
            KEEP: number;
            SAMPLES: number;
            FRAGMENT_SHADER: number;
            LINE_WIDTH: number;
            BLEND_SRC_RGB: number;
            LOW_FLOAT: number;
            VERSION: number;
        }
        declare var WebGLRenderingContext: {
            prototype: WebGLRenderingContext;
            new(): WebGLRenderingContext;
            DEPTH_FUNC: number;
            DEPTH_COMPONENT16: number;
            REPLACE: number;
            REPEAT: number;
            VERTEX_ATTRIB_ARRAY_ENABLED: number;
            FRAMEBUFFER_INCOMPLETE_DIMENSIONS: number;
            STENCIL_BUFFER_BIT: number;
            RENDERER: number;
            STENCIL_BACK_REF: number;
            TEXTURE26: number;
            RGB565: number;
            DITHER: number;
            CONSTANT_COLOR: number;
            GENERATE_MIPMAP_HINT: number;
            POINTS: number;
            DECR: number;
            INT_VEC3: number;
            TEXTURE28: number;
            ONE_MINUS_CONSTANT_ALPHA: number;
            BACK: number;
            RENDERBUFFER_STENCIL_SIZE: number;
            UNPACK_FLIP_Y_WEBGL: number;
            BLEND: number;
            TEXTURE9: number;
            ARRAY_BUFFER_BINDING: number;
            MAX_VIEWPORT_DIMS: number;
            INVALID_FRAMEBUFFER_OPERATION: number;
            TEXTURE: number;
            TEXTURE0: number;
            TEXTURE31: number;
            TEXTURE24: number;
            HIGH_INT: number;
            RENDERBUFFER_BINDING: number;
            BLEND_COLOR: number;
            FASTEST: number;
            STENCIL_WRITEMASK: number;
            ALIASED_POINT_SIZE_RANGE: number;
            TEXTURE12: number;
            DST_ALPHA: number;
            BLEND_EQUATION_RGB: number;
            FRAMEBUFFER_COMPLETE: number;
            NEAREST_MIPMAP_NEAREST: number;
            VERTEX_ATTRIB_ARRAY_SIZE: number;
            TEXTURE3: number;
            DEPTH_WRITEMASK: number;
            CONTEXT_LOST_WEBGL: number;
            INVALID_VALUE: number;
            TEXTURE_MAG_FILTER: number;
            ONE_MINUS_CONSTANT_COLOR: number;
            ONE_MINUS_SRC_ALPHA: number;
            TEXTURE_CUBE_MAP_POSITIVE_Z: number;
            NOTEQUAL: number;
            ALPHA: number;
            DEPTH_STENCIL: number;
            MAX_VERTEX_UNIFORM_VECTORS: number;
            DEPTH_COMPONENT: number;
            RENDERBUFFER_RED_SIZE: number;
            TEXTURE20: number;
            RED_BITS: number;
            RENDERBUFFER_BLUE_SIZE: number;
            SCISSOR_BOX: number;
            VENDOR: number;
            FRONT_AND_BACK: number;
            CONSTANT_ALPHA: number;
            VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: number;
            NEAREST: number;
            CULL_FACE: number;
            ALIASED_LINE_WIDTH_RANGE: number;
            TEXTURE19: number;
            FRONT: number;
            DEPTH_CLEAR_VALUE: number;
            GREEN_BITS: number;
            TEXTURE29: number;
            TEXTURE23: number;
            MAX_RENDERBUFFER_SIZE: number;
            STENCIL_ATTACHMENT: number;
            TEXTURE27: number;
            BOOL_VEC2: number;
            OUT_OF_MEMORY: number;
            MIRRORED_REPEAT: number;
            POLYGON_OFFSET_UNITS: number;
            TEXTURE_MIN_FILTER: number;
            STENCIL_BACK_PASS_DEPTH_PASS: number;
            LINE_LOOP: number;
            FLOAT_MAT3: number;
            TEXTURE14: number;
            LINEAR: number;
            RGB5_A1: number;
            ONE_MINUS_SRC_COLOR: number;
            SAMPLE_COVERAGE_INVERT: number;
            DONT_CARE: number;
            FRAMEBUFFER_BINDING: number;
            RENDERBUFFER_ALPHA_SIZE: number;
            STENCIL_REF: number;
            ZERO: number;
            DECR_WRAP: number;
            SAMPLE_COVERAGE: number;
            STENCIL_BACK_FUNC: number;
            TEXTURE30: number;
            VIEWPORT: number;
            STENCIL_BITS: number;
            FLOAT: number;
            COLOR_WRITEMASK: number;
            SAMPLE_COVERAGE_VALUE: number;
            TEXTURE_CUBE_MAP_NEGATIVE_Y: number;
            STENCIL_BACK_FAIL: number;
            FLOAT_MAT4: number;
            UNSIGNED_SHORT_4_4_4_4: number;
            TEXTURE6: number;
            RENDERBUFFER_WIDTH: number;
            RGBA4: number;
            ALWAYS: number;
            BLEND_EQUATION_ALPHA: number;
            COLOR_BUFFER_BIT: number;
            TEXTURE_CUBE_MAP: number;
            DEPTH_BUFFER_BIT: number;
            STENCIL_CLEAR_VALUE: number;
            BLEND_EQUATION: number;
            RENDERBUFFER_GREEN_SIZE: number;
            NEAREST_MIPMAP_LINEAR: number;
            VERTEX_ATTRIB_ARRAY_TYPE: number;
            INCR_WRAP: number;
            ONE_MINUS_DST_COLOR: number;
            HIGH_FLOAT: number;
            BYTE: number;
            FRONT_FACE: number;
            SAMPLE_ALPHA_TO_COVERAGE: number;
            CCW: number;
            TEXTURE13: number;
            MAX_VERTEX_ATTRIBS: number;
            MAX_VERTEX_TEXTURE_IMAGE_UNITS: number;
            TEXTURE_WRAP_T: number;
            UNPACK_PREMULTIPLY_ALPHA_WEBGL: number;
            FLOAT_VEC2: number;
            LUMINANCE: number;
            GREATER: number;
            INT_VEC2: number;
            VALIDATE_STATUS: number;
            FRAMEBUFFER: number;
            FRAMEBUFFER_UNSUPPORTED: number;
            TEXTURE5: number;
            FUNC_SUBTRACT: number;
            BLEND_DST_ALPHA: number;
            SAMPLER_CUBE: number;
            ONE_MINUS_DST_ALPHA: number;
            LESS: number;
            TEXTURE_CUBE_MAP_POSITIVE_X: number;
            BLUE_BITS: number;
            DEPTH_TEST: number;
            VERTEX_ATTRIB_ARRAY_STRIDE: number;
            DELETE_STATUS: number;
            TEXTURE18: number;
            POLYGON_OFFSET_FACTOR: number;
            UNSIGNED_INT: number;
            TEXTURE_2D: number;
            DST_COLOR: number;
            FLOAT_MAT2: number;
            COMPRESSED_TEXTURE_FORMATS: number;
            MAX_FRAGMENT_UNIFORM_VECTORS: number;
            DEPTH_STENCIL_ATTACHMENT: number;
            LUMINANCE_ALPHA: number;
            CW: number;
            VERTEX_ATTRIB_ARRAY_NORMALIZED: number;
            TEXTURE_CUBE_MAP_NEGATIVE_Z: number;
            LINEAR_MIPMAP_LINEAR: number;
            BUFFER_SIZE: number;
            SAMPLE_BUFFERS: number;
            TEXTURE15: number;
            ACTIVE_TEXTURE: number;
            VERTEX_SHADER: number;
            TEXTURE22: number;
            VERTEX_ATTRIB_ARRAY_POINTER: number;
            INCR: number;
            COMPILE_STATUS: number;
            MAX_COMBINED_TEXTURE_IMAGE_UNITS: number;
            TEXTURE7: number;
            UNSIGNED_SHORT_5_5_5_1: number;
            DEPTH_BITS: number;
            RGBA: number;
            TRIANGLE_STRIP: number;
            COLOR_CLEAR_VALUE: number;
            BROWSER_DEFAULT_WEBGL: number;
            INVALID_ENUM: number;
            SCISSOR_TEST: number;
            LINE_STRIP: number;
            FRAMEBUFFER_INCOMPLETE_ATTACHMENT: number;
            STENCIL_FUNC: number;
            FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: number;
            RENDERBUFFER_HEIGHT: number;
            TEXTURE8: number;
            TRIANGLES: number;
            FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: number;
            STENCIL_BACK_VALUE_MASK: number;
            TEXTURE25: number;
            RENDERBUFFER: number;
            LEQUAL: number;
            TEXTURE1: number;
            STENCIL_INDEX8: number;
            FUNC_ADD: number;
            STENCIL_FAIL: number;
            BLEND_SRC_ALPHA: number;
            BOOL: number;
            ALPHA_BITS: number;
            LOW_INT: number;
            TEXTURE10: number;
            SRC_COLOR: number;
            MAX_VARYING_VECTORS: number;
            BLEND_DST_RGB: number;
            TEXTURE_BINDING_CUBE_MAP: number;
            STENCIL_INDEX: number;
            TEXTURE_BINDING_2D: number;
            MEDIUM_INT: number;
            SHADER_TYPE: number;
            POLYGON_OFFSET_FILL: number;
            DYNAMIC_DRAW: number;
            TEXTURE4: number;
            STENCIL_BACK_PASS_DEPTH_FAIL: number;
            STREAM_DRAW: number;
            MAX_CUBE_MAP_TEXTURE_SIZE: number;
            TEXTURE17: number;
            TRIANGLE_FAN: number;
            UNPACK_ALIGNMENT: number;
            CURRENT_PROGRAM: number;
            LINES: number;
            INVALID_OPERATION: number;
            FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: number;
            LINEAR_MIPMAP_NEAREST: number;
            CLAMP_TO_EDGE: number;
            RENDERBUFFER_DEPTH_SIZE: number;
            TEXTURE_WRAP_S: number;
            ELEMENT_ARRAY_BUFFER: number;
            UNSIGNED_SHORT_5_6_5: number;
            ACTIVE_UNIFORMS: number;
            FLOAT_VEC3: number;
            NO_ERROR: number;
            ATTACHED_SHADERS: number;
            DEPTH_ATTACHMENT: number;
            TEXTURE11: number;
            STENCIL_TEST: number;
            ONE: number;
            FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: number;
            STATIC_DRAW: number;
            GEQUAL: number;
            BOOL_VEC4: number;
            COLOR_ATTACHMENT0: number;
            PACK_ALIGNMENT: number;
            MAX_TEXTURE_SIZE: number;
            STENCIL_PASS_DEPTH_FAIL: number;
            CULL_FACE_MODE: number;
            TEXTURE16: number;
            STENCIL_BACK_WRITEMASK: number;
            SRC_ALPHA: number;
            UNSIGNED_SHORT: number;
            TEXTURE21: number;
            FUNC_REVERSE_SUBTRACT: number;
            SHADING_LANGUAGE_VERSION: number;
            EQUAL: number;
            FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: number;
            BOOL_VEC3: number;
            SAMPLER_2D: number;
            TEXTURE_CUBE_MAP_NEGATIVE_X: number;
            MAX_TEXTURE_IMAGE_UNITS: number;
            TEXTURE_CUBE_MAP_POSITIVE_Y: number;
            RENDERBUFFER_INTERNAL_FORMAT: number;
            STENCIL_VALUE_MASK: number;
            ELEMENT_ARRAY_BUFFER_BINDING: number;
            ARRAY_BUFFER: number;
            DEPTH_RANGE: number;
            NICEST: number;
            ACTIVE_ATTRIBUTES: number;
            NEVER: number;
            FLOAT_VEC4: number;
            CURRENT_VERTEX_ATTRIB: number;
            STENCIL_PASS_DEPTH_PASS: number;
            INVERT: number;
            LINK_STATUS: number;
            RGB: number;
            INT_VEC4: number;
            TEXTURE2: number;
            UNPACK_COLORSPACE_CONVERSION_WEBGL: number;
            MEDIUM_FLOAT: number;
            SRC_ALPHA_SATURATE: number;
            BUFFER_USAGE: number;
            SHORT: number;
            NONE: number;
            UNSIGNED_BYTE: number;
            INT: number;
            SUBPIXEL_BITS: number;
            KEEP: number;
            SAMPLES: number;
            FRAGMENT_SHADER: number;
            LINE_WIDTH: number;
            BLEND_SRC_RGB: number;
            LOW_FLOAT: number;
            VERSION: number;
        }
        
        interface WebGLProgram extends WebGLObject {
        }
        declare var WebGLProgram: {
            prototype: WebGLProgram;
            new(): WebGLProgram;
        }
        
        interface OES_standard_derivatives {
            FRAGMENT_SHADER_DERIVATIVE_HINT_OES: number;
        }
        declare var OES_standard_derivatives: {
            prototype: OES_standard_derivatives;
            new(): OES_standard_derivatives;
            FRAGMENT_SHADER_DERIVATIVE_HINT_OES: number;
        }
        
        interface WebGLFramebuffer extends WebGLObject {
        }
        declare var WebGLFramebuffer: {
            prototype: WebGLFramebuffer;
            new(): WebGLFramebuffer;
        }
        
        interface WebGLShader extends WebGLObject {
        }
        declare var WebGLShader: {
            prototype: WebGLShader;
            new(): WebGLShader;
        }
        
        interface OES_texture_float_linear {
        }
        declare var OES_texture_float_linear: {
            prototype: OES_texture_float_linear;
            new(): OES_texture_float_linear;
        }
        
        interface WebGLObject {
        }
        declare var WebGLObject: {
            prototype: WebGLObject;
            new(): WebGLObject;
        }
        
        interface WebGLBuffer extends WebGLObject {
        }
        declare var WebGLBuffer: {
            prototype: WebGLBuffer;
            new(): WebGLBuffer;
        }
        
        interface WebGLShaderPrecisionFormat {
            rangeMin: number;
            rangeMax: number;
            precision: number;
        }
        declare var WebGLShaderPrecisionFormat: {
            prototype: WebGLShaderPrecisionFormat;
            new(): WebGLShaderPrecisionFormat;
        }
        
        interface EXT_texture_filter_anisotropic {
            TEXTURE_MAX_ANISOTROPY_EXT: number;
            MAX_TEXTURE_MAX_ANISOTROPY_EXT: number;
        }
        declare var EXT_texture_filter_anisotropic: {
            prototype: EXT_texture_filter_anisotropic;
            new(): EXT_texture_filter_anisotropic;
            TEXTURE_MAX_ANISOTROPY_EXT: number;
            MAX_TEXTURE_MAX_ANISOTROPY_EXT: number;
        }
        
        declare var Option: { new(text?: string, value?: string, defaultSelected?: boolean, selected?:boolean): HTMLOptionElement; };
        declare var Image: { new(width?: number, height?: number): HTMLImageElement; };
        declare var Audio: { new(src?: string): HTMLAudioElement; };
        
        declare var ondragend: (ev: DragEvent) => any;
        declare var onkeydown: (ev: KeyboardEvent) => any;
        declare var ondragover: (ev: DragEvent) => any;
        declare var onkeyup: (ev: KeyboardEvent) => any;
        declare var onreset: (ev: Event) => any;
        declare var onmouseup: (ev: MouseEvent) => any;
        declare var ondragstart: (ev: DragEvent) => any;
        declare var ondrag: (ev: DragEvent) => any;
        declare var screenX: number;
        declare var onmouseover: (ev: MouseEvent) => any;
        declare var ondragleave: (ev: DragEvent) => any;
        declare var history: History;
        declare var pageXOffset: number;
        declare var name: string;
        declare var onafterprint: (ev: Event) => any;
        declare var onpause: (ev: Event) => any;
        declare var onbeforeprint: (ev: Event) => any;
        declare var top: Window;
        declare var onmousedown: (ev: MouseEvent) => any;
        declare var onseeked: (ev: Event) => any;
        declare var opener: Window;
        declare var onclick: (ev: MouseEvent) => any;
        declare var innerHeight: number;
        declare var onwaiting: (ev: Event) => any;
        declare var ononline: (ev: Event) => any;
        declare var ondurationchange: (ev: Event) => any;
        declare var frames: Window;
        declare var onblur: (ev: FocusEvent) => any;
        declare var onemptied: (ev: Event) => any;
        declare var onseeking: (ev: Event) => any;
        declare var oncanplay: (ev: Event) => any;
        declare var outerWidth: number;
        declare var onstalled: (ev: Event) => any;
        declare var onmousemove: (ev: MouseEvent) => any;
        declare var innerWidth: number;
        declare var onoffline: (ev: Event) => any;
        declare var length: number;
        declare var screen: Screen;
        declare var onbeforeunload: (ev: BeforeUnloadEvent) => any;
        declare var onratechange: (ev: Event) => any;
        declare var onstorage: (ev: StorageEvent) => any;
        declare var onloadstart: (ev: Event) => any;
        declare var ondragenter: (ev: DragEvent) => any;
        declare var onsubmit: (ev: Event) => any;
        declare var self: Window;
        declare var document: Document;
        declare var onprogress: (ev: ProgressEvent) => any;
        declare var ondblclick: (ev: MouseEvent) => any;
        declare var pageYOffset: number;
        declare var oncontextmenu: (ev: MouseEvent) => any;
        declare var onchange: (ev: Event) => any;
        declare var onloadedmetadata: (ev: Event) => any;
        declare var onplay: (ev: Event) => any;
        declare var onerror: ErrorEventHandler;
        declare var onplaying: (ev: Event) => any;
        declare var parent: Window;
        declare var location: Location;
        declare var oncanplaythrough: (ev: Event) => any;
        declare var onabort: (ev: UIEvent) => any;
        declare var onreadystatechange: (ev: Event) => any;
        declare var outerHeight: number;
        declare var onkeypress: (ev: KeyboardEvent) => any;
        declare var frameElement: Element;
        declare var onloadeddata: (ev: Event) => any;
        declare var onsuspend: (ev: Event) => any;
        declare var window: Window;
        declare var onfocus: (ev: FocusEvent) => any;
        declare var onmessage: (ev: MessageEvent) => any;
        declare var ontimeupdate: (ev: Event) => any;
        declare var onresize: (ev: UIEvent) => any;
        declare var onselect: (ev: UIEvent) => any;
        declare var navigator: Navigator;
        declare var styleMedia: StyleMedia;
        declare var ondrop: (ev: DragEvent) => any;
        declare var onmouseout: (ev: MouseEvent) => any;
        declare var onended: (ev: Event) => any;
        declare var onhashchange: (ev: Event) => any;
        declare var onunload: (ev: Event) => any;
        declare var onscroll: (ev: UIEvent) => any;
        declare var screenY: number;
        declare var onmousewheel: (ev: MouseWheelEvent) => any;
        declare var onload: (ev: Event) => any;
        declare var onvolumechange: (ev: Event) => any;
        declare var oninput: (ev: Event) => any;
        declare var performance: Performance;
        declare var onmspointerdown: (ev: any) => any;
        declare var animationStartTime: number;
        declare var onmsgesturedoubletap: (ev: any) => any;
        declare var onmspointerhover: (ev: any) => any;
        declare var onmsgesturehold: (ev: any) => any;
        declare var onmspointermove: (ev: any) => any;
        declare var onmsgesturechange: (ev: any) => any;
        declare var onmsgesturestart: (ev: any) => any;
        declare var onmspointercancel: (ev: any) => any;
        declare var onmsgestureend: (ev: any) => any;
        declare var onmsgesturetap: (ev: any) => any;
        declare var onmspointerout: (ev: any) => any;
        declare var msAnimationStartTime: number;
        declare var applicationCache: ApplicationCache;
        declare var onmsinertiastart: (ev: any) => any;
        declare var onmspointerover: (ev: any) => any;
        declare var onpopstate: (ev: PopStateEvent) => any;
        declare var onmspointerup: (ev: any) => any;
        declare var onpageshow: (ev: PageTransitionEvent) => any;
        declare var ondevicemotion: (ev: DeviceMotionEvent) => any;
        declare var devicePixelRatio: number;
        declare var msCrypto: Crypto;
        declare var ondeviceorientation: (ev: DeviceOrientationEvent) => any;
        declare var doNotTrack: string;
        declare var onmspointerenter: (ev: any) => any;
        declare var onpagehide: (ev: PageTransitionEvent) => any;
        declare var onmspointerleave: (ev: any) => any;
        declare function alert(message?: any): void;
        declare function scroll(x?: number, y?: number): void;
        declare function focus(): void;
        declare function scrollTo(x?: number, y?: number): void;
        declare function print(): void;
        declare function prompt(message?: string, _default?: string): string;
        declare function toString(): string;
        declare function open(url?: string, target?: string, features?: string, replace?: boolean): Window;
        declare function scrollBy(x?: number, y?: number): void;
        declare function confirm(message?: string): boolean;
        declare function close(): void;
        declare function postMessage(message: any, targetOrigin: string, ports?: any): void;
        declare function showModalDialog(url?: string, argument?: any, options?: any): any;
        declare function blur(): void;
        declare function getSelection(): Selection;
        declare function getComputedStyle(elt: Element, pseudoElt?: string): CSSStyleDeclaration;
        declare function msCancelRequestAnimationFrame(handle: number): void;
        declare function matchMedia(mediaQuery: string): MediaQueryList;
        declare function cancelAnimationFrame(handle: number): void;
        declare function msIsStaticHTML(html: string): boolean;
        declare function msMatchMedia(mediaQuery: string): MediaQueryList;
        declare function requestAnimationFrame(callback: FrameRequestCallback): number;
        declare function msRequestAnimationFrame(callback: FrameRequestCallback): number;
        declare function removeEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        declare function dispatchEvent(evt: Event): boolean;
        declare function attachEvent(event: string, listener: EventListener): boolean;
        declare function detachEvent(event: string, listener: EventListener): void;
        declare var localStorage: Storage;
        declare var status: string;
        declare var onmouseleave: (ev: MouseEvent) => any;
        declare var screenLeft: number;
        declare var offscreenBuffering: any;
        declare var maxConnectionsPerServer: number;
        declare var onmouseenter: (ev: MouseEvent) => any;
        declare var clipboardData: DataTransfer;
        declare var defaultStatus: string;
        declare var clientInformation: Navigator;
        declare var closed: boolean;
        declare var onhelp: (ev: Event) => any;
        declare var external: External;
        declare var event: MSEventObj;
        declare var onfocusout: (ev: FocusEvent) => any;
        declare var screenTop: number;
        declare var onfocusin: (ev: FocusEvent) => any;
        declare function showModelessDialog(url?: string, argument?: any, options?: any): Window;
        declare function navigate(url: string): void;
        declare function resizeBy(x?: number, y?: number): void;
        declare function item(index: any): any;
        declare function resizeTo(x?: number, y?: number): void;
        declare function createPopup(arguments?: any): MSPopupWindow;
        declare function toStaticHTML(html: string): string;
        declare function execScript(code: string, language?: string): any;
        declare function msWriteProfilerMark(profilerMarkName: string): void;
        declare function moveTo(x?: number, y?: number): void;
        declare function moveBy(x?: number, y?: number): void;
        declare function showHelp(url: string, helpArg?: any, features?: string): void;
        declare function captureEvents(): void;
        declare function releaseEvents(): void;
        declare var sessionStorage: Storage;
        declare function clearTimeout(handle: number): void;
        declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;
        declare function clearInterval(handle: number): void;
        declare function setInterval(handler: any, timeout?: any, ...args: any[]): number;
        declare function msSetImmediate(expression: any, ...args: any[]): number;
        declare function clearImmediate(handle: number): void;
        declare function msClearImmediate(handle: number): void;
        declare function setImmediate(expression: any, ...args: any[]): number;
        declare function btoa(rawString: string): string;
        declare function atob(encodedString: string): string;
        declare var msIndexedDB: IDBFactory;
        declare var indexedDB: IDBFactory;
        declare var console: Console;
        declare var onpointerenter: (ev: PointerEvent) => any;
        declare var onpointerout: (ev: PointerEvent) => any;
        declare var onpointerdown: (ev: PointerEvent) => any;
        declare var onpointerup: (ev: PointerEvent) => any;
        declare var onpointercancel: (ev: PointerEvent) => any;
        declare var onpointerover: (ev: PointerEvent) => any;
        declare var onpointermove: (ev: PointerEvent) => any;
        declare var onpointerleave: (ev: PointerEvent) => any;
        declare function addEventListener(type: "mouseleave", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mouseenter", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "help", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "focusout", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "focusin", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pointerenter", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pointerout", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pointerdown", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pointerup", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pointercancel", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pointerover", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pointermove", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pointerleave", listener: (ev: PointerEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "dragend", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "keydown", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "dragover", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "keyup", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "reset", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mouseup", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "dragstart", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "drag", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mouseover", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "dragleave", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "afterprint", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "beforeprint", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mousedown", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "seeked", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "click", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "waiting", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "online", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "durationchange", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "blur", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "emptied", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "seeking", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "canplay", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "stalled", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mousemove", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "offline", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "beforeunload", listener: (ev: BeforeUnloadEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "ratechange", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "storage", listener: (ev: StorageEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "loadstart", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "dragenter", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "submit", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "progress", listener: (ev: ProgressEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "dblclick", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "contextmenu", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "change", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "loadedmetadata", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "play", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "playing", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "canplaythrough", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "abort", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "readystatechange", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "keypress", listener: (ev: KeyboardEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "loadeddata", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "suspend", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "focus", listener: (ev: FocusEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "timeupdate", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "resize", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "select", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "drop", listener: (ev: DragEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mouseout", listener: (ev: MouseEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "ended", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "hashchange", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "unload", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "scroll", listener: (ev: UIEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mousewheel", listener: (ev: MouseWheelEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "load", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "volumechange", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "input", listener: (ev: Event) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mspointerdown", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "msgesturedoubletap", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mspointerhover", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "msgesturehold", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mspointermove", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "msgesturechange", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "msgesturestart", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mspointercancel", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "msgestureend", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "msgesturetap", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mspointerout", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "msinertiastart", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mspointerover", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "popstate", listener: (ev: PopStateEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mspointerup", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pageshow", listener: (ev: PageTransitionEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "devicemotion", listener: (ev: DeviceMotionEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "deviceorientation", listener: (ev: DeviceOrientationEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mspointerenter", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "pagehide", listener: (ev: PageTransitionEvent) => any, useCapture?: boolean): void;
        declare function addEventListener(type: "mspointerleave", listener: (ev: any) => any, useCapture?: boolean): void;
        declare function addEventListener(type: string, listener: EventListener, useCapture?: boolean): void;
        
        /////////////////////////////
        /// WorkerGlobalScope APIs 
        /////////////////////////////
        // These are only available in a Web Worker 
        declare function importScripts(...urls: string[]): void;
        
        
        /////////////////////////////
        /// Windows Script Host APIS
        /////////////////////////////
        
        declare var ActiveXObject: { new (s: string): any; };
        
        interface ITextWriter {
            Write(s: string): void;
            WriteLine(s: string): void;
            Close(): void;
        }
        
        declare var WScript: {
            Echo(s: any): void;
            StdErr: ITextWriter;
            StdOut: ITextWriter;
            Arguments: { length: number; Item(n: number): string; };
            ScriptFullName: string;
            Quit(exitCode?: number): number;
        }
        
      • typescriptServices.js
        var ts;
        (function (ts) {
            (function (SyntaxKind) {
                SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown";
                SyntaxKind[SyntaxKind["EndOfFileToken"] = 1] = "EndOfFileToken";
                SyntaxKind[SyntaxKind["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia";
                SyntaxKind[SyntaxKind["MultiLineCommentTrivia"] = 3] = "MultiLineCommentTrivia";
                SyntaxKind[SyntaxKind["NewLineTrivia"] = 4] = "NewLineTrivia";
                SyntaxKind[SyntaxKind["WhitespaceTrivia"] = 5] = "WhitespaceTrivia";
                SyntaxKind[SyntaxKind["NumericLiteral"] = 6] = "NumericLiteral";
                SyntaxKind[SyntaxKind["StringLiteral"] = 7] = "StringLiteral";
                SyntaxKind[SyntaxKind["RegularExpressionLiteral"] = 8] = "RegularExpressionLiteral";
                SyntaxKind[SyntaxKind["NoSubstitutionTemplateLiteral"] = 9] = "NoSubstitutionTemplateLiteral";
                SyntaxKind[SyntaxKind["TemplateHead"] = 10] = "TemplateHead";
                SyntaxKind[SyntaxKind["TemplateMiddle"] = 11] = "TemplateMiddle";
                SyntaxKind[SyntaxKind["TemplateTail"] = 12] = "TemplateTail";
                SyntaxKind[SyntaxKind["OpenBraceToken"] = 13] = "OpenBraceToken";
                SyntaxKind[SyntaxKind["CloseBraceToken"] = 14] = "CloseBraceToken";
                SyntaxKind[SyntaxKind["OpenParenToken"] = 15] = "OpenParenToken";
                SyntaxKind[SyntaxKind["CloseParenToken"] = 16] = "CloseParenToken";
                SyntaxKind[SyntaxKind["OpenBracketToken"] = 17] = "OpenBracketToken";
                SyntaxKind[SyntaxKind["CloseBracketToken"] = 18] = "CloseBracketToken";
                SyntaxKind[SyntaxKind["DotToken"] = 19] = "DotToken";
                SyntaxKind[SyntaxKind["DotDotDotToken"] = 20] = "DotDotDotToken";
                SyntaxKind[SyntaxKind["SemicolonToken"] = 21] = "SemicolonToken";
                SyntaxKind[SyntaxKind["CommaToken"] = 22] = "CommaToken";
                SyntaxKind[SyntaxKind["LessThanToken"] = 23] = "LessThanToken";
                SyntaxKind[SyntaxKind["GreaterThanToken"] = 24] = "GreaterThanToken";
                SyntaxKind[SyntaxKind["LessThanEqualsToken"] = 25] = "LessThanEqualsToken";
                SyntaxKind[SyntaxKind["GreaterThanEqualsToken"] = 26] = "GreaterThanEqualsToken";
                SyntaxKind[SyntaxKind["EqualsEqualsToken"] = 27] = "EqualsEqualsToken";
                SyntaxKind[SyntaxKind["ExclamationEqualsToken"] = 28] = "ExclamationEqualsToken";
                SyntaxKind[SyntaxKind["EqualsEqualsEqualsToken"] = 29] = "EqualsEqualsEqualsToken";
                SyntaxKind[SyntaxKind["ExclamationEqualsEqualsToken"] = 30] = "ExclamationEqualsEqualsToken";
                SyntaxKind[SyntaxKind["EqualsGreaterThanToken"] = 31] = "EqualsGreaterThanToken";
                SyntaxKind[SyntaxKind["PlusToken"] = 32] = "PlusToken";
                SyntaxKind[SyntaxKind["MinusToken"] = 33] = "MinusToken";
                SyntaxKind[SyntaxKind["AsteriskToken"] = 34] = "AsteriskToken";
                SyntaxKind[SyntaxKind["SlashToken"] = 35] = "SlashToken";
                SyntaxKind[SyntaxKind["PercentToken"] = 36] = "PercentToken";
                SyntaxKind[SyntaxKind["PlusPlusToken"] = 37] = "PlusPlusToken";
                SyntaxKind[SyntaxKind["MinusMinusToken"] = 38] = "MinusMinusToken";
                SyntaxKind[SyntaxKind["LessThanLessThanToken"] = 39] = "LessThanLessThanToken";
                SyntaxKind[SyntaxKind["GreaterThanGreaterThanToken"] = 40] = "GreaterThanGreaterThanToken";
                SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanToken"] = 41] = "GreaterThanGreaterThanGreaterThanToken";
                SyntaxKind[SyntaxKind["AmpersandToken"] = 42] = "AmpersandToken";
                SyntaxKind[SyntaxKind["BarToken"] = 43] = "BarToken";
                SyntaxKind[SyntaxKind["CaretToken"] = 44] = "CaretToken";
                SyntaxKind[SyntaxKind["ExclamationToken"] = 45] = "ExclamationToken";
                SyntaxKind[SyntaxKind["TildeToken"] = 46] = "TildeToken";
                SyntaxKind[SyntaxKind["AmpersandAmpersandToken"] = 47] = "AmpersandAmpersandToken";
                SyntaxKind[SyntaxKind["BarBarToken"] = 48] = "BarBarToken";
                SyntaxKind[SyntaxKind["QuestionToken"] = 49] = "QuestionToken";
                SyntaxKind[SyntaxKind["ColonToken"] = 50] = "ColonToken";
                SyntaxKind[SyntaxKind["EqualsToken"] = 51] = "EqualsToken";
                SyntaxKind[SyntaxKind["PlusEqualsToken"] = 52] = "PlusEqualsToken";
                SyntaxKind[SyntaxKind["MinusEqualsToken"] = 53] = "MinusEqualsToken";
                SyntaxKind[SyntaxKind["AsteriskEqualsToken"] = 54] = "AsteriskEqualsToken";
                SyntaxKind[SyntaxKind["SlashEqualsToken"] = 55] = "SlashEqualsToken";
                SyntaxKind[SyntaxKind["PercentEqualsToken"] = 56] = "PercentEqualsToken";
                SyntaxKind[SyntaxKind["LessThanLessThanEqualsToken"] = 57] = "LessThanLessThanEqualsToken";
                SyntaxKind[SyntaxKind["GreaterThanGreaterThanEqualsToken"] = 58] = "GreaterThanGreaterThanEqualsToken";
                SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanEqualsToken"] = 59] = "GreaterThanGreaterThanGreaterThanEqualsToken";
                SyntaxKind[SyntaxKind["AmpersandEqualsToken"] = 60] = "AmpersandEqualsToken";
                SyntaxKind[SyntaxKind["BarEqualsToken"] = 61] = "BarEqualsToken";
                SyntaxKind[SyntaxKind["CaretEqualsToken"] = 62] = "CaretEqualsToken";
                SyntaxKind[SyntaxKind["Identifier"] = 63] = "Identifier";
                SyntaxKind[SyntaxKind["BreakKeyword"] = 64] = "BreakKeyword";
                SyntaxKind[SyntaxKind["CaseKeyword"] = 65] = "CaseKeyword";
                SyntaxKind[SyntaxKind["CatchKeyword"] = 66] = "CatchKeyword";
                SyntaxKind[SyntaxKind["ClassKeyword"] = 67] = "ClassKeyword";
                SyntaxKind[SyntaxKind["ConstKeyword"] = 68] = "ConstKeyword";
                SyntaxKind[SyntaxKind["ContinueKeyword"] = 69] = "ContinueKeyword";
                SyntaxKind[SyntaxKind["DebuggerKeyword"] = 70] = "DebuggerKeyword";
                SyntaxKind[SyntaxKind["DefaultKeyword"] = 71] = "DefaultKeyword";
                SyntaxKind[SyntaxKind["DeleteKeyword"] = 72] = "DeleteKeyword";
                SyntaxKind[SyntaxKind["DoKeyword"] = 73] = "DoKeyword";
                SyntaxKind[SyntaxKind["ElseKeyword"] = 74] = "ElseKeyword";
                SyntaxKind[SyntaxKind["EnumKeyword"] = 75] = "EnumKeyword";
                SyntaxKind[SyntaxKind["ExportKeyword"] = 76] = "ExportKeyword";
                SyntaxKind[SyntaxKind["ExtendsKeyword"] = 77] = "ExtendsKeyword";
                SyntaxKind[SyntaxKind["FalseKeyword"] = 78] = "FalseKeyword";
                SyntaxKind[SyntaxKind["FinallyKeyword"] = 79] = "FinallyKeyword";
                SyntaxKind[SyntaxKind["ForKeyword"] = 80] = "ForKeyword";
                SyntaxKind[SyntaxKind["FunctionKeyword"] = 81] = "FunctionKeyword";
                SyntaxKind[SyntaxKind["IfKeyword"] = 82] = "IfKeyword";
                SyntaxKind[SyntaxKind["ImportKeyword"] = 83] = "ImportKeyword";
                SyntaxKind[SyntaxKind["InKeyword"] = 84] = "InKeyword";
                SyntaxKind[SyntaxKind["InstanceOfKeyword"] = 85] = "InstanceOfKeyword";
                SyntaxKind[SyntaxKind["NewKeyword"] = 86] = "NewKeyword";
                SyntaxKind[SyntaxKind["NullKeyword"] = 87] = "NullKeyword";
                SyntaxKind[SyntaxKind["ReturnKeyword"] = 88] = "ReturnKeyword";
                SyntaxKind[SyntaxKind["SuperKeyword"] = 89] = "SuperKeyword";
                SyntaxKind[SyntaxKind["SwitchKeyword"] = 90] = "SwitchKeyword";
                SyntaxKind[SyntaxKind["ThisKeyword"] = 91] = "ThisKeyword";
                SyntaxKind[SyntaxKind["ThrowKeyword"] = 92] = "ThrowKeyword";
                SyntaxKind[SyntaxKind["TrueKeyword"] = 93] = "TrueKeyword";
                SyntaxKind[SyntaxKind["TryKeyword"] = 94] = "TryKeyword";
                SyntaxKind[SyntaxKind["TypeOfKeyword"] = 95] = "TypeOfKeyword";
                SyntaxKind[SyntaxKind["VarKeyword"] = 96] = "VarKeyword";
                SyntaxKind[SyntaxKind["VoidKeyword"] = 97] = "VoidKeyword";
                SyntaxKind[SyntaxKind["WhileKeyword"] = 98] = "WhileKeyword";
                SyntaxKind[SyntaxKind["WithKeyword"] = 99] = "WithKeyword";
                SyntaxKind[SyntaxKind["ImplementsKeyword"] = 100] = "ImplementsKeyword";
                SyntaxKind[SyntaxKind["InterfaceKeyword"] = 101] = "InterfaceKeyword";
                SyntaxKind[SyntaxKind["LetKeyword"] = 102] = "LetKeyword";
                SyntaxKind[SyntaxKind["PackageKeyword"] = 103] = "PackageKeyword";
                SyntaxKind[SyntaxKind["PrivateKeyword"] = 104] = "PrivateKeyword";
                SyntaxKind[SyntaxKind["ProtectedKeyword"] = 105] = "ProtectedKeyword";
                SyntaxKind[SyntaxKind["PublicKeyword"] = 106] = "PublicKeyword";
                SyntaxKind[SyntaxKind["StaticKeyword"] = 107] = "StaticKeyword";
                SyntaxKind[SyntaxKind["YieldKeyword"] = 108] = "YieldKeyword";
                SyntaxKind[SyntaxKind["AnyKeyword"] = 109] = "AnyKeyword";
                SyntaxKind[SyntaxKind["BooleanKeyword"] = 110] = "BooleanKeyword";
                SyntaxKind[SyntaxKind["ConstructorKeyword"] = 111] = "ConstructorKeyword";
                SyntaxKind[SyntaxKind["DeclareKeyword"] = 112] = "DeclareKeyword";
                SyntaxKind[SyntaxKind["GetKeyword"] = 113] = "GetKeyword";
                SyntaxKind[SyntaxKind["ModuleKeyword"] = 114] = "ModuleKeyword";
                SyntaxKind[SyntaxKind["RequireKeyword"] = 115] = "RequireKeyword";
                SyntaxKind[SyntaxKind["NumberKeyword"] = 116] = "NumberKeyword";
                SyntaxKind[SyntaxKind["SetKeyword"] = 117] = "SetKeyword";
                SyntaxKind[SyntaxKind["StringKeyword"] = 118] = "StringKeyword";
                SyntaxKind[SyntaxKind["TypeKeyword"] = 119] = "TypeKeyword";
                SyntaxKind[SyntaxKind["Missing"] = 120] = "Missing";
                SyntaxKind[SyntaxKind["QualifiedName"] = 121] = "QualifiedName";
                SyntaxKind[SyntaxKind["ComputedPropertyName"] = 122] = "ComputedPropertyName";
                SyntaxKind[SyntaxKind["TypeParameter"] = 123] = "TypeParameter";
                SyntaxKind[SyntaxKind["Parameter"] = 124] = "Parameter";
                SyntaxKind[SyntaxKind["Property"] = 125] = "Property";
                SyntaxKind[SyntaxKind["Method"] = 126] = "Method";
                SyntaxKind[SyntaxKind["Constructor"] = 127] = "Constructor";
                SyntaxKind[SyntaxKind["GetAccessor"] = 128] = "GetAccessor";
                SyntaxKind[SyntaxKind["SetAccessor"] = 129] = "SetAccessor";
                SyntaxKind[SyntaxKind["CallSignature"] = 130] = "CallSignature";
                SyntaxKind[SyntaxKind["ConstructSignature"] = 131] = "ConstructSignature";
                SyntaxKind[SyntaxKind["IndexSignature"] = 132] = "IndexSignature";
                SyntaxKind[SyntaxKind["TypeReference"] = 133] = "TypeReference";
                SyntaxKind[SyntaxKind["FunctionType"] = 134] = "FunctionType";
                SyntaxKind[SyntaxKind["ConstructorType"] = 135] = "ConstructorType";
                SyntaxKind[SyntaxKind["TypeQuery"] = 136] = "TypeQuery";
                SyntaxKind[SyntaxKind["TypeLiteral"] = 137] = "TypeLiteral";
                SyntaxKind[SyntaxKind["ArrayType"] = 138] = "ArrayType";
                SyntaxKind[SyntaxKind["TupleType"] = 139] = "TupleType";
                SyntaxKind[SyntaxKind["UnionType"] = 140] = "UnionType";
                SyntaxKind[SyntaxKind["ParenType"] = 141] = "ParenType";
                SyntaxKind[SyntaxKind["ArrayLiteral"] = 142] = "ArrayLiteral";
                SyntaxKind[SyntaxKind["ObjectLiteral"] = 143] = "ObjectLiteral";
                SyntaxKind[SyntaxKind["PropertyAssignment"] = 144] = "PropertyAssignment";
                SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 145] = "ShorthandPropertyAssignment";
                SyntaxKind[SyntaxKind["PropertyAccess"] = 146] = "PropertyAccess";
                SyntaxKind[SyntaxKind["IndexedAccess"] = 147] = "IndexedAccess";
                SyntaxKind[SyntaxKind["CallExpression"] = 148] = "CallExpression";
                SyntaxKind[SyntaxKind["NewExpression"] = 149] = "NewExpression";
                SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 150] = "TaggedTemplateExpression";
                SyntaxKind[SyntaxKind["TypeAssertion"] = 151] = "TypeAssertion";
                SyntaxKind[SyntaxKind["ParenExpression"] = 152] = "ParenExpression";
                SyntaxKind[SyntaxKind["FunctionExpression"] = 153] = "FunctionExpression";
                SyntaxKind[SyntaxKind["ArrowFunction"] = 154] = "ArrowFunction";
                SyntaxKind[SyntaxKind["PrefixOperator"] = 155] = "PrefixOperator";
                SyntaxKind[SyntaxKind["PostfixOperator"] = 156] = "PostfixOperator";
                SyntaxKind[SyntaxKind["BinaryExpression"] = 157] = "BinaryExpression";
                SyntaxKind[SyntaxKind["ConditionalExpression"] = 158] = "ConditionalExpression";
                SyntaxKind[SyntaxKind["TemplateExpression"] = 159] = "TemplateExpression";
                SyntaxKind[SyntaxKind["TemplateSpan"] = 160] = "TemplateSpan";
                SyntaxKind[SyntaxKind["YieldExpression"] = 161] = "YieldExpression";
                SyntaxKind[SyntaxKind["OmittedExpression"] = 162] = "OmittedExpression";
                SyntaxKind[SyntaxKind["Block"] = 163] = "Block";
                SyntaxKind[SyntaxKind["VariableStatement"] = 164] = "VariableStatement";
                SyntaxKind[SyntaxKind["EmptyStatement"] = 165] = "EmptyStatement";
                SyntaxKind[SyntaxKind["ExpressionStatement"] = 166] = "ExpressionStatement";
                SyntaxKind[SyntaxKind["IfStatement"] = 167] = "IfStatement";
                SyntaxKind[SyntaxKind["DoStatement"] = 168] = "DoStatement";
                SyntaxKind[SyntaxKind["WhileStatement"] = 169] = "WhileStatement";
                SyntaxKind[SyntaxKind["ForStatement"] = 170] = "ForStatement";
                SyntaxKind[SyntaxKind["ForInStatement"] = 171] = "ForInStatement";
                SyntaxKind[SyntaxKind["ContinueStatement"] = 172] = "ContinueStatement";
                SyntaxKind[SyntaxKind["BreakStatement"] = 173] = "BreakStatement";
                SyntaxKind[SyntaxKind["ReturnStatement"] = 174] = "ReturnStatement";
                SyntaxKind[SyntaxKind["WithStatement"] = 175] = "WithStatement";
                SyntaxKind[SyntaxKind["SwitchStatement"] = 176] = "SwitchStatement";
                SyntaxKind[SyntaxKind["CaseClause"] = 177] = "CaseClause";
                SyntaxKind[SyntaxKind["DefaultClause"] = 178] = "DefaultClause";
                SyntaxKind[SyntaxKind["LabeledStatement"] = 179] = "LabeledStatement";
                SyntaxKind[SyntaxKind["ThrowStatement"] = 180] = "ThrowStatement";
                SyntaxKind[SyntaxKind["TryStatement"] = 181] = "TryStatement";
                SyntaxKind[SyntaxKind["TryBlock"] = 182] = "TryBlock";
                SyntaxKind[SyntaxKind["CatchBlock"] = 183] = "CatchBlock";
                SyntaxKind[SyntaxKind["FinallyBlock"] = 184] = "FinallyBlock";
                SyntaxKind[SyntaxKind["DebuggerStatement"] = 185] = "DebuggerStatement";
                SyntaxKind[SyntaxKind["VariableDeclaration"] = 186] = "VariableDeclaration";
                SyntaxKind[SyntaxKind["FunctionDeclaration"] = 187] = "FunctionDeclaration";
                SyntaxKind[SyntaxKind["FunctionBlock"] = 188] = "FunctionBlock";
                SyntaxKind[SyntaxKind["ClassDeclaration"] = 189] = "ClassDeclaration";
                SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 190] = "InterfaceDeclaration";
                SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 191] = "TypeAliasDeclaration";
                SyntaxKind[SyntaxKind["EnumDeclaration"] = 192] = "EnumDeclaration";
                SyntaxKind[SyntaxKind["ModuleDeclaration"] = 193] = "ModuleDeclaration";
                SyntaxKind[SyntaxKind["ModuleBlock"] = 194] = "ModuleBlock";
                SyntaxKind[SyntaxKind["ImportDeclaration"] = 195] = "ImportDeclaration";
                SyntaxKind[SyntaxKind["ExportAssignment"] = 196] = "ExportAssignment";
                SyntaxKind[SyntaxKind["EnumMember"] = 197] = "EnumMember";
                SyntaxKind[SyntaxKind["SourceFile"] = 198] = "SourceFile";
                SyntaxKind[SyntaxKind["Program"] = 199] = "Program";
                SyntaxKind[SyntaxKind["SyntaxList"] = 200] = "SyntaxList";
                SyntaxKind[SyntaxKind["Count"] = 201] = "Count";
                SyntaxKind[SyntaxKind["FirstAssignment"] = 51] = "FirstAssignment";
                SyntaxKind[SyntaxKind["LastAssignment"] = 62] = "LastAssignment";
                SyntaxKind[SyntaxKind["FirstReservedWord"] = 64] = "FirstReservedWord";
                SyntaxKind[SyntaxKind["LastReservedWord"] = 99] = "LastReservedWord";
                SyntaxKind[SyntaxKind["FirstKeyword"] = 64] = "FirstKeyword";
                SyntaxKind[SyntaxKind["LastKeyword"] = 119] = "LastKeyword";
                SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 100] = "FirstFutureReservedWord";
                SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 108] = "LastFutureReservedWord";
                SyntaxKind[SyntaxKind["FirstTypeNode"] = 133] = "FirstTypeNode";
                SyntaxKind[SyntaxKind["LastTypeNode"] = 141] = "LastTypeNode";
                SyntaxKind[SyntaxKind["FirstPunctuation"] = 13] = "FirstPunctuation";
                SyntaxKind[SyntaxKind["LastPunctuation"] = 62] = "LastPunctuation";
                SyntaxKind[SyntaxKind["FirstToken"] = 1] = "FirstToken";
                SyntaxKind[SyntaxKind["LastToken"] = 119] = "LastToken";
                SyntaxKind[SyntaxKind["FirstTriviaToken"] = 2] = "FirstTriviaToken";
                SyntaxKind[SyntaxKind["LastTriviaToken"] = 5] = "LastTriviaToken";
                SyntaxKind[SyntaxKind["FirstLiteralToken"] = 6] = "FirstLiteralToken";
                SyntaxKind[SyntaxKind["LastLiteralToken"] = 9] = "LastLiteralToken";
                SyntaxKind[SyntaxKind["FirstTemplateToken"] = 9] = "FirstTemplateToken";
                SyntaxKind[SyntaxKind["LastTemplateToken"] = 12] = "LastTemplateToken";
                SyntaxKind[SyntaxKind["FirstOperator"] = 21] = "FirstOperator";
                SyntaxKind[SyntaxKind["LastOperator"] = 62] = "LastOperator";
                SyntaxKind[SyntaxKind["FirstBinaryOperator"] = 23] = "FirstBinaryOperator";
                SyntaxKind[SyntaxKind["LastBinaryOperator"] = 62] = "LastBinaryOperator";
            })(ts.SyntaxKind || (ts.SyntaxKind = {}));
            var SyntaxKind = ts.SyntaxKind;
            (function (NodeFlags) {
                NodeFlags[NodeFlags["Export"] = 1] = "Export";
                NodeFlags[NodeFlags["Ambient"] = 2] = "Ambient";
                NodeFlags[NodeFlags["QuestionMark"] = 4] = "QuestionMark";
                NodeFlags[NodeFlags["Rest"] = 8] = "Rest";
                NodeFlags[NodeFlags["Public"] = 16] = "Public";
                NodeFlags[NodeFlags["Private"] = 32] = "Private";
                NodeFlags[NodeFlags["Protected"] = 64] = "Protected";
                NodeFlags[NodeFlags["Static"] = 128] = "Static";
                NodeFlags[NodeFlags["MultiLine"] = 256] = "MultiLine";
                NodeFlags[NodeFlags["Synthetic"] = 512] = "Synthetic";
                NodeFlags[NodeFlags["DeclarationFile"] = 1024] = "DeclarationFile";
                NodeFlags[NodeFlags["Let"] = 2048] = "Let";
                NodeFlags[NodeFlags["Const"] = 4096] = "Const";
                NodeFlags[NodeFlags["OctalLiteral"] = 8192] = "OctalLiteral";
                NodeFlags[NodeFlags["Modifier"] = 243] = "Modifier";
                NodeFlags[NodeFlags["AccessibilityModifier"] = 112] = "AccessibilityModifier";
                NodeFlags[NodeFlags["BlockScoped"] = 6144] = "BlockScoped";
            })(ts.NodeFlags || (ts.NodeFlags = {}));
            var NodeFlags = ts.NodeFlags;
            (function (ParserContextFlags) {
                ParserContextFlags[ParserContextFlags["StrictMode"] = 1] = "StrictMode";
                ParserContextFlags[ParserContextFlags["DisallowIn"] = 2] = "DisallowIn";
                ParserContextFlags[ParserContextFlags["Yield"] = 4] = "Yield";
                ParserContextFlags[ParserContextFlags["GeneratorParameter"] = 8] = "GeneratorParameter";
            })(ts.ParserContextFlags || (ts.ParserContextFlags = {}));
            var ParserContextFlags = ts.ParserContextFlags;
            (function (EmitReturnStatus) {
                EmitReturnStatus[EmitReturnStatus["Succeeded"] = 0] = "Succeeded";
                EmitReturnStatus[EmitReturnStatus["AllOutputGenerationSkipped"] = 1] = "AllOutputGenerationSkipped";
                EmitReturnStatus[EmitReturnStatus["JSGeneratedWithSemanticErrors"] = 2] = "JSGeneratedWithSemanticErrors";
                EmitReturnStatus[EmitReturnStatus["DeclarationGenerationSkipped"] = 3] = "DeclarationGenerationSkipped";
                EmitReturnStatus[EmitReturnStatus["EmitErrorsEncountered"] = 4] = "EmitErrorsEncountered";
                EmitReturnStatus[EmitReturnStatus["CompilerOptionsErrors"] = 5] = "CompilerOptionsErrors";
            })(ts.EmitReturnStatus || (ts.EmitReturnStatus = {}));
            var EmitReturnStatus = ts.EmitReturnStatus;
            (function (TypeFormatFlags) {
                TypeFormatFlags[TypeFormatFlags["None"] = 0] = "None";
                TypeFormatFlags[TypeFormatFlags["WriteArrayAsGenericType"] = 1] = "WriteArrayAsGenericType";
                TypeFormatFlags[TypeFormatFlags["UseTypeOfFunction"] = 2] = "UseTypeOfFunction";
                TypeFormatFlags[TypeFormatFlags["NoTruncation"] = 4] = "NoTruncation";
                TypeFormatFlags[TypeFormatFlags["WriteArrowStyleSignature"] = 8] = "WriteArrowStyleSignature";
                TypeFormatFlags[TypeFormatFlags["WriteOwnNameForAnyLike"] = 16] = "WriteOwnNameForAnyLike";
                TypeFormatFlags[TypeFormatFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature";
                TypeFormatFlags[TypeFormatFlags["InElementType"] = 64] = "InElementType";
            })(ts.TypeFormatFlags || (ts.TypeFormatFlags = {}));
            var TypeFormatFlags = ts.TypeFormatFlags;
            (function (SymbolFormatFlags) {
                SymbolFormatFlags[SymbolFormatFlags["None"] = 0] = "None";
                SymbolFormatFlags[SymbolFormatFlags["WriteTypeParametersOrArguments"] = 1] = "WriteTypeParametersOrArguments";
                SymbolFormatFlags[SymbolFormatFlags["UseOnlyExternalAliasing"] = 2] = "UseOnlyExternalAliasing";
            })(ts.SymbolFormatFlags || (ts.SymbolFormatFlags = {}));
            var SymbolFormatFlags = ts.SymbolFormatFlags;
            (function (SymbolAccessibility) {
                SymbolAccessibility[SymbolAccessibility["Accessible"] = 0] = "Accessible";
                SymbolAccessibility[SymbolAccessibility["NotAccessible"] = 1] = "NotAccessible";
                SymbolAccessibility[SymbolAccessibility["CannotBeNamed"] = 2] = "CannotBeNamed";
            })(ts.SymbolAccessibility || (ts.SymbolAccessibility = {}));
            var SymbolAccessibility = ts.SymbolAccessibility;
            (function (SymbolFlags) {
                SymbolFlags[SymbolFlags["FunctionScopedVariable"] = 1] = "FunctionScopedVariable";
                SymbolFlags[SymbolFlags["BlockScopedVariable"] = 2] = "BlockScopedVariable";
                SymbolFlags[SymbolFlags["Property"] = 4] = "Property";
                SymbolFlags[SymbolFlags["EnumMember"] = 8] = "EnumMember";
                SymbolFlags[SymbolFlags["Function"] = 16] = "Function";
                SymbolFlags[SymbolFlags["Class"] = 32] = "Class";
                SymbolFlags[SymbolFlags["Interface"] = 64] = "Interface";
                SymbolFlags[SymbolFlags["ConstEnum"] = 128] = "ConstEnum";
                SymbolFlags[SymbolFlags["RegularEnum"] = 256] = "RegularEnum";
                SymbolFlags[SymbolFlags["ValueModule"] = 512] = "ValueModule";
                SymbolFlags[SymbolFlags["NamespaceModule"] = 1024] = "NamespaceModule";
                SymbolFlags[SymbolFlags["TypeLiteral"] = 2048] = "TypeLiteral";
                SymbolFlags[SymbolFlags["ObjectLiteral"] = 4096] = "ObjectLiteral";
                SymbolFlags[SymbolFlags["Method"] = 8192] = "Method";
                SymbolFlags[SymbolFlags["Constructor"] = 16384] = "Constructor";
                SymbolFlags[SymbolFlags["GetAccessor"] = 32768] = "GetAccessor";
                SymbolFlags[SymbolFlags["SetAccessor"] = 65536] = "SetAccessor";
                SymbolFlags[SymbolFlags["CallSignature"] = 131072] = "CallSignature";
                SymbolFlags[SymbolFlags["ConstructSignature"] = 262144] = "ConstructSignature";
                SymbolFlags[SymbolFlags["IndexSignature"] = 524288] = "IndexSignature";
                SymbolFlags[SymbolFlags["TypeParameter"] = 1048576] = "TypeParameter";
                SymbolFlags[SymbolFlags["TypeAlias"] = 2097152] = "TypeAlias";
                SymbolFlags[SymbolFlags["ExportValue"] = 4194304] = "ExportValue";
                SymbolFlags[SymbolFlags["ExportType"] = 8388608] = "ExportType";
                SymbolFlags[SymbolFlags["ExportNamespace"] = 16777216] = "ExportNamespace";
                SymbolFlags[SymbolFlags["Import"] = 33554432] = "Import";
                SymbolFlags[SymbolFlags["Instantiated"] = 67108864] = "Instantiated";
                SymbolFlags[SymbolFlags["Merged"] = 134217728] = "Merged";
                SymbolFlags[SymbolFlags["Transient"] = 268435456] = "Transient";
                SymbolFlags[SymbolFlags["Prototype"] = 536870912] = "Prototype";
                SymbolFlags[SymbolFlags["UnionProperty"] = 1073741824] = "UnionProperty";
                SymbolFlags[SymbolFlags["Enum"] = 384] = "Enum";
                SymbolFlags[SymbolFlags["Variable"] = 3] = "Variable";
                SymbolFlags[SymbolFlags["Value"] = 107455] = "Value";
                SymbolFlags[SymbolFlags["Type"] = 3152352] = "Type";
                SymbolFlags[SymbolFlags["Namespace"] = 1536] = "Namespace";
                SymbolFlags[SymbolFlags["Module"] = 1536] = "Module";
                SymbolFlags[SymbolFlags["Accessor"] = 98304] = "Accessor";
                SymbolFlags[SymbolFlags["Signature"] = 917504] = "Signature";
                SymbolFlags[SymbolFlags["FunctionScopedVariableExcludes"] = 107454] = "FunctionScopedVariableExcludes";
                SymbolFlags[SymbolFlags["BlockScopedVariableExcludes"] = 107455] = "BlockScopedVariableExcludes";
                SymbolFlags[SymbolFlags["ParameterExcludes"] = 107455] = "ParameterExcludes";
                SymbolFlags[SymbolFlags["PropertyExcludes"] = 107455] = "PropertyExcludes";
                SymbolFlags[SymbolFlags["EnumMemberExcludes"] = 107455] = "EnumMemberExcludes";
                SymbolFlags[SymbolFlags["FunctionExcludes"] = 106927] = "FunctionExcludes";
                SymbolFlags[SymbolFlags["ClassExcludes"] = 3258879] = "ClassExcludes";
                SymbolFlags[SymbolFlags["InterfaceExcludes"] = 3152288] = "InterfaceExcludes";
                SymbolFlags[SymbolFlags["RegularEnumExcludes"] = 3258623] = "RegularEnumExcludes";
                SymbolFlags[SymbolFlags["ConstEnumExcludes"] = 3259263] = "ConstEnumExcludes";
                SymbolFlags[SymbolFlags["ValueModuleExcludes"] = 106639] = "ValueModuleExcludes";
                SymbolFlags[SymbolFlags["NamespaceModuleExcludes"] = 0] = "NamespaceModuleExcludes";
                SymbolFlags[SymbolFlags["MethodExcludes"] = 99263] = "MethodExcludes";
                SymbolFlags[SymbolFlags["GetAccessorExcludes"] = 41919] = "GetAccessorExcludes";
                SymbolFlags[SymbolFlags["SetAccessorExcludes"] = 74687] = "SetAccessorExcludes";
                SymbolFlags[SymbolFlags["TypeParameterExcludes"] = 2103776] = "TypeParameterExcludes";
                SymbolFlags[SymbolFlags["TypeAliasExcludes"] = 3152352] = "TypeAliasExcludes";
                SymbolFlags[SymbolFlags["ImportExcludes"] = 33554432] = "ImportExcludes";
                SymbolFlags[SymbolFlags["ModuleMember"] = 35653619] = "ModuleMember";
                SymbolFlags[SymbolFlags["ExportHasLocal"] = 944] = "ExportHasLocal";
                SymbolFlags[SymbolFlags["HasLocals"] = 1041936] = "HasLocals";
                SymbolFlags[SymbolFlags["HasExports"] = 1952] = "HasExports";
                SymbolFlags[SymbolFlags["HasMembers"] = 6240] = "HasMembers";
                SymbolFlags[SymbolFlags["IsContainer"] = 1048560] = "IsContainer";
                SymbolFlags[SymbolFlags["PropertyOrAccessor"] = 98308] = "PropertyOrAccessor";
                SymbolFlags[SymbolFlags["Export"] = 29360128] = "Export";
            })(ts.SymbolFlags || (ts.SymbolFlags = {}));
            var SymbolFlags = ts.SymbolFlags;
            (function (NodeCheckFlags) {
                NodeCheckFlags[NodeCheckFlags["TypeChecked"] = 1] = "TypeChecked";
                NodeCheckFlags[NodeCheckFlags["LexicalThis"] = 2] = "LexicalThis";
                NodeCheckFlags[NodeCheckFlags["CaptureThis"] = 4] = "CaptureThis";
                NodeCheckFlags[NodeCheckFlags["EmitExtends"] = 8] = "EmitExtends";
                NodeCheckFlags[NodeCheckFlags["SuperInstance"] = 16] = "SuperInstance";
                NodeCheckFlags[NodeCheckFlags["SuperStatic"] = 32] = "SuperStatic";
                NodeCheckFlags[NodeCheckFlags["ContextChecked"] = 64] = "ContextChecked";
                NodeCheckFlags[NodeCheckFlags["EnumValuesComputed"] = 128] = "EnumValuesComputed";
            })(ts.NodeCheckFlags || (ts.NodeCheckFlags = {}));
            var NodeCheckFlags = ts.NodeCheckFlags;
            (function (TypeFlags) {
                TypeFlags[TypeFlags["Any"] = 1] = "Any";
                TypeFlags[TypeFlags["String"] = 2] = "String";
                TypeFlags[TypeFlags["Number"] = 4] = "Number";
                TypeFlags[TypeFlags["Boolean"] = 8] = "Boolean";
                TypeFlags[TypeFlags["Void"] = 16] = "Void";
                TypeFlags[TypeFlags["Undefined"] = 32] = "Undefined";
                TypeFlags[TypeFlags["Null"] = 64] = "Null";
                TypeFlags[TypeFlags["Enum"] = 128] = "Enum";
                TypeFlags[TypeFlags["StringLiteral"] = 256] = "StringLiteral";
                TypeFlags[TypeFlags["TypeParameter"] = 512] = "TypeParameter";
                TypeFlags[TypeFlags["Class"] = 1024] = "Class";
                TypeFlags[TypeFlags["Interface"] = 2048] = "Interface";
                TypeFlags[TypeFlags["Reference"] = 4096] = "Reference";
                TypeFlags[TypeFlags["Tuple"] = 8192] = "Tuple";
                TypeFlags[TypeFlags["Union"] = 16384] = "Union";
                TypeFlags[TypeFlags["Anonymous"] = 32768] = "Anonymous";
                TypeFlags[TypeFlags["FromSignature"] = 65536] = "FromSignature";
                TypeFlags[TypeFlags["Intrinsic"] = 127] = "Intrinsic";
                TypeFlags[TypeFlags["StringLike"] = 258] = "StringLike";
                TypeFlags[TypeFlags["NumberLike"] = 132] = "NumberLike";
                TypeFlags[TypeFlags["ObjectType"] = 48128] = "ObjectType";
                TypeFlags[TypeFlags["Structured"] = 65025] = "Structured";
            })(ts.TypeFlags || (ts.TypeFlags = {}));
            var TypeFlags = ts.TypeFlags;
            (function (SignatureKind) {
                SignatureKind[SignatureKind["Call"] = 0] = "Call";
                SignatureKind[SignatureKind["Construct"] = 1] = "Construct";
            })(ts.SignatureKind || (ts.SignatureKind = {}));
            var SignatureKind = ts.SignatureKind;
            (function (IndexKind) {
                IndexKind[IndexKind["String"] = 0] = "String";
                IndexKind[IndexKind["Number"] = 1] = "Number";
            })(ts.IndexKind || (ts.IndexKind = {}));
            var IndexKind = ts.IndexKind;
            (function (DiagnosticCategory) {
                DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning";
                DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error";
                DiagnosticCategory[DiagnosticCategory["Message"] = 2] = "Message";
            })(ts.DiagnosticCategory || (ts.DiagnosticCategory = {}));
            var DiagnosticCategory = ts.DiagnosticCategory;
            (function (ModuleKind) {
                ModuleKind[ModuleKind["None"] = 0] = "None";
                ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS";
                ModuleKind[ModuleKind["AMD"] = 2] = "AMD";
            })(ts.ModuleKind || (ts.ModuleKind = {}));
            var ModuleKind = ts.ModuleKind;
            (function (ScriptTarget) {
                ScriptTarget[ScriptTarget["ES3"] = 0] = "ES3";
                ScriptTarget[ScriptTarget["ES5"] = 1] = "ES5";
                ScriptTarget[ScriptTarget["ES6"] = 2] = "ES6";
                ScriptTarget[ScriptTarget["Latest"] = 2] = "Latest";
            })(ts.ScriptTarget || (ts.ScriptTarget = {}));
            var ScriptTarget = ts.ScriptTarget;
            (function (CharacterCodes) {
                CharacterCodes[CharacterCodes["nullCharacter"] = 0] = "nullCharacter";
                CharacterCodes[CharacterCodes["maxAsciiCharacter"] = 127] = "maxAsciiCharacter";
                CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed";
                CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn";
                CharacterCodes[CharacterCodes["lineSeparator"] = 8232] = "lineSeparator";
                CharacterCodes[CharacterCodes["paragraphSeparator"] = 8233] = "paragraphSeparator";
                CharacterCodes[CharacterCodes["nextLine"] = 133] = "nextLine";
                CharacterCodes[CharacterCodes["space"] = 32] = "space";
                CharacterCodes[CharacterCodes["nonBreakingSpace"] = 160] = "nonBreakingSpace";
                CharacterCodes[CharacterCodes["enQuad"] = 8192] = "enQuad";
                CharacterCodes[CharacterCodes["emQuad"] = 8193] = "emQuad";
                CharacterCodes[CharacterCodes["enSpace"] = 8194] = "enSpace";
                CharacterCodes[CharacterCodes["emSpace"] = 8195] = "emSpace";
                CharacterCodes[CharacterCodes["threePerEmSpace"] = 8196] = "threePerEmSpace";
                CharacterCodes[CharacterCodes["fourPerEmSpace"] = 8197] = "fourPerEmSpace";
                CharacterCodes[CharacterCodes["sixPerEmSpace"] = 8198] = "sixPerEmSpace";
                CharacterCodes[CharacterCodes["figureSpace"] = 8199] = "figureSpace";
                CharacterCodes[CharacterCodes["punctuationSpace"] = 8200] = "punctuationSpace";
                CharacterCodes[CharacterCodes["thinSpace"] = 8201] = "thinSpace";
                CharacterCodes[CharacterCodes["hairSpace"] = 8202] = "hairSpace";
                CharacterCodes[CharacterCodes["zeroWidthSpace"] = 8203] = "zeroWidthSpace";
                CharacterCodes[CharacterCodes["narrowNoBreakSpace"] = 8239] = "narrowNoBreakSpace";
                CharacterCodes[CharacterCodes["ideographicSpace"] = 12288] = "ideographicSpace";
                CharacterCodes[CharacterCodes["mathematicalSpace"] = 8287] = "mathematicalSpace";
                CharacterCodes[CharacterCodes["ogham"] = 5760] = "ogham";
                CharacterCodes[CharacterCodes["_"] = 95] = "_";
                CharacterCodes[CharacterCodes["$"] = 36] = "$";
                CharacterCodes[CharacterCodes["_0"] = 48] = "_0";
                CharacterCodes[CharacterCodes["_1"] = 49] = "_1";
                CharacterCodes[CharacterCodes["_2"] = 50] = "_2";
                CharacterCodes[CharacterCodes["_3"] = 51] = "_3";
                CharacterCodes[CharacterCodes["_4"] = 52] = "_4";
                CharacterCodes[CharacterCodes["_5"] = 53] = "_5";
                CharacterCodes[CharacterCodes["_6"] = 54] = "_6";
                CharacterCodes[CharacterCodes["_7"] = 55] = "_7";
                CharacterCodes[CharacterCodes["_8"] = 56] = "_8";
                CharacterCodes[CharacterCodes["_9"] = 57] = "_9";
                CharacterCodes[CharacterCodes["a"] = 97] = "a";
                CharacterCodes[CharacterCodes["b"] = 98] = "b";
                CharacterCodes[CharacterCodes["c"] = 99] = "c";
                CharacterCodes[CharacterCodes["d"] = 100] = "d";
                CharacterCodes[CharacterCodes["e"] = 101] = "e";
                CharacterCodes[CharacterCodes["f"] = 102] = "f";
                CharacterCodes[CharacterCodes["g"] = 103] = "g";
                CharacterCodes[CharacterCodes["h"] = 104] = "h";
                CharacterCodes[CharacterCodes["i"] = 105] = "i";
                CharacterCodes[CharacterCodes["j"] = 106] = "j";
                CharacterCodes[CharacterCodes["k"] = 107] = "k";
                CharacterCodes[CharacterCodes["l"] = 108] = "l";
                CharacterCodes[CharacterCodes["m"] = 109] = "m";
                CharacterCodes[CharacterCodes["n"] = 110] = "n";
                CharacterCodes[CharacterCodes["o"] = 111] = "o";
                CharacterCodes[CharacterCodes["p"] = 112] = "p";
                CharacterCodes[CharacterCodes["q"] = 113] = "q";
                CharacterCodes[CharacterCodes["r"] = 114] = "r";
                CharacterCodes[CharacterCodes["s"] = 115] = "s";
                CharacterCodes[CharacterCodes["t"] = 116] = "t";
                CharacterCodes[CharacterCodes["u"] = 117] = "u";
                CharacterCodes[CharacterCodes["v"] = 118] = "v";
                CharacterCodes[CharacterCodes["w"] = 119] = "w";
                CharacterCodes[CharacterCodes["x"] = 120] = "x";
                CharacterCodes[CharacterCodes["y"] = 121] = "y";
                CharacterCodes[CharacterCodes["z"] = 122] = "z";
                CharacterCodes[CharacterCodes["A"] = 65] = "A";
                CharacterCodes[CharacterCodes["B"] = 66] = "B";
                CharacterCodes[CharacterCodes["C"] = 67] = "C";
                CharacterCodes[CharacterCodes["D"] = 68] = "D";
                CharacterCodes[CharacterCodes["E"] = 69] = "E";
                CharacterCodes[CharacterCodes["F"] = 70] = "F";
                CharacterCodes[CharacterCodes["G"] = 71] = "G";
                CharacterCodes[CharacterCodes["H"] = 72] = "H";
                CharacterCodes[CharacterCodes["I"] = 73] = "I";
                CharacterCodes[CharacterCodes["J"] = 74] = "J";
                CharacterCodes[CharacterCodes["K"] = 75] = "K";
                CharacterCodes[CharacterCodes["L"] = 76] = "L";
                CharacterCodes[CharacterCodes["M"] = 77] = "M";
                CharacterCodes[CharacterCodes["N"] = 78] = "N";
                CharacterCodes[CharacterCodes["O"] = 79] = "O";
                CharacterCodes[CharacterCodes["P"] = 80] = "P";
                CharacterCodes[CharacterCodes["Q"] = 81] = "Q";
                CharacterCodes[CharacterCodes["R"] = 82] = "R";
                CharacterCodes[CharacterCodes["S"] = 83] = "S";
                CharacterCodes[CharacterCodes["T"] = 84] = "T";
                CharacterCodes[CharacterCodes["U"] = 85] = "U";
                CharacterCodes[CharacterCodes["V"] = 86] = "V";
                CharacterCodes[CharacterCodes["W"] = 87] = "W";
                CharacterCodes[CharacterCodes["X"] = 88] = "X";
                CharacterCodes[CharacterCodes["Y"] = 89] = "Y";
                CharacterCodes[CharacterCodes["Z"] = 90] = "Z";
                CharacterCodes[CharacterCodes["ampersand"] = 38] = "ampersand";
                CharacterCodes[CharacterCodes["asterisk"] = 42] = "asterisk";
                CharacterCodes[CharacterCodes["at"] = 64] = "at";
                CharacterCodes[CharacterCodes["backslash"] = 92] = "backslash";
                CharacterCodes[CharacterCodes["backtick"] = 96] = "backtick";
                CharacterCodes[CharacterCodes["bar"] = 124] = "bar";
                CharacterCodes[CharacterCodes["caret"] = 94] = "caret";
                CharacterCodes[CharacterCodes["closeBrace"] = 125] = "closeBrace";
                CharacterCodes[CharacterCodes["closeBracket"] = 93] = "closeBracket";
                CharacterCodes[CharacterCodes["closeParen"] = 41] = "closeParen";
                CharacterCodes[CharacterCodes["colon"] = 58] = "colon";
                CharacterCodes[CharacterCodes["comma"] = 44] = "comma";
                CharacterCodes[CharacterCodes["dot"] = 46] = "dot";
                CharacterCodes[CharacterCodes["doubleQuote"] = 34] = "doubleQuote";
                CharacterCodes[CharacterCodes["equals"] = 61] = "equals";
                CharacterCodes[CharacterCodes["exclamation"] = 33] = "exclamation";
                CharacterCodes[CharacterCodes["greaterThan"] = 62] = "greaterThan";
                CharacterCodes[CharacterCodes["lessThan"] = 60] = "lessThan";
                CharacterCodes[CharacterCodes["minus"] = 45] = "minus";
                CharacterCodes[CharacterCodes["openBrace"] = 123] = "openBrace";
                CharacterCodes[CharacterCodes["openBracket"] = 91] = "openBracket";
                CharacterCodes[CharacterCodes["openParen"] = 40] = "openParen";
                CharacterCodes[CharacterCodes["percent"] = 37] = "percent";
                CharacterCodes[CharacterCodes["plus"] = 43] = "plus";
                CharacterCodes[CharacterCodes["question"] = 63] = "question";
                CharacterCodes[CharacterCodes["semicolon"] = 59] = "semicolon";
                CharacterCodes[CharacterCodes["singleQuote"] = 39] = "singleQuote";
                CharacterCodes[CharacterCodes["slash"] = 47] = "slash";
                CharacterCodes[CharacterCodes["tilde"] = 126] = "tilde";
                CharacterCodes[CharacterCodes["backspace"] = 8] = "backspace";
                CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed";
                CharacterCodes[CharacterCodes["byteOrderMark"] = 65279] = "byteOrderMark";
                CharacterCodes[CharacterCodes["tab"] = 9] = "tab";
                CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab";
            })(ts.CharacterCodes || (ts.CharacterCodes = {}));
            var CharacterCodes = ts.CharacterCodes;
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            (function (Ternary) {
                Ternary[Ternary["False"] = 0] = "False";
                Ternary[Ternary["Maybe"] = 1] = "Maybe";
                Ternary[Ternary["True"] = -1] = "True";
            })(ts.Ternary || (ts.Ternary = {}));
            var Ternary = ts.Ternary;
            (function (Comparison) {
                Comparison[Comparison["LessThan"] = -1] = "LessThan";
                Comparison[Comparison["EqualTo"] = 0] = "EqualTo";
                Comparison[Comparison["GreaterThan"] = 1] = "GreaterThan";
            })(ts.Comparison || (ts.Comparison = {}));
            var Comparison = ts.Comparison;
            function forEach(array, callback) {
                var result;
                if (array) {
                    for (var i = 0, len = array.length; i < len; i++) {
                        if (result = callback(array[i])) {
                            break;
                        }
                    }
                }
                return result;
            }
            ts.forEach = forEach;
            function contains(array, value) {
                if (array) {
                    for (var i = 0, len = array.length; i < len; i++) {
                        if (array[i] === value) {
                            return true;
                        }
                    }
                }
                return false;
            }
            ts.contains = contains;
            function indexOf(array, value) {
                if (array) {
                    for (var i = 0, len = array.length; i < len; i++) {
                        if (array[i] === value) {
                            return i;
                        }
                    }
                }
                return -1;
            }
            ts.indexOf = indexOf;
            function countWhere(array, predicate) {
                var count = 0;
                if (array) {
                    for (var i = 0, len = array.length; i < len; i++) {
                        if (predicate(array[i])) {
                            count++;
                        }
                    }
                }
                return count;
            }
            ts.countWhere = countWhere;
            function filter(array, f) {
                if (array) {
                    var result = [];
                    for (var i = 0, len = array.length; i < len; i++) {
                        var item = array[i];
                        if (f(item)) {
                            result.push(item);
                        }
                    }
                }
                return result;
            }
            ts.filter = filter;
            function map(array, f) {
                if (array) {
                    var result = [];
                    for (var i = 0, len = array.length; i < len; i++) {
                        result.push(f(array[i]));
                    }
                }
                return result;
            }
            ts.map = map;
            function concatenate(array1, array2) {
                if (!array2 || !array2.length)
                    return array1;
                if (!array1 || !array1.length)
                    return array2;
                return array1.concat(array2);
            }
            ts.concatenate = concatenate;
            function deduplicate(array) {
                if (array) {
                    var result = [];
                    for (var i = 0, len = array.length; i < len; i++) {
                        var item = array[i];
                        if (!contains(result, item))
                            result.push(item);
                    }
                }
                return result;
            }
            ts.deduplicate = deduplicate;
            function sum(array, prop) {
                var result = 0;
                for (var i = 0; i < array.length; i++) {
                    result += array[i][prop];
                }
                return result;
            }
            ts.sum = sum;
            function lastOrUndefined(array) {
                if (array.length === 0) {
                    return undefined;
                }
                return array[array.length - 1];
            }
            ts.lastOrUndefined = lastOrUndefined;
            function binarySearch(array, value) {
                var low = 0;
                var high = array.length - 1;
                while (low <= high) {
                    var middle = low + ((high - low) >> 1);
                    var midValue = array[middle];
                    if (midValue === value) {
                        return middle;
                    }
                    else if (midValue > value) {
                        high = middle - 1;
                    }
                    else {
                        low = middle + 1;
                    }
                }
                return ~low;
            }
            ts.binarySearch = binarySearch;
            var hasOwnProperty = Object.prototype.hasOwnProperty;
            function hasProperty(map, key) {
                return hasOwnProperty.call(map, key);
            }
            ts.hasProperty = hasProperty;
            function getProperty(map, key) {
                return hasOwnProperty.call(map, key) ? map[key] : undefined;
            }
            ts.getProperty = getProperty;
            function isEmpty(map) {
                for (var id in map) {
                    if (hasProperty(map, id)) {
                        return false;
                    }
                }
                return true;
            }
            ts.isEmpty = isEmpty;
            function clone(object) {
                var result = {};
                for (var id in object) {
                    result[id] = object[id];
                }
                return result;
            }
            ts.clone = clone;
            function forEachValue(map, callback) {
                var result;
                for (var id in map) {
                    if (result = callback(map[id]))
                        break;
                }
                return result;
            }
            ts.forEachValue = forEachValue;
            function forEachKey(map, callback) {
                var result;
                for (var id in map) {
                    if (result = callback(id))
                        break;
                }
                return result;
            }
            ts.forEachKey = forEachKey;
            function lookUp(map, key) {
                return hasProperty(map, key) ? map[key] : undefined;
            }
            ts.lookUp = lookUp;
            function mapToArray(map) {
                var result = [];
                for (var id in map) {
                    result.push(map[id]);
                }
                return result;
            }
            ts.mapToArray = mapToArray;
            function arrayToMap(array, makeKey) {
                var result = {};
                forEach(array, function (value) {
                    result[makeKey(value)] = value;
                });
                return result;
            }
            ts.arrayToMap = arrayToMap;
            function formatStringFromArgs(text, args, baseIndex) {
                baseIndex = baseIndex || 0;
                return text.replace(/{(\d+)}/g, function (match, index) { return args[+index + baseIndex]; });
            }
            ts.localizedDiagnosticMessages = undefined;
            function getLocaleSpecificMessage(message) {
                return ts.localizedDiagnosticMessages && ts.localizedDiagnosticMessages[message] ? ts.localizedDiagnosticMessages[message] : message;
            }
            ts.getLocaleSpecificMessage = getLocaleSpecificMessage;
            function createFileDiagnostic(file, start, length, message) {
                Debug.assert(start >= 0, "start must be non-negative, is " + start);
                Debug.assert(length >= 0, "length must be non-negative, is " + length);
                var text = getLocaleSpecificMessage(message.key);
                if (arguments.length > 4) {
                    text = formatStringFromArgs(text, arguments, 4);
                }
                return {
                    file: file,
                    start: start,
                    length: length,
                    messageText: text,
                    category: message.category,
                    code: message.code,
                    isEarly: message.isEarly
                };
            }
            ts.createFileDiagnostic = createFileDiagnostic;
            function createCompilerDiagnostic(message) {
                var text = getLocaleSpecificMessage(message.key);
                if (arguments.length > 1) {
                    text = formatStringFromArgs(text, arguments, 1);
                }
                return {
                    file: undefined,
                    start: undefined,
                    length: undefined,
                    messageText: text,
                    category: message.category,
                    code: message.code,
                    isEarly: message.isEarly
                };
            }
            ts.createCompilerDiagnostic = createCompilerDiagnostic;
            function chainDiagnosticMessages(details, message) {
                var text = getLocaleSpecificMessage(message.key);
                if (arguments.length > 2) {
                    text = formatStringFromArgs(text, arguments, 2);
                }
                return {
                    messageText: text,
                    category: message.category,
                    code: message.code,
                    next: details
                };
            }
            ts.chainDiagnosticMessages = chainDiagnosticMessages;
            function concatenateDiagnosticMessageChains(headChain, tailChain) {
                Debug.assert(!headChain.next);
                headChain.next = tailChain;
                return headChain;
            }
            ts.concatenateDiagnosticMessageChains = concatenateDiagnosticMessageChains;
            function flattenDiagnosticChain(file, start, length, diagnosticChain, newLine) {
                Debug.assert(start >= 0, "start must be non-negative, is " + start);
                Debug.assert(length >= 0, "length must be non-negative, is " + length);
                var code = diagnosticChain.code;
                var category = diagnosticChain.category;
                var messageText = "";
                var indent = 0;
                while (diagnosticChain) {
                    if (indent) {
                        messageText += newLine;
                        for (var i = 0; i < indent; i++) {
                            messageText += "  ";
                        }
                    }
                    messageText += diagnosticChain.messageText;
                    indent++;
                    diagnosticChain = diagnosticChain.next;
                }
                return {
                    file: file,
                    start: start,
                    length: length,
                    code: code,
                    category: category,
                    messageText: messageText
                };
            }
            ts.flattenDiagnosticChain = flattenDiagnosticChain;
            function compareValues(a, b) {
                if (a === b)
                    return 0 /* EqualTo */;
                if (a === undefined)
                    return -1 /* LessThan */;
                if (b === undefined)
                    return 1 /* GreaterThan */;
                return a < b ? -1 /* LessThan */ : 1 /* GreaterThan */;
            }
            ts.compareValues = compareValues;
            function getDiagnosticFilename(diagnostic) {
                return diagnostic.file ? diagnostic.file.filename : undefined;
            }
            function compareDiagnostics(d1, d2) {
                return compareValues(getDiagnosticFilename(d1), getDiagnosticFilename(d2)) || compareValues(d1.start, d2.start) || compareValues(d1.length, d2.length) || compareValues(d1.code, d2.code) || compareValues(d1.messageText, d2.messageText) || 0;
            }
            ts.compareDiagnostics = compareDiagnostics;
            function deduplicateSortedDiagnostics(diagnostics) {
                if (diagnostics.length < 2) {
                    return diagnostics;
                }
                var newDiagnostics = [diagnostics[0]];
                var previousDiagnostic = diagnostics[0];
                for (var i = 1; i < diagnostics.length; i++) {
                    var currentDiagnostic = diagnostics[i];
                    var isDupe = compareDiagnostics(currentDiagnostic, previousDiagnostic) === 0 /* EqualTo */;
                    if (!isDupe) {
                        newDiagnostics.push(currentDiagnostic);
                        previousDiagnostic = currentDiagnostic;
                    }
                }
                return newDiagnostics;
            }
            ts.deduplicateSortedDiagnostics = deduplicateSortedDiagnostics;
            function normalizeSlashes(path) {
                return path.replace(/\\/g, "/");
            }
            ts.normalizeSlashes = normalizeSlashes;
            function getRootLength(path) {
                if (path.charCodeAt(0) === 47 /* slash */) {
                    if (path.charCodeAt(1) !== 47 /* slash */)
                        return 1;
                    var p1 = path.indexOf("/", 2);
                    if (p1 < 0)
                        return 2;
                    var p2 = path.indexOf("/", p1 + 1);
                    if (p2 < 0)
                        return p1 + 1;
                    return p2 + 1;
                }
                if (path.charCodeAt(1) === 58 /* colon */) {
                    if (path.charCodeAt(2) === 47 /* slash */)
                        return 3;
                    return 2;
                }
                return 0;
            }
            ts.getRootLength = getRootLength;
            ts.directorySeparator = "/";
            function getNormalizedParts(normalizedSlashedPath, rootLength) {
                var parts = normalizedSlashedPath.substr(rootLength).split(ts.directorySeparator);
                var normalized = [];
                for (var i = 0; i < parts.length; i++) {
                    var part = parts[i];
                    if (part !== ".") {
                        if (part === ".." && normalized.length > 0 && normalized[normalized.length - 1] !== "..") {
                            normalized.pop();
                        }
                        else {
                            normalized.push(part);
                        }
                    }
                }
                return normalized;
            }
            function normalizePath(path) {
                var path = normalizeSlashes(path);
                var rootLength = getRootLength(path);
                var normalized = getNormalizedParts(path, rootLength);
                return path.substr(0, rootLength) + normalized.join(ts.directorySeparator);
            }
            ts.normalizePath = normalizePath;
            function getDirectoryPath(path) {
                return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(ts.directorySeparator)));
            }
            ts.getDirectoryPath = getDirectoryPath;
            function isUrl(path) {
                return path && !isRootedDiskPath(path) && path.indexOf("://") !== -1;
            }
            ts.isUrl = isUrl;
            function isRootedDiskPath(path) {
                return getRootLength(path) !== 0;
            }
            ts.isRootedDiskPath = isRootedDiskPath;
            function normalizedPathComponents(path, rootLength) {
                var normalizedParts = getNormalizedParts(path, rootLength);
                return [path.substr(0, rootLength)].concat(normalizedParts);
            }
            function getNormalizedPathComponents(path, currentDirectory) {
                var path = normalizeSlashes(path);
                var rootLength = getRootLength(path);
                if (rootLength == 0) {
                    path = combinePaths(normalizeSlashes(currentDirectory), path);
                    rootLength = getRootLength(path);
                }
                return normalizedPathComponents(path, rootLength);
            }
            ts.getNormalizedPathComponents = getNormalizedPathComponents;
            function getNormalizedAbsolutePath(filename, currentDirectory) {
                return getNormalizedPathFromPathComponents(getNormalizedPathComponents(filename, currentDirectory));
            }
            ts.getNormalizedAbsolutePath = getNormalizedAbsolutePath;
            function getNormalizedPathFromPathComponents(pathComponents) {
                if (pathComponents && pathComponents.length) {
                    return pathComponents[0] + pathComponents.slice(1).join(ts.directorySeparator);
                }
            }
            ts.getNormalizedPathFromPathComponents = getNormalizedPathFromPathComponents;
            function getNormalizedPathComponentsOfUrl(url) {
                var urlLength = url.length;
                var rootLength = url.indexOf("://") + "://".length;
                while (rootLength < urlLength) {
                    if (url.charCodeAt(rootLength) === 47 /* slash */) {
                        rootLength++;
                    }
                    else {
                        break;
                    }
                }
                if (rootLength === urlLength) {
                    return [url];
                }
                var indexOfNextSlash = url.indexOf(ts.directorySeparator, rootLength);
                if (indexOfNextSlash !== -1) {
                    rootLength = indexOfNextSlash + 1;
                    return normalizedPathComponents(url, rootLength);
                }
                else {
                    return [url + ts.directorySeparator];
                }
            }
            function getNormalizedPathOrUrlComponents(pathOrUrl, currentDirectory) {
                if (isUrl(pathOrUrl)) {
                    return getNormalizedPathComponentsOfUrl(pathOrUrl);
                }
                else {
                    return getNormalizedPathComponents(pathOrUrl, currentDirectory);
                }
            }
            function getRelativePathToDirectoryOrUrl(directoryPathOrUrl, relativeOrAbsolutePath, currentDirectory, getCanonicalFileName, isAbsolutePathAnUrl) {
                var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory);
                var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory);
                if (directoryComponents.length > 1 && directoryComponents[directoryComponents.length - 1] === "") {
                    directoryComponents.length--;
                }
                for (var joinStartIndex = 0; joinStartIndex < pathComponents.length && joinStartIndex < directoryComponents.length; joinStartIndex++) {
                    if (getCanonicalFileName(directoryComponents[joinStartIndex]) !== getCanonicalFileName(pathComponents[joinStartIndex])) {
                        break;
                    }
                }
                if (joinStartIndex) {
                    var relativePath = "";
                    var relativePathComponents = pathComponents.slice(joinStartIndex, pathComponents.length);
                    for (; joinStartIndex < directoryComponents.length; joinStartIndex++) {
                        if (directoryComponents[joinStartIndex] !== "") {
                            relativePath = relativePath + ".." + ts.directorySeparator;
                        }
                    }
                    return relativePath + relativePathComponents.join(ts.directorySeparator);
                }
                var absolutePath = getNormalizedPathFromPathComponents(pathComponents);
                if (isAbsolutePathAnUrl && isRootedDiskPath(absolutePath)) {
                    absolutePath = "file:///" + absolutePath;
                }
                return absolutePath;
            }
            ts.getRelativePathToDirectoryOrUrl = getRelativePathToDirectoryOrUrl;
            function getBaseFilename(path) {
                var i = path.lastIndexOf(ts.directorySeparator);
                return i < 0 ? path : path.substring(i + 1);
            }
            ts.getBaseFilename = getBaseFilename;
            function combinePaths(path1, path2) {
                if (!(path1 && path1.length))
                    return path2;
                if (!(path2 && path2.length))
                    return path1;
                if (path2.charAt(0) === ts.directorySeparator)
                    return path2;
                if (path1.charAt(path1.length - 1) === ts.directorySeparator)
                    return path1 + path2;
                return path1 + ts.directorySeparator + path2;
            }
            ts.combinePaths = combinePaths;
            function fileExtensionIs(path, extension) {
                var pathLen = path.length;
                var extLen = extension.length;
                return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension;
            }
            ts.fileExtensionIs = fileExtensionIs;
            var supportedExtensions = [".d.ts", ".ts", ".js"];
            function removeFileExtension(path) {
                for (var i = 0; i < supportedExtensions.length; i++) {
                    var ext = supportedExtensions[i];
                    if (fileExtensionIs(path, ext)) {
                        return path.substr(0, path.length - ext.length);
                    }
                }
                return path;
            }
            ts.removeFileExtension = removeFileExtension;
            var escapedCharsRegExp = /[\t\v\f\b\0\r\n\"\\\u2028\u2029\u0085]/g;
            var escapedCharsMap = {
                "\t": "\\t",
                "\v": "\\v",
                "\f": "\\f",
                "\b": "\\b",
                "\0": "\\0",
                "\r": "\\r",
                "\n": "\\n",
                "\"": "\\\"",
                "\u2028": "\\u2028",
                "\u2029": "\\u2029",
                "\u0085": "\\u0085"
            };
            function escapeString(s) {
                return escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, function (c) {
                    return escapedCharsMap[c] || c;
                }) : s;
            }
            ts.escapeString = escapeString;
            function Symbol(flags, name) {
                this.flags = flags;
                this.name = name;
                this.declarations = undefined;
            }
            function Type(checker, flags) {
                this.flags = flags;
            }
            function Signature(checker) {
            }
            ts.objectAllocator = {
                getNodeConstructor: function (kind) {
                    function Node() {
                    }
                    Node.prototype = {
                        kind: kind,
                        pos: 0,
                        end: 0,
                        flags: 0,
                        parent: undefined
                    };
                    return Node;
                },
                getSymbolConstructor: function () { return Symbol; },
                getTypeConstructor: function () { return Type; },
                getSignatureConstructor: function () { return Signature; }
            };
            (function (AssertionLevel) {
                AssertionLevel[AssertionLevel["None"] = 0] = "None";
                AssertionLevel[AssertionLevel["Normal"] = 1] = "Normal";
                AssertionLevel[AssertionLevel["Aggressive"] = 2] = "Aggressive";
                AssertionLevel[AssertionLevel["VeryAggressive"] = 3] = "VeryAggressive";
            })(ts.AssertionLevel || (ts.AssertionLevel = {}));
            var AssertionLevel = ts.AssertionLevel;
            var Debug;
            (function (Debug) {
                var currentAssertionLevel = 0 /* None */;
                function shouldAssert(level) {
                    return currentAssertionLevel >= level;
                }
                Debug.shouldAssert = shouldAssert;
                function assert(expression, message, verboseDebugInfo) {
                    if (!expression) {
                        var verboseDebugString = "";
                        if (verboseDebugInfo) {
                            verboseDebugString = "\r\nVerbose Debug Information: " + verboseDebugInfo();
                        }
                        throw new Error("Debug Failure. False expression: " + (message || "") + verboseDebugString);
                    }
                }
                Debug.assert = assert;
                function fail(message) {
                    Debug.assert(false, message);
                }
                Debug.fail = fail;
            })(Debug = ts.Debug || (ts.Debug = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            ts.Diagnostics = {
                Unterminated_string_literal: { code: 1002, category: 1 /* Error */, key: "Unterminated string literal." },
                Identifier_expected: { code: 1003, category: 1 /* Error */, key: "Identifier expected." },
                _0_expected: { code: 1005, category: 1 /* Error */, key: "'{0}' expected." },
                A_file_cannot_have_a_reference_to_itself: { code: 1006, category: 1 /* Error */, key: "A file cannot have a reference to itself." },
                Trailing_comma_not_allowed: { code: 1009, category: 1 /* Error */, key: "Trailing comma not allowed." },
                Asterisk_Slash_expected: { code: 1010, category: 1 /* Error */, key: "'*/' expected." },
                Unexpected_token: { code: 1012, category: 1 /* Error */, key: "Unexpected token." },
                Catch_clause_parameter_cannot_have_a_type_annotation: { code: 1013, category: 1 /* Error */, key: "Catch clause parameter cannot have a type annotation." },
                A_rest_parameter_must_be_last_in_a_parameter_list: { code: 1014, category: 1 /* Error */, key: "A rest parameter must be last in a parameter list." },
                Parameter_cannot_have_question_mark_and_initializer: { code: 1015, category: 1 /* Error */, key: "Parameter cannot have question mark and initializer." },
                A_required_parameter_cannot_follow_an_optional_parameter: { code: 1016, category: 1 /* Error */, key: "A required parameter cannot follow an optional parameter." },
                An_index_signature_cannot_have_a_rest_parameter: { code: 1017, category: 1 /* Error */, key: "An index signature cannot have a rest parameter." },
                An_index_signature_parameter_cannot_have_an_accessibility_modifier: { code: 1018, category: 1 /* Error */, key: "An index signature parameter cannot have an accessibility modifier." },
                An_index_signature_parameter_cannot_have_a_question_mark: { code: 1019, category: 1 /* Error */, key: "An index signature parameter cannot have a question mark." },
                An_index_signature_parameter_cannot_have_an_initializer: { code: 1020, category: 1 /* Error */, key: "An index signature parameter cannot have an initializer." },
                An_index_signature_must_have_a_type_annotation: { code: 1021, category: 1 /* Error */, key: "An index signature must have a type annotation." },
                An_index_signature_parameter_must_have_a_type_annotation: { code: 1022, category: 1 /* Error */, key: "An index signature parameter must have a type annotation." },
                An_index_signature_parameter_type_must_be_string_or_number: { code: 1023, category: 1 /* Error */, key: "An index signature parameter type must be 'string' or 'number'." },
                A_class_or_interface_declaration_can_only_have_one_extends_clause: { code: 1024, category: 1 /* Error */, key: "A class or interface declaration can only have one 'extends' clause." },
                An_extends_clause_must_precede_an_implements_clause: { code: 1025, category: 1 /* Error */, key: "An 'extends' clause must precede an 'implements' clause." },
                A_class_can_only_extend_a_single_class: { code: 1026, category: 1 /* Error */, key: "A class can only extend a single class." },
                A_class_declaration_can_only_have_one_implements_clause: { code: 1027, category: 1 /* Error */, key: "A class declaration can only have one 'implements' clause." },
                Accessibility_modifier_already_seen: { code: 1028, category: 1 /* Error */, key: "Accessibility modifier already seen." },
                _0_modifier_must_precede_1_modifier: { code: 1029, category: 1 /* Error */, key: "'{0}' modifier must precede '{1}' modifier." },
                _0_modifier_already_seen: { code: 1030, category: 1 /* Error */, key: "'{0}' modifier already seen." },
                _0_modifier_cannot_appear_on_a_class_element: { code: 1031, category: 1 /* Error */, key: "'{0}' modifier cannot appear on a class element." },
                An_interface_declaration_cannot_have_an_implements_clause: { code: 1032, category: 1 /* Error */, key: "An interface declaration cannot have an 'implements' clause." },
                super_must_be_followed_by_an_argument_list_or_member_access: { code: 1034, category: 1 /* Error */, key: "'super' must be followed by an argument list or member access." },
                Only_ambient_modules_can_use_quoted_names: { code: 1035, category: 1 /* Error */, key: "Only ambient modules can use quoted names." },
                Statements_are_not_allowed_in_ambient_contexts: { code: 1036, category: 1 /* Error */, key: "Statements are not allowed in ambient contexts." },
                A_function_implementation_cannot_be_declared_in_an_ambient_context: { code: 1037, category: 1 /* Error */, key: "A function implementation cannot be declared in an ambient context." },
                A_declare_modifier_cannot_be_used_in_an_already_ambient_context: { code: 1038, category: 1 /* Error */, key: "A 'declare' modifier cannot be used in an already ambient context." },
                Initializers_are_not_allowed_in_ambient_contexts: { code: 1039, category: 1 /* Error */, key: "Initializers are not allowed in ambient contexts." },
                _0_modifier_cannot_appear_on_a_module_element: { code: 1044, category: 1 /* Error */, key: "'{0}' modifier cannot appear on a module element." },
                A_declare_modifier_cannot_be_used_with_an_interface_declaration: { code: 1045, category: 1 /* Error */, key: "A 'declare' modifier cannot be used with an interface declaration." },
                A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file: { code: 1046, category: 1 /* Error */, key: "A 'declare' modifier is required for a top level declaration in a .d.ts file." },
                A_rest_parameter_cannot_be_optional: { code: 1047, category: 1 /* Error */, key: "A rest parameter cannot be optional." },
                A_rest_parameter_cannot_have_an_initializer: { code: 1048, category: 1 /* Error */, key: "A rest parameter cannot have an initializer." },
                A_set_accessor_must_have_exactly_one_parameter: { code: 1049, category: 1 /* Error */, key: "A 'set' accessor must have exactly one parameter." },
                A_set_accessor_cannot_have_an_optional_parameter: { code: 1051, category: 1 /* Error */, key: "A 'set' accessor cannot have an optional parameter." },
                A_set_accessor_parameter_cannot_have_an_initializer: { code: 1052, category: 1 /* Error */, key: "A 'set' accessor parameter cannot have an initializer." },
                A_set_accessor_cannot_have_rest_parameter: { code: 1053, category: 1 /* Error */, key: "A 'set' accessor cannot have rest parameter." },
                A_get_accessor_cannot_have_parameters: { code: 1054, category: 1 /* Error */, key: "A 'get' accessor cannot have parameters." },
                Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1056, category: 1 /* Error */, key: "Accessors are only available when targeting ECMAScript 5 and higher." },
                Enum_member_must_have_initializer: { code: 1061, category: 1 /* Error */, key: "Enum member must have initializer." },
                An_export_assignment_cannot_be_used_in_an_internal_module: { code: 1063, category: 1 /* Error */, key: "An export assignment cannot be used in an internal module." },
                Ambient_enum_elements_can_only_have_integer_literal_initializers: { code: 1066, category: 1 /* Error */, key: "Ambient enum elements can only have integer literal initializers." },
                Unexpected_token_A_constructor_method_accessor_or_property_was_expected: { code: 1068, category: 1 /* Error */, key: "Unexpected token. A constructor, method, accessor, or property was expected." },
                A_declare_modifier_cannot_be_used_with_an_import_declaration: { code: 1079, category: 1 /* Error */, key: "A 'declare' modifier cannot be used with an import declaration." },
                Invalid_reference_directive_syntax: { code: 1084, category: 1 /* Error */, key: "Invalid 'reference' directive syntax." },
                Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher: { code: 1085, category: 1 /* Error */, key: "Octal literals are not available when targeting ECMAScript 5 and higher." },
                An_accessor_cannot_be_declared_in_an_ambient_context: { code: 1086, category: 1 /* Error */, key: "An accessor cannot be declared in an ambient context." },
                _0_modifier_cannot_appear_on_a_constructor_declaration: { code: 1089, category: 1 /* Error */, key: "'{0}' modifier cannot appear on a constructor declaration." },
                _0_modifier_cannot_appear_on_a_parameter: { code: 1090, category: 1 /* Error */, key: "'{0}' modifier cannot appear on a parameter." },
                Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: { code: 1091, category: 1 /* Error */, key: "Only a single variable declaration is allowed in a 'for...in' statement." },
                Type_parameters_cannot_appear_on_a_constructor_declaration: { code: 1092, category: 1 /* Error */, key: "Type parameters cannot appear on a constructor declaration." },
                Type_annotation_cannot_appear_on_a_constructor_declaration: { code: 1093, category: 1 /* Error */, key: "Type annotation cannot appear on a constructor declaration." },
                An_accessor_cannot_have_type_parameters: { code: 1094, category: 1 /* Error */, key: "An accessor cannot have type parameters." },
                A_set_accessor_cannot_have_a_return_type_annotation: { code: 1095, category: 1 /* Error */, key: "A 'set' accessor cannot have a return type annotation." },
                An_index_signature_must_have_exactly_one_parameter: { code: 1096, category: 1 /* Error */, key: "An index signature must have exactly one parameter." },
                _0_list_cannot_be_empty: { code: 1097, category: 1 /* Error */, key: "'{0}' list cannot be empty." },
                Type_parameter_list_cannot_be_empty: { code: 1098, category: 1 /* Error */, key: "Type parameter list cannot be empty." },
                Type_argument_list_cannot_be_empty: { code: 1099, category: 1 /* Error */, key: "Type argument list cannot be empty." },
                Invalid_use_of_0_in_strict_mode: { code: 1100, category: 1 /* Error */, key: "Invalid use of '{0}' in strict mode." },
                with_statements_are_not_allowed_in_strict_mode: { code: 1101, category: 1 /* Error */, key: "'with' statements are not allowed in strict mode." },
                delete_cannot_be_called_on_an_identifier_in_strict_mode: { code: 1102, category: 1 /* Error */, key: "'delete' cannot be called on an identifier in strict mode." },
                A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: { code: 1104, category: 1 /* Error */, key: "A 'continue' statement can only be used within an enclosing iteration statement." },
                A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement: { code: 1105, category: 1 /* Error */, key: "A 'break' statement can only be used within an enclosing iteration or switch statement." },
                Jump_target_cannot_cross_function_boundary: { code: 1107, category: 1 /* Error */, key: "Jump target cannot cross function boundary." },
                A_return_statement_can_only_be_used_within_a_function_body: { code: 1108, category: 1 /* Error */, key: "A 'return' statement can only be used within a function body." },
                Expression_expected: { code: 1109, category: 1 /* Error */, key: "Expression expected." },
                Type_expected: { code: 1110, category: 1 /* Error */, key: "Type expected." },
                A_constructor_implementation_cannot_be_declared_in_an_ambient_context: { code: 1111, category: 1 /* Error */, key: "A constructor implementation cannot be declared in an ambient context." },
                A_class_member_cannot_be_declared_optional: { code: 1112, category: 1 /* Error */, key: "A class member cannot be declared optional." },
                A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: { code: 1113, category: 1 /* Error */, key: "A 'default' clause cannot appear more than once in a 'switch' statement." },
                Duplicate_label_0: { code: 1114, category: 1 /* Error */, key: "Duplicate label '{0}'" },
                A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement: { code: 1115, category: 1 /* Error */, key: "A 'continue' statement can only jump to a label of an enclosing iteration statement." },
                A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement: { code: 1116, category: 1 /* Error */, key: "A 'break' statement can only jump to a label of an enclosing statement." },
                An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode: { code: 1117, category: 1 /* Error */, key: "An object literal cannot have multiple properties with the same name in strict mode." },
                An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name: { code: 1118, category: 1 /* Error */, key: "An object literal cannot have multiple get/set accessors with the same name." },
                An_object_literal_cannot_have_property_and_accessor_with_the_same_name: { code: 1119, category: 1 /* Error */, key: "An object literal cannot have property and accessor with the same name." },
                An_export_assignment_cannot_have_modifiers: { code: 1120, category: 1 /* Error */, key: "An export assignment cannot have modifiers." },
                Octal_literals_are_not_allowed_in_strict_mode: { code: 1121, category: 1 /* Error */, key: "Octal literals are not allowed in strict mode." },
                A_tuple_type_element_list_cannot_be_empty: { code: 1122, category: 1 /* Error */, key: "A tuple type element list cannot be empty." },
                Variable_declaration_list_cannot_be_empty: { code: 1123, category: 1 /* Error */, key: "Variable declaration list cannot be empty." },
                Digit_expected: { code: 1124, category: 1 /* Error */, key: "Digit expected." },
                Hexadecimal_digit_expected: { code: 1125, category: 1 /* Error */, key: "Hexadecimal digit expected." },
                Unexpected_end_of_text: { code: 1126, category: 1 /* Error */, key: "Unexpected end of text." },
                Invalid_character: { code: 1127, category: 1 /* Error */, key: "Invalid character." },
                Declaration_or_statement_expected: { code: 1128, category: 1 /* Error */, key: "Declaration or statement expected." },
                Statement_expected: { code: 1129, category: 1 /* Error */, key: "Statement expected." },
                case_or_default_expected: { code: 1130, category: 1 /* Error */, key: "'case' or 'default' expected." },
                Property_or_signature_expected: { code: 1131, category: 1 /* Error */, key: "Property or signature expected." },
                Enum_member_expected: { code: 1132, category: 1 /* Error */, key: "Enum member expected." },
                Type_reference_expected: { code: 1133, category: 1 /* Error */, key: "Type reference expected." },
                Variable_declaration_expected: { code: 1134, category: 1 /* Error */, key: "Variable declaration expected." },
                Argument_expression_expected: { code: 1135, category: 1 /* Error */, key: "Argument expression expected." },
                Property_assignment_expected: { code: 1136, category: 1 /* Error */, key: "Property assignment expected." },
                Expression_or_comma_expected: { code: 1137, category: 1 /* Error */, key: "Expression or comma expected." },
                Parameter_declaration_expected: { code: 1138, category: 1 /* Error */, key: "Parameter declaration expected." },
                Type_parameter_declaration_expected: { code: 1139, category: 1 /* Error */, key: "Type parameter declaration expected." },
                Type_argument_expected: { code: 1140, category: 1 /* Error */, key: "Type argument expected." },
                String_literal_expected: { code: 1141, category: 1 /* Error */, key: "String literal expected." },
                Line_break_not_permitted_here: { code: 1142, category: 1 /* Error */, key: "Line break not permitted here." },
                catch_or_finally_expected: { code: 1143, category: 1 /* Error */, key: "'catch' or 'finally' expected." },
                Block_or_expected: { code: 1144, category: 1 /* Error */, key: "Block or ';' expected." },
                Modifiers_not_permitted_on_index_signature_members: { code: 1145, category: 1 /* Error */, key: "Modifiers not permitted on index signature members." },
                Declaration_expected: { code: 1146, category: 1 /* Error */, key: "Declaration expected." },
                Import_declarations_in_an_internal_module_cannot_reference_an_external_module: { code: 1147, category: 1 /* Error */, key: "Import declarations in an internal module cannot reference an external module." },
                Cannot_compile_external_modules_unless_the_module_flag_is_provided: { code: 1148, category: 1 /* Error */, key: "Cannot compile external modules unless the '--module' flag is provided." },
                Filename_0_differs_from_already_included_filename_1_only_in_casing: { code: 1149, category: 1 /* Error */, key: "Filename '{0}' differs from already included filename '{1}' only in casing" },
                new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: 1 /* Error */, key: "'new T[]' cannot be used to create an array. Use 'new Array<T>()' instead." },
                var_let_or_const_expected: { code: 1152, category: 1 /* Error */, key: "'var', 'let' or 'const' expected." },
                let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: 1 /* Error */, key: "'let' declarations are only available when targeting ECMAScript 6 and higher." },
                const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: 1 /* Error */, key: "'const' declarations are only available when targeting ECMAScript 6 and higher." },
                const_declarations_must_be_initialized: { code: 1155, category: 1 /* Error */, key: "'const' declarations must be initialized" },
                const_declarations_can_only_be_declared_inside_a_block: { code: 1156, category: 1 /* Error */, key: "'const' declarations can only be declared inside a block." },
                let_declarations_can_only_be_declared_inside_a_block: { code: 1157, category: 1 /* Error */, key: "'let' declarations can only be declared inside a block." },
                Invalid_template_literal_expected: { code: 1158, category: 1 /* Error */, key: "Invalid template literal; expected '}'" },
                Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1159, category: 1 /* Error */, key: "Tagged templates are only available when targeting ECMAScript 6 and higher." },
                Unterminated_template_literal: { code: 1160, category: 1 /* Error */, key: "Unterminated template literal." },
                Unterminated_regular_expression_literal: { code: 1161, category: 1 /* Error */, key: "Unterminated regular expression literal." },
                An_object_member_cannot_be_declared_optional: { code: 1162, category: 1 /* Error */, key: "An object member cannot be declared optional." },
                yield_expression_must_be_contained_within_a_generator_declaration: { code: 1163, category: 1 /* Error */, key: "'yield' expression must be contained_within a generator declaration." },
                Computed_property_names_are_not_allowed_in_enums: { code: 1164, category: 1 /* Error */, key: "Computed property names are not allowed in enums." },
                Computed_property_names_are_not_allowed_in_an_ambient_context: { code: 1165, category: 1 /* Error */, key: "Computed property names are not allowed in an ambient context." },
                Computed_property_names_are_not_allowed_in_class_property_declarations: { code: 1166, category: 1 /* Error */, key: "Computed property names are not allowed in class property declarations." },
                Computed_property_names_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1167, category: 1 /* Error */, key: "Computed property names are only available when targeting ECMAScript 6 and higher." },
                Computed_property_names_are_not_allowed_in_method_overloads: { code: 1168, category: 1 /* Error */, key: "Computed property names are not allowed in method overloads." },
                Computed_property_names_are_not_allowed_in_interfaces: { code: 1169, category: 1 /* Error */, key: "Computed property names are not allowed in interfaces." },
                Computed_property_names_are_not_allowed_in_type_literals: { code: 1170, category: 1 /* Error */, key: "Computed property names are not allowed in type literals." },
                A_comma_expression_is_not_allowed_in_a_computed_property_name: { code: 1171, category: 1 /* Error */, key: "A comma expression is not allowed in a computed property name." },
                Duplicate_identifier_0: { code: 2300, category: 1 /* Error */, key: "Duplicate identifier '{0}'." },
                Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: 1 /* Error */, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
                Static_members_cannot_reference_class_type_parameters: { code: 2302, category: 1 /* Error */, key: "Static members cannot reference class type parameters." },
                Circular_definition_of_import_alias_0: { code: 2303, category: 1 /* Error */, key: "Circular definition of import alias '{0}'." },
                Cannot_find_name_0: { code: 2304, category: 1 /* Error */, key: "Cannot find name '{0}'." },
                Module_0_has_no_exported_member_1: { code: 2305, category: 1 /* Error */, key: "Module '{0}' has no exported member '{1}'." },
                File_0_is_not_an_external_module: { code: 2306, category: 1 /* Error */, key: "File '{0}' is not an external module." },
                Cannot_find_external_module_0: { code: 2307, category: 1 /* Error */, key: "Cannot find external module '{0}'." },
                A_module_cannot_have_more_than_one_export_assignment: { code: 2308, category: 1 /* Error */, key: "A module cannot have more than one export assignment." },
                An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements: { code: 2309, category: 1 /* Error */, key: "An export assignment cannot be used in a module with other exported elements." },
                Type_0_recursively_references_itself_as_a_base_type: { code: 2310, category: 1 /* Error */, key: "Type '{0}' recursively references itself as a base type." },
                A_class_may_only_extend_another_class: { code: 2311, category: 1 /* Error */, key: "A class may only extend another class." },
                An_interface_may_only_extend_a_class_or_another_interface: { code: 2312, category: 1 /* Error */, key: "An interface may only extend a class or another interface." },
                Constraint_of_a_type_parameter_cannot_reference_any_type_parameter_from_the_same_type_parameter_list: { code: 2313, category: 1 /* Error */, key: "Constraint of a type parameter cannot reference any type parameter from the same type parameter list." },
                Generic_type_0_requires_1_type_argument_s: { code: 2314, category: 1 /* Error */, key: "Generic type '{0}' requires {1} type argument(s)." },
                Type_0_is_not_generic: { code: 2315, category: 1 /* Error */, key: "Type '{0}' is not generic." },
                Global_type_0_must_be_a_class_or_interface_type: { code: 2316, category: 1 /* Error */, key: "Global type '{0}' must be a class or interface type." },
                Global_type_0_must_have_1_type_parameter_s: { code: 2317, category: 1 /* Error */, key: "Global type '{0}' must have {1} type parameter(s)." },
                Cannot_find_global_type_0: { code: 2318, category: 1 /* Error */, key: "Cannot find global type '{0}'." },
                Named_properties_0_of_types_1_and_2_are_not_identical: { code: 2319, category: 1 /* Error */, key: "Named properties '{0}' of types '{1}' and '{2}' are not identical." },
                Interface_0_cannot_simultaneously_extend_types_1_and_2: { code: 2320, category: 1 /* Error */, key: "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'." },
                Excessive_stack_depth_comparing_types_0_and_1: { code: 2321, category: 1 /* Error */, key: "Excessive stack depth comparing types '{0}' and '{1}'." },
                Type_0_is_not_assignable_to_type_1: { code: 2322, category: 1 /* Error */, key: "Type '{0}' is not assignable to type '{1}'." },
                Property_0_is_missing_in_type_1: { code: 2324, category: 1 /* Error */, key: "Property '{0}' is missing in type '{1}'." },
                Property_0_is_private_in_type_1_but_not_in_type_2: { code: 2325, category: 1 /* Error */, key: "Property '{0}' is private in type '{1}' but not in type '{2}'." },
                Types_of_property_0_are_incompatible: { code: 2326, category: 1 /* Error */, key: "Types of property '{0}' are incompatible." },
                Property_0_is_optional_in_type_1_but_required_in_type_2: { code: 2327, category: 1 /* Error */, key: "Property '{0}' is optional in type '{1}' but required in type '{2}'." },
                Types_of_parameters_0_and_1_are_incompatible: { code: 2328, category: 1 /* Error */, key: "Types of parameters '{0}' and '{1}' are incompatible." },
                Index_signature_is_missing_in_type_0: { code: 2329, category: 1 /* Error */, key: "Index signature is missing in type '{0}'." },
                Index_signatures_are_incompatible: { code: 2330, category: 1 /* Error */, key: "Index signatures are incompatible." },
                this_cannot_be_referenced_in_a_module_body: { code: 2331, category: 1 /* Error */, key: "'this' cannot be referenced in a module body." },
                this_cannot_be_referenced_in_current_location: { code: 2332, category: 1 /* Error */, key: "'this' cannot be referenced in current location." },
                this_cannot_be_referenced_in_constructor_arguments: { code: 2333, category: 1 /* Error */, key: "'this' cannot be referenced in constructor arguments." },
                this_cannot_be_referenced_in_a_static_property_initializer: { code: 2334, category: 1 /* Error */, key: "'this' cannot be referenced in a static property initializer." },
                super_can_only_be_referenced_in_a_derived_class: { code: 2335, category: 1 /* Error */, key: "'super' can only be referenced in a derived class." },
                super_cannot_be_referenced_in_constructor_arguments: { code: 2336, category: 1 /* Error */, key: "'super' cannot be referenced in constructor arguments." },
                Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: { code: 2337, category: 1 /* Error */, key: "Super calls are not permitted outside constructors or in nested functions inside constructors" },
                super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: { code: 2338, category: 1 /* Error */, key: "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class" },
                Property_0_does_not_exist_on_type_1: { code: 2339, category: 1 /* Error */, key: "Property '{0}' does not exist on type '{1}'." },
                Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: { code: 2340, category: 1 /* Error */, key: "Only public and protected methods of the base class are accessible via the 'super' keyword" },
                Property_0_is_private_and_only_accessible_within_class_1: { code: 2341, category: 1 /* Error */, key: "Property '{0}' is private and only accessible within class '{1}'." },
                An_index_expression_argument_must_be_of_type_string_number_or_any: { code: 2342, category: 1 /* Error */, key: "An index expression argument must be of type 'string', 'number', or 'any'." },
                Type_0_does_not_satisfy_the_constraint_1: { code: 2344, category: 1 /* Error */, key: "Type '{0}' does not satisfy the constraint '{1}'." },
                Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: { code: 2345, category: 1 /* Error */, key: "Argument of type '{0}' is not assignable to parameter of type '{1}'." },
                Supplied_parameters_do_not_match_any_signature_of_call_target: { code: 2346, category: 1 /* Error */, key: "Supplied parameters do not match any signature of call target." },
                Untyped_function_calls_may_not_accept_type_arguments: { code: 2347, category: 1 /* Error */, key: "Untyped function calls may not accept type arguments." },
                Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: { code: 2348, category: 1 /* Error */, key: "Value of type '{0}' is not callable. Did you mean to include 'new'?" },
                Cannot_invoke_an_expression_whose_type_lacks_a_call_signature: { code: 2349, category: 1 /* Error */, key: "Cannot invoke an expression whose type lacks a call signature." },
                Only_a_void_function_can_be_called_with_the_new_keyword: { code: 2350, category: 1 /* Error */, key: "Only a void function can be called with the 'new' keyword." },
                Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature: { code: 2351, category: 1 /* Error */, key: "Cannot use 'new' with an expression whose type lacks a call or construct signature." },
                Neither_type_0_nor_type_1_is_assignable_to_the_other: { code: 2352, category: 1 /* Error */, key: "Neither type '{0}' nor type '{1}' is assignable to the other." },
                No_best_common_type_exists_among_return_expressions: { code: 2354, category: 1 /* Error */, key: "No best common type exists among return expressions." },
                A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_or_consist_of_a_single_throw_statement: { code: 2355, category: 1 /* Error */, key: "A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement." },
                An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type: { code: 2356, category: 1 /* Error */, key: "An arithmetic operand must be of type 'any', 'number' or an enum type." },
                The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer: { code: 2357, category: 1 /* Error */, key: "The operand of an increment or decrement operator must be a variable, property or indexer." },
                The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2358, category: 1 /* Error */, key: "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter." },
                The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: { code: 2359, category: 1 /* Error */, key: "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type." },
                The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number: { code: 2360, category: 1 /* Error */, key: "The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'." },
                The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2361, category: 1 /* Error */, key: "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter" },
                The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: { code: 2362, category: 1 /* Error */, key: "The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
                The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: { code: 2363, category: 1 /* Error */, key: "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
                Invalid_left_hand_side_of_assignment_expression: { code: 2364, category: 1 /* Error */, key: "Invalid left-hand side of assignment expression." },
                Operator_0_cannot_be_applied_to_types_1_and_2: { code: 2365, category: 1 /* Error */, key: "Operator '{0}' cannot be applied to types '{1}' and '{2}'." },
                Type_parameter_name_cannot_be_0: { code: 2368, category: 1 /* Error */, key: "Type parameter name cannot be '{0}'" },
                A_parameter_property_is_only_allowed_in_a_constructor_implementation: { code: 2369, category: 1 /* Error */, key: "A parameter property is only allowed in a constructor implementation." },
                A_rest_parameter_must_be_of_an_array_type: { code: 2370, category: 1 /* Error */, key: "A rest parameter must be of an array type." },
                A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation: { code: 2371, category: 1 /* Error */, key: "A parameter initializer is only allowed in a function or constructor implementation." },
                Parameter_0_cannot_be_referenced_in_its_initializer: { code: 2372, category: 1 /* Error */, key: "Parameter '{0}' cannot be referenced in its initializer." },
                Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it: { code: 2373, category: 1 /* Error */, key: "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it." },
                Duplicate_string_index_signature: { code: 2374, category: 1 /* Error */, key: "Duplicate string index signature." },
                Duplicate_number_index_signature: { code: 2375, category: 1 /* Error */, key: "Duplicate number index signature." },
                A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties: { code: 2376, category: 1 /* Error */, key: "A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties." },
                Constructors_for_derived_classes_must_contain_a_super_call: { code: 2377, category: 1 /* Error */, key: "Constructors for derived classes must contain a 'super' call." },
                A_get_accessor_must_return_a_value_or_consist_of_a_single_throw_statement: { code: 2378, category: 1 /* Error */, key: "A 'get' accessor must return a value or consist of a single 'throw' statement." },
                Getter_and_setter_accessors_do_not_agree_in_visibility: { code: 2379, category: 1 /* Error */, key: "Getter and setter accessors do not agree in visibility." },
                get_and_set_accessor_must_have_the_same_type: { code: 2380, category: 1 /* Error */, key: "'get' and 'set' accessor must have the same type." },
                A_signature_with_an_implementation_cannot_use_a_string_literal_type: { code: 2381, category: 1 /* Error */, key: "A signature with an implementation cannot use a string literal type." },
                Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: { code: 2382, category: 1 /* Error */, key: "Specialized overload signature is not assignable to any non-specialized signature." },
                Overload_signatures_must_all_be_exported_or_not_exported: { code: 2383, category: 1 /* Error */, key: "Overload signatures must all be exported or not exported." },
                Overload_signatures_must_all_be_ambient_or_non_ambient: { code: 2384, category: 1 /* Error */, key: "Overload signatures must all be ambient or non-ambient." },
                Overload_signatures_must_all_be_public_private_or_protected: { code: 2385, category: 1 /* Error */, key: "Overload signatures must all be public, private or protected." },
                Overload_signatures_must_all_be_optional_or_required: { code: 2386, category: 1 /* Error */, key: "Overload signatures must all be optional or required." },
                Function_overload_must_be_static: { code: 2387, category: 1 /* Error */, key: "Function overload must be static." },
                Function_overload_must_not_be_static: { code: 2388, category: 1 /* Error */, key: "Function overload must not be static." },
                Function_implementation_name_must_be_0: { code: 2389, category: 1 /* Error */, key: "Function implementation name must be '{0}'." },
                Constructor_implementation_is_missing: { code: 2390, category: 1 /* Error */, key: "Constructor implementation is missing." },
                Function_implementation_is_missing_or_not_immediately_following_the_declaration: { code: 2391, category: 1 /* Error */, key: "Function implementation is missing or not immediately following the declaration." },
                Multiple_constructor_implementations_are_not_allowed: { code: 2392, category: 1 /* Error */, key: "Multiple constructor implementations are not allowed." },
                Duplicate_function_implementation: { code: 2393, category: 1 /* Error */, key: "Duplicate function implementation." },
                Overload_signature_is_not_compatible_with_function_implementation: { code: 2394, category: 1 /* Error */, key: "Overload signature is not compatible with function implementation." },
                Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: { code: 2395, category: 1 /* Error */, key: "Individual declarations in merged declaration {0} must be all exported or all local." },
                Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: { code: 2396, category: 1 /* Error */, key: "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters." },
                Duplicate_identifier_i_Compiler_uses_i_to_initialize_rest_parameter: { code: 2397, category: 1 /* Error */, key: "Duplicate identifier '_i'. Compiler uses '_i' to initialize rest parameter." },
                Expression_resolves_to_variable_declaration_i_that_compiler_uses_to_initialize_rest_parameter: { code: 2398, category: 1 /* Error */, key: "Expression resolves to variable declaration '_i' that compiler uses to initialize rest parameter." },
                Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: { code: 2399, category: 1 /* Error */, key: "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference." },
                Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: { code: 2400, category: 1 /* Error */, key: "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference." },
                Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: { code: 2401, category: 1 /* Error */, key: "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference." },
                Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: { code: 2402, category: 1 /* Error */, key: "Expression resolves to '_super' that compiler uses to capture base class reference." },
                Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2: { code: 2403, category: 1 /* Error */, key: "Subsequent variable declarations must have the same type.  Variable '{0}' must be of type '{1}', but here has type '{2}'." },
                The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation: { code: 2404, category: 1 /* Error */, key: "The left-hand side of a 'for...in' statement cannot use a type annotation." },
                The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any: { code: 2405, category: 1 /* Error */, key: "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'." },
                Invalid_left_hand_side_in_for_in_statement: { code: 2406, category: 1 /* Error */, key: "Invalid left-hand side in 'for...in' statement." },
                The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2407, category: 1 /* Error */, key: "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter." },
                Setters_cannot_return_a_value: { code: 2408, category: 1 /* Error */, key: "Setters cannot return a value." },
                Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: { code: 2409, category: 1 /* Error */, key: "Return type of constructor signature must be assignable to the instance type of the class" },
                All_symbols_within_a_with_block_will_be_resolved_to_any: { code: 2410, category: 1 /* Error */, key: "All symbols within a 'with' block will be resolved to 'any'." },
                Property_0_of_type_1_is_not_assignable_to_string_index_type_2: { code: 2411, category: 1 /* Error */, key: "Property '{0}' of type '{1}' is not assignable to string index type '{2}'." },
                Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2: { code: 2412, category: 1 /* Error */, key: "Property '{0}' of type '{1}' is not assignable to numeric index type '{2}'." },
                Numeric_index_type_0_is_not_assignable_to_string_index_type_1: { code: 2413, category: 1 /* Error */, key: "Numeric index type '{0}' is not assignable to string index type '{1}'." },
                Class_name_cannot_be_0: { code: 2414, category: 1 /* Error */, key: "Class name cannot be '{0}'" },
                Class_0_incorrectly_extends_base_class_1: { code: 2415, category: 1 /* Error */, key: "Class '{0}' incorrectly extends base class '{1}'." },
                Class_static_side_0_incorrectly_extends_base_class_static_side_1: { code: 2417, category: 1 /* Error */, key: "Class static side '{0}' incorrectly extends base class static side '{1}'." },
                Type_name_0_in_extends_clause_does_not_reference_constructor_function_for_0: { code: 2419, category: 1 /* Error */, key: "Type name '{0}' in extends clause does not reference constructor function for '{0}'." },
                Class_0_incorrectly_implements_interface_1: { code: 2420, category: 1 /* Error */, key: "Class '{0}' incorrectly implements interface '{1}'." },
                A_class_may_only_implement_another_class_or_interface: { code: 2422, category: 1 /* Error */, key: "A class may only implement another class or interface." },
                Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor: { code: 2423, category: 1 /* Error */, key: "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor." },
                Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property: { code: 2424, category: 1 /* Error */, key: "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member property." },
                Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: { code: 2425, category: 1 /* Error */, key: "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function." },
                Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: { code: 2426, category: 1 /* Error */, key: "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function." },
                Interface_name_cannot_be_0: { code: 2427, category: 1 /* Error */, key: "Interface name cannot be '{0}'" },
                All_declarations_of_an_interface_must_have_identical_type_parameters: { code: 2428, category: 1 /* Error */, key: "All declarations of an interface must have identical type parameters." },
                Interface_0_incorrectly_extends_interface_1: { code: 2430, category: 1 /* Error */, key: "Interface '{0}' incorrectly extends interface '{1}'." },
                Enum_name_cannot_be_0: { code: 2431, category: 1 /* Error */, key: "Enum name cannot be '{0}'" },
                In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element: { code: 2432, category: 1 /* Error */, key: "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element." },
                A_module_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged: { code: 2433, category: 1 /* Error */, key: "A module declaration cannot be in a different file from a class or function with which it is merged" },
                A_module_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged: { code: 2434, category: 1 /* Error */, key: "A module declaration cannot be located prior to a class or function with which it is merged" },
                Ambient_external_modules_cannot_be_nested_in_other_modules: { code: 2435, category: 1 /* Error */, key: "Ambient external modules cannot be nested in other modules." },
                Ambient_external_module_declaration_cannot_specify_relative_module_name: { code: 2436, category: 1 /* Error */, key: "Ambient external module declaration cannot specify relative module name." },
                Module_0_is_hidden_by_a_local_declaration_with_the_same_name: { code: 2437, category: 1 /* Error */, key: "Module '{0}' is hidden by a local declaration with the same name" },
                Import_name_cannot_be_0: { code: 2438, category: 1 /* Error */, key: "Import name cannot be '{0}'" },
                Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name: { code: 2439, category: 1 /* Error */, key: "Import declaration in an ambient external module declaration cannot reference external module through relative external module name." },
                Import_declaration_conflicts_with_local_declaration_of_0: { code: 2440, category: 1 /* Error */, key: "Import declaration conflicts with local declaration of '{0}'" },
                Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_an_external_module: { code: 2441, category: 1 /* Error */, key: "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of an external module." },
                Types_have_separate_declarations_of_a_private_property_0: { code: 2442, category: 1 /* Error */, key: "Types have separate declarations of a private property '{0}'." },
                Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2: { code: 2443, category: 1 /* Error */, key: "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'." },
                Property_0_is_protected_in_type_1_but_public_in_type_2: { code: 2444, category: 1 /* Error */, key: "Property '{0}' is protected in type '{1}' but public in type '{2}'." },
                Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: { code: 2445, category: 1 /* Error */, key: "Property '{0}' is protected and only accessible within class '{1}' and its subclasses." },
                Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: { code: 2446, category: 1 /* Error */, key: "Property '{0}' is protected and only accessible through an instance of class '{1}'." },
                The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: { code: 2447, category: 1 /* Error */, key: "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead." },
                Block_scoped_variable_0_used_before_its_declaration: { code: 2448, category: 1 /* Error */, key: "Block-scoped variable '{0}' used before its declaration.", isEarly: true },
                The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant: { code: 2449, category: 1 /* Error */, key: "The operand of an increment or decrement operator cannot be a constant.", isEarly: true },
                Left_hand_side_of_assignment_expression_cannot_be_a_constant: { code: 2450, category: 1 /* Error */, key: "Left-hand side of assignment expression cannot be a constant.", isEarly: true },
                Cannot_redeclare_block_scoped_variable_0: { code: 2451, category: 1 /* Error */, key: "Cannot redeclare block-scoped variable '{0}'.", isEarly: true },
                An_enum_member_cannot_have_a_numeric_name: { code: 2452, category: 1 /* Error */, key: "An enum member cannot have a numeric name." },
                The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly: { code: 2453, category: 1 /* Error */, key: "The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly." },
                Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0: { code: 2455, category: 1 /* Error */, key: "Type argument candidate '{1}' is not a valid type argument because it is not a supertype of candidate '{0}'." },
                Type_alias_0_circularly_references_itself: { code: 2456, category: 1 /* Error */, key: "Type alias '{0}' circularly references itself." },
                Type_alias_name_cannot_be_0: { code: 2457, category: 1 /* Error */, key: "Type alias name cannot be '{0}'" },
                An_AMD_module_cannot_have_multiple_name_assignments: { code: 2458, category: 1 /* Error */, key: "An AMD module cannot have multiple name assignments." },
                Import_declaration_0_is_using_private_name_1: { code: 4000, category: 1 /* Error */, key: "Import declaration '{0}' is using private name '{1}'." },
                Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: 1 /* Error */, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
                Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: 1 /* Error */, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
                Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: { code: 4006, category: 1 /* Error */, key: "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'." },
                Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: { code: 4008, category: 1 /* Error */, key: "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'." },
                Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: { code: 4010, category: 1 /* Error */, key: "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'." },
                Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: { code: 4012, category: 1 /* Error */, key: "Type parameter '{0}' of public method from exported class has or is using private name '{1}'." },
                Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: { code: 4014, category: 1 /* Error */, key: "Type parameter '{0}' of method from exported interface has or is using private name '{1}'." },
                Type_parameter_0_of_exported_function_has_or_is_using_private_name_1: { code: 4016, category: 1 /* Error */, key: "Type parameter '{0}' of exported function has or is using private name '{1}'." },
                Implements_clause_of_exported_class_0_has_or_is_using_private_name_1: { code: 4019, category: 1 /* Error */, key: "Implements clause of exported class '{0}' has or is using private name '{1}'." },
                Extends_clause_of_exported_class_0_has_or_is_using_private_name_1: { code: 4020, category: 1 /* Error */, key: "Extends clause of exported class '{0}' has or is using private name '{1}'." },
                Extends_clause_of_exported_interface_0_has_or_is_using_private_name_1: { code: 4022, category: 1 /* Error */, key: "Extends clause of exported interface '{0}' has or is using private name '{1}'." },
                Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 4023, category: 1 /* Error */, key: "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named." },
                Exported_variable_0_has_or_is_using_name_1_from_private_module_2: { code: 4024, category: 1 /* Error */, key: "Exported variable '{0}' has or is using name '{1}' from private module '{2}'." },
                Exported_variable_0_has_or_is_using_private_name_1: { code: 4025, category: 1 /* Error */, key: "Exported variable '{0}' has or is using private name '{1}'." },
                Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 4026, category: 1 /* Error */, key: "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named." },
                Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4027, category: 1 /* Error */, key: "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'." },
                Public_static_property_0_of_exported_class_has_or_is_using_private_name_1: { code: 4028, category: 1 /* Error */, key: "Public static property '{0}' of exported class has or is using private name '{1}'." },
                Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 4029, category: 1 /* Error */, key: "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named." },
                Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4030, category: 1 /* Error */, key: "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'." },
                Public_property_0_of_exported_class_has_or_is_using_private_name_1: { code: 4031, category: 1 /* Error */, key: "Public property '{0}' of exported class has or is using private name '{1}'." },
                Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: { code: 4032, category: 1 /* Error */, key: "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'." },
                Property_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4033, category: 1 /* Error */, key: "Property '{0}' of exported interface has or is using private name '{1}'." },
                Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4034, category: 1 /* Error */, key: "Parameter '{0}' of public static property setter from exported class has or is using name '{1}' from private module '{2}'." },
                Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1: { code: 4035, category: 1 /* Error */, key: "Parameter '{0}' of public static property setter from exported class has or is using private name '{1}'." },
                Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4036, category: 1 /* Error */, key: "Parameter '{0}' of public property setter from exported class has or is using name '{1}' from private module '{2}'." },
                Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1: { code: 4037, category: 1 /* Error */, key: "Parameter '{0}' of public property setter from exported class has or is using private name '{1}'." },
                Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: { code: 4038, category: 1 /* Error */, key: "Return type of public static property getter from exported class has or is using name '{0}' from external module {1} but cannot be named." },
                Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1: { code: 4039, category: 1 /* Error */, key: "Return type of public static property getter from exported class has or is using name '{0}' from private module '{1}'." },
                Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0: { code: 4040, category: 1 /* Error */, key: "Return type of public static property getter from exported class has or is using private name '{0}'." },
                Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: { code: 4041, category: 1 /* Error */, key: "Return type of public property getter from exported class has or is using name '{0}' from external module {1} but cannot be named." },
                Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1: { code: 4042, category: 1 /* Error */, key: "Return type of public property getter from exported class has or is using name '{0}' from private module '{1}'." },
                Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0: { code: 4043, category: 1 /* Error */, key: "Return type of public property getter from exported class has or is using private name '{0}'." },
                Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: { code: 4044, category: 1 /* Error */, key: "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'." },
                Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0: { code: 4045, category: 1 /* Error */, key: "Return type of constructor signature from exported interface has or is using private name '{0}'." },
                Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: { code: 4046, category: 1 /* Error */, key: "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'." },
                Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0: { code: 4047, category: 1 /* Error */, key: "Return type of call signature from exported interface has or is using private name '{0}'." },
                Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: { code: 4048, category: 1 /* Error */, key: "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'." },
                Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0: { code: 4049, category: 1 /* Error */, key: "Return type of index signature from exported interface has or is using private name '{0}'." },
                Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: { code: 4050, category: 1 /* Error */, key: "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named." },
                Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: { code: 4051, category: 1 /* Error */, key: "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'." },
                Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0: { code: 4052, category: 1 /* Error */, key: "Return type of public static method from exported class has or is using private name '{0}'." },
                Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: { code: 4053, category: 1 /* Error */, key: "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named." },
                Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: { code: 4054, category: 1 /* Error */, key: "Return type of public method from exported class has or is using name '{0}' from private module '{1}'." },
                Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0: { code: 4055, category: 1 /* Error */, key: "Return type of public method from exported class has or is using private name '{0}'." },
                Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1: { code: 4056, category: 1 /* Error */, key: "Return type of method from exported interface has or is using name '{0}' from private module '{1}'." },
                Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0: { code: 4057, category: 1 /* Error */, key: "Return type of method from exported interface has or is using private name '{0}'." },
                Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: { code: 4058, category: 1 /* Error */, key: "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named." },
                Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1: { code: 4059, category: 1 /* Error */, key: "Return type of exported function has or is using name '{0}' from private module '{1}'." },
                Return_type_of_exported_function_has_or_is_using_private_name_0: { code: 4060, category: 1 /* Error */, key: "Return type of exported function has or is using private name '{0}'." },
                Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 4061, category: 1 /* Error */, key: "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named." },
                Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4062, category: 1 /* Error */, key: "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'." },
                Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1: { code: 4063, category: 1 /* Error */, key: "Parameter '{0}' of constructor from exported class has or is using private name '{1}'." },
                Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: { code: 4064, category: 1 /* Error */, key: "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'." },
                Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: { code: 4065, category: 1 /* Error */, key: "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'." },
                Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: { code: 4066, category: 1 /* Error */, key: "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'." },
                Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: { code: 4067, category: 1 /* Error */, key: "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'." },
                Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 4068, category: 1 /* Error */, key: "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named." },
                Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4069, category: 1 /* Error */, key: "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'." },
                Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: { code: 4070, category: 1 /* Error */, key: "Parameter '{0}' of public static method from exported class has or is using private name '{1}'." },
                Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 4071, category: 1 /* Error */, key: "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named." },
                Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4072, category: 1 /* Error */, key: "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'." },
                Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: { code: 4073, category: 1 /* Error */, key: "Parameter '{0}' of public method from exported class has or is using private name '{1}'." },
                Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2: { code: 4074, category: 1 /* Error */, key: "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'." },
                Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: { code: 4075, category: 1 /* Error */, key: "Parameter '{0}' of method from exported interface has or is using private name '{1}'." },
                Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: { code: 4076, category: 1 /* Error */, key: "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named." },
                Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2: { code: 4077, category: 1 /* Error */, key: "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'." },
                Parameter_0_of_exported_function_has_or_is_using_private_name_1: { code: 4078, category: 1 /* Error */, key: "Parameter '{0}' of exported function has or is using private name '{1}'." },
                Exported_type_alias_0_has_or_is_using_private_name_1: { code: 4081, category: 1 /* Error */, key: "Exported type alias '{0}' has or is using private name '{1}'." },
                Enum_declarations_must_all_be_const_or_non_const: { code: 4082, category: 1 /* Error */, key: "Enum declarations must all be const or non-const." },
                In_const_enum_declarations_member_initializer_must_be_constant_expression: { code: 4083, category: 1 /* Error */, key: "In 'const' enum declarations member initializer must be constant expression.", isEarly: true },
                const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: { code: 4084, category: 1 /* Error */, key: "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment." },
                Index_expression_arguments_in_const_enums_must_be_of_type_string: { code: 4085, category: 1 /* Error */, key: "Index expression arguments in 'const' enums must be of type 'string'." },
                const_enum_member_initializer_was_evaluated_to_a_non_finite_value: { code: 4086, category: 1 /* Error */, key: "'const' enum member initializer was evaluated to a non-finite value." },
                const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: { code: 4087, category: 1 /* Error */, key: "'const' enum member initializer was evaluated to disallowed value 'NaN'." },
                The_current_host_does_not_support_the_0_option: { code: 5001, category: 1 /* Error */, key: "The current host does not support the '{0}' option." },
                Cannot_find_the_common_subdirectory_path_for_the_input_files: { code: 5009, category: 1 /* Error */, key: "Cannot find the common subdirectory path for the input files." },
                Cannot_read_file_0_Colon_1: { code: 5012, category: 1 /* Error */, key: "Cannot read file '{0}': {1}" },
                Unsupported_file_encoding: { code: 5013, category: 1 /* Error */, key: "Unsupported file encoding." },
                Unknown_compiler_option_0: { code: 5023, category: 1 /* Error */, key: "Unknown compiler option '{0}'." },
                Could_not_write_file_0_Colon_1: { code: 5033, category: 1 /* Error */, key: "Could not write file '{0}': {1}" },
                Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option: { code: 5038, category: 1 /* Error */, key: "Option mapRoot cannot be specified without specifying sourcemap option." },
                Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option: { code: 5039, category: 1 /* Error */, key: "Option sourceRoot cannot be specified without specifying sourcemap option." },
                Concatenate_and_emit_output_to_single_file: { code: 6001, category: 2 /* Message */, key: "Concatenate and emit output to single file." },
                Generates_corresponding_d_ts_file: { code: 6002, category: 2 /* Message */, key: "Generates corresponding '.d.ts' file." },
                Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: 2 /* Message */, key: "Specifies the location where debugger should locate map files instead of generated locations." },
                Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: { code: 6004, category: 2 /* Message */, key: "Specifies the location where debugger should locate TypeScript files instead of source locations." },
                Watch_input_files: { code: 6005, category: 2 /* Message */, key: "Watch input files." },
                Redirect_output_structure_to_the_directory: { code: 6006, category: 2 /* Message */, key: "Redirect output structure to the directory." },
                Do_not_erase_const_enum_declarations_in_generated_code: { code: 6007, category: 2 /* Message */, key: "Do not erase const enum declarations in generated code." },
                Do_not_emit_outputs_if_any_type_checking_errors_were_reported: { code: 6008, category: 2 /* Message */, key: "Do not emit outputs if any type checking errors were reported." },
                Do_not_emit_comments_to_output: { code: 6009, category: 2 /* Message */, key: "Do not emit comments to output." },
                Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES6_experimental: { code: 6015, category: 2 /* Message */, key: "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' (experimental)" },
                Specify_module_code_generation_Colon_commonjs_or_amd: { code: 6016, category: 2 /* Message */, key: "Specify module code generation: 'commonjs' or 'amd'" },
                Print_this_message: { code: 6017, category: 2 /* Message */, key: "Print this message." },
                Print_the_compiler_s_version: { code: 6019, category: 2 /* Message */, key: "Print the compiler's version." },
                Syntax_Colon_0: { code: 6023, category: 2 /* Message */, key: "Syntax: {0}" },
                options: { code: 6024, category: 2 /* Message */, key: "options" },
                file: { code: 6025, category: 2 /* Message */, key: "file" },
                Examples_Colon_0: { code: 6026, category: 2 /* Message */, key: "Examples: {0}" },
                Options_Colon: { code: 6027, category: 2 /* Message */, key: "Options:" },
                Version_0: { code: 6029, category: 2 /* Message */, key: "Version {0}" },
                Insert_command_line_options_and_files_from_a_file: { code: 6030, category: 2 /* Message */, key: "Insert command line options and files from a file." },
                File_change_detected_Compiling: { code: 6032, category: 2 /* Message */, key: "File change detected. Compiling..." },
                KIND: { code: 6034, category: 2 /* Message */, key: "KIND" },
                FILE: { code: 6035, category: 2 /* Message */, key: "FILE" },
                VERSION: { code: 6036, category: 2 /* Message */, key: "VERSION" },
                LOCATION: { code: 6037, category: 2 /* Message */, key: "LOCATION" },
                DIRECTORY: { code: 6038, category: 2 /* Message */, key: "DIRECTORY" },
                Compilation_complete_Watching_for_file_changes: { code: 6042, category: 2 /* Message */, key: "Compilation complete. Watching for file changes." },
                Generates_corresponding_map_file: { code: 6043, category: 2 /* Message */, key: "Generates corresponding '.map' file." },
                Compiler_option_0_expects_an_argument: { code: 6044, category: 1 /* Error */, key: "Compiler option '{0}' expects an argument." },
                Unterminated_quoted_string_in_response_file_0: { code: 6045, category: 1 /* Error */, key: "Unterminated quoted string in response file '{0}'." },
                Argument_for_module_option_must_be_commonjs_or_amd: { code: 6046, category: 1 /* Error */, key: "Argument for '--module' option must be 'commonjs' or 'amd'." },
                Argument_for_target_option_must_be_es3_es5_or_es6: { code: 6047, category: 1 /* Error */, key: "Argument for '--target' option must be 'es3', 'es5', or 'es6'." },
                Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: { code: 6048, category: 1 /* Error */, key: "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'." },
                Unsupported_locale_0: { code: 6049, category: 1 /* Error */, key: "Unsupported locale '{0}'." },
                Unable_to_open_file_0: { code: 6050, category: 1 /* Error */, key: "Unable to open file '{0}'." },
                Corrupted_locale_file_0: { code: 6051, category: 1 /* Error */, key: "Corrupted locale file {0}." },
                Warn_on_expressions_and_declarations_with_an_implied_any_type: { code: 6052, category: 2 /* Message */, key: "Warn on expressions and declarations with an implied 'any' type." },
                File_0_not_found: { code: 6053, category: 1 /* Error */, key: "File '{0}' not found." },
                File_0_must_have_extension_ts_or_d_ts: { code: 6054, category: 1 /* Error */, key: "File '{0}' must have extension '.ts' or '.d.ts'." },
                Variable_0_implicitly_has_an_1_type: { code: 7005, category: 1 /* Error */, key: "Variable '{0}' implicitly has an '{1}' type." },
                Parameter_0_implicitly_has_an_1_type: { code: 7006, category: 1 /* Error */, key: "Parameter '{0}' implicitly has an '{1}' type." },
                Member_0_implicitly_has_an_1_type: { code: 7008, category: 1 /* Error */, key: "Member '{0}' implicitly has an '{1}' type." },
                new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type: { code: 7009, category: 1 /* Error */, key: "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type." },
                _0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type: { code: 7010, category: 1 /* Error */, key: "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type." },
                Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: { code: 7011, category: 1 /* Error */, key: "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type." },
                Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: { code: 7013, category: 1 /* Error */, key: "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type." },
                Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_type_annotation: { code: 7016, category: 1 /* Error */, key: "Property '{0}' implicitly has type 'any', because its 'set' accessor lacks a type annotation." },
                Index_signature_of_object_type_implicitly_has_an_any_type: { code: 7017, category: 1 /* Error */, key: "Index signature of object type implicitly has an 'any' type." },
                Object_literal_s_property_0_implicitly_has_an_1_type: { code: 7018, category: 1 /* Error */, key: "Object literal's property '{0}' implicitly has an '{1}' type." },
                Rest_parameter_0_implicitly_has_an_any_type: { code: 7019, category: 1 /* Error */, key: "Rest parameter '{0}' implicitly has an 'any[]' type." },
                Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: { code: 7020, category: 1 /* Error */, key: "Call signature, which lacks return-type annotation, implicitly has an 'any' return type." },
                _0_implicitly_has_type_any_because_it_is_referenced_directly_or_indirectly_in_its_own_type_annotation: { code: 7021, category: 1 /* Error */, key: "'{0}' implicitly has type 'any' because it is referenced directly or indirectly in its own type annotation." },
                _0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: 1 /* Error */, key: "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer." },
                _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: 1 /* Error */, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
                Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: 1 /* Error */, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
                You_cannot_rename_this_element: { code: 8000, category: 1 /* Error */, key: "You cannot rename this element." },
                yield_expressions_are_not_currently_supported: { code: 9000, category: 1 /* Error */, key: "'yield' expressions are not currently supported." },
                generators_are_not_currently_supported: { code: 9001, category: 1 /* Error */, key: "'generators' are not currently supported." }
            };
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var textToToken = {
                "any": 109 /* AnyKeyword */,
                "boolean": 110 /* BooleanKeyword */,
                "break": 64 /* BreakKeyword */,
                "case": 65 /* CaseKeyword */,
                "catch": 66 /* CatchKeyword */,
                "class": 67 /* ClassKeyword */,
                "continue": 69 /* ContinueKeyword */,
                "const": 68 /* ConstKeyword */,
                "constructor": 111 /* ConstructorKeyword */,
                "debugger": 70 /* DebuggerKeyword */,
                "declare": 112 /* DeclareKeyword */,
                "default": 71 /* DefaultKeyword */,
                "delete": 72 /* DeleteKeyword */,
                "do": 73 /* DoKeyword */,
                "else": 74 /* ElseKeyword */,
                "enum": 75 /* EnumKeyword */,
                "export": 76 /* ExportKeyword */,
                "extends": 77 /* ExtendsKeyword */,
                "false": 78 /* FalseKeyword */,
                "finally": 79 /* FinallyKeyword */,
                "for": 80 /* ForKeyword */,
                "function": 81 /* FunctionKeyword */,
                "get": 113 /* GetKeyword */,
                "if": 82 /* IfKeyword */,
                "implements": 100 /* ImplementsKeyword */,
                "import": 83 /* ImportKeyword */,
                "in": 84 /* InKeyword */,
                "instanceof": 85 /* InstanceOfKeyword */,
                "interface": 101 /* InterfaceKeyword */,
                "let": 102 /* LetKeyword */,
                "module": 114 /* ModuleKeyword */,
                "new": 86 /* NewKeyword */,
                "null": 87 /* NullKeyword */,
                "number": 116 /* NumberKeyword */,
                "package": 103 /* PackageKeyword */,
                "private": 104 /* PrivateKeyword */,
                "protected": 105 /* ProtectedKeyword */,
                "public": 106 /* PublicKeyword */,
                "require": 115 /* RequireKeyword */,
                "return": 88 /* ReturnKeyword */,
                "set": 117 /* SetKeyword */,
                "static": 107 /* StaticKeyword */,
                "string": 118 /* StringKeyword */,
                "super": 89 /* SuperKeyword */,
                "switch": 90 /* SwitchKeyword */,
                "this": 91 /* ThisKeyword */,
                "throw": 92 /* ThrowKeyword */,
                "true": 93 /* TrueKeyword */,
                "try": 94 /* TryKeyword */,
                "type": 119 /* TypeKeyword */,
                "typeof": 95 /* TypeOfKeyword */,
                "var": 96 /* VarKeyword */,
                "void": 97 /* VoidKeyword */,
                "while": 98 /* WhileKeyword */,
                "with": 99 /* WithKeyword */,
                "yield": 108 /* YieldKeyword */,
                "{": 13 /* OpenBraceToken */,
                "}": 14 /* CloseBraceToken */,
                "(": 15 /* OpenParenToken */,
                ")": 16 /* CloseParenToken */,
                "[": 17 /* OpenBracketToken */,
                "]": 18 /* CloseBracketToken */,
                ".": 19 /* DotToken */,
                "...": 20 /* DotDotDotToken */,
                ";": 21 /* SemicolonToken */,
                ",": 22 /* CommaToken */,
                "<": 23 /* LessThanToken */,
                ">": 24 /* GreaterThanToken */,
                "<=": 25 /* LessThanEqualsToken */,
                ">=": 26 /* GreaterThanEqualsToken */,
                "==": 27 /* EqualsEqualsToken */,
                "!=": 28 /* ExclamationEqualsToken */,
                "===": 29 /* EqualsEqualsEqualsToken */,
                "!==": 30 /* ExclamationEqualsEqualsToken */,
                "=>": 31 /* EqualsGreaterThanToken */,
                "+": 32 /* PlusToken */,
                "-": 33 /* MinusToken */,
                "*": 34 /* AsteriskToken */,
                "/": 35 /* SlashToken */,
                "%": 36 /* PercentToken */,
                "++": 37 /* PlusPlusToken */,
                "--": 38 /* MinusMinusToken */,
                "<<": 39 /* LessThanLessThanToken */,
                ">>": 40 /* GreaterThanGreaterThanToken */,
                ">>>": 41 /* GreaterThanGreaterThanGreaterThanToken */,
                "&": 42 /* AmpersandToken */,
                "|": 43 /* BarToken */,
                "^": 44 /* CaretToken */,
                "!": 45 /* ExclamationToken */,
                "~": 46 /* TildeToken */,
                "&&": 47 /* AmpersandAmpersandToken */,
                "||": 48 /* BarBarToken */,
                "?": 49 /* QuestionToken */,
                ":": 50 /* ColonToken */,
                "=": 51 /* EqualsToken */,
                "+=": 52 /* PlusEqualsToken */,
                "-=": 53 /* MinusEqualsToken */,
                "*=": 54 /* AsteriskEqualsToken */,
                "/=": 55 /* SlashEqualsToken */,
                "%=": 56 /* PercentEqualsToken */,
                "<<=": 57 /* LessThanLessThanEqualsToken */,
                ">>=": 58 /* GreaterThanGreaterThanEqualsToken */,
                ">>>=": 59 /* GreaterThanGreaterThanGreaterThanEqualsToken */,
                "&=": 60 /* AmpersandEqualsToken */,
                "|=": 61 /* BarEqualsToken */,
                "^=": 62 /* CaretEqualsToken */
            };
            var unicodeES3IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1610, 1649, 1747, 1749, 1749, 1765, 1766, 1786, 1788, 1808, 1808, 1810, 1836, 1920, 1957, 2309, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2784, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3424, 3425, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, 3913, 3946, 3976, 3979, 4096, 4129, 4131, 4135, 4137, 4138, 4176, 4181, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6067, 6176, 6263, 6272, 6312, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8319, 8319, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12346, 12353, 12436, 12445, 12446, 12449, 12538, 12540, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65138, 65140, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
            var unicodeES3IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 768, 846, 864, 866, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1155, 1158, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1441, 1443, 1465, 1467, 1469, 1471, 1471, 1473, 1474, 1476, 1476, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1621, 1632, 1641, 1648, 1747, 1749, 1756, 1759, 1768, 1770, 1773, 1776, 1788, 1808, 1836, 1840, 1866, 1920, 1968, 2305, 2307, 2309, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2492, 2494, 2500, 2503, 2504, 2507, 2509, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2562, 2562, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2649, 2652, 2654, 2654, 2662, 2676, 2689, 2691, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2784, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2876, 2883, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2913, 2918, 2927, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3031, 3031, 3047, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3134, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3168, 3169, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3262, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3297, 3302, 3311, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3390, 3395, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3425, 3430, 3439, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3946, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028, 4038, 4038, 4096, 4129, 4131, 4135, 4137, 4138, 4140, 4146, 4150, 4153, 4160, 4169, 4176, 4185, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 4969, 4977, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6099, 6112, 6121, 6160, 6169, 6176, 6263, 6272, 6313, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8319, 8319, 8400, 8412, 8417, 8417, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12346, 12353, 12436, 12441, 12442, 12445, 12446, 12449, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65056, 65059, 65075, 65076, 65101, 65103, 65136, 65138, 65140, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
            var unicodeES5IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2208, 2208, 2210, 2220, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, 7413, 7414, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
            var unicodeES5IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2048, 2093, 2112, 2139, 2208, 2208, 2210, 2220, 2276, 2302, 2304, 2403, 2406, 2415, 2417, 2423, 2425, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3396, 3398, 3400, 3402, 3406, 3415, 3415, 3424, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6263, 6272, 6314, 6320, 6389, 6400, 6428, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6617, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7376, 7378, 7380, 7414, 7424, 7654, 7676, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12442, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42647, 42655, 42737, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43047, 43072, 43123, 43136, 43204, 43216, 43225, 43232, 43255, 43259, 43259, 43264, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43643, 43648, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65062, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
            function lookupInUnicodeMap(code, map) {
                if (code < map[0]) {
                    return false;
                }
                var lo = 0;
                var hi = map.length;
                var mid;
                while (lo + 1 < hi) {
                    mid = lo + (hi - lo) / 2;
                    mid -= mid % 2;
                    if (map[mid] <= code && code <= map[mid + 1]) {
                        return true;
                    }
                    if (code < map[mid]) {
                        hi = mid;
                    }
                    else {
                        lo = mid + 2;
                    }
                }
                return false;
            }
            function isUnicodeIdentifierStart(code, languageVersion) {
                return languageVersion === 0 /* ES3 */ ? lookupInUnicodeMap(code, unicodeES3IdentifierStart) : lookupInUnicodeMap(code, unicodeES5IdentifierStart);
            }
            function isUnicodeIdentifierPart(code, languageVersion) {
                return languageVersion === 0 /* ES3 */ ? lookupInUnicodeMap(code, unicodeES3IdentifierPart) : lookupInUnicodeMap(code, unicodeES5IdentifierPart);
            }
            function makeReverseMap(source) {
                var result = [];
                for (var name in source) {
                    if (source.hasOwnProperty(name)) {
                        result[source[name]] = name;
                    }
                }
                return result;
            }
            var tokenStrings = makeReverseMap(textToToken);
            function tokenToString(t) {
                return tokenStrings[t];
            }
            ts.tokenToString = tokenToString;
            function computeLineStarts(text) {
                var result = new Array();
                var pos = 0;
                var lineStart = 0;
                while (pos < text.length) {
                    var ch = text.charCodeAt(pos++);
                    switch (ch) {
                        case 13 /* carriageReturn */:
                            if (text.charCodeAt(pos) === 10 /* lineFeed */) {
                                pos++;
                            }
                        case 10 /* lineFeed */:
                            result.push(lineStart);
                            lineStart = pos;
                            break;
                        default:
                            if (ch > 127 /* maxAsciiCharacter */ && isLineBreak(ch)) {
                                result.push(lineStart);
                                lineStart = pos;
                            }
                            break;
                    }
                }
                result.push(lineStart);
                return result;
            }
            ts.computeLineStarts = computeLineStarts;
            function getPositionFromLineAndCharacter(lineStarts, line, character) {
                ts.Debug.assert(line > 0);
                return lineStarts[line - 1] + character - 1;
            }
            ts.getPositionFromLineAndCharacter = getPositionFromLineAndCharacter;
            function getLineAndCharacterOfPosition(lineStarts, position) {
                var lineNumber = ts.binarySearch(lineStarts, position);
                if (lineNumber < 0) {
                    lineNumber = (~lineNumber) - 1;
                }
                return {
                    line: lineNumber + 1,
                    character: position - lineStarts[lineNumber] + 1
                };
            }
            ts.getLineAndCharacterOfPosition = getLineAndCharacterOfPosition;
            function positionToLineAndCharacter(text, pos) {
                var lineStarts = computeLineStarts(text);
                return getLineAndCharacterOfPosition(lineStarts, pos);
            }
            ts.positionToLineAndCharacter = positionToLineAndCharacter;
            var hasOwnProperty = Object.prototype.hasOwnProperty;
            function isWhiteSpace(ch) {
                return ch === 32 /* space */ || ch === 9 /* tab */ || ch === 11 /* verticalTab */ || ch === 12 /* formFeed */ || ch === 160 /* nonBreakingSpace */ || ch === 5760 /* ogham */ || ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ || ch === 8239 /* narrowNoBreakSpace */ || ch === 8287 /* mathematicalSpace */ || ch === 12288 /* ideographicSpace */ || ch === 65279 /* byteOrderMark */;
            }
            ts.isWhiteSpace = isWhiteSpace;
            function isLineBreak(ch) {
                return ch === 10 /* lineFeed */ || ch === 13 /* carriageReturn */ || ch === 8232 /* lineSeparator */ || ch === 8233 /* paragraphSeparator */ || ch === 133 /* nextLine */;
            }
            ts.isLineBreak = isLineBreak;
            function isDigit(ch) {
                return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
            }
            function isOctalDigit(ch) {
                return ch >= 48 /* _0 */ && ch <= 55 /* _7 */;
            }
            ts.isOctalDigit = isOctalDigit;
            function skipTrivia(text, pos, stopAfterLineBreak) {
                while (true) {
                    var ch = text.charCodeAt(pos);
                    switch (ch) {
                        case 13 /* carriageReturn */:
                            if (text.charCodeAt(pos + 1) === 10 /* lineFeed */)
                                pos++;
                        case 10 /* lineFeed */:
                            pos++;
                            if (stopAfterLineBreak)
                                return pos;
                            continue;
                        case 9 /* tab */:
                        case 11 /* verticalTab */:
                        case 12 /* formFeed */:
                        case 32 /* space */:
                            pos++;
                            continue;
                        case 47 /* slash */:
                            if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                                pos += 2;
                                while (pos < text.length) {
                                    if (isLineBreak(text.charCodeAt(pos))) {
                                        break;
                                    }
                                    pos++;
                                }
                                continue;
                            }
                            if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                                pos += 2;
                                while (pos < text.length) {
                                    if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                        pos += 2;
                                        break;
                                    }
                                    pos++;
                                }
                                continue;
                            }
                            break;
                        default:
                            if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpace(ch) || isLineBreak(ch))) {
                                pos++;
                                continue;
                            }
                            break;
                    }
                    return pos;
                }
            }
            ts.skipTrivia = skipTrivia;
            function getCommentRanges(text, pos, trailing) {
                var result;
                var collecting = trailing || pos === 0;
                while (true) {
                    var ch = text.charCodeAt(pos);
                    switch (ch) {
                        case 13 /* carriageReturn */:
                            if (text.charCodeAt(pos + 1) === 10 /* lineFeed */)
                                pos++;
                        case 10 /* lineFeed */:
                            pos++;
                            if (trailing) {
                                return result;
                            }
                            collecting = true;
                            if (result && result.length) {
                                result[result.length - 1].hasTrailingNewLine = true;
                            }
                            continue;
                        case 9 /* tab */:
                        case 11 /* verticalTab */:
                        case 12 /* formFeed */:
                        case 32 /* space */:
                            pos++;
                            continue;
                        case 47 /* slash */:
                            var nextChar = text.charCodeAt(pos + 1);
                            var hasTrailingNewLine = false;
                            if (nextChar === 47 /* slash */ || nextChar === 42 /* asterisk */) {
                                var startPos = pos;
                                pos += 2;
                                if (nextChar === 47 /* slash */) {
                                    while (pos < text.length) {
                                        if (isLineBreak(text.charCodeAt(pos))) {
                                            hasTrailingNewLine = true;
                                            break;
                                        }
                                        pos++;
                                    }
                                }
                                else {
                                    while (pos < text.length) {
                                        if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                            pos += 2;
                                            break;
                                        }
                                        pos++;
                                    }
                                }
                                if (collecting) {
                                    if (!result)
                                        result = [];
                                    result.push({ pos: startPos, end: pos, hasTrailingNewLine: hasTrailingNewLine });
                                }
                                continue;
                            }
                            break;
                        default:
                            if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpace(ch) || isLineBreak(ch))) {
                                if (result && result.length && isLineBreak(ch)) {
                                    result[result.length - 1].hasTrailingNewLine = true;
                                }
                                pos++;
                                continue;
                            }
                            break;
                    }
                    return result;
                }
            }
            function getLeadingCommentRanges(text, pos) {
                return getCommentRanges(text, pos, false);
            }
            ts.getLeadingCommentRanges = getLeadingCommentRanges;
            function getTrailingCommentRanges(text, pos) {
                return getCommentRanges(text, pos, true);
            }
            ts.getTrailingCommentRanges = getTrailingCommentRanges;
            function isIdentifierStart(ch, languageVersion) {
                return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ || ch === 36 /* $ */ || ch === 95 /* _ */ || ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierStart(ch, languageVersion);
            }
            ts.isIdentifierStart = isIdentifierStart;
            function isIdentifierPart(ch, languageVersion) {
                return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ || ch >= 48 /* _0 */ && ch <= 57 /* _9 */ || ch === 36 /* $ */ || ch === 95 /* _ */ || ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierPart(ch, languageVersion);
            }
            ts.isIdentifierPart = isIdentifierPart;
            function createScanner(languageVersion, skipTrivia, text, onError, onComment) {
                var pos;
                var len;
                var startPos;
                var tokenPos;
                var token;
                var tokenValue;
                var precedingLineBreak;
                function error(message) {
                    if (onError) {
                        onError(message);
                    }
                }
                function isIdentifierStart(ch) {
                    return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ || ch === 36 /* $ */ || ch === 95 /* _ */ || ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierStart(ch, languageVersion);
                }
                function isIdentifierPart(ch) {
                    return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ || ch >= 48 /* _0 */ && ch <= 57 /* _9 */ || ch === 36 /* $ */ || ch === 95 /* _ */ || ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierPart(ch, languageVersion);
                }
                function scanNumber() {
                    var start = pos;
                    while (isDigit(text.charCodeAt(pos)))
                        pos++;
                    if (text.charCodeAt(pos) === 46 /* dot */) {
                        pos++;
                        while (isDigit(text.charCodeAt(pos)))
                            pos++;
                    }
                    var end = pos;
                    if (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */) {
                        pos++;
                        if (text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */)
                            pos++;
                        if (isDigit(text.charCodeAt(pos))) {
                            pos++;
                            while (isDigit(text.charCodeAt(pos)))
                                pos++;
                            end = pos;
                        }
                        else {
                            error(ts.Diagnostics.Digit_expected);
                        }
                    }
                    return +(text.substring(start, end));
                }
                function scanOctalDigits() {
                    var start = pos;
                    while (isOctalDigit(text.charCodeAt(pos))) {
                        pos++;
                    }
                    return +(text.substring(start, pos));
                }
                function scanHexDigits(count, mustMatchCount) {
                    var digits = 0;
                    var value = 0;
                    while (digits < count || !mustMatchCount) {
                        var ch = text.charCodeAt(pos);
                        if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) {
                            value = value * 16 + ch - 48 /* _0 */;
                        }
                        else if (ch >= 65 /* A */ && ch <= 70 /* F */) {
                            value = value * 16 + ch - 65 /* A */ + 10;
                        }
                        else if (ch >= 97 /* a */ && ch <= 102 /* f */) {
                            value = value * 16 + ch - 97 /* a */ + 10;
                        }
                        else {
                            break;
                        }
                        pos++;
                        digits++;
                    }
                    if (digits < count) {
                        value = -1;
                    }
                    return value;
                }
                function scanString() {
                    var quote = text.charCodeAt(pos++);
                    var result = "";
                    var start = pos;
                    while (true) {
                        if (pos >= len) {
                            result += text.substring(start, pos);
                            error(ts.Diagnostics.Unterminated_string_literal);
                            break;
                        }
                        var ch = text.charCodeAt(pos);
                        if (ch === quote) {
                            result += text.substring(start, pos);
                            pos++;
                            break;
                        }
                        if (ch === 92 /* backslash */) {
                            result += text.substring(start, pos);
                            result += scanEscapeSequence();
                            start = pos;
                            continue;
                        }
                        if (isLineBreak(ch)) {
                            result += text.substring(start, pos);
                            error(ts.Diagnostics.Unterminated_string_literal);
                            break;
                        }
                        pos++;
                    }
                    return result;
                }
                function scanTemplateAndSetTokenValue() {
                    var startedWithBacktick = text.charCodeAt(pos) === 96 /* backtick */;
                    pos++;
                    var start = pos;
                    var contents = "";
                    var resultingToken;
                    while (true) {
                        if (pos >= len) {
                            contents += text.substring(start, pos);
                            error(ts.Diagnostics.Unterminated_template_literal);
                            resultingToken = startedWithBacktick ? 9 /* NoSubstitutionTemplateLiteral */ : 12 /* TemplateTail */;
                            break;
                        }
                        var currChar = text.charCodeAt(pos);
                        if (currChar === 96 /* backtick */) {
                            contents += text.substring(start, pos);
                            pos++;
                            resultingToken = startedWithBacktick ? 9 /* NoSubstitutionTemplateLiteral */ : 12 /* TemplateTail */;
                            break;
                        }
                        if (currChar === 36 /* $ */ && pos + 1 < len && text.charCodeAt(pos + 1) === 123 /* openBrace */) {
                            contents += text.substring(start, pos);
                            pos += 2;
                            resultingToken = startedWithBacktick ? 10 /* TemplateHead */ : 11 /* TemplateMiddle */;
                            break;
                        }
                        if (currChar === 92 /* backslash */) {
                            contents += text.substring(start, pos);
                            contents += scanEscapeSequence();
                            start = pos;
                            continue;
                        }
                        if (currChar === 13 /* carriageReturn */) {
                            contents += text.substring(start, pos);
                            if (pos + 1 < len && text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                                pos++;
                            }
                            pos++;
                            contents += "\n";
                            start = pos;
                            continue;
                        }
                        pos++;
                    }
                    ts.Debug.assert(resultingToken !== undefined);
                    tokenValue = contents;
                    return resultingToken;
                }
                function scanEscapeSequence() {
                    pos++;
                    if (pos >= len) {
                        error(ts.Diagnostics.Unexpected_end_of_text);
                        return "";
                    }
                    var ch = text.charCodeAt(pos++);
                    switch (ch) {
                        case 48 /* _0 */:
                            return "\0";
                        case 98 /* b */:
                            return "\b";
                        case 116 /* t */:
                            return "\t";
                        case 110 /* n */:
                            return "\n";
                        case 118 /* v */:
                            return "\v";
                        case 102 /* f */:
                            return "\f";
                        case 114 /* r */:
                            return "\r";
                        case 39 /* singleQuote */:
                            return "\'";
                        case 34 /* doubleQuote */:
                            return "\"";
                        case 120 /* x */:
                        case 117 /* u */:
                            var ch = scanHexDigits(ch === 120 /* x */ ? 2 : 4, true);
                            if (ch >= 0) {
                                return String.fromCharCode(ch);
                            }
                            else {
                                error(ts.Diagnostics.Hexadecimal_digit_expected);
                                return "";
                            }
                        case 13 /* carriageReturn */:
                            if (pos < len && text.charCodeAt(pos) === 10 /* lineFeed */) {
                                pos++;
                            }
                        case 10 /* lineFeed */:
                        case 8232 /* lineSeparator */:
                        case 8233 /* paragraphSeparator */:
                            return "";
                        default:
                            return String.fromCharCode(ch);
                    }
                }
                function peekUnicodeEscape() {
                    if (pos + 5 < len && text.charCodeAt(pos + 1) === 117 /* u */) {
                        var start = pos;
                        pos += 2;
                        var value = scanHexDigits(4, true);
                        pos = start;
                        return value;
                    }
                    return -1;
                }
                function scanIdentifierParts() {
                    var result = "";
                    var start = pos;
                    while (pos < len) {
                        var ch = text.charCodeAt(pos);
                        if (isIdentifierPart(ch)) {
                            pos++;
                        }
                        else if (ch === 92 /* backslash */) {
                            ch = peekUnicodeEscape();
                            if (!(ch >= 0 && isIdentifierPart(ch))) {
                                break;
                            }
                            result += text.substring(start, pos);
                            result += String.fromCharCode(ch);
                            pos += 6;
                            start = pos;
                        }
                        else {
                            break;
                        }
                    }
                    result += text.substring(start, pos);
                    return result;
                }
                function getIdentifierToken() {
                    var len = tokenValue.length;
                    if (len >= 2 && len <= 11) {
                        var ch = tokenValue.charCodeAt(0);
                        if (ch >= 97 /* a */ && ch <= 122 /* z */ && hasOwnProperty.call(textToToken, tokenValue)) {
                            return token = textToToken[tokenValue];
                        }
                    }
                    return token = 63 /* Identifier */;
                }
                function scan() {
                    startPos = pos;
                    precedingLineBreak = false;
                    while (true) {
                        tokenPos = pos;
                        if (pos >= len) {
                            return token = 1 /* EndOfFileToken */;
                        }
                        var ch = text.charCodeAt(pos);
                        switch (ch) {
                            case 10 /* lineFeed */:
                            case 13 /* carriageReturn */:
                                precedingLineBreak = true;
                                if (skipTrivia) {
                                    pos++;
                                    continue;
                                }
                                else {
                                    if (ch === 13 /* carriageReturn */ && pos + 1 < len && text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                                        pos += 2;
                                    }
                                    else {
                                        pos++;
                                    }
                                    return token = 4 /* NewLineTrivia */;
                                }
                            case 9 /* tab */:
                            case 11 /* verticalTab */:
                            case 12 /* formFeed */:
                            case 32 /* space */:
                                if (skipTrivia) {
                                    pos++;
                                    continue;
                                }
                                else {
                                    while (pos < len && isWhiteSpace(text.charCodeAt(pos))) {
                                        pos++;
                                    }
                                    return token = 5 /* WhitespaceTrivia */;
                                }
                            case 33 /* exclamation */:
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                        return pos += 3, token = 30 /* ExclamationEqualsEqualsToken */;
                                    }
                                    return pos += 2, token = 28 /* ExclamationEqualsToken */;
                                }
                                return pos++, token = 45 /* ExclamationToken */;
                            case 34 /* doubleQuote */:
                            case 39 /* singleQuote */:
                                tokenValue = scanString();
                                return token = 7 /* StringLiteral */;
                            case 96 /* backtick */:
                                return token = scanTemplateAndSetTokenValue();
                            case 37 /* percent */:
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    return pos += 2, token = 56 /* PercentEqualsToken */;
                                }
                                return pos++, token = 36 /* PercentToken */;
                            case 38 /* ampersand */:
                                if (text.charCodeAt(pos + 1) === 38 /* ampersand */) {
                                    return pos += 2, token = 47 /* AmpersandAmpersandToken */;
                                }
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    return pos += 2, token = 60 /* AmpersandEqualsToken */;
                                }
                                return pos++, token = 42 /* AmpersandToken */;
                            case 40 /* openParen */:
                                return pos++, token = 15 /* OpenParenToken */;
                            case 41 /* closeParen */:
                                return pos++, token = 16 /* CloseParenToken */;
                            case 42 /* asterisk */:
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    return pos += 2, token = 54 /* AsteriskEqualsToken */;
                                }
                                return pos++, token = 34 /* AsteriskToken */;
                            case 43 /* plus */:
                                if (text.charCodeAt(pos + 1) === 43 /* plus */) {
                                    return pos += 2, token = 37 /* PlusPlusToken */;
                                }
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    return pos += 2, token = 52 /* PlusEqualsToken */;
                                }
                                return pos++, token = 32 /* PlusToken */;
                            case 44 /* comma */:
                                return pos++, token = 22 /* CommaToken */;
                            case 45 /* minus */:
                                if (text.charCodeAt(pos + 1) === 45 /* minus */) {
                                    return pos += 2, token = 38 /* MinusMinusToken */;
                                }
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    return pos += 2, token = 53 /* MinusEqualsToken */;
                                }
                                return pos++, token = 33 /* MinusToken */;
                            case 46 /* dot */:
                                if (isDigit(text.charCodeAt(pos + 1))) {
                                    tokenValue = "" + scanNumber();
                                    return token = 6 /* NumericLiteral */;
                                }
                                if (text.charCodeAt(pos + 1) === 46 /* dot */ && text.charCodeAt(pos + 2) === 46 /* dot */) {
                                    return pos += 3, token = 20 /* DotDotDotToken */;
                                }
                                return pos++, token = 19 /* DotToken */;
                            case 47 /* slash */:
                                if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                                    pos += 2;
                                    while (pos < len) {
                                        if (isLineBreak(text.charCodeAt(pos))) {
                                            break;
                                        }
                                        pos++;
                                    }
                                    if (onComment) {
                                        onComment(tokenPos, pos);
                                    }
                                    if (skipTrivia) {
                                        continue;
                                    }
                                    else {
                                        return token = 2 /* SingleLineCommentTrivia */;
                                    }
                                }
                                if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                                    pos += 2;
                                    var commentClosed = false;
                                    while (pos < len) {
                                        var ch = text.charCodeAt(pos);
                                        if (ch === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                            pos += 2;
                                            commentClosed = true;
                                            break;
                                        }
                                        if (isLineBreak(ch)) {
                                            precedingLineBreak = true;
                                        }
                                        pos++;
                                    }
                                    if (!commentClosed) {
                                        error(ts.Diagnostics.Asterisk_Slash_expected);
                                    }
                                    if (onComment) {
                                        onComment(tokenPos, pos);
                                    }
                                    if (skipTrivia) {
                                        continue;
                                    }
                                    else {
                                        return token = 3 /* MultiLineCommentTrivia */;
                                    }
                                }
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    return pos += 2, token = 55 /* SlashEqualsToken */;
                                }
                                return pos++, token = 35 /* SlashToken */;
                            case 48 /* _0 */:
                                if (pos + 2 < len && (text.charCodeAt(pos + 1) === 88 /* X */ || text.charCodeAt(pos + 1) === 120 /* x */)) {
                                    pos += 2;
                                    var value = scanHexDigits(1, false);
                                    if (value < 0) {
                                        error(ts.Diagnostics.Hexadecimal_digit_expected);
                                        value = 0;
                                    }
                                    tokenValue = "" + value;
                                    return token = 6 /* NumericLiteral */;
                                }
                                if (pos + 1 < len && isOctalDigit(text.charCodeAt(pos + 1))) {
                                    tokenValue = "" + scanOctalDigits();
                                    return token = 6 /* NumericLiteral */;
                                }
                            case 49 /* _1 */:
                            case 50 /* _2 */:
                            case 51 /* _3 */:
                            case 52 /* _4 */:
                            case 53 /* _5 */:
                            case 54 /* _6 */:
                            case 55 /* _7 */:
                            case 56 /* _8 */:
                            case 57 /* _9 */:
                                tokenValue = "" + scanNumber();
                                return token = 6 /* NumericLiteral */;
                            case 58 /* colon */:
                                return pos++, token = 50 /* ColonToken */;
                            case 59 /* semicolon */:
                                return pos++, token = 21 /* SemicolonToken */;
                            case 60 /* lessThan */:
                                if (text.charCodeAt(pos + 1) === 60 /* lessThan */) {
                                    if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                        return pos += 3, token = 57 /* LessThanLessThanEqualsToken */;
                                    }
                                    return pos += 2, token = 39 /* LessThanLessThanToken */;
                                }
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    return pos += 2, token = 25 /* LessThanEqualsToken */;
                                }
                                return pos++, token = 23 /* LessThanToken */;
                            case 61 /* equals */:
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                        return pos += 3, token = 29 /* EqualsEqualsEqualsToken */;
                                    }
                                    return pos += 2, token = 27 /* EqualsEqualsToken */;
                                }
                                if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                                    return pos += 2, token = 31 /* EqualsGreaterThanToken */;
                                }
                                return pos++, token = 51 /* EqualsToken */;
                            case 62 /* greaterThan */:
                                return pos++, token = 24 /* GreaterThanToken */;
                            case 63 /* question */:
                                return pos++, token = 49 /* QuestionToken */;
                            case 91 /* openBracket */:
                                return pos++, token = 17 /* OpenBracketToken */;
                            case 93 /* closeBracket */:
                                return pos++, token = 18 /* CloseBracketToken */;
                            case 94 /* caret */:
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    return pos += 2, token = 62 /* CaretEqualsToken */;
                                }
                                return pos++, token = 44 /* CaretToken */;
                            case 123 /* openBrace */:
                                return pos++, token = 13 /* OpenBraceToken */;
                            case 124 /* bar */:
                                if (text.charCodeAt(pos + 1) === 124 /* bar */) {
                                    return pos += 2, token = 48 /* BarBarToken */;
                                }
                                if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                    return pos += 2, token = 61 /* BarEqualsToken */;
                                }
                                return pos++, token = 43 /* BarToken */;
                            case 125 /* closeBrace */:
                                return pos++, token = 14 /* CloseBraceToken */;
                            case 126 /* tilde */:
                                return pos++, token = 46 /* TildeToken */;
                            case 92 /* backslash */:
                                var ch = peekUnicodeEscape();
                                if (ch >= 0 && isIdentifierStart(ch)) {
                                    pos += 6;
                                    tokenValue = String.fromCharCode(ch) + scanIdentifierParts();
                                    return token = getIdentifierToken();
                                }
                                error(ts.Diagnostics.Invalid_character);
                                return pos++, token = 0 /* Unknown */;
                            default:
                                if (isIdentifierStart(ch)) {
                                    pos++;
                                    while (pos < len && isIdentifierPart(ch = text.charCodeAt(pos)))
                                        pos++;
                                    tokenValue = text.substring(tokenPos, pos);
                                    if (ch === 92 /* backslash */) {
                                        tokenValue += scanIdentifierParts();
                                    }
                                    return token = getIdentifierToken();
                                }
                                else if (isWhiteSpace(ch)) {
                                    pos++;
                                    continue;
                                }
                                else if (isLineBreak(ch)) {
                                    precedingLineBreak = true;
                                    pos++;
                                    continue;
                                }
                                error(ts.Diagnostics.Invalid_character);
                                return pos++, token = 0 /* Unknown */;
                        }
                    }
                }
                function reScanGreaterToken() {
                    if (token === 24 /* GreaterThanToken */) {
                        if (text.charCodeAt(pos) === 62 /* greaterThan */) {
                            if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                                if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                    return pos += 3, token = 59 /* GreaterThanGreaterThanGreaterThanEqualsToken */;
                                }
                                return pos += 2, token = 41 /* GreaterThanGreaterThanGreaterThanToken */;
                            }
                            if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                                return pos += 2, token = 58 /* GreaterThanGreaterThanEqualsToken */;
                            }
                            return pos++, token = 40 /* GreaterThanGreaterThanToken */;
                        }
                        if (text.charCodeAt(pos) === 61 /* equals */) {
                            return pos++, token = 26 /* GreaterThanEqualsToken */;
                        }
                    }
                    return token;
                }
                function reScanSlashToken() {
                    if (token === 35 /* SlashToken */ || token === 55 /* SlashEqualsToken */) {
                        var p = tokenPos + 1;
                        var inEscape = false;
                        var inCharacterClass = false;
                        while (true) {
                            if (p >= len) {
                                error(ts.Diagnostics.Unterminated_regular_expression_literal);
                                break;
                            }
                            var ch = text.charCodeAt(p);
                            if (isLineBreak(ch)) {
                                error(ts.Diagnostics.Unterminated_regular_expression_literal);
                                break;
                            }
                            if (inEscape) {
                                inEscape = false;
                            }
                            else if (ch === 47 /* slash */ && !inCharacterClass) {
                                p++;
                                break;
                            }
                            else if (ch === 91 /* openBracket */) {
                                inCharacterClass = true;
                            }
                            else if (ch === 92 /* backslash */) {
                                inEscape = true;
                            }
                            else if (ch === 93 /* closeBracket */) {
                                inCharacterClass = false;
                            }
                            p++;
                        }
                        while (p < len && isIdentifierPart(text.charCodeAt(p))) {
                            p++;
                        }
                        pos = p;
                        tokenValue = text.substring(tokenPos, pos);
                        token = 8 /* RegularExpressionLiteral */;
                    }
                    return token;
                }
                function reScanTemplateToken() {
                    ts.Debug.assert(token === 14 /* CloseBraceToken */, "'reScanTemplateToken' should only be called on a '}'");
                    pos = tokenPos;
                    return token = scanTemplateAndSetTokenValue();
                }
                function tryScan(callback) {
                    var savePos = pos;
                    var saveStartPos = startPos;
                    var saveTokenPos = tokenPos;
                    var saveToken = token;
                    var saveTokenValue = tokenValue;
                    var savePrecedingLineBreak = precedingLineBreak;
                    var result = callback();
                    if (!result) {
                        pos = savePos;
                        startPos = saveStartPos;
                        tokenPos = saveTokenPos;
                        token = saveToken;
                        tokenValue = saveTokenValue;
                        precedingLineBreak = savePrecedingLineBreak;
                    }
                    return result;
                }
                function setText(newText) {
                    text = newText || "";
                    len = text.length;
                    setTextPos(0);
                }
                function setTextPos(textPos) {
                    pos = textPos;
                    startPos = textPos;
                    tokenPos = textPos;
                    token = 0 /* Unknown */;
                    precedingLineBreak = false;
                }
                setText(text);
                return {
                    getStartPos: function () { return startPos; },
                    getTextPos: function () { return pos; },
                    getToken: function () { return token; },
                    getTokenPos: function () { return tokenPos; },
                    getTokenText: function () { return text.substring(tokenPos, pos); },
                    getTokenValue: function () { return tokenValue; },
                    hasPrecedingLineBreak: function () { return precedingLineBreak; },
                    isIdentifier: function () { return token === 63 /* Identifier */ || token > 99 /* LastReservedWord */; },
                    isReservedWord: function () { return token >= 64 /* FirstReservedWord */ && token <= 99 /* LastReservedWord */; },
                    reScanGreaterToken: reScanGreaterToken,
                    reScanSlashToken: reScanSlashToken,
                    reScanTemplateToken: reScanTemplateToken,
                    scan: scan,
                    setText: setText,
                    setTextPos: setTextPos,
                    tryScan: tryScan
                };
            }
            ts.createScanner = createScanner;
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var nodeConstructors = new Array(201 /* Count */);
            function getNodeConstructor(kind) {
                return nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind));
            }
            ts.getNodeConstructor = getNodeConstructor;
            function createRootNode(kind, pos, end, flags) {
                var node = new (getNodeConstructor(kind))();
                node.pos = pos;
                node.end = end;
                node.flags = flags;
                return node;
            }
            function getSourceFileOfNode(node) {
                while (node && node.kind !== 198 /* SourceFile */)
                    node = node.parent;
                return node;
            }
            ts.getSourceFileOfNode = getSourceFileOfNode;
            function nodePosToString(node) {
                var file = getSourceFileOfNode(node);
                var loc = file.getLineAndCharacterFromPosition(node.pos);
                return file.filename + "(" + loc.line + "," + loc.character + ")";
            }
            ts.nodePosToString = nodePosToString;
            function getStartPosOfNode(node) {
                return node.pos;
            }
            ts.getStartPosOfNode = getStartPosOfNode;
            function getTokenPosOfNode(node, sourceFile) {
                if (node.pos === node.end) {
                    return node.pos;
                }
                return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
            }
            ts.getTokenPosOfNode = getTokenPosOfNode;
            function getSourceTextOfNodeFromSourceFile(sourceFile, node) {
                var text = sourceFile.text;
                return text.substring(ts.skipTrivia(text, node.pos), node.end);
            }
            ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
            function getTextOfNodeFromSourceText(sourceText, node) {
                return sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end);
            }
            ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
            function getTextOfNode(node) {
                return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node);
            }
            ts.getTextOfNode = getTextOfNode;
            function escapeIdentifier(identifier) {
                return identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier;
            }
            ts.escapeIdentifier = escapeIdentifier;
            function unescapeIdentifier(identifier) {
                return identifier.length >= 3 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ && identifier.charCodeAt(2) === 95 /* _ */ ? identifier.substr(1) : identifier;
            }
            ts.unescapeIdentifier = unescapeIdentifier;
            function declarationNameToString(name) {
                return name.kind === 120 /* Missing */ ? "(Missing)" : getTextOfNode(name);
            }
            ts.declarationNameToString = declarationNameToString;
            function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
                node = getErrorSpanForNode(node);
                var file = getSourceFileOfNode(node);
                var start = node.kind === 120 /* Missing */ ? node.pos : ts.skipTrivia(file.text, node.pos);
                var length = node.end - start;
                return ts.createFileDiagnostic(file, start, length, message, arg0, arg1, arg2);
            }
            ts.createDiagnosticForNode = createDiagnosticForNode;
            function createDiagnosticForNodeFromMessageChain(node, messageChain, newLine) {
                node = getErrorSpanForNode(node);
                var file = getSourceFileOfNode(node);
                var start = ts.skipTrivia(file.text, node.pos);
                var length = node.end - start;
                return ts.flattenDiagnosticChain(file, start, length, messageChain, newLine);
            }
            ts.createDiagnosticForNodeFromMessageChain = createDiagnosticForNodeFromMessageChain;
            function getErrorSpanForNode(node) {
                var errorSpan;
                switch (node.kind) {
                    case 186 /* VariableDeclaration */:
                    case 189 /* ClassDeclaration */:
                    case 190 /* InterfaceDeclaration */:
                    case 193 /* ModuleDeclaration */:
                    case 192 /* EnumDeclaration */:
                    case 197 /* EnumMember */:
                        errorSpan = node.name;
                        break;
                }
                return errorSpan && errorSpan.pos < errorSpan.end ? errorSpan : node;
            }
            ts.getErrorSpanForNode = getErrorSpanForNode;
            function isExternalModule(file) {
                return file.externalModuleIndicator !== undefined;
            }
            ts.isExternalModule = isExternalModule;
            function isDeclarationFile(file) {
                return (file.flags & 1024 /* DeclarationFile */) !== 0;
            }
            ts.isDeclarationFile = isDeclarationFile;
            function isConstEnumDeclaration(node) {
                return node.kind === 192 /* EnumDeclaration */ && isConst(node);
            }
            ts.isConstEnumDeclaration = isConstEnumDeclaration;
            function isConst(node) {
                return !!(node.flags & 4096 /* Const */);
            }
            ts.isConst = isConst;
            function isLet(node) {
                return !!(node.flags & 2048 /* Let */);
            }
            ts.isLet = isLet;
            function isPrologueDirective(node) {
                return node.kind === 166 /* ExpressionStatement */ && node.expression.kind === 7 /* StringLiteral */;
            }
            ts.isPrologueDirective = isPrologueDirective;
            function isEvalOrArgumentsIdentifier(node) {
                return node.kind === 63 /* Identifier */ && node.text && (node.text === "eval" || node.text === "arguments");
            }
            function isUseStrictPrologueDirective(node) {
                ts.Debug.assert(isPrologueDirective(node));
                return node.expression.text === "use strict";
            }
            function getLeadingCommentRangesOfNode(node, sourceFileOfNode) {
                sourceFileOfNode = sourceFileOfNode || getSourceFileOfNode(node);
                if (node.kind === 124 /* Parameter */ || node.kind === 123 /* TypeParameter */) {
                    return ts.concatenate(ts.getTrailingCommentRanges(sourceFileOfNode.text, node.pos), ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos));
                }
                else {
                    return ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos);
                }
            }
            ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
            function getJsDocComments(node, sourceFileOfNode) {
                return ts.filter(getLeadingCommentRangesOfNode(node, sourceFileOfNode), function (comment) { return isJsDocComment(comment); });
                function isJsDocComment(comment) {
                    return sourceFileOfNode.text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ && sourceFileOfNode.text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ && sourceFileOfNode.text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
                }
            }
            ts.getJsDocComments = getJsDocComments;
            ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*<reference\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
            function forEachChild(node, cbNode, cbNodes) {
                function child(node) {
                    if (node)
                        return cbNode(node);
                }
                function children(nodes) {
                    if (nodes) {
                        if (cbNodes)
                            return cbNodes(nodes);
                        var result;
                        for (var i = 0, len = nodes.length; i < len; i++) {
                            if (result = cbNode(nodes[i]))
                                break;
                        }
                        return result;
                    }
                }
                if (!node)
                    return;
                switch (node.kind) {
                    case 121 /* QualifiedName */:
                        return child(node.left) || child(node.right);
                    case 123 /* TypeParameter */:
                        return child(node.name) || child(node.constraint);
                    case 124 /* Parameter */:
                        return child(node.name) || child(node.type) || child(node.initializer);
                    case 125 /* Property */:
                    case 144 /* PropertyAssignment */:
                    case 145 /* ShorthandPropertyAssignment */:
                        return child(node.name) || child(node.type) || child(node.initializer);
                    case 134 /* FunctionType */:
                    case 135 /* ConstructorType */:
                    case 130 /* CallSignature */:
                    case 131 /* ConstructSignature */:
                    case 132 /* IndexSignature */:
                        return children(node.typeParameters) || children(node.parameters) || child(node.type);
                    case 126 /* Method */:
                    case 127 /* Constructor */:
                    case 128 /* GetAccessor */:
                    case 129 /* SetAccessor */:
                    case 153 /* FunctionExpression */:
                    case 187 /* FunctionDeclaration */:
                    case 154 /* ArrowFunction */:
                        return child(node.name) || children(node.typeParameters) || children(node.parameters) || child(node.type) || child(node.body);
                    case 133 /* TypeReference */:
                        return child(node.typeName) || children(node.typeArguments);
                    case 136 /* TypeQuery */:
                        return child(node.exprName);
                    case 137 /* TypeLiteral */:
                        return children(node.members);
                    case 138 /* ArrayType */:
                        return child(node.elementType);
                    case 139 /* TupleType */:
                        return children(node.elementTypes);
                    case 140 /* UnionType */:
                        return children(node.types);
                    case 141 /* ParenType */:
                        return child(node.type);
                    case 142 /* ArrayLiteral */:
                        return children(node.elements);
                    case 143 /* ObjectLiteral */:
                        return children(node.properties);
                    case 146 /* PropertyAccess */:
                        return child(node.left) || child(node.right);
                    case 147 /* IndexedAccess */:
                        return child(node.object) || child(node.index);
                    case 148 /* CallExpression */:
                    case 149 /* NewExpression */:
                        return child(node.func) || children(node.typeArguments) || children(node.arguments);
                    case 150 /* TaggedTemplateExpression */:
                        return child(node.tag) || child(node.template);
                    case 151 /* TypeAssertion */:
                        return child(node.type) || child(node.operand);
                    case 152 /* ParenExpression */:
                        return child(node.expression);
                    case 155 /* PrefixOperator */:
                    case 156 /* PostfixOperator */:
                        return child(node.operand);
                    case 157 /* BinaryExpression */:
                        return child(node.left) || child(node.right);
                    case 158 /* ConditionalExpression */:
                        return child(node.condition) || child(node.whenTrue) || child(node.whenFalse);
                    case 163 /* Block */:
                    case 182 /* TryBlock */:
                    case 184 /* FinallyBlock */:
                    case 188 /* FunctionBlock */:
                    case 194 /* ModuleBlock */:
                    case 198 /* SourceFile */:
                        return children(node.statements);
                    case 164 /* VariableStatement */:
                        return children(node.declarations);
                    case 166 /* ExpressionStatement */:
                        return child(node.expression);
                    case 167 /* IfStatement */:
                        return child(node.expression) || child(node.thenStatement) || child(node.elseStatement);
                    case 168 /* DoStatement */:
                        return child(node.statement) || child(node.expression);
                    case 169 /* WhileStatement */:
                        return child(node.expression) || child(node.statement);
                    case 170 /* ForStatement */:
                        return children(node.declarations) || child(node.initializer) || child(node.condition) || child(node.iterator) || child(node.statement);
                    case 171 /* ForInStatement */:
                        return children(node.declarations) || child(node.variable) || child(node.expression) || child(node.statement);
                    case 172 /* ContinueStatement */:
                    case 173 /* BreakStatement */:
                        return child(node.label);
                    case 174 /* ReturnStatement */:
                        return child(node.expression);
                    case 175 /* WithStatement */:
                        return child(node.expression) || child(node.statement);
                    case 176 /* SwitchStatement */:
                        return child(node.expression) || children(node.clauses);
                    case 177 /* CaseClause */:
                    case 178 /* DefaultClause */:
                        return child(node.expression) || children(node.statements);
                    case 179 /* LabeledStatement */:
                        return child(node.label) || child(node.statement);
                    case 180 /* ThrowStatement */:
                        return child(node.expression);
                    case 181 /* TryStatement */:
                        return child(node.tryBlock) || child(node.catchBlock) || child(node.finallyBlock);
                    case 183 /* CatchBlock */:
                        return child(node.variable) || children(node.statements);
                    case 186 /* VariableDeclaration */:
                        return child(node.name) || child(node.type) || child(node.initializer);
                    case 189 /* ClassDeclaration */:
                        return child(node.name) || children(node.typeParameters) || child(node.baseType) || children(node.implementedTypes) || children(node.members);
                    case 190 /* InterfaceDeclaration */:
                        return child(node.name) || children(node.typeParameters) || children(node.baseTypes) || children(node.members);
                    case 191 /* TypeAliasDeclaration */:
                        return child(node.name) || child(node.type);
                    case 192 /* EnumDeclaration */:
                        return child(node.name) || children(node.members);
                    case 197 /* EnumMember */:
                        return child(node.name) || child(node.initializer);
                    case 193 /* ModuleDeclaration */:
                        return child(node.name) || child(node.body);
                    case 195 /* ImportDeclaration */:
                        return child(node.name) || child(node.entityName) || child(node.externalModuleName);
                    case 196 /* ExportAssignment */:
                        return child(node.exportName);
                    case 159 /* TemplateExpression */:
                        return child(node.head) || children(node.templateSpans);
                    case 160 /* TemplateSpan */:
                        return child(node.expression) || child(node.literal);
                    case 122 /* ComputedPropertyName */:
                        return child(node.expression);
                }
            }
            ts.forEachChild = forEachChild;
            function forEachReturnStatement(body, visitor) {
                return traverse(body);
                function traverse(node) {
                    switch (node.kind) {
                        case 174 /* ReturnStatement */:
                            return visitor(node);
                        case 163 /* Block */:
                        case 188 /* FunctionBlock */:
                        case 167 /* IfStatement */:
                        case 168 /* DoStatement */:
                        case 169 /* WhileStatement */:
                        case 170 /* ForStatement */:
                        case 171 /* ForInStatement */:
                        case 175 /* WithStatement */:
                        case 176 /* SwitchStatement */:
                        case 177 /* CaseClause */:
                        case 178 /* DefaultClause */:
                        case 179 /* LabeledStatement */:
                        case 181 /* TryStatement */:
                        case 182 /* TryBlock */:
                        case 183 /* CatchBlock */:
                        case 184 /* FinallyBlock */:
                            return forEachChild(node, traverse);
                    }
                }
            }
            ts.forEachReturnStatement = forEachReturnStatement;
            function isAnyFunction(node) {
                if (node) {
                    switch (node.kind) {
                        case 153 /* FunctionExpression */:
                        case 187 /* FunctionDeclaration */:
                        case 154 /* ArrowFunction */:
                        case 126 /* Method */:
                        case 128 /* GetAccessor */:
                        case 129 /* SetAccessor */:
                        case 127 /* Constructor */:
                            return true;
                    }
                }
                return false;
            }
            ts.isAnyFunction = isAnyFunction;
            function getContainingFunction(node) {
                while (true) {
                    node = node.parent;
                    if (!node || isAnyFunction(node)) {
                        return node;
                    }
                }
            }
            ts.getContainingFunction = getContainingFunction;
            function getThisContainer(node, includeArrowFunctions) {
                while (true) {
                    node = node.parent;
                    if (!node) {
                        return undefined;
                    }
                    switch (node.kind) {
                        case 154 /* ArrowFunction */:
                            if (!includeArrowFunctions) {
                                continue;
                            }
                        case 187 /* FunctionDeclaration */:
                        case 153 /* FunctionExpression */:
                        case 193 /* ModuleDeclaration */:
                        case 125 /* Property */:
                        case 126 /* Method */:
                        case 127 /* Constructor */:
                        case 128 /* GetAccessor */:
                        case 129 /* SetAccessor */:
                        case 192 /* EnumDeclaration */:
                        case 198 /* SourceFile */:
                            return node;
                    }
                }
            }
            ts.getThisContainer = getThisContainer;
            function getSuperContainer(node) {
                while (true) {
                    node = node.parent;
                    if (!node) {
                        return undefined;
                    }
                    switch (node.kind) {
                        case 125 /* Property */:
                        case 126 /* Method */:
                        case 127 /* Constructor */:
                        case 128 /* GetAccessor */:
                        case 129 /* SetAccessor */:
                            return node;
                    }
                }
            }
            ts.getSuperContainer = getSuperContainer;
            function getInvokedExpression(node) {
                if (node.kind === 150 /* TaggedTemplateExpression */) {
                    return node.tag;
                }
                return node.func;
            }
            ts.getInvokedExpression = getInvokedExpression;
            function isExpression(node) {
                switch (node.kind) {
                    case 91 /* ThisKeyword */:
                    case 89 /* SuperKeyword */:
                    case 87 /* NullKeyword */:
                    case 93 /* TrueKeyword */:
                    case 78 /* FalseKeyword */:
                    case 8 /* RegularExpressionLiteral */:
                    case 142 /* ArrayLiteral */:
                    case 143 /* ObjectLiteral */:
                    case 146 /* PropertyAccess */:
                    case 147 /* IndexedAccess */:
                    case 148 /* CallExpression */:
                    case 149 /* NewExpression */:
                    case 150 /* TaggedTemplateExpression */:
                    case 151 /* TypeAssertion */:
                    case 152 /* ParenExpression */:
                    case 153 /* FunctionExpression */:
                    case 154 /* ArrowFunction */:
                    case 155 /* PrefixOperator */:
                    case 156 /* PostfixOperator */:
                    case 157 /* BinaryExpression */:
                    case 158 /* ConditionalExpression */:
                    case 159 /* TemplateExpression */:
                    case 9 /* NoSubstitutionTemplateLiteral */:
                    case 162 /* OmittedExpression */:
                        return true;
                    case 121 /* QualifiedName */:
                        while (node.parent.kind === 121 /* QualifiedName */)
                            node = node.parent;
                        return node.parent.kind === 136 /* TypeQuery */;
                    case 63 /* Identifier */:
                        if (node.parent.kind === 136 /* TypeQuery */) {
                            return true;
                        }
                    case 6 /* NumericLiteral */:
                    case 7 /* StringLiteral */:
                        var parent = node.parent;
                        switch (parent.kind) {
                            case 186 /* VariableDeclaration */:
                            case 124 /* Parameter */:
                            case 125 /* Property */:
                            case 197 /* EnumMember */:
                            case 144 /* PropertyAssignment */:
                                return parent.initializer === node;
                            case 166 /* ExpressionStatement */:
                            case 167 /* IfStatement */:
                            case 168 /* DoStatement */:
                            case 169 /* WhileStatement */:
                            case 174 /* ReturnStatement */:
                            case 175 /* WithStatement */:
                            case 176 /* SwitchStatement */:
                            case 177 /* CaseClause */:
                            case 180 /* ThrowStatement */:
                            case 176 /* SwitchStatement */:
                                return parent.expression === node;
                            case 170 /* ForStatement */:
                                return parent.initializer === node || parent.condition === node || parent.iterator === node;
                            case 171 /* ForInStatement */:
                                return parent.variable === node || parent.expression === node;
                            case 151 /* TypeAssertion */:
                                return node === parent.operand;
                            case 160 /* TemplateSpan */:
                                return node === parent.expression;
                            default:
                                if (isExpression(parent)) {
                                    return true;
                                }
                        }
                }
                return false;
            }
            ts.isExpression = isExpression;
            function hasRestParameters(s) {
                return s.parameters.length > 0 && (s.parameters[s.parameters.length - 1].flags & 8 /* Rest */) !== 0;
            }
            ts.hasRestParameters = hasRestParameters;
            function isLiteralKind(kind) {
                return 6 /* FirstLiteralToken */ <= kind && kind <= 9 /* LastLiteralToken */;
            }
            ts.isLiteralKind = isLiteralKind;
            function isTextualLiteralKind(kind) {
                return kind === 7 /* StringLiteral */ || kind === 9 /* NoSubstitutionTemplateLiteral */;
            }
            ts.isTextualLiteralKind = isTextualLiteralKind;
            function isTemplateLiteralKind(kind) {
                return 9 /* FirstTemplateToken */ <= kind && kind <= 12 /* LastTemplateToken */;
            }
            ts.isTemplateLiteralKind = isTemplateLiteralKind;
            function isInAmbientContext(node) {
                while (node) {
                    if (node.flags & (2 /* Ambient */ | 1024 /* DeclarationFile */))
                        return true;
                    node = node.parent;
                }
                return false;
            }
            ts.isInAmbientContext = isInAmbientContext;
            function isDeclaration(node) {
                switch (node.kind) {
                    case 123 /* TypeParameter */:
                    case 124 /* Parameter */:
                    case 186 /* VariableDeclaration */:
                    case 125 /* Property */:
                    case 144 /* PropertyAssignment */:
                    case 145 /* ShorthandPropertyAssignment */:
                    case 197 /* EnumMember */:
                    case 126 /* Method */:
                    case 187 /* FunctionDeclaration */:
                    case 128 /* GetAccessor */:
                    case 129 /* SetAccessor */:
                    case 127 /* Constructor */:
                    case 189 /* ClassDeclaration */:
                    case 190 /* InterfaceDeclaration */:
                    case 191 /* TypeAliasDeclaration */:
                    case 192 /* EnumDeclaration */:
                    case 193 /* ModuleDeclaration */:
                    case 195 /* ImportDeclaration */:
                        return true;
                }
                return false;
            }
            ts.isDeclaration = isDeclaration;
            function isStatement(n) {
                switch (n.kind) {
                    case 173 /* BreakStatement */:
                    case 172 /* ContinueStatement */:
                    case 185 /* DebuggerStatement */:
                    case 168 /* DoStatement */:
                    case 166 /* ExpressionStatement */:
                    case 165 /* EmptyStatement */:
                    case 171 /* ForInStatement */:
                    case 170 /* ForStatement */:
                    case 167 /* IfStatement */:
                    case 179 /* LabeledStatement */:
                    case 174 /* ReturnStatement */:
                    case 176 /* SwitchStatement */:
                    case 92 /* ThrowKeyword */:
                    case 181 /* TryStatement */:
                    case 164 /* VariableStatement */:
                    case 169 /* WhileStatement */:
                    case 175 /* WithStatement */:
                    case 196 /* ExportAssignment */:
                        return true;
                    default:
                        return false;
                }
            }
            ts.isStatement = isStatement;
            function isDeclarationOrFunctionExpressionOrCatchVariableName(name) {
                if (name.kind !== 63 /* Identifier */ && name.kind !== 7 /* StringLiteral */ && name.kind !== 6 /* NumericLiteral */) {
                    return false;
                }
                var parent = name.parent;
                if (isDeclaration(parent) || parent.kind === 153 /* FunctionExpression */) {
                    return parent.name === name;
                }
                if (parent.kind === 183 /* CatchBlock */) {
                    return parent.variable === name;
                }
                return false;
            }
            ts.isDeclarationOrFunctionExpressionOrCatchVariableName = isDeclarationOrFunctionExpressionOrCatchVariableName;
            function tryResolveScriptReference(program, sourceFile, reference) {
                if (!program.getCompilerOptions().noResolve) {
                    var referenceFileName = ts.isRootedDiskPath(reference.filename) ? reference.filename : ts.combinePaths(ts.getDirectoryPath(sourceFile.filename), reference.filename);
                    referenceFileName = ts.getNormalizedAbsolutePath(referenceFileName, program.getCompilerHost().getCurrentDirectory());
                    return program.getSourceFile(referenceFileName);
                }
            }
            ts.tryResolveScriptReference = tryResolveScriptReference;
            function getAncestor(node, kind) {
                switch (kind) {
                    case 189 /* ClassDeclaration */:
                        while (node) {
                            switch (node.kind) {
                                case 189 /* ClassDeclaration */:
                                    return node;
                                case 192 /* EnumDeclaration */:
                                case 190 /* InterfaceDeclaration */:
                                case 191 /* TypeAliasDeclaration */:
                                case 193 /* ModuleDeclaration */:
                                case 195 /* ImportDeclaration */:
                                    return undefined;
                                default:
                                    node = node.parent;
                                    continue;
                            }
                        }
                        break;
                    default:
                        while (node) {
                            if (node.kind === kind) {
                                return node;
                            }
                            node = node.parent;
                        }
                        break;
                }
                return undefined;
            }
            ts.getAncestor = getAncestor;
            var ParsingContext;
            (function (ParsingContext) {
                ParsingContext[ParsingContext["SourceElements"] = 0] = "SourceElements";
                ParsingContext[ParsingContext["ModuleElements"] = 1] = "ModuleElements";
                ParsingContext[ParsingContext["BlockStatements"] = 2] = "BlockStatements";
                ParsingContext[ParsingContext["SwitchClauses"] = 3] = "SwitchClauses";
                ParsingContext[ParsingContext["SwitchClauseStatements"] = 4] = "SwitchClauseStatements";
                ParsingContext[ParsingContext["TypeMembers"] = 5] = "TypeMembers";
                ParsingContext[ParsingContext["ClassMembers"] = 6] = "ClassMembers";
                ParsingContext[ParsingContext["EnumMembers"] = 7] = "EnumMembers";
                ParsingContext[ParsingContext["BaseTypeReferences"] = 8] = "BaseTypeReferences";
                ParsingContext[ParsingContext["VariableDeclarations"] = 9] = "VariableDeclarations";
                ParsingContext[ParsingContext["ArgumentExpressions"] = 10] = "ArgumentExpressions";
                ParsingContext[ParsingContext["ObjectLiteralMembers"] = 11] = "ObjectLiteralMembers";
                ParsingContext[ParsingContext["ArrayLiteralMembers"] = 12] = "ArrayLiteralMembers";
                ParsingContext[ParsingContext["Parameters"] = 13] = "Parameters";
                ParsingContext[ParsingContext["TypeParameters"] = 14] = "TypeParameters";
                ParsingContext[ParsingContext["TypeArguments"] = 15] = "TypeArguments";
                ParsingContext[ParsingContext["TupleElementTypes"] = 16] = "TupleElementTypes";
                ParsingContext[ParsingContext["Count"] = 17] = "Count";
            })(ParsingContext || (ParsingContext = {}));
            var Tristate;
            (function (Tristate) {
                Tristate[Tristate["False"] = 0] = "False";
                Tristate[Tristate["True"] = 1] = "True";
                Tristate[Tristate["Unknown"] = 2] = "Unknown";
            })(Tristate || (Tristate = {}));
            function parsingContextErrors(context) {
                switch (context) {
                    case 0 /* SourceElements */: return ts.Diagnostics.Declaration_or_statement_expected;
                    case 1 /* ModuleElements */: return ts.Diagnostics.Declaration_or_statement_expected;
                    case 2 /* BlockStatements */: return ts.Diagnostics.Statement_expected;
                    case 3 /* SwitchClauses */: return ts.Diagnostics.case_or_default_expected;
                    case 4 /* SwitchClauseStatements */: return ts.Diagnostics.Statement_expected;
                    case 5 /* TypeMembers */: return ts.Diagnostics.Property_or_signature_expected;
                    case 6 /* ClassMembers */: return ts.Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
                    case 7 /* EnumMembers */: return ts.Diagnostics.Enum_member_expected;
                    case 8 /* BaseTypeReferences */: return ts.Diagnostics.Type_reference_expected;
                    case 9 /* VariableDeclarations */: return ts.Diagnostics.Variable_declaration_expected;
                    case 10 /* ArgumentExpressions */: return ts.Diagnostics.Argument_expression_expected;
                    case 11 /* ObjectLiteralMembers */: return ts.Diagnostics.Property_assignment_expected;
                    case 12 /* ArrayLiteralMembers */: return ts.Diagnostics.Expression_or_comma_expected;
                    case 13 /* Parameters */: return ts.Diagnostics.Parameter_declaration_expected;
                    case 14 /* TypeParameters */: return ts.Diagnostics.Type_parameter_declaration_expected;
                    case 15 /* TypeArguments */: return ts.Diagnostics.Type_argument_expected;
                    case 16 /* TupleElementTypes */: return ts.Diagnostics.Type_expected;
                }
            }
            ;
            var LookAheadMode;
            (function (LookAheadMode) {
                LookAheadMode[LookAheadMode["NotLookingAhead"] = 0] = "NotLookingAhead";
                LookAheadMode[LookAheadMode["NoErrorYet"] = 1] = "NoErrorYet";
                LookAheadMode[LookAheadMode["Error"] = 2] = "Error";
            })(LookAheadMode || (LookAheadMode = {}));
            function getFileReferenceFromReferencePath(comment, commentRange) {
                var simpleReferenceRegEx = /^\/\/\/\s*<reference\s+/gim;
                var isNoDefaultLibRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/gim;
                if (simpleReferenceRegEx.exec(comment)) {
                    if (isNoDefaultLibRegEx.exec(comment)) {
                        return {
                            isNoDefaultLib: true
                        };
                    }
                    else {
                        var matchResult = ts.fullTripleSlashReferencePathRegEx.exec(comment);
                        if (matchResult) {
                            var start = commentRange.pos;
                            var end = commentRange.end;
                            return {
                                fileReference: {
                                    pos: start,
                                    end: end,
                                    filename: matchResult[3]
                                },
                                isNoDefaultLib: false
                            };
                        }
                        else {
                            return {
                                diagnostic: ts.Diagnostics.Invalid_reference_directive_syntax,
                                isNoDefaultLib: false
                            };
                        }
                    }
                }
                return undefined;
            }
            ts.getFileReferenceFromReferencePath = getFileReferenceFromReferencePath;
            function isKeyword(token) {
                return 64 /* FirstKeyword */ <= token && token <= 119 /* LastKeyword */;
            }
            ts.isKeyword = isKeyword;
            function isTrivia(token) {
                return 2 /* FirstTriviaToken */ <= token && token <= 5 /* LastTriviaToken */;
            }
            ts.isTrivia = isTrivia;
            function isUnterminatedTemplateEnd(node) {
                ts.Debug.assert(isTemplateLiteralKind(node.kind));
                var sourceText = getSourceFileOfNode(node).text;
                if (node.end !== sourceText.length) {
                    return false;
                }
                if (node.kind !== 12 /* TemplateTail */ && node.kind !== 9 /* NoSubstitutionTemplateLiteral */) {
                    return false;
                }
                return sourceText.charCodeAt(node.end - 1) !== 96 /* backtick */ || node.text.length === 0;
            }
            ts.isUnterminatedTemplateEnd = isUnterminatedTemplateEnd;
            function isModifier(token) {
                switch (token) {
                    case 106 /* PublicKeyword */:
                    case 104 /* PrivateKeyword */:
                    case 105 /* ProtectedKeyword */:
                    case 107 /* StaticKeyword */:
                    case 76 /* ExportKeyword */:
                    case 112 /* DeclareKeyword */:
                        return true;
                }
                return false;
            }
            ts.isModifier = isModifier;
            function modifierToFlag(token) {
                switch (token) {
                    case 107 /* StaticKeyword */: return 128 /* Static */;
                    case 106 /* PublicKeyword */: return 16 /* Public */;
                    case 105 /* ProtectedKeyword */: return 64 /* Protected */;
                    case 104 /* PrivateKeyword */: return 32 /* Private */;
                    case 76 /* ExportKeyword */: return 1 /* Export */;
                    case 112 /* DeclareKeyword */: return 2 /* Ambient */;
                }
                return 0;
            }
            function createSourceFile(filename, sourceText, languageVersion, version, isOpen) {
                if (isOpen === void 0) { isOpen = false; }
                var file;
                var scanner;
                var token;
                var parsingContext;
                var commentRanges;
                var identifiers = {};
                var identifierCount = 0;
                var nodeCount = 0;
                var lineStarts;
                var lookAheadMode = 0 /* NotLookingAhead */;
                var contextFlags = 0;
                function setContextFlag(val, flag) {
                    if (val) {
                        contextFlags |= flag;
                    }
                    else {
                        contextFlags &= ~flag;
                    }
                }
                function setStrictModeContext(val) {
                    setContextFlag(val, 1 /* StrictMode */);
                }
                function setDisallowInContext(val) {
                    setContextFlag(val, 2 /* DisallowIn */);
                }
                function setYieldContext(val) {
                    setContextFlag(val, 4 /* Yield */);
                }
                function setGeneratorParameterContext(val) {
                    setContextFlag(val, 8 /* GeneratorParameter */);
                }
                function allowInAnd(func) {
                    if (contextFlags & 2 /* DisallowIn */) {
                        setDisallowInContext(false);
                        var result = func();
                        setDisallowInContext(true);
                        return result;
                    }
                    return func();
                }
                function disallowInAnd(func) {
                    if (contextFlags & 2 /* DisallowIn */) {
                        return func();
                    }
                    setDisallowInContext(true);
                    var result = func();
                    setDisallowInContext(false);
                    return result;
                }
                function doInYieldContext(func) {
                    if (contextFlags & 4 /* Yield */) {
                        return func();
                    }
                    setYieldContext(true);
                    var result = func();
                    setYieldContext(false);
                    return result;
                }
                function doOutsideOfYieldContext(func) {
                    if (contextFlags & 4 /* Yield */) {
                        setYieldContext(false);
                        var result = func();
                        setYieldContext(true);
                        return result;
                    }
                    return func();
                }
                function inYieldContext() {
                    return (contextFlags & 4 /* Yield */) !== 0;
                }
                function inStrictModeContext() {
                    return (contextFlags & 1 /* StrictMode */) !== 0;
                }
                function inGeneratorParameterContext() {
                    return (contextFlags & 8 /* GeneratorParameter */) !== 0;
                }
                function inDisallowInContext() {
                    return (contextFlags & 2 /* DisallowIn */) !== 0;
                }
                function getLineStarts() {
                    return lineStarts || (lineStarts = ts.computeLineStarts(sourceText));
                }
                function getLineAndCharacterFromSourcePosition(position) {
                    return ts.getLineAndCharacterOfPosition(getLineStarts(), position);
                }
                function getPositionFromSourceLineAndCharacter(line, character) {
                    return ts.getPositionFromLineAndCharacter(getLineStarts(), line, character);
                }
                function error(message, arg0, arg1, arg2) {
                    var start = scanner.getTokenPos();
                    var length = scanner.getTextPos() - start;
                    errorAtPos(start, length, message, arg0, arg1, arg2);
                }
                function errorAtPos(start, length, message, arg0, arg1, arg2) {
                    var lastErrorPos = file.parseDiagnostics.length ? file.parseDiagnostics[file.parseDiagnostics.length - 1].start : -1;
                    if (start !== lastErrorPos) {
                        var diagnostic = ts.createFileDiagnostic(file, start, length, message, arg0, arg1, arg2);
                        diagnostic.isParseError = true;
                        file.parseDiagnostics.push(diagnostic);
                    }
                    if (lookAheadMode === 1 /* NoErrorYet */) {
                        lookAheadMode = 2 /* Error */;
                    }
                }
                function scanError(message) {
                    var pos = scanner.getTextPos();
                    errorAtPos(pos, 0, message);
                }
                function onComment(pos, end) {
                    if (commentRanges)
                        commentRanges.push({ pos: pos, end: end });
                }
                function getNodePos() {
                    return scanner.getStartPos();
                }
                function getNodeEnd() {
                    return scanner.getStartPos();
                }
                function nextToken() {
                    return token = scanner.scan();
                }
                function getTokenPos(pos) {
                    return ts.skipTrivia(sourceText, pos);
                }
                function reScanGreaterToken() {
                    return token = scanner.reScanGreaterToken();
                }
                function reScanSlashToken() {
                    return token = scanner.reScanSlashToken();
                }
                function reScanTemplateToken() {
                    return token = scanner.reScanTemplateToken();
                }
                function lookAheadHelper(callback, alwaysResetState) {
                    var saveToken = token;
                    var saveSyntacticErrorsLength = file.parseDiagnostics.length;
                    var saveLookAheadMode = lookAheadMode;
                    lookAheadMode = 1 /* NoErrorYet */;
                    var result = callback();
                    ts.Debug.assert(lookAheadMode === 2 /* Error */ || lookAheadMode === 1 /* NoErrorYet */);
                    if (lookAheadMode === 2 /* Error */) {
                        result = undefined;
                    }
                    lookAheadMode = saveLookAheadMode;
                    if (!result || alwaysResetState) {
                        token = saveToken;
                        file.parseDiagnostics.length = saveSyntacticErrorsLength;
                    }
                    return result;
                }
                function lookAhead(callback) {
                    var result;
                    scanner.tryScan(function () {
                        result = lookAheadHelper(callback, true);
                        return false;
                    });
                    return result;
                }
                function tryParse(callback) {
                    return scanner.tryScan(function () { return lookAheadHelper(callback, false); });
                }
                function isIdentifier() {
                    if (token === 63 /* Identifier */) {
                        return true;
                    }
                    if (token === 108 /* YieldKeyword */ && inYieldContext()) {
                        return false;
                    }
                    return inStrictModeContext() ? token > 108 /* LastFutureReservedWord */ : token > 99 /* LastReservedWord */;
                }
                function parseExpected(t) {
                    if (token === t) {
                        nextToken();
                        return true;
                    }
                    error(ts.Diagnostics._0_expected, ts.tokenToString(t));
                    return false;
                }
                function parseOptional(t) {
                    if (token === t) {
                        nextToken();
                        return true;
                    }
                    return false;
                }
                function parseOptionalToken(t) {
                    if (token === t) {
                        var node = createNode(t);
                        nextToken();
                        return finishNode(node);
                    }
                    return undefined;
                }
                function canParseSemicolon() {
                    if (token === 21 /* SemicolonToken */) {
                        return true;
                    }
                    return token === 14 /* CloseBraceToken */ || token === 1 /* EndOfFileToken */ || scanner.hasPrecedingLineBreak();
                }
                function parseSemicolon() {
                    if (canParseSemicolon()) {
                        if (token === 21 /* SemicolonToken */) {
                            nextToken();
                        }
                    }
                    else {
                        error(ts.Diagnostics._0_expected, ";");
                    }
                }
                function createNode(kind, pos) {
                    nodeCount++;
                    var node = new (nodeConstructors[kind] || (nodeConstructors[kind] = ts.objectAllocator.getNodeConstructor(kind)))();
                    if (!(pos >= 0)) {
                        pos = scanner.getStartPos();
                    }
                    node.pos = pos;
                    node.end = pos;
                    return node;
                }
                function finishNode(node) {
                    node.end = scanner.getStartPos();
                    if (contextFlags) {
                        node.parserContextFlags = contextFlags;
                    }
                    return node;
                }
                function createMissingNode(pos) {
                    return createNode(120 /* Missing */, pos);
                }
                function internIdentifier(text) {
                    text = escapeIdentifier(text);
                    return ts.hasProperty(identifiers, text) ? identifiers[text] : (identifiers[text] = text);
                }
                function createIdentifier(isIdentifier) {
                    identifierCount++;
                    if (isIdentifier) {
                        var node = createNode(63 /* Identifier */);
                        node.text = internIdentifier(scanner.getTokenValue());
                        nextToken();
                        return finishNode(node);
                    }
                    error(ts.Diagnostics.Identifier_expected);
                    var node = createMissingNode();
                    node.text = "";
                    return node;
                }
                function parseIdentifier() {
                    return createIdentifier(isIdentifier());
                }
                function parseIdentifierName() {
                    return createIdentifier(token >= 63 /* Identifier */);
                }
                function isLiteralPropertyName() {
                    return token >= 63 /* Identifier */ || token === 7 /* StringLiteral */ || token === 6 /* NumericLiteral */;
                }
                function parsePropertyName() {
                    if (token === 7 /* StringLiteral */ || token === 6 /* NumericLiteral */) {
                        return parseLiteralNode(true);
                    }
                    if (token === 17 /* OpenBracketToken */) {
                        return parseComputedPropertyName();
                    }
                    return parseIdentifierName();
                }
                function parseComputedPropertyName() {
                    var node = createNode(122 /* ComputedPropertyName */);
                    parseExpected(17 /* OpenBracketToken */);
                    var yieldContext = inYieldContext();
                    if (inGeneratorParameterContext()) {
                        setYieldContext(false);
                    }
                    node.expression = allowInAnd(parseExpression);
                    if (inGeneratorParameterContext()) {
                        setYieldContext(yieldContext);
                    }
                    parseExpected(18 /* CloseBracketToken */);
                    return finishNode(node);
                }
                function parseContextualModifier(t) {
                    return token === t && tryParse(function () {
                        nextToken();
                        return canFollowModifier();
                    });
                }
                function parseAnyContextualModifier() {
                    return isModifier(token) && tryParse(function () {
                        nextToken();
                        return canFollowModifier();
                    });
                }
                function canFollowModifier() {
                    return token === 17 /* OpenBracketToken */ || token === 34 /* AsteriskToken */ || isLiteralPropertyName();
                }
                function isListElement(kind, inErrorRecovery) {
                    switch (kind) {
                        case 0 /* SourceElements */:
                        case 1 /* ModuleElements */:
                            return isSourceElement(inErrorRecovery);
                        case 2 /* BlockStatements */:
                        case 4 /* SwitchClauseStatements */:
                            return isStatement(inErrorRecovery);
                        case 3 /* SwitchClauses */:
                            return token === 65 /* CaseKeyword */ || token === 71 /* DefaultKeyword */;
                        case 5 /* TypeMembers */:
                            return isStartOfTypeMember();
                        case 6 /* ClassMembers */:
                            return lookAhead(isClassMemberStart);
                        case 7 /* EnumMembers */:
                            return token === 17 /* OpenBracketToken */ || isLiteralPropertyName();
                        case 11 /* ObjectLiteralMembers */:
                            return token === 17 /* OpenBracketToken */ || token === 34 /* AsteriskToken */ || isLiteralPropertyName();
                        case 8 /* BaseTypeReferences */:
                            return isIdentifier() && ((token !== 77 /* ExtendsKeyword */ && token !== 100 /* ImplementsKeyword */) || !lookAhead(function () { return (nextToken(), isIdentifier()); }));
                        case 9 /* VariableDeclarations */:
                        case 14 /* TypeParameters */:
                            return isIdentifier();
                        case 10 /* ArgumentExpressions */:
                            return token === 22 /* CommaToken */ || isStartOfExpression();
                        case 12 /* ArrayLiteralMembers */:
                            return token === 22 /* CommaToken */ || isStartOfExpression();
                        case 13 /* Parameters */:
                            return isStartOfParameter();
                        case 15 /* TypeArguments */:
                        case 16 /* TupleElementTypes */:
                            return token === 22 /* CommaToken */ || isStartOfType();
                    }
                    ts.Debug.fail("Non-exhaustive case in 'isListElement'.");
                }
                function isListTerminator(kind) {
                    if (token === 1 /* EndOfFileToken */) {
                        return true;
                    }
                    switch (kind) {
                        case 1 /* ModuleElements */:
                        case 2 /* BlockStatements */:
                        case 3 /* SwitchClauses */:
                        case 5 /* TypeMembers */:
                        case 6 /* ClassMembers */:
                        case 7 /* EnumMembers */:
                        case 11 /* ObjectLiteralMembers */:
                            return token === 14 /* CloseBraceToken */;
                        case 4 /* SwitchClauseStatements */:
                            return token === 14 /* CloseBraceToken */ || token === 65 /* CaseKeyword */ || token === 71 /* DefaultKeyword */;
                        case 8 /* BaseTypeReferences */:
                            return token === 13 /* OpenBraceToken */ || token === 77 /* ExtendsKeyword */ || token === 100 /* ImplementsKeyword */;
                        case 9 /* VariableDeclarations */:
                            return isVariableDeclaratorListTerminator();
                        case 14 /* TypeParameters */:
                            return token === 24 /* GreaterThanToken */ || token === 15 /* OpenParenToken */ || token === 13 /* OpenBraceToken */ || token === 77 /* ExtendsKeyword */ || token === 100 /* ImplementsKeyword */;
                        case 10 /* ArgumentExpressions */:
                            return token === 16 /* CloseParenToken */ || token === 21 /* SemicolonToken */;
                        case 12 /* ArrayLiteralMembers */:
                        case 16 /* TupleElementTypes */:
                            return token === 18 /* CloseBracketToken */;
                        case 13 /* Parameters */:
                            return token === 16 /* CloseParenToken */ || token === 18 /* CloseBracketToken */ || token === 13 /* OpenBraceToken */;
                        case 15 /* TypeArguments */:
                            return token === 24 /* GreaterThanToken */ || token === 15 /* OpenParenToken */;
                    }
                }
                function isVariableDeclaratorListTerminator() {
                    if (canParseSemicolon()) {
                        return true;
                    }
                    if (token === 84 /* InKeyword */) {
                        return true;
                    }
                    if (token === 31 /* EqualsGreaterThanToken */) {
                        return true;
                    }
                    return false;
                }
                function isInSomeParsingContext() {
                    for (var kind = 0; kind < 17 /* Count */; kind++) {
                        if (parsingContext & (1 << kind)) {
                            if (isListElement(kind, true) || isListTerminator(kind)) {
                                return true;
                            }
                        }
                    }
                    return false;
                }
                function parseList(kind, checkForStrictMode, parseElement) {
                    var saveParsingContext = parsingContext;
                    parsingContext |= 1 << kind;
                    var result = [];
                    result.pos = getNodePos();
                    var savedStrictModeContext = inStrictModeContext();
                    while (!isListTerminator(kind)) {
                        if (isListElement(kind, false)) {
                            var element = parseElement();
                            result.push(element);
                            if (!inStrictModeContext() && checkForStrictMode) {
                                if (isPrologueDirective(element)) {
                                    if (isUseStrictPrologueDirective(element)) {
                                        setStrictModeContext(true);
                                        checkForStrictMode = false;
                                    }
                                }
                                else {
                                    checkForStrictMode = false;
                                }
                            }
                        }
                        else {
                            error(parsingContextErrors(kind));
                            if (isInSomeParsingContext()) {
                                break;
                            }
                            nextToken();
                        }
                    }
                    setStrictModeContext(savedStrictModeContext);
                    result.end = getNodeEnd();
                    parsingContext = saveParsingContext;
                    return result;
                }
                function parseDelimitedList(kind, parseElement) {
                    var saveParsingContext = parsingContext;
                    parsingContext |= 1 << kind;
                    var result = [];
                    result.pos = getNodePos();
                    var commaStart = -1;
                    while (true) {
                        if (isListElement(kind, false)) {
                            result.push(parseElement());
                            commaStart = scanner.getTokenPos();
                            if (parseOptional(22 /* CommaToken */)) {
                                continue;
                            }
                            commaStart = -1;
                            if (isListTerminator(kind)) {
                                break;
                            }
                            error(ts.Diagnostics._0_expected, ",");
                        }
                        else if (isListTerminator(kind)) {
                            break;
                        }
                        else {
                            error(parsingContextErrors(kind));
                            if (isInSomeParsingContext()) {
                                break;
                            }
                            nextToken();
                        }
                    }
                    if (commaStart >= 0) {
                        result.hasTrailingComma = true;
                    }
                    result.end = getNodeEnd();
                    parsingContext = saveParsingContext;
                    return result;
                }
                function createMissingList() {
                    var pos = getNodePos();
                    var result = [];
                    result.pos = pos;
                    result.end = pos;
                    return result;
                }
                function parseBracketedList(kind, parseElement, open, close) {
                    if (parseExpected(open)) {
                        var result = parseDelimitedList(kind, parseElement);
                        parseExpected(close);
                        return result;
                    }
                    return createMissingList();
                }
                function parseEntityName(allowReservedWords) {
                    var entity = parseIdentifier();
                    while (parseOptional(19 /* DotToken */)) {
                        var node = createNode(121 /* QualifiedName */, entity.pos);
                        node.left = entity;
                        node.right = allowReservedWords ? parseIdentifierName() : parseIdentifier();
                        entity = finishNode(node);
                    }
                    return entity;
                }
                function parseTokenNode() {
                    var node = createNode(token);
                    nextToken();
                    return finishNode(node);
                }
                function parseTemplateExpression() {
                    var template = createNode(159 /* TemplateExpression */);
                    template.head = parseLiteralNode();
                    ts.Debug.assert(template.head.kind === 10 /* TemplateHead */, "Template head has wrong token kind");
                    var templateSpans = [];
                    templateSpans.pos = getNodePos();
                    do {
                        templateSpans.push(parseTemplateSpan());
                    } while (templateSpans[templateSpans.length - 1].literal.kind === 11 /* TemplateMiddle */);
                    templateSpans.end = getNodeEnd();
                    template.templateSpans = templateSpans;
                    return finishNode(template);
                }
                function parseTemplateSpan() {
                    var span = createNode(160 /* TemplateSpan */);
                    span.expression = allowInAnd(parseExpression);
                    var literal;
                    if (token === 14 /* CloseBraceToken */) {
                        reScanTemplateToken();
                        literal = parseLiteralNode();
                    }
                    else {
                        error(ts.Diagnostics.Invalid_template_literal_expected);
                        literal = createMissingNode();
                        literal.text = "";
                    }
                    span.literal = literal;
                    return finishNode(span);
                }
                function parseLiteralNode(internName) {
                    var node = createNode(token);
                    var text = scanner.getTokenValue();
                    node.text = internName ? internIdentifier(text) : text;
                    var tokenPos = scanner.getTokenPos();
                    nextToken();
                    finishNode(node);
                    if (node.kind === 6 /* NumericLiteral */ && sourceText.charCodeAt(tokenPos) === 48 /* _0 */ && ts.isOctalDigit(sourceText.charCodeAt(tokenPos + 1))) {
                        node.flags |= 8192 /* OctalLiteral */;
                    }
                    return node;
                }
                function parseStringLiteral() {
                    if (token === 7 /* StringLiteral */) {
                        return parseLiteralNode(true);
                    }
                    error(ts.Diagnostics.String_literal_expected);
                    return createMissingNode();
                }
                function parseTypeReference() {
                    var node = createNode(133 /* TypeReference */);
                    node.typeName = parseEntityName(false);
                    if (!scanner.hasPrecedingLineBreak() && token === 23 /* LessThanToken */) {
                        node.typeArguments = parseTypeArguments();
                    }
                    return finishNode(node);
                }
                function parseTypeQuery() {
                    var node = createNode(136 /* TypeQuery */);
                    parseExpected(95 /* TypeOfKeyword */);
                    node.exprName = parseEntityName(true);
                    return finishNode(node);
                }
                function parseTypeParameter() {
                    var node = createNode(123 /* TypeParameter */);
                    node.name = parseIdentifier();
                    if (parseOptional(77 /* ExtendsKeyword */)) {
                        if (isStartOfType() || !isStartOfExpression()) {
                            node.constraint = parseType();
                        }
                        else {
                            node.expression = parseUnaryExpression();
                        }
                    }
                    return finishNode(node);
                }
                function parseTypeParameters() {
                    if (token === 23 /* LessThanToken */) {
                        return parseBracketedList(14 /* TypeParameters */, parseTypeParameter, 23 /* LessThanToken */, 24 /* GreaterThanToken */);
                    }
                }
                function parseParameterType() {
                    return parseOptional(50 /* ColonToken */) ? token === 7 /* StringLiteral */ ? parseStringLiteral() : parseType() : undefined;
                }
                function isStartOfParameter() {
                    return token === 20 /* DotDotDotToken */ || isIdentifier() || isModifier(token);
                }
                function setModifiers(node, modifiers) {
                    if (modifiers) {
                        node.flags |= modifiers.flags;
                        node.modifiers = modifiers;
                    }
                }
                function parseParameter() {
                    var node = createNode(124 /* Parameter */);
                    var modifiers = parseModifiers();
                    setModifiers(node, modifiers);
                    if (parseOptional(20 /* DotDotDotToken */)) {
                        node.flags |= 8 /* Rest */;
                    }
                    node.name = inGeneratorParameterContext() ? doInYieldContext(parseIdentifier) : parseIdentifier();
                    if (node.name.kind === 120 /* Missing */ && node.flags === 0 && isModifier(token)) {
                        nextToken();
                    }
                    if (parseOptional(49 /* QuestionToken */)) {
                        node.flags |= 4 /* QuestionMark */;
                    }
                    node.type = parseParameterType();
                    node.initializer = inGeneratorParameterContext() ? doOutsideOfYieldContext(parseParameterInitializer) : parseParameterInitializer();
                    return finishNode(node);
                }
                function parseParameterInitializer() {
                    return parseInitializer(true);
                }
                function parseSignature(kind, returnToken, returnTokenRequired, yieldAndGeneratorParameterContext) {
                    var signature = {};
                    fillSignature(kind, returnToken, returnTokenRequired, yieldAndGeneratorParameterContext, signature);
                    return signature;
                }
                function fillSignature(kind, returnToken, returnTokenRequired, yieldAndGeneratorParameterContext, signature) {
                    if (kind === 131 /* ConstructSignature */) {
                        parseExpected(86 /* NewKeyword */);
                    }
                    signature.typeParameters = parseTypeParameters();
                    signature.parameters = parseParameterList(yieldAndGeneratorParameterContext);
                    if (returnTokenRequired) {
                        parseExpected(returnToken);
                        signature.type = parseType();
                    }
                    else if (parseOptional(returnToken)) {
                        signature.type = parseType();
                    }
                }
                function parseParameterList(yieldAndGeneratorParameterContext) {
                    if (parseExpected(15 /* OpenParenToken */)) {
                        var savedYieldContext = inYieldContext();
                        var savedGeneratorParameterContext = inGeneratorParameterContext();
                        setYieldContext(yieldAndGeneratorParameterContext);
                        setGeneratorParameterContext(yieldAndGeneratorParameterContext);
                        var result = parseDelimitedList(13 /* Parameters */, parseParameter);
                        parseExpected(16 /* CloseParenToken */);
                        setYieldContext(savedYieldContext);
                        setGeneratorParameterContext(savedGeneratorParameterContext);
                        return result;
                    }
                    return createMissingList();
                }
                function parseSignatureMember(kind, returnToken) {
                    var node = createNode(kind);
                    fillSignature(kind, returnToken, false, false, node);
                    parseSemicolon();
                    return finishNode(node);
                }
                function isIndexSignature() {
                    if (token !== 17 /* OpenBracketToken */) {
                        return false;
                    }
                    return lookAhead(function () {
                        if (nextToken() === 20 /* DotDotDotToken */ || token === 18 /* CloseBracketToken */) {
                            return true;
                        }
                        if (isModifier(token)) {
                            nextToken();
                            if (isIdentifier()) {
                                return true;
                            }
                        }
                        else if (!isIdentifier()) {
                            return false;
                        }
                        else {
                            nextToken();
                        }
                        if (token === 50 /* ColonToken */ || token === 22 /* CommaToken */) {
                            return true;
                        }
                        if (token !== 49 /* QuestionToken */) {
                            return false;
                        }
                        return nextToken() === 50 /* ColonToken */ || token === 22 /* CommaToken */ || token === 18 /* CloseBracketToken */;
                    });
                }
                function parseIndexSignatureMember(fullStart, modifiers) {
                    var node = createNode(132 /* IndexSignature */, fullStart);
                    setModifiers(node, modifiers);
                    node.parameters = parseBracketedList(13 /* Parameters */, parseParameter, 17 /* OpenBracketToken */, 18 /* CloseBracketToken */);
                    node.type = parseTypeAnnotation();
                    parseSemicolon();
                    return finishNode(node);
                }
                function parsePropertyOrMethod() {
                    var fullStart = scanner.getStartPos();
                    var name = parsePropertyName();
                    var flags = 0;
                    if (parseOptional(49 /* QuestionToken */)) {
                        flags = 4 /* QuestionMark */;
                    }
                    if (token === 15 /* OpenParenToken */ || token === 23 /* LessThanToken */) {
                        var method = createNode(126 /* Method */, fullStart);
                        method.name = name;
                        method.flags = flags;
                        fillSignature(130 /* CallSignature */, 50 /* ColonToken */, false, false, method);
                        parseSemicolon();
                        return finishNode(method);
                    }
                    else {
                        var property = createNode(125 /* Property */, fullStart);
                        property.name = name;
                        property.flags = flags;
                        property.type = parseTypeAnnotation();
                        parseSemicolon();
                        return finishNode(property);
                    }
                }
                function isStartOfTypeMember() {
                    switch (token) {
                        case 15 /* OpenParenToken */:
                        case 23 /* LessThanToken */:
                        case 17 /* OpenBracketToken */:
                            return true;
                        default:
                            return isLiteralPropertyName() && lookAhead(function () { return nextToken() === 15 /* OpenParenToken */ || token === 23 /* LessThanToken */ || token === 49 /* QuestionToken */ || token === 50 /* ColonToken */ || canParseSemicolon(); });
                    }
                }
                function parseTypeMember() {
                    switch (token) {
                        case 15 /* OpenParenToken */:
                        case 23 /* LessThanToken */:
                            return parseSignatureMember(130 /* CallSignature */, 50 /* ColonToken */);
                        case 17 /* OpenBracketToken */:
                            return isIndexSignature() ? parseIndexSignatureMember(scanner.getStartPos(), undefined) : parsePropertyOrMethod();
                        case 86 /* NewKeyword */:
                            if (lookAhead(function () { return nextToken() === 15 /* OpenParenToken */ || token === 23 /* LessThanToken */; })) {
                                return parseSignatureMember(131 /* ConstructSignature */, 50 /* ColonToken */);
                            }
                        case 7 /* StringLiteral */:
                        case 6 /* NumericLiteral */:
                            return parsePropertyOrMethod();
                        default:
                            if (token >= 63 /* Identifier */) {
                                return parsePropertyOrMethod();
                            }
                    }
                }
                function parseTypeLiteral() {
                    var node = createNode(137 /* TypeLiteral */);
                    node.members = parseObjectType();
                    return finishNode(node);
                }
                function parseObjectType() {
                    var members;
                    if (parseExpected(13 /* OpenBraceToken */)) {
                        members = parseList(5 /* TypeMembers */, false, parseTypeMember);
                        parseExpected(14 /* CloseBraceToken */);
                    }
                    else {
                        members = createMissingList();
                    }
                    return members;
                }
                function parseTupleType() {
                    var node = createNode(139 /* TupleType */);
                    node.elementTypes = parseBracketedList(16 /* TupleElementTypes */, parseType, 17 /* OpenBracketToken */, 18 /* CloseBracketToken */);
                    return finishNode(node);
                }
                function parseParenType() {
                    var node = createNode(141 /* ParenType */);
                    parseExpected(15 /* OpenParenToken */);
                    node.type = parseType();
                    parseExpected(16 /* CloseParenToken */);
                    return finishNode(node);
                }
                function parseFunctionType(typeKind) {
                    var node = createNode(typeKind);
                    fillSignature(typeKind === 134 /* FunctionType */ ? 130 /* CallSignature */ : 131 /* ConstructSignature */, 31 /* EqualsGreaterThanToken */, true, false, node);
                    return finishNode(node);
                }
                function parseKeywordAndNoDot() {
                    var node = parseTokenNode();
                    return token === 19 /* DotToken */ ? undefined : node;
                }
                function parseNonArrayType() {
                    switch (token) {
                        case 109 /* AnyKeyword */:
                        case 118 /* StringKeyword */:
                        case 116 /* NumberKeyword */:
                        case 110 /* BooleanKeyword */:
                        case 97 /* VoidKeyword */:
                            var node = tryParse(parseKeywordAndNoDot);
                            return node || parseTypeReference();
                        case 95 /* TypeOfKeyword */:
                            return parseTypeQuery();
                        case 13 /* OpenBraceToken */:
                            return parseTypeLiteral();
                        case 17 /* OpenBracketToken */:
                            return parseTupleType();
                        case 15 /* OpenParenToken */:
                            return parseParenType();
                        default:
                            if (isIdentifier()) {
                                return parseTypeReference();
                            }
                    }
                    error(ts.Diagnostics.Type_expected);
                    return createMissingNode();
                }
                function isStartOfType() {
                    switch (token) {
                        case 109 /* AnyKeyword */:
                        case 118 /* StringKeyword */:
                        case 116 /* NumberKeyword */:
                        case 110 /* BooleanKeyword */:
                        case 97 /* VoidKeyword */:
                        case 95 /* TypeOfKeyword */:
                        case 13 /* OpenBraceToken */:
                        case 17 /* OpenBracketToken */:
                        case 23 /* LessThanToken */:
                        case 86 /* NewKeyword */:
                            return true;
                        case 15 /* OpenParenToken */:
                            return lookAhead(function () {
                                nextToken();
                                return token === 16 /* CloseParenToken */ || isStartOfParameter() || isStartOfType();
                            });
                        default:
                            return isIdentifier();
                    }
                }
                function parsePrimaryType() {
                    var type = parseNonArrayType();
                    while (!scanner.hasPrecedingLineBreak() && parseOptional(17 /* OpenBracketToken */)) {
                        parseExpected(18 /* CloseBracketToken */);
                        var node = createNode(138 /* ArrayType */, type.pos);
                        node.elementType = type;
                        type = finishNode(node);
                    }
                    return type;
                }
                function parseUnionType() {
                    var type = parsePrimaryType();
                    if (token === 43 /* BarToken */) {
                        var types = [type];
                        types.pos = type.pos;
                        while (parseOptional(43 /* BarToken */)) {
                            types.push(parsePrimaryType());
                        }
                        types.end = getNodeEnd();
                        var node = createNode(140 /* UnionType */, type.pos);
                        node.types = types;
                        type = finishNode(node);
                    }
                    return type;
                }
                function isStartOfFunctionType() {
                    return token === 23 /* LessThanToken */ || token === 15 /* OpenParenToken */ && lookAhead(function () {
                        nextToken();
                        if (token === 16 /* CloseParenToken */ || token === 20 /* DotDotDotToken */) {
                            return true;
                        }
                        if (isIdentifier() || isModifier(token)) {
                            nextToken();
                            if (token === 50 /* ColonToken */ || token === 22 /* CommaToken */ || token === 49 /* QuestionToken */ || token === 51 /* EqualsToken */ || isIdentifier() || isModifier(token)) {
                                return true;
                            }
                            if (token === 16 /* CloseParenToken */) {
                                nextToken();
                                if (token === 31 /* EqualsGreaterThanToken */) {
                                    return true;
                                }
                            }
                        }
                        return false;
                    });
                }
                function parseType() {
                    var savedYieldContext = inYieldContext();
                    var savedGeneratorParameterContext = inGeneratorParameterContext();
                    setYieldContext(false);
                    setGeneratorParameterContext(false);
                    var result = parseTypeWorker();
                    setYieldContext(savedYieldContext);
                    setGeneratorParameterContext(savedGeneratorParameterContext);
                    return result;
                }
                function parseTypeWorker() {
                    if (isStartOfFunctionType()) {
                        return parseFunctionType(134 /* FunctionType */);
                    }
                    if (token === 86 /* NewKeyword */) {
                        return parseFunctionType(135 /* ConstructorType */);
                    }
                    return parseUnionType();
                }
                function parseTypeAnnotation() {
                    return parseOptional(50 /* ColonToken */) ? parseType() : undefined;
                }
                function isStartOfExpression() {
                    switch (token) {
                        case 91 /* ThisKeyword */:
                        case 89 /* SuperKeyword */:
                        case 87 /* NullKeyword */:
                        case 93 /* TrueKeyword */:
                        case 78 /* FalseKeyword */:
                        case 6 /* NumericLiteral */:
                        case 7 /* StringLiteral */:
                        case 9 /* NoSubstitutionTemplateLiteral */:
                        case 10 /* TemplateHead */:
                        case 15 /* OpenParenToken */:
                        case 17 /* OpenBracketToken */:
                        case 13 /* OpenBraceToken */:
                        case 81 /* FunctionKeyword */:
                        case 86 /* NewKeyword */:
                        case 35 /* SlashToken */:
                        case 55 /* SlashEqualsToken */:
                        case 32 /* PlusToken */:
                        case 33 /* MinusToken */:
                        case 46 /* TildeToken */:
                        case 45 /* ExclamationToken */:
                        case 72 /* DeleteKeyword */:
                        case 95 /* TypeOfKeyword */:
                        case 97 /* VoidKeyword */:
                        case 37 /* PlusPlusToken */:
                        case 38 /* MinusMinusToken */:
                        case 23 /* LessThanToken */:
                        case 63 /* Identifier */:
                        case 108 /* YieldKeyword */:
                            return true;
                        default:
                            return isIdentifier();
                    }
                }
                function isStartOfExpressionStatement() {
                    return token !== 13 /* OpenBraceToken */ && token !== 81 /* FunctionKeyword */ && isStartOfExpression();
                }
                function parseExpression() {
                    var expr = parseAssignmentExpression();
                    while (parseOptional(22 /* CommaToken */)) {
                        expr = makeBinaryExpression(expr, 22 /* CommaToken */, parseAssignmentExpression());
                    }
                    return expr;
                }
                function parseInitializer(inParameter) {
                    if (token !== 51 /* EqualsToken */) {
                        if (scanner.hasPrecedingLineBreak() || (inParameter && token === 13 /* OpenBraceToken */) || !isStartOfExpression()) {
                            return undefined;
                        }
                    }
                    parseExpected(51 /* EqualsToken */);
                    return parseAssignmentExpression();
                }
                function parseAssignmentExpression() {
                    if (isYieldExpression()) {
                        return parseYieldExpression();
                    }
                    var arrowExpression = tryParseParenthesizedArrowFunctionExpression();
                    if (arrowExpression) {
                        return arrowExpression;
                    }
                    var expr = parseConditionalExpression();
                    if (expr.kind === 63 /* Identifier */ && token === 31 /* EqualsGreaterThanToken */) {
                        return parseSimpleArrowFunctionExpression(expr);
                    }
                    if (isLeftHandSideExpression(expr) && isAssignmentOperator(token)) {
                        var operator = token;
                        nextToken();
                        return makeBinaryExpression(expr, operator, parseAssignmentExpression());
                    }
                    return expr;
                }
                function isYieldExpression() {
                    if (token === 108 /* YieldKeyword */) {
                        if (inYieldContext()) {
                            return true;
                        }
                        if (inStrictModeContext()) {
                            return true;
                        }
                        return lookAhead(function () {
                            nextToken();
                            return !scanner.hasPrecedingLineBreak() && isIdentifier();
                        });
                    }
                    return false;
                }
                function parseYieldExpression() {
                    var node = createNode(161 /* YieldExpression */);
                    nextToken();
                    if (!scanner.hasPrecedingLineBreak() && (token === 34 /* AsteriskToken */ || isStartOfExpression())) {
                        node.asteriskToken = parseOptionalToken(34 /* AsteriskToken */);
                        node.expression = parseAssignmentExpression();
                        return finishNode(node);
                    }
                    else {
                        return finishNode(node);
                    }
                }
                function parseSimpleArrowFunctionExpression(identifier) {
                    ts.Debug.assert(token === 31 /* EqualsGreaterThanToken */, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
                    parseExpected(31 /* EqualsGreaterThanToken */);
                    var parameter = createNode(124 /* Parameter */, identifier.pos);
                    parameter.name = identifier;
                    finishNode(parameter);
                    var parameters = [];
                    parameters.push(parameter);
                    parameters.pos = parameter.pos;
                    parameters.end = parameter.end;
                    var signature = { parameters: parameters };
                    return parseArrowExpressionTail(identifier.pos, signature);
                }
                function tryParseParenthesizedArrowFunctionExpression() {
                    var triState = isParenthesizedArrowFunctionExpression();
                    if (triState === 0 /* False */) {
                        return undefined;
                    }
                    var pos = getNodePos();
                    if (triState === 1 /* True */) {
                        var sig = parseSignature(130 /* CallSignature */, 50 /* ColonToken */, false, false);
                        if (parseExpected(31 /* EqualsGreaterThanToken */) || token === 13 /* OpenBraceToken */) {
                            return parseArrowExpressionTail(pos, sig);
                        }
                        else {
                            return makeFunctionExpression(154 /* ArrowFunction */, pos, undefined, undefined, sig, createMissingNode());
                        }
                    }
                    var sig = tryParseSignatureIfArrowOrBraceFollows();
                    if (sig) {
                        parseExpected(31 /* EqualsGreaterThanToken */);
                        return parseArrowExpressionTail(pos, sig);
                    }
                    else {
                        return undefined;
                    }
                }
                function isParenthesizedArrowFunctionExpression() {
                    if (token === 15 /* OpenParenToken */ || token === 23 /* LessThanToken */) {
                        return lookAhead(function () {
                            var first = token;
                            var second = nextToken();
                            if (first === 15 /* OpenParenToken */) {
                                if (second === 16 /* CloseParenToken */) {
                                    var third = nextToken();
                                    switch (third) {
                                        case 31 /* EqualsGreaterThanToken */:
                                        case 50 /* ColonToken */:
                                        case 13 /* OpenBraceToken */:
                                            return 1 /* True */;
                                        default:
                                            return 0 /* False */;
                                    }
                                }
                                if (second === 20 /* DotDotDotToken */) {
                                    return 1 /* True */;
                                }
                                if (!isIdentifier()) {
                                    return 0 /* False */;
                                }
                                if (nextToken() === 50 /* ColonToken */) {
                                    return 1 /* True */;
                                }
                                return 2 /* Unknown */;
                            }
                            else {
                                ts.Debug.assert(first === 23 /* LessThanToken */);
                                if (!isIdentifier()) {
                                    return 0 /* False */;
                                }
                                return 2 /* Unknown */;
                            }
                        });
                    }
                    if (token === 31 /* EqualsGreaterThanToken */) {
                        return 1 /* True */;
                    }
                    return 0 /* False */;
                }
                function tryParseSignatureIfArrowOrBraceFollows() {
                    return tryParse(function () {
                        var sig = parseSignature(130 /* CallSignature */, 50 /* ColonToken */, false, false);
                        if (token === 31 /* EqualsGreaterThanToken */ || token === 13 /* OpenBraceToken */) {
                            return sig;
                        }
                        return undefined;
                    });
                }
                function parseArrowExpressionTail(pos, sig) {
                    var body;
                    if (token === 13 /* OpenBraceToken */) {
                        body = parseFunctionBlock(false, false);
                    }
                    else if (isStatement(true) && !isStartOfExpressionStatement() && token !== 81 /* FunctionKeyword */) {
                        body = parseFunctionBlock(false, true);
                    }
                    else {
                        body = parseAssignmentExpression();
                    }
                    return makeFunctionExpression(154 /* ArrowFunction */, pos, undefined, undefined, sig, body);
                }
                function parseConditionalExpression() {
                    var expr = parseBinaryOperators(parseUnaryExpression(), 0);
                    while (parseOptional(49 /* QuestionToken */)) {
                        var node = createNode(158 /* ConditionalExpression */, expr.pos);
                        node.condition = expr;
                        node.whenTrue = allowInAnd(parseAssignmentExpression);
                        parseExpected(50 /* ColonToken */);
                        node.whenFalse = parseAssignmentExpression();
                        expr = finishNode(node);
                    }
                    return expr;
                }
                function parseBinaryOperators(expr, minPrecedence) {
                    while (true) {
                        reScanGreaterToken();
                        var precedence = getOperatorPrecedence();
                        if (precedence && precedence > minPrecedence && (!inDisallowInContext() || token !== 84 /* InKeyword */)) {
                            var operator = token;
                            nextToken();
                            expr = makeBinaryExpression(expr, operator, parseBinaryOperators(parseUnaryExpression(), precedence));
                            continue;
                        }
                        return expr;
                    }
                }
                function getOperatorPrecedence() {
                    switch (token) {
                        case 48 /* BarBarToken */:
                            return 1;
                        case 47 /* AmpersandAmpersandToken */:
                            return 2;
                        case 43 /* BarToken */:
                            return 3;
                        case 44 /* CaretToken */:
                            return 4;
                        case 42 /* AmpersandToken */:
                            return 5;
                        case 27 /* EqualsEqualsToken */:
                        case 28 /* ExclamationEqualsToken */:
                        case 29 /* EqualsEqualsEqualsToken */:
                        case 30 /* ExclamationEqualsEqualsToken */:
                            return 6;
                        case 23 /* LessThanToken */:
                        case 24 /* GreaterThanToken */:
                        case 25 /* LessThanEqualsToken */:
                        case 26 /* GreaterThanEqualsToken */:
                        case 85 /* InstanceOfKeyword */:
                        case 84 /* InKeyword */:
                            return 7;
                        case 39 /* LessThanLessThanToken */:
                        case 40 /* GreaterThanGreaterThanToken */:
                        case 41 /* GreaterThanGreaterThanGreaterThanToken */:
                            return 8;
                        case 32 /* PlusToken */:
                        case 33 /* MinusToken */:
                            return 9;
                        case 34 /* AsteriskToken */:
                        case 35 /* SlashToken */:
                        case 36 /* PercentToken */:
                            return 10;
                    }
                    return undefined;
                }
                function makeBinaryExpression(left, operator, right) {
                    var node = createNode(157 /* BinaryExpression */, left.pos);
                    node.left = left;
                    node.operator = operator;
                    node.right = right;
                    return finishNode(node);
                }
                function parseUnaryExpression() {
                    var pos = getNodePos();
                    switch (token) {
                        case 32 /* PlusToken */:
                        case 33 /* MinusToken */:
                        case 46 /* TildeToken */:
                        case 45 /* ExclamationToken */:
                        case 72 /* DeleteKeyword */:
                        case 95 /* TypeOfKeyword */:
                        case 97 /* VoidKeyword */:
                        case 37 /* PlusPlusToken */:
                        case 38 /* MinusMinusToken */:
                            var operator = token;
                            nextToken();
                            return makeUnaryExpression(155 /* PrefixOperator */, pos, operator, parseUnaryExpression());
                        case 23 /* LessThanToken */:
                            return parseTypeAssertion();
                    }
                    var primaryExpression = parsePrimaryExpression();
                    var illegalUsageOfSuperKeyword = primaryExpression.kind === 89 /* SuperKeyword */ && token !== 15 /* OpenParenToken */ && token !== 19 /* DotToken */;
                    if (illegalUsageOfSuperKeyword) {
                        error(ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
                    }
                    var expr = parseCallAndAccess(primaryExpression, false);
                    ts.Debug.assert(isLeftHandSideExpression(expr));
                    if ((token === 37 /* PlusPlusToken */ || token === 38 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
                        var operator = token;
                        nextToken();
                        expr = makeUnaryExpression(156 /* PostfixOperator */, expr.pos, operator, expr);
                    }
                    return expr;
                }
                function parseTypeAssertion() {
                    var node = createNode(151 /* TypeAssertion */);
                    parseExpected(23 /* LessThanToken */);
                    node.type = parseType();
                    parseExpected(24 /* GreaterThanToken */);
                    node.operand = parseUnaryExpression();
                    return finishNode(node);
                }
                function makeUnaryExpression(kind, pos, operator, operand) {
                    var node = createNode(kind, pos);
                    node.operator = operator;
                    node.operand = operand;
                    return finishNode(node);
                }
                function parseCallAndAccess(expr, inNewExpression) {
                    while (true) {
                        var dotOrBracketStart = scanner.getTokenPos();
                        if (parseOptional(19 /* DotToken */)) {
                            var propertyAccess = createNode(146 /* PropertyAccess */, expr.pos);
                            var id;
                            if (scanner.hasPrecedingLineBreak() && scanner.isReservedWord()) {
                                var matchesPattern = lookAhead(function () {
                                    nextToken();
                                    return !scanner.hasPrecedingLineBreak() && (scanner.isIdentifier() || scanner.isReservedWord);
                                });
                                if (matchesPattern) {
                                    errorAtPos(dotOrBracketStart + 1, 0, ts.Diagnostics.Identifier_expected);
                                    id = createMissingNode();
                                }
                            }
                            propertyAccess.left = expr;
                            propertyAccess.right = id || parseIdentifierName();
                            expr = finishNode(propertyAccess);
                            continue;
                        }
                        if (parseOptional(17 /* OpenBracketToken */)) {
                            var indexedAccess = createNode(147 /* IndexedAccess */, expr.pos);
                            indexedAccess.object = expr;
                            if (inNewExpression && parseOptional(18 /* CloseBracketToken */)) {
                                indexedAccess.index = createMissingNode();
                            }
                            else {
                                indexedAccess.index = allowInAnd(parseExpression);
                                if (indexedAccess.index.kind === 7 /* StringLiteral */ || indexedAccess.index.kind === 6 /* NumericLiteral */) {
                                    var literal = indexedAccess.index;
                                    literal.text = internIdentifier(literal.text);
                                }
                                parseExpected(18 /* CloseBracketToken */);
                            }
                            expr = finishNode(indexedAccess);
                            continue;
                        }
                        if ((token === 15 /* OpenParenToken */ || token === 23 /* LessThanToken */) && !inNewExpression) {
                            var callExpr = createNode(148 /* CallExpression */, expr.pos);
                            callExpr.func = expr;
                            if (token === 23 /* LessThanToken */) {
                                if (!(callExpr.typeArguments = tryParse(parseTypeArgumentsAndOpenParen)))
                                    return expr;
                            }
                            else {
                                parseExpected(15 /* OpenParenToken */);
                            }
                            callExpr.arguments = parseDelimitedList(10 /* ArgumentExpressions */, parseArgumentExpression);
                            parseExpected(16 /* CloseParenToken */);
                            expr = finishNode(callExpr);
                            continue;
                        }
                        if (token === 9 /* NoSubstitutionTemplateLiteral */ || token === 10 /* TemplateHead */) {
                            var tagExpression = createNode(150 /* TaggedTemplateExpression */, expr.pos);
                            tagExpression.tag = expr;
                            tagExpression.template = token === 9 /* NoSubstitutionTemplateLiteral */ ? parseLiteralNode() : parseTemplateExpression();
                            expr = finishNode(tagExpression);
                            continue;
                        }
                        return expr;
                    }
                }
                function parseTypeArgumentsAndOpenParen() {
                    var result = parseTypeArguments();
                    parseExpected(15 /* OpenParenToken */);
                    return result;
                }
                function parseTypeArguments() {
                    return parseBracketedList(15 /* TypeArguments */, parseSingleTypeArgument, 23 /* LessThanToken */, 24 /* GreaterThanToken */);
                }
                function parseSingleTypeArgument() {
                    if (token === 22 /* CommaToken */) {
                        return createNode(120 /* Missing */);
                    }
                    return parseType();
                }
                function parsePrimaryExpression() {
                    switch (token) {
                        case 91 /* ThisKeyword */:
                        case 89 /* SuperKeyword */:
                        case 87 /* NullKeyword */:
                        case 93 /* TrueKeyword */:
                        case 78 /* FalseKeyword */:
                            return parseTokenNode();
                        case 6 /* NumericLiteral */:
                        case 7 /* StringLiteral */:
                        case 9 /* NoSubstitutionTemplateLiteral */:
                            return parseLiteralNode();
                        case 15 /* OpenParenToken */:
                            return parseParenExpression();
                        case 17 /* OpenBracketToken */:
                            return parseArrayLiteral();
                        case 13 /* OpenBraceToken */:
                            return parseObjectLiteral();
                        case 81 /* FunctionKeyword */:
                            return parseFunctionExpression();
                        case 86 /* NewKeyword */:
                            return parseNewExpression();
                        case 35 /* SlashToken */:
                        case 55 /* SlashEqualsToken */:
                            if (reScanSlashToken() === 8 /* RegularExpressionLiteral */) {
                                return parseLiteralNode();
                            }
                            break;
                        case 10 /* TemplateHead */:
                            return parseTemplateExpression();
                        default:
                            if (isIdentifier()) {
                                return parseIdentifier();
                            }
                    }
                    error(ts.Diagnostics.Expression_expected);
                    return createMissingNode();
                }
                function parseParenExpression() {
                    var node = createNode(152 /* ParenExpression */);
                    parseExpected(15 /* OpenParenToken */);
                    node.expression = allowInAnd(parseExpression);
                    parseExpected(16 /* CloseParenToken */);
                    return finishNode(node);
                }
                function parseAssignmentExpressionOrOmittedExpression() {
                    return token === 22 /* CommaToken */ ? createNode(162 /* OmittedExpression */) : parseAssignmentExpression();
                }
                function parseArrayLiteralElement() {
                    return parseAssignmentExpressionOrOmittedExpression();
                }
                function parseArgumentExpression() {
                    return allowInAnd(parseAssignmentExpressionOrOmittedExpression);
                }
                function parseArrayLiteral() {
                    var node = createNode(142 /* ArrayLiteral */);
                    parseExpected(17 /* OpenBracketToken */);
                    if (scanner.hasPrecedingLineBreak())
                        node.flags |= 256 /* MultiLine */;
                    node.elements = parseDelimitedList(12 /* ArrayLiteralMembers */, parseArrayLiteralElement);
                    parseExpected(18 /* CloseBracketToken */);
                    return finishNode(node);
                }
                function parsePropertyAssignment() {
                    var nodePos = scanner.getStartPos();
                    var asteriskToken = parseOptionalToken(34 /* AsteriskToken */);
                    var tokenIsIdentifier = isIdentifier();
                    var nameToken = token;
                    var propertyName = parsePropertyName();
                    var node;
                    if (asteriskToken || token === 15 /* OpenParenToken */ || token === 23 /* LessThanToken */) {
                        node = createNode(144 /* PropertyAssignment */, nodePos);
                        node.name = propertyName;
                        var sig = parseSignature(130 /* CallSignature */, 50 /* ColonToken */, false, !!asteriskToken);
                        var body = parseFunctionBlock(!!asteriskToken, false);
                        node.initializer = makeFunctionExpression(153 /* FunctionExpression */, node.pos, asteriskToken, undefined, sig, body);
                        return finishNode(node);
                    }
                    var flags = 0;
                    if (token === 49 /* QuestionToken */) {
                        flags |= 4 /* QuestionMark */;
                        nextToken();
                    }
                    if ((token === 22 /* CommaToken */ || token === 14 /* CloseBraceToken */) && tokenIsIdentifier) {
                        node = createNode(145 /* ShorthandPropertyAssignment */, nodePos);
                        node.name = propertyName;
                    }
                    else {
                        node = createNode(144 /* PropertyAssignment */, nodePos);
                        node.name = propertyName;
                        parseExpected(50 /* ColonToken */);
                        node.initializer = allowInAnd(parseAssignmentExpression);
                    }
                    node.flags = flags;
                    return finishNode(node);
                }
                function parseObjectLiteralMember() {
                    var initialPos = getNodePos();
                    var initialToken = token;
                    if (parseContextualModifier(113 /* GetKeyword */) || parseContextualModifier(117 /* SetKeyword */)) {
                        var kind = initialToken === 113 /* GetKeyword */ ? 128 /* GetAccessor */ : 129 /* SetAccessor */;
                        return parseMemberAccessorDeclaration(kind, initialPos, undefined);
                    }
                    return parsePropertyAssignment();
                }
                function parseObjectLiteral() {
                    var node = createNode(143 /* ObjectLiteral */);
                    parseExpected(13 /* OpenBraceToken */);
                    if (scanner.hasPrecedingLineBreak()) {
                        node.flags |= 256 /* MultiLine */;
                    }
                    node.properties = parseDelimitedList(11 /* ObjectLiteralMembers */, parseObjectLiteralMember);
                    parseExpected(14 /* CloseBraceToken */);
                    return finishNode(node);
                }
                function parseFunctionExpression() {
                    var pos = getNodePos();
                    parseExpected(81 /* FunctionKeyword */);
                    var asteriskToken = parseOptionalToken(34 /* AsteriskToken */);
                    var name = asteriskToken ? doInYieldContext(parseOptionalIdentifier) : parseOptionalIdentifier();
                    var sig = parseSignature(130 /* CallSignature */, 50 /* ColonToken */, false, !!asteriskToken);
                    var body = parseFunctionBlock(!!asteriskToken, false);
                    return makeFunctionExpression(153 /* FunctionExpression */, pos, asteriskToken, name, sig, body);
                }
                function parseOptionalIdentifier() {
                    return isIdentifier() ? parseIdentifier() : undefined;
                }
                function makeFunctionExpression(kind, pos, asteriskToken, name, sig, body) {
                    var node = createNode(kind, pos);
                    node.asteriskToken = asteriskToken;
                    node.name = name;
                    node.typeParameters = sig.typeParameters;
                    node.parameters = sig.parameters;
                    node.type = sig.type;
                    node.body = body;
                    return finishNode(node);
                }
                function parseNewExpression() {
                    var node = createNode(149 /* NewExpression */);
                    parseExpected(86 /* NewKeyword */);
                    node.func = parseCallAndAccess(parsePrimaryExpression(), true);
                    if (parseOptional(15 /* OpenParenToken */) || token === 23 /* LessThanToken */ && (node.typeArguments = tryParse(parseTypeArgumentsAndOpenParen))) {
                        node.arguments = parseDelimitedList(10 /* ArgumentExpressions */, parseArgumentExpression);
                        parseExpected(16 /* CloseParenToken */);
                    }
                    return finishNode(node);
                }
                function parseBlock(ignoreMissingOpenBrace, checkForStrictMode) {
                    var node = createNode(163 /* Block */);
                    if (parseExpected(13 /* OpenBraceToken */) || ignoreMissingOpenBrace) {
                        node.statements = parseList(2 /* BlockStatements */, checkForStrictMode, parseStatement);
                        parseExpected(14 /* CloseBraceToken */);
                    }
                    else {
                        node.statements = createMissingList();
                    }
                    return finishNode(node);
                }
                function parseFunctionBlock(allowYield, ignoreMissingOpenBrace) {
                    var savedYieldContext = inYieldContext();
                    setYieldContext(allowYield);
                    var block = parseBlock(ignoreMissingOpenBrace, true);
                    block.kind = 188 /* FunctionBlock */;
                    setYieldContext(savedYieldContext);
                    return block;
                }
                function parseEmptyStatement() {
                    var node = createNode(165 /* EmptyStatement */);
                    parseExpected(21 /* SemicolonToken */);
                    return finishNode(node);
                }
                function parseIfStatement() {
                    var node = createNode(167 /* IfStatement */);
                    parseExpected(82 /* IfKeyword */);
                    parseExpected(15 /* OpenParenToken */);
                    node.expression = allowInAnd(parseExpression);
                    parseExpected(16 /* CloseParenToken */);
                    node.thenStatement = parseStatement();
                    node.elseStatement = parseOptional(74 /* ElseKeyword */) ? parseStatement() : undefined;
                    return finishNode(node);
                }
                function parseDoStatement() {
                    var node = createNode(168 /* DoStatement */);
                    parseExpected(73 /* DoKeyword */);
                    node.statement = parseStatement();
                    parseExpected(98 /* WhileKeyword */);
                    parseExpected(15 /* OpenParenToken */);
                    node.expression = allowInAnd(parseExpression);
                    parseExpected(16 /* CloseParenToken */);
                    parseOptional(21 /* SemicolonToken */);
                    return finishNode(node);
                }
                function parseWhileStatement() {
                    var node = createNode(169 /* WhileStatement */);
                    parseExpected(98 /* WhileKeyword */);
                    parseExpected(15 /* OpenParenToken */);
                    node.expression = allowInAnd(parseExpression);
                    parseExpected(16 /* CloseParenToken */);
                    node.statement = parseStatement();
                    return finishNode(node);
                }
                function parseForOrForInStatement() {
                    var pos = getNodePos();
                    parseExpected(80 /* ForKeyword */);
                    parseExpected(15 /* OpenParenToken */);
                    if (token !== 21 /* SemicolonToken */) {
                        if (parseOptional(96 /* VarKeyword */)) {
                            var declarations = disallowInAnd(parseVariableDeclarationList);
                        }
                        else if (parseOptional(102 /* LetKeyword */)) {
                            var declarations = setFlag(disallowInAnd(parseVariableDeclarationList), 2048 /* Let */);
                        }
                        else if (parseOptional(68 /* ConstKeyword */)) {
                            var declarations = setFlag(disallowInAnd(parseVariableDeclarationList), 4096 /* Const */);
                        }
                        else {
                            var varOrInit = disallowInAnd(parseExpression);
                        }
                    }
                    var forOrForInStatement;
                    if (parseOptional(84 /* InKeyword */)) {
                        var forInStatement = createNode(171 /* ForInStatement */, pos);
                        if (declarations) {
                            forInStatement.declarations = declarations;
                        }
                        else {
                            forInStatement.variable = varOrInit;
                        }
                        forInStatement.expression = allowInAnd(parseExpression);
                        parseExpected(16 /* CloseParenToken */);
                        forOrForInStatement = forInStatement;
                    }
                    else {
                        var forStatement = createNode(170 /* ForStatement */, pos);
                        if (declarations) {
                            forStatement.declarations = declarations;
                        }
                        if (varOrInit) {
                            forStatement.initializer = varOrInit;
                        }
                        parseExpected(21 /* SemicolonToken */);
                        if (token !== 21 /* SemicolonToken */ && token !== 16 /* CloseParenToken */) {
                            forStatement.condition = allowInAnd(parseExpression);
                        }
                        parseExpected(21 /* SemicolonToken */);
                        if (token !== 16 /* CloseParenToken */) {
                            forStatement.iterator = allowInAnd(parseExpression);
                        }
                        parseExpected(16 /* CloseParenToken */);
                        forOrForInStatement = forStatement;
                    }
                    forOrForInStatement.statement = parseStatement();
                    return finishNode(forOrForInStatement);
                }
                function parseBreakOrContinueStatement(kind) {
                    var node = createNode(kind);
                    parseExpected(kind === 173 /* BreakStatement */ ? 64 /* BreakKeyword */ : 69 /* ContinueKeyword */);
                    if (!canParseSemicolon()) {
                        node.label = parseIdentifier();
                    }
                    parseSemicolon();
                    return finishNode(node);
                }
                function parseReturnStatement() {
                    var node = createNode(174 /* ReturnStatement */);
                    parseExpected(88 /* ReturnKeyword */);
                    if (!canParseSemicolon()) {
                        node.expression = allowInAnd(parseExpression);
                    }
                    parseSemicolon();
                    return finishNode(node);
                }
                function parseWithStatement() {
                    var node = createNode(175 /* WithStatement */);
                    parseExpected(99 /* WithKeyword */);
                    parseExpected(15 /* OpenParenToken */);
                    node.expression = allowInAnd(parseExpression);
                    parseExpected(16 /* CloseParenToken */);
                    node.statement = parseStatement();
                    return finishNode(node);
                }
                function parseCaseClause() {
                    var node = createNode(177 /* CaseClause */);
                    parseExpected(65 /* CaseKeyword */);
                    node.expression = allowInAnd(parseExpression);
                    parseExpected(50 /* ColonToken */);
                    node.statements = parseList(4 /* SwitchClauseStatements */, false, parseStatement);
                    return finishNode(node);
                }
                function parseDefaultClause() {
                    var node = createNode(178 /* DefaultClause */);
                    parseExpected(71 /* DefaultKeyword */);
                    parseExpected(50 /* ColonToken */);
                    node.statements = parseList(4 /* SwitchClauseStatements */, false, parseStatement);
                    return finishNode(node);
                }
                function parseCaseOrDefaultClause() {
                    return token === 65 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
                }
                function parseSwitchStatement() {
                    var node = createNode(176 /* SwitchStatement */);
                    parseExpected(90 /* SwitchKeyword */);
                    parseExpected(15 /* OpenParenToken */);
                    node.expression = allowInAnd(parseExpression);
                    parseExpected(16 /* CloseParenToken */);
                    parseExpected(13 /* OpenBraceToken */);
                    node.clauses = parseList(3 /* SwitchClauses */, false, parseCaseOrDefaultClause);
                    parseExpected(14 /* CloseBraceToken */);
                    return finishNode(node);
                }
                function parseThrowStatement() {
                    var node = createNode(180 /* ThrowStatement */);
                    parseExpected(92 /* ThrowKeyword */);
                    if (scanner.hasPrecedingLineBreak()) {
                        error(ts.Diagnostics.Line_break_not_permitted_here);
                    }
                    node.expression = allowInAnd(parseExpression);
                    parseSemicolon();
                    return finishNode(node);
                }
                function parseTryStatement() {
                    var node = createNode(181 /* TryStatement */);
                    node.tryBlock = parseTokenAndBlock(94 /* TryKeyword */, 182 /* TryBlock */);
                    if (token === 66 /* CatchKeyword */) {
                        node.catchBlock = parseCatchBlock();
                    }
                    if (token === 79 /* FinallyKeyword */) {
                        node.finallyBlock = parseTokenAndBlock(79 /* FinallyKeyword */, 184 /* FinallyBlock */);
                    }
                    if (!(node.catchBlock || node.finallyBlock)) {
                        error(ts.Diagnostics.catch_or_finally_expected);
                    }
                    return finishNode(node);
                }
                function parseTokenAndBlock(token, kind) {
                    var pos = getNodePos();
                    parseExpected(token);
                    var result = parseBlock(false, false);
                    result.kind = kind;
                    result.pos = pos;
                    return result;
                }
                function parseCatchBlock() {
                    var pos = getNodePos();
                    parseExpected(66 /* CatchKeyword */);
                    parseExpected(15 /* OpenParenToken */);
                    var variable = parseIdentifier();
                    var typeAnnotation = parseTypeAnnotation();
                    parseExpected(16 /* CloseParenToken */);
                    var result = parseBlock(false, false);
                    result.kind = 183 /* CatchBlock */;
                    result.pos = pos;
                    result.variable = variable;
                    result.type = typeAnnotation;
                    return result;
                }
                function parseDebuggerStatement() {
                    var node = createNode(185 /* DebuggerStatement */);
                    parseExpected(70 /* DebuggerKeyword */);
                    parseSemicolon();
                    return finishNode(node);
                }
                function isLabel() {
                    return isIdentifier() && lookAhead(function () { return nextToken() === 50 /* ColonToken */; });
                }
                function parseLabeledStatement() {
                    var node = createNode(179 /* LabeledStatement */);
                    node.label = parseIdentifier();
                    parseExpected(50 /* ColonToken */);
                    node.statement = parseStatement();
                    return finishNode(node);
                }
                function parseExpressionStatement() {
                    var node = createNode(166 /* ExpressionStatement */);
                    node.expression = allowInAnd(parseExpression);
                    parseSemicolon();
                    return finishNode(node);
                }
                function isStatement(inErrorRecovery) {
                    switch (token) {
                        case 21 /* SemicolonToken */:
                            return !inErrorRecovery;
                        case 13 /* OpenBraceToken */:
                        case 96 /* VarKeyword */:
                        case 102 /* LetKeyword */:
                        case 81 /* FunctionKeyword */:
                        case 82 /* IfKeyword */:
                        case 73 /* DoKeyword */:
                        case 98 /* WhileKeyword */:
                        case 80 /* ForKeyword */:
                        case 69 /* ContinueKeyword */:
                        case 64 /* BreakKeyword */:
                        case 88 /* ReturnKeyword */:
                        case 99 /* WithKeyword */:
                        case 90 /* SwitchKeyword */:
                        case 92 /* ThrowKeyword */:
                        case 94 /* TryKeyword */:
                        case 70 /* DebuggerKeyword */:
                        case 66 /* CatchKeyword */:
                        case 79 /* FinallyKeyword */:
                            return true;
                        case 68 /* ConstKeyword */:
                            var isConstEnum = lookAhead(function () { return nextToken() === 75 /* EnumKeyword */; });
                            return !isConstEnum;
                        case 101 /* InterfaceKeyword */:
                        case 67 /* ClassKeyword */:
                        case 114 /* ModuleKeyword */:
                        case 75 /* EnumKeyword */:
                        case 119 /* TypeKeyword */:
                            if (isDeclarationStart()) {
                                return false;
                            }
                        case 106 /* PublicKeyword */:
                        case 104 /* PrivateKeyword */:
                        case 105 /* ProtectedKeyword */:
                        case 107 /* StaticKeyword */:
                            if (lookAhead(function () { return nextToken() >= 63 /* Identifier */; })) {
                                return false;
                            }
                        default:
                            return isStartOfExpression();
                    }
                }
                function parseStatement() {
                    switch (token) {
                        case 13 /* OpenBraceToken */:
                            return parseBlock(false, false);
                        case 96 /* VarKeyword */:
                        case 102 /* LetKeyword */:
                        case 68 /* ConstKeyword */:
                            return parseVariableStatement(scanner.getStartPos(), undefined);
                        case 81 /* FunctionKeyword */:
                            return parseFunctionDeclaration(scanner.getStartPos(), undefined);
                        case 21 /* SemicolonToken */:
                            return parseEmptyStatement();
                        case 82 /* IfKeyword */:
                            return parseIfStatement();
                        case 73 /* DoKeyword */:
                            return parseDoStatement();
                        case 98 /* WhileKeyword */:
                            return parseWhileStatement();
                        case 80 /* ForKeyword */:
                            return parseForOrForInStatement();
                        case 69 /* ContinueKeyword */:
                            return parseBreakOrContinueStatement(172 /* ContinueStatement */);
                        case 64 /* BreakKeyword */:
                            return parseBreakOrContinueStatement(173 /* BreakStatement */);
                        case 88 /* ReturnKeyword */:
                            return parseReturnStatement();
                        case 99 /* WithKeyword */:
                            return parseWithStatement();
                        case 90 /* SwitchKeyword */:
                            return parseSwitchStatement();
                        case 92 /* ThrowKeyword */:
                            return parseThrowStatement();
                        case 94 /* TryKeyword */:
                        case 66 /* CatchKeyword */:
                        case 79 /* FinallyKeyword */:
                            return parseTryStatement();
                        case 70 /* DebuggerKeyword */:
                            return parseDebuggerStatement();
                        default:
                            return isLabel() ? parseLabeledStatement() : parseExpressionStatement();
                    }
                }
                function parseFunctionBlockOrSemicolon(isGenerator) {
                    if (token === 13 /* OpenBraceToken */) {
                        return parseFunctionBlock(isGenerator, false);
                    }
                    if (canParseSemicolon()) {
                        parseSemicolon();
                        return undefined;
                    }
                    error(ts.Diagnostics.Block_or_expected);
                }
                function parseVariableDeclaration() {
                    var node = createNode(186 /* VariableDeclaration */);
                    node.name = parseIdentifier();
                    node.type = parseTypeAnnotation();
                    node.initializer = parseInitializer(false);
                    return finishNode(node);
                }
                function setFlag(array, flag) {
                    for (var i = 0, n = array.length; i < n; i++) {
                        array[i].flags |= flag;
                    }
                    return array;
                }
                function parseVariableDeclarationList() {
                    return parseDelimitedList(9 /* VariableDeclarations */, parseVariableDeclaration);
                }
                function parseVariableStatement(fullStart, modifiers) {
                    var node = createNode(164 /* VariableStatement */, fullStart);
                    setModifiers(node, modifiers);
                    if (token === 102 /* LetKeyword */) {
                        node.flags |= 2048 /* Let */;
                    }
                    else if (token === 68 /* ConstKeyword */) {
                        node.flags |= 4096 /* Const */;
                    }
                    else {
                        ts.Debug.assert(token === 96 /* VarKeyword */);
                    }
                    nextToken();
                    node.declarations = allowInAnd(parseVariableDeclarationList);
                    setFlag(node.declarations, node.flags);
                    parseSemicolon();
                    return finishNode(node);
                }
                function parseFunctionDeclaration(fullStart, modifiers) {
                    var node = createNode(187 /* FunctionDeclaration */, fullStart);
                    setModifiers(node, modifiers);
                    parseExpected(81 /* FunctionKeyword */);
                    node.asteriskToken = parseOptionalToken(34 /* AsteriskToken */);
                    node.name = parseIdentifier();
                    fillSignature(130 /* CallSignature */, 50 /* ColonToken */, false, !!node.asteriskToken, node);
                    node.body = parseFunctionBlockOrSemicolon(!!node.asteriskToken);
                    return finishNode(node);
                }
                function parseConstructorDeclaration(pos, modifiers) {
                    var node = createNode(127 /* Constructor */, pos);
                    setModifiers(node, modifiers);
                    parseExpected(111 /* ConstructorKeyword */);
                    fillSignature(130 /* CallSignature */, 50 /* ColonToken */, false, false, node);
                    node.body = parseFunctionBlockOrSemicolon(false);
                    return finishNode(node);
                }
                function parsePropertyMemberDeclaration(fullStart, modifiers) {
                    var flags = modifiers ? modifiers.flags : 0;
                    var asteriskToken = parseOptionalToken(34 /* AsteriskToken */);
                    var name = parsePropertyName();
                    if (parseOptional(49 /* QuestionToken */)) {
                        flags |= 4 /* QuestionMark */;
                    }
                    if (asteriskToken || token === 15 /* OpenParenToken */ || token === 23 /* LessThanToken */) {
                        var method = createNode(126 /* Method */, fullStart);
                        setModifiers(method, modifiers);
                        if (flags) {
                            method.flags = flags;
                        }
                        method.asteriskToken = asteriskToken;
                        method.name = name;
                        fillSignature(130 /* CallSignature */, 50 /* ColonToken */, false, !!asteriskToken, method);
                        method.body = parseFunctionBlockOrSemicolon(!!asteriskToken);
                        return finishNode(method);
                    }
                    else {
                        var property = createNode(125 /* Property */, fullStart);
                        setModifiers(property, modifiers);
                        if (flags) {
                            property.flags = flags;
                        }
                        property.name = name;
                        property.type = parseTypeAnnotation();
                        property.initializer = allowInAnd(function () { return parseInitializer(false); });
                        parseSemicolon();
                        return finishNode(property);
                    }
                }
                function parseMemberAccessorDeclaration(kind, fullStart, modifiers) {
                    var node = createNode(kind, fullStart);
                    setModifiers(node, modifiers);
                    node.name = parsePropertyName();
                    fillSignature(130 /* CallSignature */, 50 /* ColonToken */, false, false, node);
                    node.body = parseFunctionBlockOrSemicolon(false);
                    return finishNode(node);
                }
                function isClassMemberStart() {
                    var idToken;
                    while (isModifier(token)) {
                        idToken = token;
                        nextToken();
                    }
                    if (token === 34 /* AsteriskToken */) {
                        return true;
                    }
                    if (isLiteralPropertyName()) {
                        idToken = token;
                        nextToken();
                    }
                    if (token === 17 /* OpenBracketToken */) {
                        return true;
                    }
                    if (idToken !== undefined) {
                        if (!isKeyword(idToken) || idToken === 117 /* SetKeyword */ || idToken === 113 /* GetKeyword */) {
                            return true;
                        }
                        switch (token) {
                            case 15 /* OpenParenToken */:
                            case 23 /* LessThanToken */:
                            case 50 /* ColonToken */:
                            case 51 /* EqualsToken */:
                            case 49 /* QuestionToken */:
                                return true;
                            default:
                                return canParseSemicolon();
                        }
                    }
                    return false;
                }
                function parseModifiers() {
                    var flags = 0;
                    var modifiers;
                    while (true) {
                        var modifierStart = scanner.getTokenPos();
                        var modifierKind = token;
                        if (!parseAnyContextualModifier()) {
                            break;
                        }
                        if (!modifiers) {
                            modifiers = [];
                        }
                        flags |= modifierToFlag(modifierKind);
                        modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
                    }
                    if (modifiers) {
                        modifiers.flags = flags;
                    }
                    return modifiers;
                }
                function parseClassMemberDeclaration() {
                    var fullStart = getNodePos();
                    var modifiers = parseModifiers();
                    if (parseContextualModifier(113 /* GetKeyword */)) {
                        return parseMemberAccessorDeclaration(128 /* GetAccessor */, fullStart, modifiers);
                    }
                    if (parseContextualModifier(117 /* SetKeyword */)) {
                        return parseMemberAccessorDeclaration(129 /* SetAccessor */, fullStart, modifiers);
                    }
                    if (token === 111 /* ConstructorKeyword */) {
                        return parseConstructorDeclaration(fullStart, modifiers);
                    }
                    if (isIndexSignature()) {
                        return parseIndexSignatureMember(fullStart, modifiers);
                    }
                    if (token >= 63 /* Identifier */ || token === 7 /* StringLiteral */ || token === 6 /* NumericLiteral */ || token === 34 /* AsteriskToken */ || token === 17 /* OpenBracketToken */) {
                        return parsePropertyMemberDeclaration(fullStart, modifiers);
                    }
                    ts.Debug.fail("Should not have attempted to parse class member declaration.");
                }
                function parseClassDeclaration(fullStart, modifiers) {
                    var node = createNode(189 /* ClassDeclaration */, fullStart);
                    setModifiers(node, modifiers);
                    parseExpected(67 /* ClassKeyword */);
                    node.name = parseIdentifier();
                    node.typeParameters = parseTypeParameters();
                    node.baseType = inGeneratorParameterContext() ? doOutsideOfYieldContext(parseClassBaseType) : parseClassBaseType();
                    if (parseOptional(100 /* ImplementsKeyword */)) {
                        node.implementedTypes = parseDelimitedList(8 /* BaseTypeReferences */, parseTypeReference);
                    }
                    if (parseExpected(13 /* OpenBraceToken */)) {
                        node.members = inGeneratorParameterContext() ? doOutsideOfYieldContext(parseClassMembers) : parseClassMembers();
                        parseExpected(14 /* CloseBraceToken */);
                    }
                    else {
                        node.members = createMissingList();
                    }
                    return finishNode(node);
                }
                function parseClassMembers() {
                    return parseList(6 /* ClassMembers */, false, parseClassMemberDeclaration);
                }
                function parseClassBaseType() {
                    return parseOptional(77 /* ExtendsKeyword */) ? parseTypeReference() : undefined;
                }
                function parseInterfaceDeclaration(fullStart, modifiers) {
                    var node = createNode(190 /* InterfaceDeclaration */, fullStart);
                    setModifiers(node, modifiers);
                    parseExpected(101 /* InterfaceKeyword */);
                    node.name = parseIdentifier();
                    node.typeParameters = parseTypeParameters();
                    if (parseOptional(77 /* ExtendsKeyword */)) {
                        node.baseTypes = parseDelimitedList(8 /* BaseTypeReferences */, parseTypeReference);
                    }
                    node.members = parseObjectType();
                    return finishNode(node);
                }
                function parseTypeAliasDeclaration(fullStart, modifiers) {
                    var node = createNode(191 /* TypeAliasDeclaration */, fullStart);
                    setModifiers(node, modifiers);
                    parseExpected(119 /* TypeKeyword */);
                    node.name = parseIdentifier();
                    parseExpected(51 /* EqualsToken */);
                    node.type = parseType();
                    parseSemicolon();
                    return finishNode(node);
                }
                function parseEnumMember() {
                    var node = createNode(197 /* EnumMember */, scanner.getStartPos());
                    node.name = parsePropertyName();
                    node.initializer = allowInAnd(function () { return parseInitializer(false); });
                    return finishNode(node);
                }
                function parseAndCheckEnumDeclaration(fullStart, flags) {
                    var node = createNode(192 /* EnumDeclaration */, fullStart);
                    node.flags = flags;
                    if (flags & 4096 /* Const */) {
                        parseExpected(68 /* ConstKeyword */);
                    }
                    parseExpected(75 /* EnumKeyword */);
                    node.name = parseIdentifier();
                    if (parseExpected(13 /* OpenBraceToken */)) {
                        node.members = parseDelimitedList(7 /* EnumMembers */, parseEnumMember);
                        parseExpected(14 /* CloseBraceToken */);
                    }
                    else {
                        node.members = createMissingList();
                    }
                    return finishNode(node);
                }
                function parseModuleBody() {
                    var node = createNode(194 /* ModuleBlock */, scanner.getStartPos());
                    if (parseExpected(13 /* OpenBraceToken */)) {
                        node.statements = parseList(1 /* ModuleElements */, false, parseModuleElement);
                        parseExpected(14 /* CloseBraceToken */);
                    }
                    else {
                        node.statements = createMissingList();
                    }
                    return finishNode(node);
                }
                function parseInternalModuleTail(fullStart, flags) {
                    var node = createNode(193 /* ModuleDeclaration */, fullStart);
                    node.flags = flags;
                    node.name = parseIdentifier();
                    node.body = parseOptional(19 /* DotToken */) ? parseInternalModuleTail(getNodePos(), 1 /* Export */) : parseModuleBody();
                    return finishNode(node);
                }
                function parseAmbientExternalModuleDeclaration(fullStart, flags) {
                    var node = createNode(193 /* ModuleDeclaration */, fullStart);
                    node.flags = flags;
                    node.name = parseStringLiteral();
                    node.body = parseModuleBody();
                    return finishNode(node);
                }
                function parseModuleDeclaration(fullStart, flags) {
                    parseExpected(114 /* ModuleKeyword */);
                    return token === 7 /* StringLiteral */ ? parseAmbientExternalModuleDeclaration(fullStart, flags) : parseInternalModuleTail(fullStart, flags);
                }
                function parseImportDeclaration(fullStart, modifiers) {
                    var node = createNode(195 /* ImportDeclaration */, fullStart);
                    setModifiers(node, modifiers);
                    parseExpected(83 /* ImportKeyword */);
                    node.name = parseIdentifier();
                    parseExpected(51 /* EqualsToken */);
                    var entityName = parseEntityName(false);
                    if (entityName.kind === 63 /* Identifier */ && entityName.text === "require" && parseOptional(15 /* OpenParenToken */)) {
                        node.externalModuleName = parseStringLiteral();
                        parseExpected(16 /* CloseParenToken */);
                    }
                    else {
                        node.entityName = entityName;
                    }
                    parseSemicolon();
                    return finishNode(node);
                }
                function parseExportAssignmentTail(fullStart, modifiers) {
                    var node = createNode(196 /* ExportAssignment */, fullStart);
                    setModifiers(node, modifiers);
                    node.exportName = parseIdentifier();
                    parseSemicolon();
                    return finishNode(node);
                }
                function isDeclarationStart() {
                    switch (token) {
                        case 96 /* VarKeyword */:
                        case 102 /* LetKeyword */:
                        case 68 /* ConstKeyword */:
                        case 81 /* FunctionKeyword */:
                            return true;
                        case 67 /* ClassKeyword */:
                        case 101 /* InterfaceKeyword */:
                        case 75 /* EnumKeyword */:
                        case 83 /* ImportKeyword */:
                        case 119 /* TypeKeyword */:
                            return lookAhead(function () { return nextToken() >= 63 /* Identifier */; });
                        case 114 /* ModuleKeyword */:
                            return lookAhead(function () { return nextToken() >= 63 /* Identifier */ || token === 7 /* StringLiteral */; });
                        case 76 /* ExportKeyword */:
                            return lookAhead(function () { return nextToken() === 51 /* EqualsToken */ || isDeclarationStart(); });
                        case 112 /* DeclareKeyword */:
                        case 106 /* PublicKeyword */:
                        case 104 /* PrivateKeyword */:
                        case 105 /* ProtectedKeyword */:
                        case 107 /* StaticKeyword */:
                            return lookAhead(function () {
                                nextToken();
                                return isDeclarationStart();
                            });
                    }
                }
                function parseDeclaration() {
                    var fullStart = getNodePos();
                    var modifiers = parseModifiers();
                    if (token === 76 /* ExportKeyword */) {
                        nextToken();
                        if (parseOptional(51 /* EqualsToken */)) {
                            return parseExportAssignmentTail(fullStart, modifiers);
                        }
                    }
                    var flags = modifiers ? modifiers.flags : 0;
                    var result;
                    switch (token) {
                        case 96 /* VarKeyword */:
                        case 102 /* LetKeyword */:
                            result = parseVariableStatement(fullStart, modifiers);
                            break;
                        case 68 /* ConstKeyword */:
                            var isConstEnum = lookAhead(function () { return nextToken() === 75 /* EnumKeyword */; });
                            if (isConstEnum) {
                                result = parseAndCheckEnumDeclaration(fullStart, flags | 4096 /* Const */);
                            }
                            else {
                                result = parseVariableStatement(fullStart, modifiers);
                            }
                            break;
                        case 81 /* FunctionKeyword */:
                            result = parseFunctionDeclaration(fullStart, modifiers);
                            break;
                        case 67 /* ClassKeyword */:
                            result = parseClassDeclaration(fullStart, modifiers);
                            break;
                        case 101 /* InterfaceKeyword */:
                            result = parseInterfaceDeclaration(fullStart, modifiers);
                            break;
                        case 119 /* TypeKeyword */:
                            result = parseTypeAliasDeclaration(fullStart, modifiers);
                            break;
                        case 75 /* EnumKeyword */:
                            result = parseAndCheckEnumDeclaration(fullStart, flags);
                            break;
                        case 114 /* ModuleKeyword */:
                            result = parseModuleDeclaration(fullStart, flags);
                            break;
                        case 83 /* ImportKeyword */:
                            result = parseImportDeclaration(fullStart, modifiers);
                            break;
                        default:
                            error(ts.Diagnostics.Declaration_expected);
                    }
                    if (modifiers) {
                        result.modifiers = modifiers;
                    }
                    return result;
                }
                function isSourceElement(inErrorRecovery) {
                    return isDeclarationStart() || isStatement(inErrorRecovery);
                }
                function parseSourceElement() {
                    return parseSourceElementOrModuleElement();
                }
                function parseModuleElement() {
                    return parseSourceElementOrModuleElement();
                }
                function parseSourceElementOrModuleElement() {
                    return isDeclarationStart() ? parseDeclaration() : parseStatement();
                }
                function processReferenceComments() {
                    var referencedFiles = [];
                    var amdDependencies = [];
                    var amdModuleName;
                    commentRanges = [];
                    token = scanner.scan();
                    for (var i = 0; i < commentRanges.length; i++) {
                        var range = commentRanges[i];
                        var comment = sourceText.substring(range.pos, range.end);
                        var referencePathMatchResult = getFileReferenceFromReferencePath(comment, range);
                        if (referencePathMatchResult) {
                            var fileReference = referencePathMatchResult.fileReference;
                            file.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
                            var diagnostic = referencePathMatchResult.diagnostic;
                            if (fileReference) {
                                referencedFiles.push(fileReference);
                            }
                            if (diagnostic) {
                                errorAtPos(range.pos, range.end - range.pos, diagnostic);
                            }
                        }
                        else {
                            var amdModuleNameRegEx = /^\/\/\/\s*<amd-module\s+name\s*=\s*('|")(.+?)\1/gim;
                            var amdModuleNameMatchResult = amdModuleNameRegEx.exec(comment);
                            if (amdModuleNameMatchResult) {
                                if (amdModuleName) {
                                    errorAtPos(range.pos, range.end - range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments);
                                }
                                amdModuleName = amdModuleNameMatchResult[2];
                            }
                            var amdDependencyRegEx = /^\/\/\/\s*<amd-dependency\s+path\s*=\s*('|")(.+?)\1/gim;
                            var amdDependencyMatchResult = amdDependencyRegEx.exec(comment);
                            if (amdDependencyMatchResult) {
                                amdDependencies.push(amdDependencyMatchResult[2]);
                            }
                        }
                    }
                    commentRanges = undefined;
                    return {
                        referencedFiles: referencedFiles,
                        amdDependencies: amdDependencies,
                        amdModuleName: amdModuleName
                    };
                }
                function getExternalModuleIndicator() {
                    return ts.forEach(file.statements, function (node) { return node.flags & 1 /* Export */ || node.kind === 195 /* ImportDeclaration */ && node.externalModuleName || node.kind === 196 /* ExportAssignment */ ? node : undefined; });
                }
                var syntacticDiagnostics;
                function getSyntacticDiagnostics() {
                    if (syntacticDiagnostics === undefined) {
                        if (file.parseDiagnostics.length > 0) {
                            syntacticDiagnostics = file.parseDiagnostics;
                        }
                        else {
                            syntacticDiagnostics = file.grammarDiagnostics;
                            checkGrammar(sourceText, languageVersion, file);
                        }
                    }
                    ts.Debug.assert(syntacticDiagnostics !== undefined);
                    return syntacticDiagnostics;
                }
                scanner = ts.createScanner(languageVersion, true, sourceText, scanError, onComment);
                var rootNodeFlags = 0;
                if (ts.fileExtensionIs(filename, ".d.ts")) {
                    rootNodeFlags = 1024 /* DeclarationFile */;
                }
                file = createRootNode(198 /* SourceFile */, 0, sourceText.length, rootNodeFlags);
                file.filename = ts.normalizePath(filename);
                file.text = sourceText;
                file.getLineAndCharacterFromPosition = getLineAndCharacterFromSourcePosition;
                file.getPositionFromLineAndCharacter = getPositionFromSourceLineAndCharacter;
                file.getLineStarts = getLineStarts;
                file.getSyntacticDiagnostics = getSyntacticDiagnostics;
                file.parseDiagnostics = [];
                file.grammarDiagnostics = [];
                file.semanticDiagnostics = [];
                var referenceComments = processReferenceComments();
                file.referencedFiles = referenceComments.referencedFiles;
                file.amdDependencies = referenceComments.amdDependencies;
                file.amdModuleName = referenceComments.amdModuleName;
                file.statements = parseList(0 /* SourceElements */, true, parseSourceElement);
                file.externalModuleIndicator = getExternalModuleIndicator();
                file.nodeCount = nodeCount;
                file.identifierCount = identifierCount;
                file.version = version;
                file.isOpen = isOpen;
                file.languageVersion = languageVersion;
                file.identifiers = identifiers;
                return file;
            }
            ts.createSourceFile = createSourceFile;
            function isLeftHandSideExpression(expr) {
                if (expr) {
                    switch (expr.kind) {
                        case 146 /* PropertyAccess */:
                        case 147 /* IndexedAccess */:
                        case 149 /* NewExpression */:
                        case 148 /* CallExpression */:
                        case 150 /* TaggedTemplateExpression */:
                        case 142 /* ArrayLiteral */:
                        case 152 /* ParenExpression */:
                        case 143 /* ObjectLiteral */:
                        case 153 /* FunctionExpression */:
                        case 63 /* Identifier */:
                        case 120 /* Missing */:
                        case 8 /* RegularExpressionLiteral */:
                        case 6 /* NumericLiteral */:
                        case 7 /* StringLiteral */:
                        case 9 /* NoSubstitutionTemplateLiteral */:
                        case 159 /* TemplateExpression */:
                        case 78 /* FalseKeyword */:
                        case 87 /* NullKeyword */:
                        case 91 /* ThisKeyword */:
                        case 93 /* TrueKeyword */:
                        case 89 /* SuperKeyword */:
                            return true;
                    }
                }
                return false;
            }
            function isAssignmentOperator(token) {
                return token >= 51 /* FirstAssignment */ && token <= 62 /* LastAssignment */;
            }
            function checkGrammar(sourceText, languageVersion, file) {
                var grammarDiagnostics = file.grammarDiagnostics;
                var scanner = ts.createScanner(languageVersion, true, sourceText);
                var inAmbientContext = ts.fileExtensionIs(file.filename, ".d.ts");
                var inFunctionBlock = false;
                var parent;
                visitNode(file);
                function visitNode(node) {
                    var savedParent = parent;
                    node.parent = parent;
                    parent = node;
                    if (!checkModifiers(node)) {
                        var savedInFunctionBlock = inFunctionBlock;
                        if (node.kind === 188 /* FunctionBlock */) {
                            inFunctionBlock = true;
                        }
                        var savedInAmbientContext = inAmbientContext;
                        if (node.flags & 2 /* Ambient */) {
                            inAmbientContext = true;
                        }
                        checkNodeAndChildren(node);
                        inAmbientContext = savedInAmbientContext;
                        inFunctionBlock = savedInFunctionBlock;
                    }
                    parent = savedParent;
                }
                function checkNodeAndChildren(node) {
                    var nodeKind = node.kind;
                    if (inAmbientContext && checkForStatementInAmbientContext(node, nodeKind)) {
                        return;
                    }
                    if (checkNode(node, nodeKind)) {
                        return;
                    }
                    forEachChild(node, visitNode);
                }
                function checkNode(node, nodeKind) {
                    switch (nodeKind) {
                        case 154 /* ArrowFunction */:
                        case 130 /* CallSignature */:
                        case 135 /* ConstructorType */:
                        case 131 /* ConstructSignature */:
                        case 134 /* FunctionType */:
                            return checkAnyParsedSignature(node);
                        case 173 /* BreakStatement */:
                        case 172 /* ContinueStatement */:
                            return checkBreakOrContinueStatement(node);
                        case 148 /* CallExpression */:
                        case 149 /* NewExpression */:
                            return checkCallOrNewExpression(node);
                        case 192 /* EnumDeclaration */: return checkEnumDeclaration(node);
                        case 157 /* BinaryExpression */: return checkBinaryExpression(node);
                        case 183 /* CatchBlock */: return checkCatchBlock(node);
                        case 189 /* ClassDeclaration */: return checkClassDeclaration(node);
                        case 122 /* ComputedPropertyName */: return checkComputedPropertyName(node);
                        case 127 /* Constructor */: return checkConstructor(node);
                        case 196 /* ExportAssignment */: return checkExportAssignment(node);
                        case 171 /* ForInStatement */: return checkForInStatement(node);
                        case 170 /* ForStatement */: return checkForStatement(node);
                        case 187 /* FunctionDeclaration */: return checkFunctionDeclaration(node);
                        case 153 /* FunctionExpression */: return checkFunctionExpression(node);
                        case 128 /* GetAccessor */: return checkGetAccessor(node);
                        case 147 /* IndexedAccess */: return checkIndexedAccess(node);
                        case 132 /* IndexSignature */: return checkIndexSignature(node);
                        case 190 /* InterfaceDeclaration */: return checkInterfaceDeclaration(node);
                        case 179 /* LabeledStatement */: return checkLabeledStatement(node);
                        case 126 /* Method */: return checkMethod(node);
                        case 193 /* ModuleDeclaration */: return checkModuleDeclaration(node);
                        case 143 /* ObjectLiteral */: return checkObjectLiteral(node);
                        case 6 /* NumericLiteral */: return checkNumericLiteral(node);
                        case 124 /* Parameter */: return checkParameter(node);
                        case 156 /* PostfixOperator */: return checkPostfixOperator(node);
                        case 155 /* PrefixOperator */: return checkPrefixOperator(node);
                        case 125 /* Property */: return checkProperty(node);
                        case 144 /* PropertyAssignment */: return checkPropertyAssignment(node);
                        case 174 /* ReturnStatement */: return checkReturnStatement(node);
                        case 129 /* SetAccessor */: return checkSetAccessor(node);
                        case 198 /* SourceFile */: return checkSourceFile(node);
                        case 145 /* ShorthandPropertyAssignment */: return checkShorthandPropertyAssignment(node);
                        case 176 /* SwitchStatement */: return checkSwitchStatement(node);
                        case 150 /* TaggedTemplateExpression */: return checkTaggedTemplateExpression(node);
                        case 139 /* TupleType */: return checkTupleType(node);
                        case 123 /* TypeParameter */: return checkTypeParameter(node);
                        case 133 /* TypeReference */: return checkTypeReference(node);
                        case 186 /* VariableDeclaration */: return checkVariableDeclaration(node);
                        case 164 /* VariableStatement */: return checkVariableStatement(node);
                        case 175 /* WithStatement */: return checkWithStatement(node);
                        case 161 /* YieldExpression */: return checkYieldExpression(node);
                    }
                }
                function grammarErrorOnFirstToken(node, message, arg0, arg1, arg2) {
                    var start = ts.skipTrivia(sourceText, node.pos);
                    scanner.setTextPos(start);
                    scanner.scan();
                    var end = scanner.getTextPos();
                    grammarDiagnostics.push(ts.createFileDiagnostic(file, start, end - start, message, arg0, arg1, arg2));
                    return true;
                }
                function grammarErrorOnNode(node, message, arg0, arg1, arg2) {
                    var span = getErrorSpanForNode(node);
                    var start = span.end > span.pos ? ts.skipTrivia(file.text, span.pos) : span.pos;
                    var length = span.end - start;
                    grammarDiagnostics.push(ts.createFileDiagnostic(file, start, length, message, arg0, arg1, arg2));
                    return true;
                }
                function grammarErrorAtPos(start, length, message, arg0, arg1, arg2) {
                    grammarDiagnostics.push(ts.createFileDiagnostic(file, start, length, message, arg0, arg1, arg2));
                    return true;
                }
                function reportInvalidUseInStrictMode(node) {
                    var name = sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end);
                    return grammarErrorOnNode(node, ts.Diagnostics.Invalid_use_of_0_in_strict_mode, name);
                }
                function checkForStatementInAmbientContext(node, kind) {
                    switch (kind) {
                        case 163 /* Block */:
                        case 165 /* EmptyStatement */:
                        case 167 /* IfStatement */:
                        case 168 /* DoStatement */:
                        case 169 /* WhileStatement */:
                        case 170 /* ForStatement */:
                        case 171 /* ForInStatement */:
                        case 172 /* ContinueStatement */:
                        case 173 /* BreakStatement */:
                        case 174 /* ReturnStatement */:
                        case 175 /* WithStatement */:
                        case 176 /* SwitchStatement */:
                        case 180 /* ThrowStatement */:
                        case 181 /* TryStatement */:
                        case 185 /* DebuggerStatement */:
                        case 179 /* LabeledStatement */:
                        case 166 /* ExpressionStatement */:
                            return grammarErrorOnFirstToken(node, ts.Diagnostics.Statements_are_not_allowed_in_ambient_contexts);
                    }
                }
                function checkAnyParsedSignature(node) {
                    return checkTypeParameterList(node.typeParameters) || checkParameterList(node.parameters);
                }
                function checkBinaryExpression(node) {
                    if (node.parserContextFlags & 1 /* StrictMode */) {
                        if (isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operator)) {
                            if (isEvalOrArgumentsIdentifier(node.left)) {
                                return reportInvalidUseInStrictMode(node.left);
                            }
                        }
                    }
                }
                function isIterationStatement(node, lookInLabeledStatements) {
                    switch (node.kind) {
                        case 170 /* ForStatement */:
                        case 171 /* ForInStatement */:
                        case 168 /* DoStatement */:
                        case 169 /* WhileStatement */:
                            return true;
                        case 179 /* LabeledStatement */:
                            return lookInLabeledStatements && isIterationStatement(node.statement, lookInLabeledStatements);
                    }
                    return false;
                }
                function checkLabeledStatement(node) {
                    var current = node.parent;
                    while (current) {
                        if (isAnyFunction(current)) {
                            break;
                        }
                        if (current.kind === 179 /* LabeledStatement */ && current.label.text === node.label.text) {
                            return grammarErrorOnNode(node.label, ts.Diagnostics.Duplicate_label_0, getTextOfNodeFromSourceText(sourceText, node.label));
                        }
                        current = current.parent;
                    }
                }
                function checkBreakOrContinueStatement(node) {
                    var current = node;
                    while (current) {
                        if (isAnyFunction(current)) {
                            return grammarErrorOnNode(node, ts.Diagnostics.Jump_target_cannot_cross_function_boundary);
                        }
                        switch (current.kind) {
                            case 179 /* LabeledStatement */:
                                if (node.label && current.label.text === node.label.text) {
                                    var isMisplacedContinueLabel = node.kind === 172 /* ContinueStatement */ && !isIterationStatement(current.statement, true);
                                    if (isMisplacedContinueLabel) {
                                        return grammarErrorOnNode(node, ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement);
                                    }
                                    return false;
                                }
                                break;
                            case 176 /* SwitchStatement */:
                                if (node.kind === 173 /* BreakStatement */ && !node.label) {
                                    return false;
                                }
                                break;
                            default:
                                if (isIterationStatement(current, false) && !node.label) {
                                    return false;
                                }
                                break;
                        }
                        current = current.parent;
                    }
                    if (node.label) {
                        var message = node.kind === 173 /* BreakStatement */ ? ts.Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement : ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement;
                        return grammarErrorOnNode(node, message);
                    }
                    else {
                        var message = node.kind === 173 /* BreakStatement */ ? ts.Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement : ts.Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement;
                        return grammarErrorOnNode(node, message);
                    }
                }
                function checkCallOrNewExpression(node) {
                    return checkTypeArguments(node.typeArguments) || checkArguments(node.arguments);
                }
                function checkArguments(arguments) {
                    return checkForDisallowedTrailingComma(arguments) || checkForOmittedArgument(arguments);
                }
                function checkTypeArguments(typeArguments) {
                    return checkForDisallowedTrailingComma(typeArguments) || checkForAtLeastOneTypeArgument(typeArguments) || checkForMissingTypeArgument(typeArguments);
                }
                function checkForOmittedArgument(arguments) {
                    if (arguments) {
                        for (var i = 0, n = arguments.length; i < n; i++) {
                            var arg = arguments[i];
                            if (arg.kind === 162 /* OmittedExpression */) {
                                return grammarErrorAtPos(arg.pos, 0, ts.Diagnostics.Argument_expression_expected);
                            }
                        }
                    }
                }
                function checkForMissingTypeArgument(typeArguments) {
                    if (typeArguments) {
                        for (var i = 0, n = typeArguments.length; i < n; i++) {
                            var arg = typeArguments[i];
                            if (arg.kind === 120 /* Missing */) {
                                return grammarErrorAtPos(arg.pos, 0, ts.Diagnostics.Type_expected);
                            }
                        }
                    }
                }
                function checkForAtLeastOneTypeArgument(typeArguments) {
                    if (typeArguments && typeArguments.length === 0) {
                        var start = typeArguments.pos - "<".length;
                        var end = ts.skipTrivia(sourceText, typeArguments.end) + ">".length;
                        return grammarErrorAtPos(start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
                    }
                }
                function checkForDisallowedTrailingComma(list) {
                    if (list && list.hasTrailingComma) {
                        var start = list.end - ",".length;
                        var end = list.end;
                        return grammarErrorAtPos(start, end - start, ts.Diagnostics.Trailing_comma_not_allowed);
                    }
                }
                function checkCatchBlock(node) {
                    if (node.type) {
                        var colonStart = ts.skipTrivia(sourceText, node.variable.end);
                        return grammarErrorAtPos(colonStart, ":".length, ts.Diagnostics.Catch_clause_parameter_cannot_have_a_type_annotation);
                    }
                    if (node.parserContextFlags & 1 /* StrictMode */ && isEvalOrArgumentsIdentifier(node.variable)) {
                        return reportInvalidUseInStrictMode(node.variable);
                    }
                }
                function checkClassDeclaration(node) {
                    return checkForDisallowedTrailingComma(node.implementedTypes) || checkForAtLeastOneHeritageClause(node.implementedTypes, "implements");
                }
                function checkForAtLeastOneHeritageClause(types, listType) {
                    if (types && types.length === 0) {
                        return grammarErrorAtPos(types.pos, 0, ts.Diagnostics._0_list_cannot_be_empty, listType);
                    }
                }
                function checkConstructor(node) {
                    return checkAnyParsedSignature(node) || checkConstructorTypeParameters(node) || checkConstructorTypeAnnotation(node) || checkForBodyInAmbientContext(node.body, true);
                }
                function checkConstructorTypeParameters(node) {
                    if (node.typeParameters) {
                        return grammarErrorAtPos(node.typeParameters.pos, node.typeParameters.end - node.typeParameters.pos, ts.Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
                    }
                }
                function checkConstructorTypeAnnotation(node) {
                    if (node.type) {
                        return grammarErrorOnNode(node.type, ts.Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration);
                    }
                }
                function checkEnumDeclaration(enumDecl) {
                    var enumIsConst = (enumDecl.flags & 4096 /* Const */) !== 0;
                    var hasError = false;
                    if (!enumIsConst) {
                        var inConstantEnumMemberSection = true;
                        for (var i = 0, n = enumDecl.members.length; i < n; i++) {
                            var node = enumDecl.members[i];
                            if (node.name.kind === 122 /* ComputedPropertyName */) {
                                hasError = grammarErrorOnNode(node.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
                            }
                            else if (inAmbientContext) {
                                if (node.initializer && !isIntegerLiteral(node.initializer)) {
                                    hasError = grammarErrorOnNode(node.name, ts.Diagnostics.Ambient_enum_elements_can_only_have_integer_literal_initializers) || hasError;
                                }
                            }
                            else if (node.initializer) {
                                inConstantEnumMemberSection = isIntegerLiteral(node.initializer);
                            }
                            else if (!inConstantEnumMemberSection) {
                                hasError = grammarErrorOnNode(node.name, ts.Diagnostics.Enum_member_must_have_initializer) || hasError;
                            }
                        }
                    }
                    return hasError;
                }
                function isIntegerLiteral(expression) {
                    function isInteger(literalExpression) {
                        return /^[0-9]+([eE]\+?[0-9]+)?$/.test(literalExpression.text);
                    }
                    if (expression.kind === 155 /* PrefixOperator */) {
                        var unaryExpression = expression;
                        if (unaryExpression.operator === 32 /* PlusToken */ || unaryExpression.operator === 33 /* MinusToken */) {
                            expression = unaryExpression.operand;
                        }
                    }
                    if (expression.kind === 6 /* NumericLiteral */) {
                        return isInteger(expression);
                    }
                    return false;
                }
                function checkExportAssignment(node) {
                    if (node.flags & 243 /* Modifier */) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers);
                    }
                }
                function checkForInStatement(node) {
                    return checkVariableDeclarations(node.declarations) || checkForMoreThanOneDeclaration(node.declarations);
                }
                function checkForStatement(node) {
                    return checkVariableDeclarations(node.declarations);
                }
                function checkForMoreThanOneDeclaration(declarations) {
                    if (declarations && declarations.length > 1) {
                        return grammarErrorOnFirstToken(declarations[1], ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement);
                    }
                }
                function checkFunctionDeclaration(node) {
                    return checkAnyParsedSignature(node) || checkFunctionName(node.name) || checkForBodyInAmbientContext(node.body, false) || checkForGenerator(node);
                }
                function checkForGenerator(node) {
                    if (node.asteriskToken) {
                        return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.generators_are_not_currently_supported);
                    }
                }
                function checkFunctionExpression(node) {
                    return checkAnyParsedSignature(node) || checkFunctionName(node.name) || checkForGenerator(node);
                }
                function checkFunctionName(name) {
                    if (name && name.parserContextFlags & 1 /* StrictMode */ && isEvalOrArgumentsIdentifier(name)) {
                        return reportInvalidUseInStrictMode(name);
                    }
                }
                function checkGetAccessor(node) {
                    return checkAnyParsedSignature(node) || checkAccessor(node);
                }
                function checkIndexedAccess(node) {
                    if (node.index.kind === 120 /* Missing */ && node.parent.kind === 149 /* NewExpression */ && node.parent.func === node) {
                        var start = ts.skipTrivia(sourceText, node.parent.pos);
                        var end = node.end;
                        return grammarErrorAtPos(start, end - start, ts.Diagnostics.new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead);
                    }
                }
                function checkIndexSignature(node) {
                    return checkIndexSignatureParameters(node) || checkForIndexSignatureModifiers(node);
                }
                function checkForIndexSignatureModifiers(node) {
                    if (node.flags & 243 /* Modifier */) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_not_permitted_on_index_signature_members);
                    }
                }
                function checkIndexSignatureParameters(node) {
                    var parameter = node.parameters[0];
                    if (node.parameters.length !== 1) {
                        if (parameter) {
                            return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
                        }
                        else {
                            return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
                        }
                    }
                    else if (parameter.flags & 8 /* Rest */) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter);
                    }
                    else if (parameter.flags & 243 /* Modifier */) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier);
                    }
                    else if (parameter.flags & 4 /* QuestionMark */) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark);
                    }
                    else if (parameter.initializer) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_initializer);
                    }
                    else if (!parameter.type) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_must_have_a_type_annotation);
                    }
                    else if (parameter.type.kind !== 118 /* StringKeyword */ && parameter.type.kind !== 116 /* NumberKeyword */) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_must_be_string_or_number);
                    }
                    else if (!node.type) {
                        return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_a_type_annotation);
                    }
                }
                function checkInterfaceDeclaration(node) {
                    return checkForDisallowedTrailingComma(node.baseTypes) || checkForAtLeastOneHeritageClause(node.baseTypes, "extends");
                }
                function checkMethod(node) {
                    if (checkAnyParsedSignature(node) || checkForBodyInAmbientContext(node.body, false) || checkForGenerator(node)) {
                        return true;
                    }
                    if (node.parent.kind === 189 /* ClassDeclaration */) {
                        if (checkForInvalidQuestionMark(node, ts.Diagnostics.A_class_member_cannot_be_declared_optional)) {
                            return true;
                        }
                        if (inAmbientContext) {
                            return checkForDisallowedComputedProperty(node.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_an_ambient_context);
                        }
                        else if (!node.body) {
                            return checkForDisallowedComputedProperty(node.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_method_overloads);
                        }
                    }
                    else if (node.parent.kind === 190 /* InterfaceDeclaration */) {
                        return checkForDisallowedComputedProperty(node.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_interfaces);
                    }
                    else if (node.parent.kind === 137 /* TypeLiteral */) {
                        return checkForDisallowedComputedProperty(node.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_type_literals);
                    }
                }
                function checkForBodyInAmbientContext(body, isConstructor) {
                    if (inAmbientContext && body && body.kind === 188 /* FunctionBlock */) {
                        var diagnostic = isConstructor ? ts.Diagnostics.A_constructor_implementation_cannot_be_declared_in_an_ambient_context : ts.Diagnostics.A_function_implementation_cannot_be_declared_in_an_ambient_context;
                        return grammarErrorOnFirstToken(body, diagnostic);
                    }
                }
                function checkModuleDeclaration(node) {
                    return checkModuleDeclarationName(node) || checkModuleDeclarationStatements(node);
                }
                function checkModuleDeclarationName(node) {
                    if (!inAmbientContext && node.name.kind === 7 /* StringLiteral */) {
                        return grammarErrorOnNode(node.name, ts.Diagnostics.Only_ambient_modules_can_use_quoted_names);
                    }
                }
                function checkModuleDeclarationStatements(node) {
                    if (node.name.kind === 63 /* Identifier */ && node.body.kind === 194 /* ModuleBlock */) {
                        var statements = node.body.statements;
                        for (var i = 0, n = statements.length; i < n; i++) {
                            var statement = statements[i];
                            if (statement.kind === 196 /* ExportAssignment */) {
                                return grammarErrorOnNode(statement, ts.Diagnostics.An_export_assignment_cannot_be_used_in_an_internal_module);
                            }
                            else if (statement.kind === 195 /* ImportDeclaration */ && statement.externalModuleName) {
                                return grammarErrorOnNode(statement.externalModuleName, ts.Diagnostics.Import_declarations_in_an_internal_module_cannot_reference_an_external_module);
                            }
                        }
                    }
                }
                function checkObjectLiteral(node) {
                    var seen = {};
                    var Property = 1;
                    var GetAccessor = 2;
                    var SetAccesor = 4;
                    var GetOrSetAccessor = GetAccessor | SetAccesor;
                    var inStrictMode = (node.parserContextFlags & 1 /* StrictMode */) !== 0;
                    for (var i = 0, n = node.properties.length; i < n; i++) {
                        var prop = node.properties[i];
                        var name = prop.name;
                        if (prop.kind === 162 /* OmittedExpression */ || name.kind === 122 /* ComputedPropertyName */) {
                            continue;
                        }
                        var currentKind;
                        if (prop.kind === 144 /* PropertyAssignment */) {
                            currentKind = Property;
                        }
                        else if (prop.kind === 145 /* ShorthandPropertyAssignment */) {
                            currentKind = Property;
                        }
                        else if (prop.kind === 128 /* GetAccessor */) {
                            currentKind = GetAccessor;
                        }
                        else if (prop.kind === 129 /* SetAccessor */) {
                            currentKind = SetAccesor;
                        }
                        else {
                            ts.Debug.fail("Unexpected syntax kind:" + prop.kind);
                        }
                        if (!ts.hasProperty(seen, name.text)) {
                            seen[name.text] = currentKind;
                        }
                        else {
                            var existingKind = seen[name.text];
                            if (currentKind === Property && existingKind === Property) {
                                if (inStrictMode) {
                                    grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode);
                                }
                            }
                            else if ((currentKind & GetOrSetAccessor) && (existingKind & GetOrSetAccessor)) {
                                if (existingKind !== GetOrSetAccessor && currentKind !== existingKind) {
                                    seen[name.text] = currentKind | existingKind;
                                }
                                else {
                                    return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name);
                                }
                            }
                            else {
                                return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name);
                            }
                        }
                    }
                }
                function checkNumericLiteral(node) {
                    if (node.flags & 8192 /* OctalLiteral */) {
                        if (node.parserContextFlags & 1 /* StrictMode */) {
                            return grammarErrorOnNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode);
                        }
                        else if (languageVersion >= 1 /* ES5 */) {
                            return grammarErrorOnNode(node, ts.Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher);
                        }
                    }
                }
                function checkModifiers(node) {
                    switch (node.kind) {
                        case 128 /* GetAccessor */:
                        case 129 /* SetAccessor */:
                        case 127 /* Constructor */:
                        case 125 /* Property */:
                        case 126 /* Method */:
                        case 132 /* IndexSignature */:
                        case 189 /* ClassDeclaration */:
                        case 190 /* InterfaceDeclaration */:
                        case 193 /* ModuleDeclaration */:
                        case 192 /* EnumDeclaration */:
                        case 196 /* ExportAssignment */:
                        case 164 /* VariableStatement */:
                        case 187 /* FunctionDeclaration */:
                        case 191 /* TypeAliasDeclaration */:
                        case 195 /* ImportDeclaration */:
                        case 124 /* Parameter */:
                            break;
                        default:
                            return false;
                    }
                    if (!node.modifiers) {
                        return;
                    }
                    var lastStatic, lastPrivate, lastProtected, lastDeclare;
                    var flags = 0;
                    for (var i = 0, n = node.modifiers.length; i < n; i++) {
                        var modifier = node.modifiers[i];
                        switch (modifier.kind) {
                            case 106 /* PublicKeyword */:
                            case 105 /* ProtectedKeyword */:
                            case 104 /* PrivateKeyword */:
                                var text;
                                if (modifier.kind === 106 /* PublicKeyword */) {
                                    text = "public";
                                }
                                else if (modifier.kind === 105 /* ProtectedKeyword */) {
                                    text = "protected";
                                    lastProtected = modifier;
                                }
                                else {
                                    text = "private";
                                    lastPrivate = modifier;
                                }
                                if (flags & 112 /* AccessibilityModifier */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics.Accessibility_modifier_already_seen);
                                }
                                else if (flags & 128 /* Static */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "static");
                                }
                                else if (node.parent.kind === 194 /* ModuleBlock */ || node.parent.kind === 198 /* SourceFile */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_element, text);
                                }
                                flags |= modifierToFlag(modifier.kind);
                                break;
                            case 107 /* StaticKeyword */:
                                if (flags & 128 /* Static */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "static");
                                }
                                else if (node.parent.kind === 194 /* ModuleBlock */ || node.parent.kind === 198 /* SourceFile */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_element, "static");
                                }
                                else if (node.kind === 124 /* Parameter */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static");
                                }
                                flags |= 128 /* Static */;
                                lastStatic = modifier;
                                break;
                            case 76 /* ExportKeyword */:
                                if (flags & 1 /* Export */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "export");
                                }
                                else if (flags & 2 /* Ambient */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare");
                                }
                                else if (node.parent.kind === 189 /* ClassDeclaration */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "export");
                                }
                                else if (node.kind === 124 /* Parameter */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export");
                                }
                                flags |= 1 /* Export */;
                                break;
                            case 112 /* DeclareKeyword */:
                                if (flags & 2 /* Ambient */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "declare");
                                }
                                else if (node.parent.kind === 189 /* ClassDeclaration */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "declare");
                                }
                                else if (node.kind === 124 /* Parameter */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
                                }
                                else if (inAmbientContext && node.parent.kind === 194 /* ModuleBlock */) {
                                    return grammarErrorOnNode(modifier, ts.Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
                                }
                                flags |= 2 /* Ambient */;
                                lastDeclare = modifier;
                                break;
                        }
                    }
                    if (node.kind === 127 /* Constructor */) {
                        if (flags & 128 /* Static */) {
                            return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static");
                        }
                        else if (flags & 64 /* Protected */) {
                            return grammarErrorOnNode(lastProtected, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "protected");
                        }
                        else if (flags & 32 /* Private */) {
                            return grammarErrorOnNode(lastPrivate, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "private");
                        }
                    }
                    else if (node.kind === 195 /* ImportDeclaration */ && flags & 2 /* Ambient */) {
                        return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_declare_modifier_cannot_be_used_with_an_import_declaration, "declare");
                    }
                    else if (node.kind === 190 /* InterfaceDeclaration */ && flags & 2 /* Ambient */) {
                        return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_declare_modifier_cannot_be_used_with_an_interface_declaration, "declare");
                    }
                }
                function checkParameter(node) {
                    if (node.parserContextFlags & 1 /* StrictMode */ && isEvalOrArgumentsIdentifier(node.name)) {
                        return reportInvalidUseInStrictMode(node.name);
                    }
                }
                function checkTypeParameterList(typeParameters) {
                    if (checkForDisallowedTrailingComma(typeParameters)) {
                        return true;
                    }
                    if (typeParameters && typeParameters.length === 0) {
                        var start = typeParameters.pos - "<".length;
                        var end = ts.skipTrivia(sourceText, typeParameters.end) + ">".length;
                        return grammarErrorAtPos(start, end - start, ts.Diagnostics.Type_parameter_list_cannot_be_empty);
                    }
                }
                function checkParameterList(parameters) {
                    if (checkForDisallowedTrailingComma(parameters)) {
                        return true;
                    }
                    var seenOptionalParameter = false;
                    var parameterCount = parameters.length;
                    for (var i = 0; i < parameterCount; i++) {
                        var parameter = parameters[i];
                        if (parameter.flags & 8 /* Rest */) {
                            if (i !== (parameterCount - 1)) {
                                return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
                            }
                            if (parameter.flags & 4 /* QuestionMark */) {
                                return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_parameter_cannot_be_optional);
                            }
                            if (parameter.initializer) {
                                return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_parameter_cannot_have_an_initializer);
                            }
                        }
                        else if (parameter.flags & 4 /* QuestionMark */ || parameter.initializer) {
                            seenOptionalParameter = true;
                            if (parameter.flags & 4 /* QuestionMark */ && parameter.initializer) {
                                return grammarErrorOnNode(parameter.name, ts.Diagnostics.Parameter_cannot_have_question_mark_and_initializer);
                            }
                        }
                        else {
                            if (seenOptionalParameter) {
                                return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter);
                            }
                        }
                    }
                }
                function checkPostfixOperator(node) {
                    if (node.parserContextFlags & 1 /* StrictMode */ && isEvalOrArgumentsIdentifier(node.operand)) {
                        return reportInvalidUseInStrictMode(node.operand);
                    }
                }
                function checkPrefixOperator(node) {
                    if (node.parserContextFlags & 1 /* StrictMode */) {
                        if ((node.operator === 37 /* PlusPlusToken */ || node.operator === 38 /* MinusMinusToken */) && isEvalOrArgumentsIdentifier(node.operand)) {
                            return reportInvalidUseInStrictMode(node.operand);
                        }
                        else if (node.operator === 72 /* DeleteKeyword */ && node.operand.kind === 63 /* Identifier */) {
                            return grammarErrorOnNode(node.operand, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode);
                        }
                    }
                }
                function checkProperty(node) {
                    if (node.parent.kind === 189 /* ClassDeclaration */) {
                        if (checkForInvalidQuestionMark(node, ts.Diagnostics.A_class_member_cannot_be_declared_optional) || checkForDisallowedComputedProperty(node.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_class_property_declarations)) {
                            return true;
                        }
                    }
                    else if (node.parent.kind === 190 /* InterfaceDeclaration */) {
                        if (checkForDisallowedComputedProperty(node.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_interfaces)) {
                            return true;
                        }
                    }
                    else if (node.parent.kind === 137 /* TypeLiteral */) {
                        if (checkForDisallowedComputedProperty(node.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_type_literals)) {
                            return true;
                        }
                    }
                    return checkForInitializerInAmbientContext(node);
                }
                function checkComputedPropertyName(node) {
                    if (languageVersion < 2 /* ES6 */) {
                        return grammarErrorOnNode(node, ts.Diagnostics.Computed_property_names_are_only_available_when_targeting_ECMAScript_6_and_higher);
                    }
                    else if (node.expression.kind === 157 /* BinaryExpression */ && node.expression.operator === 22 /* CommaToken */) {
                        return grammarErrorOnNode(node.expression, ts.Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name);
                    }
                }
                function checkForDisallowedComputedProperty(node, message) {
                    if (node.kind === 122 /* ComputedPropertyName */) {
                        return grammarErrorOnNode(node, message);
                    }
                }
                function checkForInitializerInAmbientContext(node) {
                    if (inAmbientContext && node.initializer) {
                        return grammarErrorOnFirstToken(node.initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
                    }
                }
                function checkPropertyAssignment(node) {
                    return checkForInvalidQuestionMark(node, ts.Diagnostics.An_object_member_cannot_be_declared_optional);
                }
                function checkForInvalidQuestionMark(node, message) {
                    if (node.flags & 4 /* QuestionMark */) {
                        var pos = ts.skipTrivia(sourceText, node.name.end);
                        return grammarErrorAtPos(pos, "?".length, message);
                    }
                }
                function checkReturnStatement(node) {
                    if (!inFunctionBlock) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.A_return_statement_can_only_be_used_within_a_function_body);
                    }
                }
                function checkSetAccessor(node) {
                    return checkAnyParsedSignature(node) || checkAccessor(node);
                }
                function checkAccessor(accessor) {
                    var kind = accessor.kind;
                    if (languageVersion < 1 /* ES5 */) {
                        return grammarErrorOnNode(accessor.name, ts.Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
                    }
                    else if (inAmbientContext) {
                        return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context);
                    }
                    else if (accessor.body === undefined) {
                        return grammarErrorAtPos(accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
                    }
                    else if (accessor.typeParameters) {
                        return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_have_type_parameters);
                    }
                    else if (kind === 128 /* GetAccessor */ && accessor.parameters.length) {
                        return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_get_accessor_cannot_have_parameters);
                    }
                    else if (kind === 129 /* SetAccessor */) {
                        if (accessor.type) {
                            return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
                        }
                        else if (accessor.parameters.length !== 1) {
                            return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
                        }
                        else {
                            var parameter = accessor.parameters[0];
                            if (parameter.flags & 8 /* Rest */) {
                                return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_cannot_have_rest_parameter);
                            }
                            else if (parameter.flags & 243 /* Modifier */) {
                                return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
                            }
                            else if (parameter.flags & 4 /* QuestionMark */) {
                                return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
                            }
                            else if (parameter.initializer) {
                                return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
                            }
                        }
                    }
                }
                function checkSourceFile(node) {
                    return inAmbientContext && checkTopLevelElementsForRequiredDeclareModifier(file);
                }
                function checkTopLevelElementsForRequiredDeclareModifier(file) {
                    for (var i = 0, n = file.statements.length; i < n; i++) {
                        var decl = file.statements[i];
                        if (isDeclaration(decl) || decl.kind === 164 /* VariableStatement */) {
                            if (checkTopLevelElementForRequiredDeclareModifier(decl)) {
                                return true;
                            }
                        }
                    }
                }
                function checkTopLevelElementForRequiredDeclareModifier(node) {
                    if (node.kind === 190 /* InterfaceDeclaration */ || node.kind === 195 /* ImportDeclaration */ || node.kind === 196 /* ExportAssignment */ || (node.flags & 2 /* Ambient */)) {
                        return false;
                    }
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file);
                }
                function checkShorthandPropertyAssignment(node) {
                    return checkForInvalidQuestionMark(node, ts.Diagnostics.An_object_member_cannot_be_declared_optional);
                }
                function checkSwitchStatement(node) {
                    var firstDefaultClause;
                    for (var i = 0, n = node.clauses.length; i < n; i++) {
                        var clause = node.clauses[i];
                        if (clause.kind === 178 /* DefaultClause */) {
                            if (firstDefaultClause === undefined) {
                                firstDefaultClause = clause;
                            }
                            else {
                                var start = ts.skipTrivia(file.text, clause.pos);
                                var end = clause.statements.length > 0 ? clause.statements[0].pos : clause.end;
                                return grammarErrorAtPos(start, end - start, ts.Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement);
                            }
                        }
                    }
                }
                function checkTaggedTemplateExpression(node) {
                    if (languageVersion < 2 /* ES6 */) {
                        return grammarErrorOnFirstToken(node.template, ts.Diagnostics.Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher);
                    }
                }
                function checkTupleType(node) {
                    return checkForDisallowedTrailingComma(node.elementTypes) || checkForAtLeastOneType(node);
                }
                function checkForAtLeastOneType(node) {
                    if (node.elementTypes.length === 0) {
                        return grammarErrorOnNode(node, ts.Diagnostics.A_tuple_type_element_list_cannot_be_empty);
                    }
                }
                function checkTypeParameter(node) {
                    if (node.expression) {
                        return grammarErrorOnFirstToken(node.expression, ts.Diagnostics.Type_expected);
                    }
                }
                function checkTypeReference(node) {
                    return checkTypeArguments(node.typeArguments);
                }
                function checkVariableDeclaration(node) {
                    if (inAmbientContext && node.initializer) {
                        var equalsPos = node.type ? ts.skipTrivia(sourceText, node.type.end) : ts.skipTrivia(sourceText, node.name.end);
                        return grammarErrorAtPos(equalsPos, "=".length, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
                    }
                    if (!inAmbientContext && !node.initializer && isConst(node)) {
                        return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_must_be_initialized);
                    }
                    if (node.parserContextFlags & 1 /* StrictMode */ && isEvalOrArgumentsIdentifier(node.name)) {
                        return reportInvalidUseInStrictMode(node.name);
                    }
                }
                function checkVariableDeclarations(declarations) {
                    if (declarations) {
                        if (checkForDisallowedTrailingComma(declarations)) {
                            return true;
                        }
                        if (!declarations.length) {
                            return grammarErrorAtPos(declarations.pos, declarations.end - declarations.pos, ts.Diagnostics.Variable_declaration_list_cannot_be_empty);
                        }
                        var decl = declarations[0];
                        if (languageVersion < 2 /* ES6 */) {
                            if (isLet(decl)) {
                                return grammarErrorOnFirstToken(decl, ts.Diagnostics.let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
                            }
                            else if (isConst(decl)) {
                                return grammarErrorOnFirstToken(decl, ts.Diagnostics.const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher);
                            }
                        }
                    }
                }
                function checkVariableStatement(node) {
                    return checkVariableDeclarations(node.declarations) || checkForDisallowedLetOrConstStatement(node);
                }
                function checkForDisallowedLetOrConstStatement(node) {
                    if (!allowLetAndConstDeclarations(node.parent)) {
                        if (isLet(node)) {
                            return grammarErrorOnNode(node, ts.Diagnostics.let_declarations_can_only_be_declared_inside_a_block);
                        }
                        else if (isConst(node)) {
                            return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_can_only_be_declared_inside_a_block);
                        }
                    }
                }
                function allowLetAndConstDeclarations(parent) {
                    switch (parent.kind) {
                        case 167 /* IfStatement */:
                        case 168 /* DoStatement */:
                        case 169 /* WhileStatement */:
                        case 175 /* WithStatement */:
                        case 170 /* ForStatement */:
                        case 171 /* ForInStatement */:
                            return false;
                        case 179 /* LabeledStatement */:
                            return allowLetAndConstDeclarations(parent.parent);
                    }
                    return true;
                }
                function checkWithStatement(node) {
                    if (node.parserContextFlags & 1 /* StrictMode */) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
                    }
                }
                function checkYieldExpression(node) {
                    if (!(node.parserContextFlags & 4 /* Yield */)) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.yield_expression_must_be_contained_within_a_generator_declaration);
                    }
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.yield_expressions_are_not_currently_supported);
                }
            }
            function createProgram(rootNames, options, host) {
                var program;
                var files = [];
                var filesByName = {};
                var errors = [];
                var seenNoDefaultLib = options.noLib;
                var commonSourceDirectory;
                ts.forEach(rootNames, function (name) { return processRootFile(name, false); });
                if (!seenNoDefaultLib) {
                    processRootFile(host.getDefaultLibFilename(), true);
                }
                verifyCompilerOptions();
                errors.sort(ts.compareDiagnostics);
                program = {
                    getSourceFile: getSourceFile,
                    getSourceFiles: function () { return files; },
                    getCompilerOptions: function () { return options; },
                    getCompilerHost: function () { return host; },
                    getDiagnostics: getDiagnostics,
                    getGlobalDiagnostics: getGlobalDiagnostics,
                    getTypeChecker: function (fullTypeCheckMode) { return ts.createTypeChecker(program, fullTypeCheckMode); },
                    getCommonSourceDirectory: function () { return commonSourceDirectory; }
                };
                return program;
                function getSourceFile(filename) {
                    filename = host.getCanonicalFileName(filename);
                    return ts.hasProperty(filesByName, filename) ? filesByName[filename] : undefined;
                }
                function getDiagnostics(sourceFile) {
                    return sourceFile ? ts.filter(errors, function (e) { return e.file === sourceFile; }) : errors;
                }
                function getGlobalDiagnostics() {
                    return ts.filter(errors, function (e) { return !e.file; });
                }
                function hasExtension(filename) {
                    return ts.getBaseFilename(filename).indexOf(".") >= 0;
                }
                function processRootFile(filename, isDefaultLib) {
                    processSourceFile(ts.normalizePath(filename), isDefaultLib);
                }
                function processSourceFile(filename, isDefaultLib, refFile, refPos, refEnd) {
                    if (refEnd !== undefined && refPos !== undefined) {
                        var start = refPos;
                        var length = refEnd - refPos;
                    }
                    var diagnostic;
                    if (hasExtension(filename)) {
                        if (!ts.fileExtensionIs(filename, ".ts")) {
                            diagnostic = ts.Diagnostics.File_0_must_have_extension_ts_or_d_ts;
                        }
                        else if (!findSourceFile(filename, isDefaultLib, refFile, refPos, refEnd)) {
                            diagnostic = ts.Diagnostics.File_0_not_found;
                        }
                        else if (refFile && host.getCanonicalFileName(filename) === host.getCanonicalFileName(refFile.filename)) {
                            diagnostic = ts.Diagnostics.A_file_cannot_have_a_reference_to_itself;
                        }
                    }
                    else {
                        if (!(findSourceFile(filename + ".ts", isDefaultLib, refFile, refPos, refEnd) || findSourceFile(filename + ".d.ts", isDefaultLib, refFile, refPos, refEnd))) {
                            diagnostic = ts.Diagnostics.File_0_not_found;
                            filename += ".ts";
                        }
                    }
                    if (diagnostic) {
                        if (refFile) {
                            errors.push(ts.createFileDiagnostic(refFile, start, length, diagnostic, filename));
                        }
                        else {
                            errors.push(ts.createCompilerDiagnostic(diagnostic, filename));
                        }
                    }
                }
                function findSourceFile(filename, isDefaultLib, refFile, refStart, refLength) {
                    var canonicalName = host.getCanonicalFileName(filename);
                    if (ts.hasProperty(filesByName, canonicalName)) {
                        return getSourceFileFromCache(filename, canonicalName, false);
                    }
                    else {
                        var normalizedAbsolutePath = ts.getNormalizedAbsolutePath(filename, host.getCurrentDirectory());
                        var canonicalAbsolutePath = host.getCanonicalFileName(normalizedAbsolutePath);
                        if (ts.hasProperty(filesByName, canonicalAbsolutePath)) {
                            return getSourceFileFromCache(normalizedAbsolutePath, canonicalAbsolutePath, true);
                        }
                        var file = filesByName[canonicalName] = host.getSourceFile(filename, options.target, function (hostErrorMessage) {
                            errors.push(ts.createFileDiagnostic(refFile, refStart, refLength, ts.Diagnostics.Cannot_read_file_0_Colon_1, filename, hostErrorMessage));
                        });
                        if (file) {
                            seenNoDefaultLib = seenNoDefaultLib || file.hasNoDefaultLib;
                            filesByName[canonicalAbsolutePath] = file;
                            if (!options.noResolve) {
                                var basePath = ts.getDirectoryPath(filename);
                                processReferencedFiles(file, basePath);
                                processImportedModules(file, basePath);
                            }
                            if (isDefaultLib) {
                                files.unshift(file);
                            }
                            else {
                                files.push(file);
                            }
                            ts.forEach(file.getSyntacticDiagnostics(), function (e) {
                                errors.push(e);
                            });
                        }
                    }
                    return file;
                    function getSourceFileFromCache(filename, canonicalName, useAbsolutePath) {
                        var file = filesByName[canonicalName];
                        if (file && host.useCaseSensitiveFileNames()) {
                            var sourceFileName = useAbsolutePath ? ts.getNormalizedAbsolutePath(file.filename, host.getCurrentDirectory()) : file.filename;
                            if (canonicalName !== sourceFileName) {
                                errors.push(ts.createFileDiagnostic(refFile, refStart, refLength, ts.Diagnostics.Filename_0_differs_from_already_included_filename_1_only_in_casing, filename, sourceFileName));
                            }
                        }
                        return file;
                    }
                }
                function processReferencedFiles(file, basePath) {
                    ts.forEach(file.referencedFiles, function (ref) {
                        var referencedFilename = ts.isRootedDiskPath(ref.filename) ? ref.filename : ts.combinePaths(basePath, ref.filename);
                        processSourceFile(ts.normalizePath(referencedFilename), false, file, ref.pos, ref.end);
                    });
                }
                function processImportedModules(file, basePath) {
                    ts.forEach(file.statements, function (node) {
                        if (node.kind === 195 /* ImportDeclaration */ && node.externalModuleName) {
                            var nameLiteral = node.externalModuleName;
                            var moduleName = nameLiteral.text;
                            if (moduleName) {
                                var searchPath = basePath;
                                while (true) {
                                    var searchName = ts.normalizePath(ts.combinePaths(searchPath, moduleName));
                                    if (findModuleSourceFile(searchName + ".ts", nameLiteral) || findModuleSourceFile(searchName + ".d.ts", nameLiteral)) {
                                        break;
                                    }
                                    var parentPath = ts.getDirectoryPath(searchPath);
                                    if (parentPath === searchPath) {
                                        break;
                                    }
                                    searchPath = parentPath;
                                }
                            }
                        }
                        else if (node.kind === 193 /* ModuleDeclaration */ && node.name.kind === 7 /* StringLiteral */ && (node.flags & 2 /* Ambient */ || isDeclarationFile(file))) {
                            forEachChild(node.body, function (node) {
                                if (node.kind === 195 /* ImportDeclaration */ && node.externalModuleName) {
                                    var nameLiteral = node.externalModuleName;
                                    var moduleName = nameLiteral.text;
                                    if (moduleName) {
                                        var searchName = ts.normalizePath(ts.combinePaths(basePath, moduleName));
                                        var tsFile = findModuleSourceFile(searchName + ".ts", nameLiteral);
                                        if (!tsFile) {
                                            findModuleSourceFile(searchName + ".d.ts", nameLiteral);
                                        }
                                    }
                                }
                            });
                        }
                    });
                    function findModuleSourceFile(filename, nameLiteral) {
                        return findSourceFile(filename, false, file, nameLiteral.pos, nameLiteral.end - nameLiteral.pos);
                    }
                }
                function verifyCompilerOptions() {
                    if (!options.sourceMap && (options.mapRoot || options.sourceRoot)) {
                        if (options.mapRoot) {
                            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option));
                        }
                        if (options.sourceRoot) {
                            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option));
                        }
                        return;
                    }
                    var firstExternalModule = ts.forEach(files, function (f) { return isExternalModule(f) ? f : undefined; });
                    if (firstExternalModule && options.module === 0 /* None */) {
                        var externalModuleErrorSpan = getErrorSpanForNode(firstExternalModule.externalModuleIndicator);
                        var errorStart = ts.skipTrivia(firstExternalModule.text, externalModuleErrorSpan.pos);
                        var errorLength = externalModuleErrorSpan.end - errorStart;
                        errors.push(ts.createFileDiagnostic(firstExternalModule, errorStart, errorLength, ts.Diagnostics.Cannot_compile_external_modules_unless_the_module_flag_is_provided));
                    }
                    if (options.outDir || options.sourceRoot || (options.mapRoot && (!options.out || firstExternalModule !== undefined))) {
                        var commonPathComponents;
                        ts.forEach(files, function (sourceFile) {
                            if (!(sourceFile.flags & 1024 /* DeclarationFile */) && !ts.fileExtensionIs(sourceFile.filename, ".js")) {
                                var sourcePathComponents = ts.getNormalizedPathComponents(sourceFile.filename, host.getCurrentDirectory());
                                sourcePathComponents.pop();
                                if (commonPathComponents) {
                                    for (var i = 0; i < Math.min(commonPathComponents.length, sourcePathComponents.length); i++) {
                                        if (commonPathComponents[i] !== sourcePathComponents[i]) {
                                            if (i === 0) {
                                                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
                                                return;
                                            }
                                            commonPathComponents.length = i;
                                            break;
                                        }
                                    }
                                    if (sourcePathComponents.length < commonPathComponents.length) {
                                        commonPathComponents.length = sourcePathComponents.length;
                                    }
                                }
                                else {
                                    commonPathComponents = sourcePathComponents;
                                }
                            }
                        });
                        commonSourceDirectory = ts.getNormalizedPathFromPathComponents(commonPathComponents);
                        if (commonSourceDirectory) {
                            commonSourceDirectory += ts.directorySeparator;
                        }
                    }
                }
            }
            ts.createProgram = createProgram;
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            (function (ModuleInstanceState) {
                ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
                ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
                ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
            })(ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
            var ModuleInstanceState = ts.ModuleInstanceState;
            function getModuleInstanceState(node) {
                if (node.kind === 190 /* InterfaceDeclaration */) {
                    return 0 /* NonInstantiated */;
                }
                else if (ts.isConstEnumDeclaration(node)) {
                    return 2 /* ConstEnumOnly */;
                }
                else if (node.kind === 195 /* ImportDeclaration */ && !(node.flags & 1 /* Export */)) {
                    return 0 /* NonInstantiated */;
                }
                else if (node.kind === 194 /* ModuleBlock */) {
                    var state = 0 /* NonInstantiated */;
                    ts.forEachChild(node, function (n) {
                        switch (getModuleInstanceState(n)) {
                            case 0 /* NonInstantiated */:
                                return false;
                            case 2 /* ConstEnumOnly */:
                                state = 2 /* ConstEnumOnly */;
                                return false;
                            case 1 /* Instantiated */:
                                state = 1 /* Instantiated */;
                                return true;
                        }
                    });
                    return state;
                }
                else if (node.kind === 193 /* ModuleDeclaration */) {
                    return getModuleInstanceState(node.body);
                }
                else {
                    return 1 /* Instantiated */;
                }
            }
            ts.getModuleInstanceState = getModuleInstanceState;
            function hasComputedNameButNotSymbol(declaration) {
                return declaration.name && declaration.name.kind === 122 /* ComputedPropertyName */;
            }
            ts.hasComputedNameButNotSymbol = hasComputedNameButNotSymbol;
            function bindSourceFile(file) {
                var parent;
                var container;
                var blockScopeContainer;
                var lastContainer;
                var symbolCount = 0;
                var Symbol = ts.objectAllocator.getSymbolConstructor();
                if (!file.locals) {
                    file.locals = {};
                    container = blockScopeContainer = file;
                    bind(file);
                    file.symbolCount = symbolCount;
                }
                function createSymbol(flags, name) {
                    symbolCount++;
                    return new Symbol(flags, name);
                }
                function addDeclarationToSymbol(symbol, node, symbolKind) {
                    symbol.flags |= symbolKind;
                    if (!symbol.declarations)
                        symbol.declarations = [];
                    symbol.declarations.push(node);
                    if (symbolKind & 1952 /* HasExports */ && !symbol.exports)
                        symbol.exports = {};
                    if (symbolKind & 6240 /* HasMembers */ && !symbol.members)
                        symbol.members = {};
                    node.symbol = symbol;
                    if (symbolKind & 107455 /* Value */ && !symbol.valueDeclaration)
                        symbol.valueDeclaration = node;
                }
                function getDeclarationName(node) {
                    if (node.name) {
                        if (node.kind === 193 /* ModuleDeclaration */ && node.name.kind === 7 /* StringLiteral */) {
                            return '"' + node.name.text + '"';
                        }
                        ts.Debug.assert(!hasComputedNameButNotSymbol(node));
                        return node.name.text;
                    }
                    switch (node.kind) {
                        case 135 /* ConstructorType */:
                        case 127 /* Constructor */:
                            return "__constructor";
                        case 134 /* FunctionType */:
                        case 130 /* CallSignature */:
                            return "__call";
                        case 131 /* ConstructSignature */:
                            return "__new";
                        case 132 /* IndexSignature */:
                            return "__index";
                    }
                }
                function getDisplayName(node) {
                    return node.name ? ts.declarationNameToString(node.name) : getDeclarationName(node);
                }
                function declareSymbol(symbols, parent, node, includes, excludes) {
                    if (hasComputedNameButNotSymbol(node)) {
                        return undefined;
                    }
                    var name = getDeclarationName(node);
                    if (name !== undefined) {
                        var symbol = ts.hasProperty(symbols, name) ? symbols[name] : (symbols[name] = createSymbol(0, name));
                        if (symbol.flags & excludes) {
                            if (node.name) {
                                node.name.parent = node;
                            }
                            var message = symbol.flags & 2 /* BlockScopedVariable */ ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 : ts.Diagnostics.Duplicate_identifier_0;
                            ts.forEach(symbol.declarations, function (declaration) {
                                file.semanticDiagnostics.push(ts.createDiagnosticForNode(declaration.name, message, getDisplayName(declaration)));
                            });
                            file.semanticDiagnostics.push(ts.createDiagnosticForNode(node.name, message, getDisplayName(node)));
                            symbol = createSymbol(0, name);
                        }
                    }
                    else {
                        symbol = createSymbol(0, "__missing");
                    }
                    addDeclarationToSymbol(symbol, node, includes);
                    symbol.parent = parent;
                    if (node.kind === 189 /* ClassDeclaration */ && symbol.exports) {
                        var prototypeSymbol = createSymbol(4 /* Property */ | 536870912 /* Prototype */, "prototype");
                        if (ts.hasProperty(symbol.exports, prototypeSymbol.name)) {
                            if (node.name) {
                                node.name.parent = node;
                            }
                            file.semanticDiagnostics.push(ts.createDiagnosticForNode(symbol.exports[prototypeSymbol.name].declarations[0], ts.Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
                        }
                        symbol.exports[prototypeSymbol.name] = prototypeSymbol;
                        prototypeSymbol.parent = symbol;
                    }
                    return symbol;
                }
                function isAmbientContext(node) {
                    while (node) {
                        if (node.flags & 2 /* Ambient */)
                            return true;
                        node = node.parent;
                    }
                    return false;
                }
                function declareModuleMember(node, symbolKind, symbolExcludes) {
                    var exportKind = 0;
                    if (symbolKind & 107455 /* Value */) {
                        exportKind |= 4194304 /* ExportValue */;
                    }
                    if (symbolKind & 3152352 /* Type */) {
                        exportKind |= 8388608 /* ExportType */;
                    }
                    if (symbolKind & 1536 /* Namespace */) {
                        exportKind |= 16777216 /* ExportNamespace */;
                    }
                    if (node.flags & 1 /* Export */ || (node.kind !== 195 /* ImportDeclaration */ && isAmbientContext(container))) {
                        if (exportKind) {
                            var local = declareSymbol(container.locals, undefined, node, exportKind, symbolExcludes);
                            local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
                            node.localSymbol = local;
                        }
                        else {
                            declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
                        }
                    }
                    else {
                        declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes);
                    }
                }
                function bindChildren(node, symbolKind, isBlockScopeContainer) {
                    if (symbolKind & 1041936 /* HasLocals */) {
                        node.locals = {};
                    }
                    var saveParent = parent;
                    var saveContainer = container;
                    var savedBlockScopeContainer = blockScopeContainer;
                    parent = node;
                    if (symbolKind & 1048560 /* IsContainer */) {
                        container = node;
                        if (lastContainer !== container && !container.nextContainer) {
                            if (lastContainer) {
                                lastContainer.nextContainer = container;
                            }
                            lastContainer = container;
                        }
                    }
                    if (isBlockScopeContainer) {
                        blockScopeContainer = node;
                    }
                    ts.forEachChild(node, bind);
                    container = saveContainer;
                    parent = saveParent;
                    blockScopeContainer = savedBlockScopeContainer;
                }
                function bindDeclaration(node, symbolKind, symbolExcludes, isBlockScopeContainer) {
                    switch (container.kind) {
                        case 193 /* ModuleDeclaration */:
                            declareModuleMember(node, symbolKind, symbolExcludes);
                            break;
                        case 198 /* SourceFile */:
                            if (ts.isExternalModule(container)) {
                                declareModuleMember(node, symbolKind, symbolExcludes);
                                break;
                            }
                        case 134 /* FunctionType */:
                        case 135 /* ConstructorType */:
                        case 130 /* CallSignature */:
                        case 131 /* ConstructSignature */:
                        case 132 /* IndexSignature */:
                        case 126 /* Method */:
                        case 127 /* Constructor */:
                        case 128 /* GetAccessor */:
                        case 129 /* SetAccessor */:
                        case 187 /* FunctionDeclaration */:
                        case 153 /* FunctionExpression */:
                        case 154 /* ArrowFunction */:
                            declareSymbol(container.locals, undefined, node, symbolKind, symbolExcludes);
                            break;
                        case 189 /* ClassDeclaration */:
                            if (node.flags & 128 /* Static */) {
                                declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
                                break;
                            }
                        case 137 /* TypeLiteral */:
                        case 143 /* ObjectLiteral */:
                        case 190 /* InterfaceDeclaration */:
                            declareSymbol(container.symbol.members, container.symbol, node, symbolKind, symbolExcludes);
                            break;
                        case 192 /* EnumDeclaration */:
                            declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes);
                            break;
                    }
                    bindChildren(node, symbolKind, isBlockScopeContainer);
                }
                function bindConstructorDeclaration(node) {
                    bindDeclaration(node, 16384 /* Constructor */, 0, true);
                    ts.forEach(node.parameters, function (p) {
                        if (p.flags & (16 /* Public */ | 32 /* Private */ | 64 /* Protected */)) {
                            bindDeclaration(p, 4 /* Property */, 107455 /* PropertyExcludes */, false);
                        }
                    });
                }
                function bindModuleDeclaration(node) {
                    if (node.name.kind === 7 /* StringLiteral */) {
                        bindDeclaration(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */, true);
                    }
                    else {
                        var state = getModuleInstanceState(node);
                        if (state === 0 /* NonInstantiated */) {
                            bindDeclaration(node, 1024 /* NamespaceModule */, 0 /* NamespaceModuleExcludes */, true);
                        }
                        else {
                            bindDeclaration(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */, true);
                            if (state === 2 /* ConstEnumOnly */) {
                                node.symbol.constEnumOnlyModule = true;
                            }
                            else if (node.symbol.constEnumOnlyModule) {
                                node.symbol.constEnumOnlyModule = false;
                            }
                        }
                    }
                }
                function bindFunctionOrConstructorType(node) {
                    var symbolKind = node.kind === 134 /* FunctionType */ ? 131072 /* CallSignature */ : 262144 /* ConstructSignature */;
                    var symbol = createSymbol(symbolKind, getDeclarationName(node));
                    addDeclarationToSymbol(symbol, node, symbolKind);
                    bindChildren(node, symbolKind, false);
                    var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type");
                    addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
                    typeLiteralSymbol.members = {};
                    typeLiteralSymbol.members[node.kind === 134 /* FunctionType */ ? "__call" : "__new"] = symbol;
                }
                function bindAnonymousDeclaration(node, symbolKind, name, isBlockScopeContainer) {
                    var symbol = createSymbol(symbolKind, name);
                    addDeclarationToSymbol(symbol, node, symbolKind);
                    bindChildren(node, symbolKind, isBlockScopeContainer);
                }
                function bindCatchVariableDeclaration(node) {
                    var symbol = createSymbol(1 /* FunctionScopedVariable */, node.variable.text || "__missing");
                    addDeclarationToSymbol(symbol, node, 1 /* FunctionScopedVariable */);
                    var saveParent = parent;
                    var savedBlockScopeContainer = blockScopeContainer;
                    parent = blockScopeContainer = node;
                    ts.forEachChild(node, bind);
                    parent = saveParent;
                    blockScopeContainer = savedBlockScopeContainer;
                }
                function bindBlockScopedVariableDeclaration(node) {
                    switch (blockScopeContainer.kind) {
                        case 193 /* ModuleDeclaration */:
                            declareModuleMember(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */);
                            break;
                        case 198 /* SourceFile */:
                            if (ts.isExternalModule(container)) {
                                declareModuleMember(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */);
                                break;
                            }
                        default:
                            if (!blockScopeContainer.locals) {
                                blockScopeContainer.locals = {};
                            }
                            declareSymbol(blockScopeContainer.locals, undefined, node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */);
                    }
                    bindChildren(node, 2 /* BlockScopedVariable */, false);
                }
                function bind(node) {
                    node.parent = parent;
                    switch (node.kind) {
                        case 123 /* TypeParameter */:
                            bindDeclaration(node, 1048576 /* TypeParameter */, 2103776 /* TypeParameterExcludes */, false);
                            break;
                        case 124 /* Parameter */:
                            bindDeclaration(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */, false);
                            break;
                        case 186 /* VariableDeclaration */:
                            if (node.flags & 6144 /* BlockScoped */) {
                                bindBlockScopedVariableDeclaration(node);
                            }
                            else {
                                bindDeclaration(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */, false);
                            }
                            break;
                        case 125 /* Property */:
                        case 144 /* PropertyAssignment */:
                        case 145 /* ShorthandPropertyAssignment */:
                            bindDeclaration(node, 4 /* Property */, 107455 /* PropertyExcludes */, false);
                            break;
                        case 197 /* EnumMember */:
                            bindDeclaration(node, 8 /* EnumMember */, 107455 /* EnumMemberExcludes */, false);
                            break;
                        case 130 /* CallSignature */:
                            bindDeclaration(node, 131072 /* CallSignature */, 0, false);
                            break;
                        case 131 /* ConstructSignature */:
                            bindDeclaration(node, 262144 /* ConstructSignature */, 0, true);
                            break;
                        case 126 /* Method */:
                            bindDeclaration(node, 8192 /* Method */, 99263 /* MethodExcludes */, true);
                            break;
                        case 132 /* IndexSignature */:
                            bindDeclaration(node, 524288 /* IndexSignature */, 0, false);
                            break;
                        case 187 /* FunctionDeclaration */:
                            bindDeclaration(node, 16 /* Function */, 106927 /* FunctionExcludes */, true);
                            break;
                        case 127 /* Constructor */:
                            bindConstructorDeclaration(node);
                            break;
                        case 128 /* GetAccessor */:
                            bindDeclaration(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */, true);
                            break;
                        case 129 /* SetAccessor */:
                            bindDeclaration(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */, true);
                            break;
                        case 134 /* FunctionType */:
                        case 135 /* ConstructorType */:
                            bindFunctionOrConstructorType(node);
                            break;
                        case 137 /* TypeLiteral */:
                            bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type", false);
                            break;
                        case 143 /* ObjectLiteral */:
                            bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object", false);
                            break;
                        case 153 /* FunctionExpression */:
                        case 154 /* ArrowFunction */:
                            bindAnonymousDeclaration(node, 16 /* Function */, "__function", true);
                            break;
                        case 183 /* CatchBlock */:
                            bindCatchVariableDeclaration(node);
                            break;
                        case 189 /* ClassDeclaration */:
                            bindDeclaration(node, 32 /* Class */, 3258879 /* ClassExcludes */, false);
                            break;
                        case 190 /* InterfaceDeclaration */:
                            bindDeclaration(node, 64 /* Interface */, 3152288 /* InterfaceExcludes */, false);
                            break;
                        case 191 /* TypeAliasDeclaration */:
                            bindDeclaration(node, 2097152 /* TypeAlias */, 3152352 /* TypeAliasExcludes */, false);
                            break;
                        case 192 /* EnumDeclaration */:
                            if (ts.isConst(node)) {
                                bindDeclaration(node, 128 /* ConstEnum */, 3259263 /* ConstEnumExcludes */, false);
                            }
                            else {
                                bindDeclaration(node, 256 /* RegularEnum */, 3258623 /* RegularEnumExcludes */, false);
                            }
                            break;
                        case 193 /* ModuleDeclaration */:
                            bindModuleDeclaration(node);
                            break;
                        case 195 /* ImportDeclaration */:
                            bindDeclaration(node, 33554432 /* Import */, 33554432 /* ImportExcludes */, false);
                            break;
                        case 198 /* SourceFile */:
                            if (ts.isExternalModule(node)) {
                                bindAnonymousDeclaration(node, 512 /* ValueModule */, '"' + ts.removeFileExtension(node.filename) + '"', true);
                                break;
                            }
                        case 163 /* Block */:
                        case 182 /* TryBlock */:
                        case 183 /* CatchBlock */:
                        case 184 /* FinallyBlock */:
                        case 170 /* ForStatement */:
                        case 171 /* ForInStatement */:
                        case 176 /* SwitchStatement */:
                            bindChildren(node, 0, true);
                            break;
                        default:
                            var saveParent = parent;
                            parent = node;
                            ts.forEachChild(node, bind);
                            parent = saveParent;
                    }
                }
            }
            ts.bindSourceFile = bindSourceFile;
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var indentStrings = ["", "    "];
            function getIndentString(level) {
                if (indentStrings[level] === undefined) {
                    indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
                }
                return indentStrings[level];
            }
            ts.getIndentString = getIndentString;
            function getIndentSize() {
                return indentStrings[1].length;
            }
            function shouldEmitToOwnFile(sourceFile, compilerOptions) {
                if (!ts.isDeclarationFile(sourceFile)) {
                    if ((ts.isExternalModule(sourceFile) || !compilerOptions.out) && !ts.fileExtensionIs(sourceFile.filename, ".js")) {
                        return true;
                    }
                    return false;
                }
                return false;
            }
            ts.shouldEmitToOwnFile = shouldEmitToOwnFile;
            function isExternalModuleOrDeclarationFile(sourceFile) {
                return ts.isExternalModule(sourceFile) || ts.isDeclarationFile(sourceFile);
            }
            ts.isExternalModuleOrDeclarationFile = isExternalModuleOrDeclarationFile;
            function createTextWriter(newLine) {
                var output = "";
                var indent = 0;
                var lineStart = true;
                var lineCount = 0;
                var linePos = 0;
                function write(s) {
                    if (s && s.length) {
                        if (lineStart) {
                            output += getIndentString(indent);
                            lineStart = false;
                        }
                        output += s;
                    }
                }
                function rawWrite(s) {
                    if (s !== undefined) {
                        if (lineStart) {
                            lineStart = false;
                        }
                        output += s;
                    }
                }
                function writeLiteral(s) {
                    if (s && s.length) {
                        write(s);
                        var lineStartsOfS = ts.computeLineStarts(s);
                        if (lineStartsOfS.length > 1) {
                            lineCount = lineCount + lineStartsOfS.length - 1;
                            linePos = output.length - s.length + lineStartsOfS[lineStartsOfS.length - 1];
                        }
                    }
                }
                function writeLine() {
                    if (!lineStart) {
                        output += newLine;
                        lineCount++;
                        linePos = output.length;
                        lineStart = true;
                    }
                }
                function writeTextOfNode(sourceFile, node) {
                    write(ts.getSourceTextOfNodeFromSourceFile(sourceFile, node));
                }
                return {
                    write: write,
                    rawWrite: rawWrite,
                    writeTextOfNode: writeTextOfNode,
                    writeLiteral: writeLiteral,
                    writeLine: writeLine,
                    increaseIndent: function () { return indent++; },
                    decreaseIndent: function () { return indent--; },
                    getIndent: function () { return indent; },
                    getTextPos: function () { return output.length; },
                    getLine: function () { return lineCount + 1; },
                    getColumn: function () { return lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1; },
                    getText: function () { return output; }
                };
            }
            function getLineOfLocalPosition(currentSourceFile, pos) {
                return currentSourceFile.getLineAndCharacterFromPosition(pos).line;
            }
            function emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments) {
                if (leadingComments && leadingComments.length && node.pos !== leadingComments[0].pos && getLineOfLocalPosition(currentSourceFile, node.pos) !== getLineOfLocalPosition(currentSourceFile, leadingComments[0].pos)) {
                    writer.writeLine();
                }
            }
            function emitComments(currentSourceFile, writer, comments, trailingSeparator, newLine, writeComment) {
                var emitLeadingSpace = !trailingSeparator;
                ts.forEach(comments, function (comment) {
                    if (emitLeadingSpace) {
                        writer.write(" ");
                        emitLeadingSpace = false;
                    }
                    writeComment(currentSourceFile, writer, comment, newLine);
                    if (comment.hasTrailingNewLine) {
                        writer.writeLine();
                    }
                    else if (trailingSeparator) {
                        writer.write(" ");
                    }
                    else {
                        emitLeadingSpace = true;
                    }
                });
            }
            function writeCommentRange(currentSourceFile, writer, comment, newLine) {
                if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 42 /* asterisk */) {
                    var firstCommentLineAndCharacter = currentSourceFile.getLineAndCharacterFromPosition(comment.pos);
                    var firstCommentLineIndent;
                    for (var pos = comment.pos, currentLine = firstCommentLineAndCharacter.line; pos < comment.end; currentLine++) {
                        var nextLineStart = currentSourceFile.getPositionFromLineAndCharacter(currentLine + 1, 1);
                        if (pos !== comment.pos) {
                            if (firstCommentLineIndent === undefined) {
                                firstCommentLineIndent = calculateIndent(currentSourceFile.getPositionFromLineAndCharacter(firstCommentLineAndCharacter.line, 1), comment.pos);
                            }
                            var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
                            var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(pos, nextLineStart);
                            if (spacesToEmit > 0) {
                                var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
                                var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
                                writer.rawWrite(indentSizeSpaceString);
                                while (numberOfSingleSpacesToEmit) {
                                    writer.rawWrite(" ");
                                    numberOfSingleSpacesToEmit--;
                                }
                            }
                            else {
                                writer.rawWrite("");
                            }
                        }
                        writeTrimmedCurrentLine(pos, nextLineStart);
                        pos = nextLineStart;
                    }
                }
                else {
                    writer.write(currentSourceFile.text.substring(comment.pos, comment.end));
                }
                function writeTrimmedCurrentLine(pos, nextLineStart) {
                    var end = Math.min(comment.end, nextLineStart - 1);
                    var currentLineText = currentSourceFile.text.substring(pos, end).replace(/^\s+|\s+$/g, '');
                    if (currentLineText) {
                        writer.write(currentLineText);
                        if (end !== comment.end) {
                            writer.writeLine();
                        }
                    }
                    else {
                        writer.writeLiteral(newLine);
                    }
                }
                function calculateIndent(pos, end) {
                    var currentLineIndent = 0;
                    for (; pos < end && ts.isWhiteSpace(currentSourceFile.text.charCodeAt(pos)); pos++) {
                        if (currentSourceFile.text.charCodeAt(pos) === 9 /* tab */) {
                            currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
                        }
                        else {
                            currentLineIndent++;
                        }
                    }
                    return currentLineIndent;
                }
            }
            function getFirstConstructorWithBody(node) {
                return ts.forEach(node.members, function (member) {
                    if (member.kind === 127 /* Constructor */ && member.body) {
                        return member;
                    }
                });
            }
            function getAllAccessorDeclarations(node, accessor) {
                var firstAccessor;
                var getAccessor;
                var setAccessor;
                if (accessor.name.kind === 122 /* ComputedPropertyName */) {
                    firstAccessor = accessor;
                    if (accessor.kind === 128 /* GetAccessor */) {
                        getAccessor = accessor;
                    }
                    else if (accessor.kind === 129 /* SetAccessor */) {
                        setAccessor = accessor;
                    }
                    else {
                        ts.Debug.fail("Accessor has wrong kind");
                    }
                }
                else {
                    ts.forEach(node.members, function (member) {
                        if ((member.kind === 128 /* GetAccessor */ || member.kind === 129 /* SetAccessor */) && member.name.text === accessor.name.text && (member.flags & 128 /* Static */) === (accessor.flags & 128 /* Static */)) {
                            if (!firstAccessor) {
                                firstAccessor = member;
                            }
                            if (member.kind === 128 /* GetAccessor */ && !getAccessor) {
                                getAccessor = member;
                            }
                            if (member.kind === 129 /* SetAccessor */ && !setAccessor) {
                                setAccessor = member;
                            }
                        }
                    });
                }
                return {
                    firstAccessor: firstAccessor,
                    getAccessor: getAccessor,
                    setAccessor: setAccessor
                };
            }
            function getSourceFilePathInNewDir(sourceFile, program, newDirPath) {
                var compilerHost = program.getCompilerHost();
                var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.filename, compilerHost.getCurrentDirectory());
                sourceFilePath = sourceFilePath.replace(program.getCommonSourceDirectory(), "");
                return ts.combinePaths(newDirPath, sourceFilePath);
            }
            function getOwnEmitOutputFilePath(sourceFile, program, extension) {
                var compilerOptions = program.getCompilerOptions();
                if (compilerOptions.outDir) {
                    var emitOutputFilePathWithoutExtension = ts.removeFileExtension(getSourceFilePathInNewDir(sourceFile, program, compilerOptions.outDir));
                }
                else {
                    var emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.filename);
                }
                return emitOutputFilePathWithoutExtension + extension;
            }
            function writeFile(compilerHost, diagnostics, filename, data, writeByteOrderMark) {
                compilerHost.writeFile(filename, data, writeByteOrderMark, function (hostErrorMessage) {
                    diagnostics.push(ts.createCompilerDiagnostic(ts.Diagnostics.Could_not_write_file_0_Colon_1, filename, hostErrorMessage));
                });
            }
            function emitDeclarations(program, resolver, diagnostics, jsFilePath, root) {
                var newLine = program.getCompilerHost().getNewLine();
                var compilerOptions = program.getCompilerOptions();
                var compilerHost = program.getCompilerHost();
                var write;
                var writeLine;
                var increaseIndent;
                var decreaseIndent;
                var writeTextOfNode;
                var writer = createAndSetNewTextWriterWithSymbolWriter();
                var enclosingDeclaration;
                var currentSourceFile;
                var reportedDeclarationError = false;
                var emitJsDocComments = compilerOptions.removeComments ? function (declaration) {
                } : writeJsDocComments;
                var aliasDeclarationEmitInfo = [];
                function createAndSetNewTextWriterWithSymbolWriter() {
                    var writer = createTextWriter(newLine);
                    writer.trackSymbol = trackSymbol;
                    writer.writeKeyword = writer.write;
                    writer.writeOperator = writer.write;
                    writer.writePunctuation = writer.write;
                    writer.writeSpace = writer.write;
                    writer.writeStringLiteral = writer.writeLiteral;
                    writer.writeParameter = writer.write;
                    writer.writeSymbol = writer.write;
                    setWriter(writer);
                    return writer;
                }
                function setWriter(newWriter) {
                    writer = newWriter;
                    write = newWriter.write;
                    writeTextOfNode = newWriter.writeTextOfNode;
                    writeLine = newWriter.writeLine;
                    increaseIndent = newWriter.increaseIndent;
                    decreaseIndent = newWriter.decreaseIndent;
                }
                function writeAsychronousImportDeclarations(importDeclarations) {
                    var oldWriter = writer;
                    ts.forEach(importDeclarations, function (aliasToWrite) {
                        var aliasEmitInfo = ts.forEach(aliasDeclarationEmitInfo, function (declEmitInfo) { return declEmitInfo.declaration === aliasToWrite ? declEmitInfo : undefined; });
                        if (aliasEmitInfo) {
                            createAndSetNewTextWriterWithSymbolWriter();
                            for (var declarationIndent = aliasEmitInfo.indent; declarationIndent; declarationIndent--) {
                                increaseIndent();
                            }
                            writeImportDeclaration(aliasToWrite);
                            aliasEmitInfo.asynchronousOutput = writer.getText();
                        }
                    });
                    setWriter(oldWriter);
                }
                function handleSymbolAccessibilityError(symbolAccesibilityResult) {
                    if (symbolAccesibilityResult.accessibility === 0 /* Accessible */) {
                        if (symbolAccesibilityResult && symbolAccesibilityResult.aliasesToMakeVisible) {
                            writeAsychronousImportDeclarations(symbolAccesibilityResult.aliasesToMakeVisible);
                        }
                    }
                    else {
                        reportedDeclarationError = true;
                        var errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccesibilityResult);
                        if (errorInfo) {
                            if (errorInfo.typeName) {
                                diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, errorInfo.typeName), symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
                            }
                            else {
                                diagnostics.push(ts.createDiagnosticForNode(symbolAccesibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccesibilityResult.errorSymbolName, symbolAccesibilityResult.errorModuleName));
                            }
                        }
                    }
                }
                function trackSymbol(symbol, enclosingDeclaration, meaning) {
                    handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning));
                }
                function writeTypeAtLocation(location, type, getSymbolAccessibilityDiagnostic) {
                    writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
                    write(": ");
                    if (type) {
                        emitType(type);
                    }
                    else {
                        resolver.writeTypeAtLocation(location, enclosingDeclaration, 2 /* UseTypeOfFunction */, writer);
                    }
                }
                function writeReturnTypeAtSignature(signature, getSymbolAccessibilityDiagnostic) {
                    writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
                    write(": ");
                    if (signature.type) {
                        emitType(signature.type);
                    }
                    else {
                        resolver.writeReturnTypeOfSignatureDeclaration(signature, enclosingDeclaration, 2 /* UseTypeOfFunction */, writer);
                    }
                }
                function emitLines(nodes) {
                    for (var i = 0, n = nodes.length; i < n; i++) {
                        emitNode(nodes[i]);
                    }
                }
                function emitSeparatedList(nodes, separator, eachNodeEmitFn) {
                    var currentWriterPos = writer.getTextPos();
                    for (var i = 0, n = nodes.length; i < n; i++) {
                        if (currentWriterPos !== writer.getTextPos()) {
                            write(separator);
                        }
                        currentWriterPos = writer.getTextPos();
                        eachNodeEmitFn(nodes[i]);
                    }
                }
                function emitCommaList(nodes, eachNodeEmitFn) {
                    emitSeparatedList(nodes, ", ", eachNodeEmitFn);
                }
                function writeJsDocComments(declaration) {
                    if (declaration) {
                        var jsDocComments = ts.getJsDocComments(declaration, currentSourceFile);
                        emitNewLineBeforeLeadingComments(currentSourceFile, writer, declaration, jsDocComments);
                        emitComments(currentSourceFile, writer, jsDocComments, true, newLine, writeCommentRange);
                    }
                }
                function emitTypeWithNewGetSymbolAccessibilityDiangostic(type, getSymbolAccessibilityDiagnostic) {
                    writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic;
                    emitType(type);
                }
                function emitType(type) {
                    switch (type.kind) {
                        case 109 /* AnyKeyword */:
                        case 118 /* StringKeyword */:
                        case 116 /* NumberKeyword */:
                        case 110 /* BooleanKeyword */:
                        case 97 /* VoidKeyword */:
                        case 7 /* StringLiteral */:
                            return writeTextOfNode(currentSourceFile, type);
                        case 133 /* TypeReference */:
                            return emitTypeReference(type);
                        case 136 /* TypeQuery */:
                            return emitTypeQuery(type);
                        case 138 /* ArrayType */:
                            return emitArrayType(type);
                        case 139 /* TupleType */:
                            return emitTupleType(type);
                        case 140 /* UnionType */:
                            return emitUnionType(type);
                        case 141 /* ParenType */:
                            return emitParenType(type);
                        case 134 /* FunctionType */:
                        case 135 /* ConstructorType */:
                            return emitSignatureDeclarationWithJsDocComments(type);
                        case 137 /* TypeLiteral */:
                            return emitTypeLiteral(type);
                        case 63 /* Identifier */:
                            return emitEntityName(type);
                        case 121 /* QualifiedName */:
                            return emitEntityName(type);
                        default:
                            ts.Debug.fail("Unknown type annotation: " + type.kind);
                    }
                    function emitEntityName(entityName) {
                        var visibilityResult = resolver.isEntityNameVisible(entityName, entityName.parent.kind === 195 /* ImportDeclaration */ ? entityName.parent : enclosingDeclaration);
                        handleSymbolAccessibilityError(visibilityResult);
                        writeEntityName(entityName);
                        function writeEntityName(entityName) {
                            if (entityName.kind === 63 /* Identifier */) {
                                writeTextOfNode(currentSourceFile, entityName);
                            }
                            else {
                                var qualifiedName = entityName;
                                writeEntityName(qualifiedName.left);
                                write(".");
                                writeTextOfNode(currentSourceFile, qualifiedName.right);
                            }
                        }
                    }
                    function emitTypeReference(type) {
                        emitEntityName(type.typeName);
                        if (type.typeArguments) {
                            write("<");
                            emitCommaList(type.typeArguments, emitType);
                            write(">");
                        }
                    }
                    function emitTypeQuery(type) {
                        write("typeof ");
                        emitEntityName(type.exprName);
                    }
                    function emitArrayType(type) {
                        emitType(type.elementType);
                        write("[]");
                    }
                    function emitTupleType(type) {
                        write("[");
                        emitCommaList(type.elementTypes, emitType);
                        write("]");
                    }
                    function emitUnionType(type) {
                        emitSeparatedList(type.types, " | ", emitType);
                    }
                    function emitParenType(type) {
                        write("(");
                        emitType(type.type);
                        write(")");
                    }
                    function emitTypeLiteral(type) {
                        write("{");
                        if (type.members.length) {
                            writeLine();
                            increaseIndent();
                            emitLines(type.members);
                            decreaseIndent();
                        }
                        write("}");
                    }
                }
                function emitSourceFile(node) {
                    currentSourceFile = node;
                    enclosingDeclaration = node;
                    emitLines(node.statements);
                }
                function emitExportAssignment(node) {
                    write("export = ");
                    writeTextOfNode(currentSourceFile, node.exportName);
                    write(";");
                    writeLine();
                }
                function emitModuleElementDeclarationFlags(node) {
                    if (node.parent === currentSourceFile) {
                        if (node.flags & 1 /* Export */) {
                            write("export ");
                        }
                        if (node.kind !== 190 /* InterfaceDeclaration */) {
                            write("declare ");
                        }
                    }
                }
                function emitClassMemberDeclarationFlags(node) {
                    if (node.flags & 32 /* Private */) {
                        write("private ");
                    }
                    else if (node.flags & 64 /* Protected */) {
                        write("protected ");
                    }
                    if (node.flags & 128 /* Static */) {
                        write("static ");
                    }
                }
                function emitImportDeclaration(node) {
                    var nodeEmitInfo = {
                        declaration: node,
                        outputPos: writer.getTextPos(),
                        indent: writer.getIndent(),
                        hasWritten: resolver.isDeclarationVisible(node)
                    };
                    aliasDeclarationEmitInfo.push(nodeEmitInfo);
                    if (nodeEmitInfo.hasWritten) {
                        writeImportDeclaration(node);
                    }
                }
                function writeImportDeclaration(node) {
                    emitJsDocComments(node);
                    if (node.flags & 1 /* Export */) {
                        write("export ");
                    }
                    write("import ");
                    writeTextOfNode(currentSourceFile, node.name);
                    write(" = ");
                    if (node.entityName) {
                        emitTypeWithNewGetSymbolAccessibilityDiangostic(node.entityName, getImportEntityNameVisibilityError);
                        write(";");
                    }
                    else {
                        write("require(");
                        writeTextOfNode(currentSourceFile, node.externalModuleName);
                        write(");");
                    }
                    writer.writeLine();
                    function getImportEntityNameVisibilityError(symbolAccesibilityResult) {
                        return {
                            diagnosticMessage: ts.Diagnostics.Import_declaration_0_is_using_private_name_1,
                            errorNode: node,
                            typeName: node.name
                        };
                    }
                }
                function emitModuleDeclaration(node) {
                    if (resolver.isDeclarationVisible(node)) {
                        emitJsDocComments(node);
                        emitModuleElementDeclarationFlags(node);
                        write("module ");
                        writeTextOfNode(currentSourceFile, node.name);
                        while (node.body.kind !== 194 /* ModuleBlock */) {
                            node = node.body;
                            write(".");
                            writeTextOfNode(currentSourceFile, node.name);
                        }
                        var prevEnclosingDeclaration = enclosingDeclaration;
                        enclosingDeclaration = node;
                        write(" {");
                        writeLine();
                        increaseIndent();
                        emitLines(node.body.statements);
                        decreaseIndent();
                        write("}");
                        writeLine();
                        enclosingDeclaration = prevEnclosingDeclaration;
                    }
                }
                function emitTypeAliasDeclaration(node) {
                    if (resolver.isDeclarationVisible(node)) {
                        emitJsDocComments(node);
                        emitModuleElementDeclarationFlags(node);
                        write("type ");
                        writeTextOfNode(currentSourceFile, node.name);
                        write(" = ");
                        emitTypeWithNewGetSymbolAccessibilityDiangostic(node.type, getTypeAliasDeclarationVisibilityError);
                        write(";");
                        writeLine();
                    }
                    function getTypeAliasDeclarationVisibilityError(symbolAccesibilityResult) {
                        return {
                            diagnosticMessage: ts.Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
                            errorNode: node.type,
                            typeName: node.name
                        };
                    }
                }
                function emitEnumDeclaration(node) {
                    if (resolver.isDeclarationVisible(node)) {
                        emitJsDocComments(node);
                        emitModuleElementDeclarationFlags(node);
                        if (ts.isConst(node)) {
                            write("const ");
                        }
                        write("enum ");
                        writeTextOfNode(currentSourceFile, node.name);
                        write(" {");
                        writeLine();
                        increaseIndent();
                        emitLines(node.members);
                        decreaseIndent();
                        write("}");
                        writeLine();
                    }
                }
                function emitEnumMemberDeclaration(node) {
                    emitJsDocComments(node);
                    writeTextOfNode(currentSourceFile, node.name);
                    var enumMemberValue = resolver.getEnumMemberValue(node);
                    if (enumMemberValue !== undefined) {
                        write(" = ");
                        write(enumMemberValue.toString());
                    }
                    write(",");
                    writeLine();
                }
                function emitTypeParameters(typeParameters) {
                    function emitTypeParameter(node) {
                        increaseIndent();
                        emitJsDocComments(node);
                        decreaseIndent();
                        writeTextOfNode(currentSourceFile, node.name);
                        if (node.constraint && (node.parent.kind !== 126 /* Method */ || !(node.parent.flags & 32 /* Private */))) {
                            write(" extends ");
                            if (node.parent.kind === 134 /* FunctionType */ || node.parent.kind === 135 /* ConstructorType */ || (node.parent.parent && node.parent.parent.kind === 137 /* TypeLiteral */)) {
                                ts.Debug.assert(node.parent.kind === 126 /* Method */ || node.parent.kind === 134 /* FunctionType */ || node.parent.kind === 135 /* ConstructorType */ || node.parent.kind === 130 /* CallSignature */ || node.parent.kind === 131 /* ConstructSignature */);
                                emitType(node.constraint);
                            }
                            else {
                                emitTypeWithNewGetSymbolAccessibilityDiangostic(node.constraint, getTypeParameterConstraintVisibilityError);
                            }
                        }
                        function getTypeParameterConstraintVisibilityError(symbolAccesibilityResult) {
                            var diagnosticMessage;
                            switch (node.parent.kind) {
                                case 189 /* ClassDeclaration */:
                                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1;
                                    break;
                                case 190 /* InterfaceDeclaration */:
                                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
                                    break;
                                case 131 /* ConstructSignature */:
                                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                                    break;
                                case 130 /* CallSignature */:
                                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                                    break;
                                case 126 /* Method */:
                                    if (node.parent.flags & 128 /* Static */) {
                                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
                                    }
                                    else if (node.parent.parent.kind === 189 /* ClassDeclaration */) {
                                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
                                    }
                                    else {
                                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
                                    }
                                    break;
                                case 187 /* FunctionDeclaration */:
                                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1;
                                    break;
                                default:
                                    ts.Debug.fail("This is unknown parent for type parameter: " + node.parent.kind);
                            }
                            return {
                                diagnosticMessage: diagnosticMessage,
                                errorNode: node,
                                typeName: node.name
                            };
                        }
                    }
                    if (typeParameters) {
                        write("<");
                        emitCommaList(typeParameters, emitTypeParameter);
                        write(">");
                    }
                }
                function emitHeritageClause(typeReferences, isImplementsList) {
                    if (typeReferences) {
                        write(isImplementsList ? " implements " : " extends ");
                        emitCommaList(typeReferences, emitTypeOfTypeReference);
                    }
                    function emitTypeOfTypeReference(node) {
                        emitTypeWithNewGetSymbolAccessibilityDiangostic(node, getHeritageClauseVisibilityError);
                        function getHeritageClauseVisibilityError(symbolAccesibilityResult) {
                            var diagnosticMessage;
                            if (node.parent.kind === 189 /* ClassDeclaration */) {
                                diagnosticMessage = isImplementsList ? ts.Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 : ts.Diagnostics.Extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
                            }
                            else {
                                diagnosticMessage = ts.Diagnostics.Extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
                            }
                            return {
                                diagnosticMessage: diagnosticMessage,
                                errorNode: node,
                                typeName: node.parent.name
                            };
                        }
                    }
                }
                function emitClassDeclaration(node) {
                    function emitParameterProperties(constructorDeclaration) {
                        if (constructorDeclaration) {
                            ts.forEach(constructorDeclaration.parameters, function (param) {
                                if (param.flags & 112 /* AccessibilityModifier */) {
                                    emitPropertyDeclaration(param);
                                }
                            });
                        }
                    }
                    if (resolver.isDeclarationVisible(node)) {
                        emitJsDocComments(node);
                        emitModuleElementDeclarationFlags(node);
                        write("class ");
                        writeTextOfNode(currentSourceFile, node.name);
                        var prevEnclosingDeclaration = enclosingDeclaration;
                        enclosingDeclaration = node;
                        emitTypeParameters(node.typeParameters);
                        if (node.baseType) {
                            emitHeritageClause([node.baseType], false);
                        }
                        emitHeritageClause(node.implementedTypes, true);
                        write(" {");
                        writeLine();
                        increaseIndent();
                        emitParameterProperties(getFirstConstructorWithBody(node));
                        emitLines(node.members);
                        decreaseIndent();
                        write("}");
                        writeLine();
                        enclosingDeclaration = prevEnclosingDeclaration;
                    }
                }
                function emitInterfaceDeclaration(node) {
                    if (resolver.isDeclarationVisible(node)) {
                        emitJsDocComments(node);
                        emitModuleElementDeclarationFlags(node);
                        write("interface ");
                        writeTextOfNode(currentSourceFile, node.name);
                        var prevEnclosingDeclaration = enclosingDeclaration;
                        enclosingDeclaration = node;
                        emitTypeParameters(node.typeParameters);
                        emitHeritageClause(node.baseTypes, false);
                        write(" {");
                        writeLine();
                        increaseIndent();
                        emitLines(node.members);
                        decreaseIndent();
                        write("}");
                        writeLine();
                        enclosingDeclaration = prevEnclosingDeclaration;
                    }
                }
                function emitPropertyDeclaration(node) {
                    emitJsDocComments(node);
                    emitClassMemberDeclarationFlags(node);
                    emitVariableDeclaration(node);
                    write(";");
                    writeLine();
                }
                function emitVariableDeclaration(node) {
                    if (node.kind !== 186 /* VariableDeclaration */ || resolver.isDeclarationVisible(node)) {
                        writeTextOfNode(currentSourceFile, node.name);
                        if (node.kind === 125 /* Property */ && (node.flags & 4 /* QuestionMark */)) {
                            write("?");
                        }
                        if (node.kind === 125 /* Property */ && node.parent.kind === 137 /* TypeLiteral */) {
                            emitTypeOfVariableDeclarationFromTypeLiteral(node);
                        }
                        else if (!(node.flags & 32 /* Private */)) {
                            writeTypeAtLocation(node, node.type, getVariableDeclarationTypeVisibilityError);
                        }
                    }
                    function getVariableDeclarationTypeVisibilityError(symbolAccesibilityResult) {
                        var diagnosticMessage;
                        if (node.kind === 186 /* VariableDeclaration */) {
                            diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Exported_variable_0_has_or_is_using_private_name_1;
                        }
                        else if (node.kind === 125 /* Property */) {
                            if (node.flags & 128 /* Static */) {
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
                            }
                            else if (node.parent.kind === 189 /* ClassDeclaration */) {
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
                            }
                            else {
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
                            }
                        }
                        return diagnosticMessage !== undefined ? {
                            diagnosticMessage: diagnosticMessage,
                            errorNode: node,
                            typeName: node.name
                        } : undefined;
                    }
                }
                function emitTypeOfVariableDeclarationFromTypeLiteral(node) {
                    if (node.type) {
                        write(": ");
                        emitType(node.type);
                    }
                }
                function emitVariableStatement(node) {
                    var hasDeclarationWithEmit = ts.forEach(node.declarations, function (varDeclaration) { return resolver.isDeclarationVisible(varDeclaration); });
                    if (hasDeclarationWithEmit) {
                        emitJsDocComments(node);
                        emitModuleElementDeclarationFlags(node);
                        if (ts.isLet(node)) {
                            write("let ");
                        }
                        else if (ts.isConst(node)) {
                            write("const ");
                        }
                        else {
                            write("var ");
                        }
                        emitCommaList(node.declarations, emitVariableDeclaration);
                        write(";");
                        writeLine();
                    }
                }
                function emitAccessorDeclaration(node) {
                    var accessors = getAllAccessorDeclarations(node.parent, node);
                    if (node === accessors.firstAccessor) {
                        emitJsDocComments(accessors.getAccessor);
                        emitJsDocComments(accessors.setAccessor);
                        emitClassMemberDeclarationFlags(node);
                        writeTextOfNode(currentSourceFile, node.name);
                        if (!(node.flags & 32 /* Private */)) {
                            var accessorWithTypeAnnotation = node;
                            var type = getTypeAnnotationFromAccessor(node);
                            if (!type) {
                                var anotherAccessor = node.kind === 128 /* GetAccessor */ ? accessors.setAccessor : accessors.getAccessor;
                                type = getTypeAnnotationFromAccessor(anotherAccessor);
                                if (type) {
                                    accessorWithTypeAnnotation = anotherAccessor;
                                }
                            }
                            writeTypeAtLocation(node, type, getAccessorDeclarationTypeVisibilityError);
                        }
                        write(";");
                        writeLine();
                    }
                    function getTypeAnnotationFromAccessor(accessor) {
                        if (accessor) {
                            return accessor.kind === 128 /* GetAccessor */ ? accessor.type : accessor.parameters[0].type;
                        }
                    }
                    function getAccessorDeclarationTypeVisibilityError(symbolAccesibilityResult) {
                        var diagnosticMessage;
                        if (accessorWithTypeAnnotation.kind === 129 /* SetAccessor */) {
                            if (accessorWithTypeAnnotation.parent.flags & 128 /* Static */) {
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? ts.Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1;
                            }
                            else {
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? ts.Diagnostics.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1;
                            }
                            return {
                                diagnosticMessage: diagnosticMessage,
                                errorNode: accessorWithTypeAnnotation.parameters[0],
                                typeName: accessorWithTypeAnnotation.name
                            };
                        }
                        else {
                            if (accessorWithTypeAnnotation.flags & 128 /* Static */) {
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : ts.Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 : ts.Diagnostics.Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0;
                            }
                            else {
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : ts.Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1 : ts.Diagnostics.Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0;
                            }
                            return {
                                diagnosticMessage: diagnosticMessage,
                                errorNode: accessorWithTypeAnnotation.name,
                                typeName: undefined
                            };
                        }
                    }
                }
                function emitFunctionDeclaration(node) {
                    if ((node.kind !== 187 /* FunctionDeclaration */ || resolver.isDeclarationVisible(node)) && !resolver.isImplementationOfOverload(node)) {
                        emitJsDocComments(node);
                        if (node.kind === 187 /* FunctionDeclaration */) {
                            emitModuleElementDeclarationFlags(node);
                        }
                        else if (node.kind === 126 /* Method */) {
                            emitClassMemberDeclarationFlags(node);
                        }
                        if (node.kind === 187 /* FunctionDeclaration */) {
                            write("function ");
                            writeTextOfNode(currentSourceFile, node.name);
                        }
                        else if (node.kind === 127 /* Constructor */) {
                            write("constructor");
                        }
                        else {
                            writeTextOfNode(currentSourceFile, node.name);
                            if (node.flags & 4 /* QuestionMark */) {
                                write("?");
                            }
                        }
                        emitSignatureDeclaration(node);
                    }
                }
                function emitSignatureDeclarationWithJsDocComments(node) {
                    emitJsDocComments(node);
                    emitSignatureDeclaration(node);
                }
                function emitSignatureDeclaration(node) {
                    if (node.kind === 131 /* ConstructSignature */ || node.kind === 135 /* ConstructorType */) {
                        write("new ");
                    }
                    emitTypeParameters(node.typeParameters);
                    if (node.kind === 132 /* IndexSignature */) {
                        write("[");
                    }
                    else {
                        write("(");
                    }
                    var prevEnclosingDeclaration = enclosingDeclaration;
                    enclosingDeclaration = node;
                    emitCommaList(node.parameters, emitParameterDeclaration);
                    if (node.kind === 132 /* IndexSignature */) {
                        write("]");
                    }
                    else {
                        write(")");
                    }
                    var isFunctionTypeOrConstructorType = node.kind === 134 /* FunctionType */ || node.kind === 135 /* ConstructorType */;
                    if (isFunctionTypeOrConstructorType || node.parent.kind === 137 /* TypeLiteral */) {
                        if (node.type) {
                            write(isFunctionTypeOrConstructorType ? " => " : ": ");
                            emitType(node.type);
                        }
                    }
                    else if (node.kind !== 127 /* Constructor */ && !(node.flags & 32 /* Private */)) {
                        writeReturnTypeAtSignature(node, getReturnTypeVisibilityError);
                    }
                    enclosingDeclaration = prevEnclosingDeclaration;
                    if (!isFunctionTypeOrConstructorType) {
                        write(";");
                        writeLine();
                    }
                    function getReturnTypeVisibilityError(symbolAccesibilityResult) {
                        var diagnosticMessage;
                        switch (node.kind) {
                            case 131 /* ConstructSignature */:
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0;
                                break;
                            case 130 /* CallSignature */:
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0;
                                break;
                            case 132 /* IndexSignature */:
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0;
                                break;
                            case 126 /* Method */:
                                if (node.flags & 128 /* Static */) {
                                    diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0;
                                }
                                else if (node.parent.kind === 189 /* ClassDeclaration */) {
                                    diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0;
                                }
                                else {
                                    diagnosticMessage = symbolAccesibilityResult.errorModuleName ? ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 : ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0;
                                }
                                break;
                            case 187 /* FunctionDeclaration */:
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 : ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_private_name_0;
                                break;
                            default:
                                ts.Debug.fail("This is unknown kind for signature: " + node.kind);
                        }
                        return {
                            diagnosticMessage: diagnosticMessage,
                            errorNode: node.name || node
                        };
                    }
                }
                function emitParameterDeclaration(node) {
                    increaseIndent();
                    emitJsDocComments(node);
                    if (node.flags & 8 /* Rest */) {
                        write("...");
                    }
                    writeTextOfNode(currentSourceFile, node.name);
                    if (node.initializer || (node.flags & 4 /* QuestionMark */)) {
                        write("?");
                    }
                    decreaseIndent();
                    if (node.parent.kind === 134 /* FunctionType */ || node.parent.kind === 135 /* ConstructorType */ || node.parent.parent.kind === 137 /* TypeLiteral */) {
                        emitTypeOfVariableDeclarationFromTypeLiteral(node);
                    }
                    else if (!(node.parent.flags & 32 /* Private */)) {
                        writeTypeAtLocation(node, node.type, getParameterDeclarationTypeVisibilityError);
                    }
                    function getParameterDeclarationTypeVisibilityError(symbolAccesibilityResult) {
                        var diagnosticMessage;
                        switch (node.parent.kind) {
                            case 127 /* Constructor */:
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
                                break;
                            case 131 /* ConstructSignature */:
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                                break;
                            case 130 /* CallSignature */:
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                                break;
                            case 126 /* Method */:
                                if (node.parent.flags & 128 /* Static */) {
                                    diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
                                }
                                else if (node.parent.parent.kind === 189 /* ClassDeclaration */) {
                                    diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
                                }
                                else {
                                    diagnosticMessage = symbolAccesibilityResult.errorModuleName ? ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
                                }
                                break;
                            case 187 /* FunctionDeclaration */:
                                diagnosticMessage = symbolAccesibilityResult.errorModuleName ? symbolAccesibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
                                break;
                            default:
                                ts.Debug.fail("This is unknown parent for parameter: " + node.parent.kind);
                        }
                        return {
                            diagnosticMessage: diagnosticMessage,
                            errorNode: node,
                            typeName: node.name
                        };
                    }
                }
                function emitNode(node) {
                    switch (node.kind) {
                        case 127 /* Constructor */:
                        case 187 /* FunctionDeclaration */:
                        case 126 /* Method */:
                            return emitFunctionDeclaration(node);
                        case 131 /* ConstructSignature */:
                        case 130 /* CallSignature */:
                        case 132 /* IndexSignature */:
                            return emitSignatureDeclarationWithJsDocComments(node);
                        case 128 /* GetAccessor */:
                        case 129 /* SetAccessor */:
                            return emitAccessorDeclaration(node);
                        case 164 /* VariableStatement */:
                            return emitVariableStatement(node);
                        case 125 /* Property */:
                            return emitPropertyDeclaration(node);
                        case 190 /* InterfaceDeclaration */:
                            return emitInterfaceDeclaration(node);
                        case 189 /* ClassDeclaration */:
                            return emitClassDeclaration(node);
                        case 191 /* TypeAliasDeclaration */:
                            return emitTypeAliasDeclaration(node);
                        case 197 /* EnumMember */:
                            return emitEnumMemberDeclaration(node);
                        case 192 /* EnumDeclaration */:
                            return emitEnumDeclaration(node);
                        case 193 /* ModuleDeclaration */:
                            return emitModuleDeclaration(node);
                        case 195 /* ImportDeclaration */:
                            return emitImportDeclaration(node);
                        case 196 /* ExportAssignment */:
                            return emitExportAssignment(node);
                        case 198 /* SourceFile */:
                            return emitSourceFile(node);
                    }
                }
                var referencePathsOutput = "";
                function writeReferencePath(referencedFile) {
                    var declFileName = referencedFile.flags & 1024 /* DeclarationFile */ ? referencedFile.filename : shouldEmitToOwnFile(referencedFile, compilerOptions) ? getOwnEmitOutputFilePath(referencedFile, program, ".d.ts") : ts.removeFileExtension(compilerOptions.out) + ".d.ts";
                    declFileName = ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizeSlashes(jsFilePath)), declFileName, compilerHost.getCurrentDirectory(), compilerHost.getCanonicalFileName, false);
                    referencePathsOutput += "/// <reference path=\"" + declFileName + "\" />" + newLine;
                }
                if (root) {
                    if (!compilerOptions.noResolve) {
                        var addedGlobalFileReference = false;
                        ts.forEach(root.referencedFiles, function (fileReference) {
                            var referencedFile = ts.tryResolveScriptReference(program, root, fileReference);
                            if (referencedFile && ((referencedFile.flags & 1024 /* DeclarationFile */) || shouldEmitToOwnFile(referencedFile, compilerOptions) || !addedGlobalFileReference)) {
                                writeReferencePath(referencedFile);
                                if (!isExternalModuleOrDeclarationFile(referencedFile)) {
                                    addedGlobalFileReference = true;
                                }
                            }
                        });
                    }
                    emitNode(root);
                }
                else {
                    var emittedReferencedFiles = [];
                    ts.forEach(program.getSourceFiles(), function (sourceFile) {
                        if (!isExternalModuleOrDeclarationFile(sourceFile)) {
                            if (!compilerOptions.noResolve) {
                                ts.forEach(sourceFile.referencedFiles, function (fileReference) {
                                    var referencedFile = ts.tryResolveScriptReference(program, sourceFile, fileReference);
                                    if (referencedFile && (isExternalModuleOrDeclarationFile(referencedFile) && !ts.contains(emittedReferencedFiles, referencedFile))) {
                                        writeReferencePath(referencedFile);
                                        emittedReferencedFiles.push(referencedFile);
                                    }
                                });
                            }
                            emitNode(sourceFile);
                        }
                    });
                }
                return {
                    reportedDeclarationError: reportedDeclarationError,
                    aliasDeclarationEmitInfo: aliasDeclarationEmitInfo,
                    synchronousDeclarationOutput: writer.getText(),
                    referencePathsOutput: referencePathsOutput
                };
            }
            function getDeclarationDiagnostics(program, resolver, targetSourceFile) {
                var diagnostics = [];
                var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, program, ".js");
                emitDeclarations(program, resolver, diagnostics, jsFilePath, targetSourceFile);
                return diagnostics;
            }
            ts.getDeclarationDiagnostics = getDeclarationDiagnostics;
            function emitFiles(resolver, targetSourceFile) {
                var program = resolver.getProgram();
                var compilerHost = program.getCompilerHost();
                var compilerOptions = program.getCompilerOptions();
                var sourceMapDataList = compilerOptions.sourceMap ? [] : undefined;
                var diagnostics = [];
                var newLine = program.getCompilerHost().getNewLine();
                function emitJavaScript(jsFilePath, root) {
                    var writer = createTextWriter(newLine);
                    var write = writer.write;
                    var writeTextOfNode = writer.writeTextOfNode;
                    var writeLine = writer.writeLine;
                    var increaseIndent = writer.increaseIndent;
                    var decreaseIndent = writer.decreaseIndent;
                    var currentSourceFile;
                    var extendsEmitted = false;
                    var writeEmittedFiles = writeJavaScriptFile;
                    var emitLeadingComments = compilerOptions.removeComments ? function (node) {
                    } : emitLeadingDeclarationComments;
                    var emitTrailingComments = compilerOptions.removeComments ? function (node) {
                    } : emitTrailingDeclarationComments;
                    var emitLeadingCommentsOfPosition = compilerOptions.removeComments ? function (pos) {
                    } : emitLeadingCommentsOfLocalPosition;
                    var detachedCommentsInfo;
                    var emitDetachedComments = compilerOptions.removeComments ? function (node) {
                    } : emitDetachedCommentsAtPosition;
                    var emitPinnedOrTripleSlashComments = compilerOptions.removeComments ? function (node) {
                    } : emitPinnedOrTripleSlashCommentsOfNode;
                    var writeComment = writeCommentRange;
                    var emit = emitNode;
                    var emitStart = function (node) {
                    };
                    var emitEnd = function (node) {
                    };
                    var emitToken = emitTokenText;
                    var scopeEmitStart = function (scopeDeclaration, scopeName) {
                    };
                    var scopeEmitEnd = function () {
                    };
                    var sourceMapData;
                    function initializeEmitterWithSourceMaps() {
                        var sourceMapDir;
                        var sourceMapSourceIndex = -1;
                        var sourceMapNameIndexMap = {};
                        var sourceMapNameIndices = [];
                        function getSourceMapNameIndex() {
                            return sourceMapNameIndices.length ? sourceMapNameIndices[sourceMapNameIndices.length - 1] : -1;
                        }
                        var lastRecordedSourceMapSpan;
                        var lastEncodedSourceMapSpan = {
                            emittedLine: 1,
                            emittedColumn: 1,
                            sourceLine: 1,
                            sourceColumn: 1,
                            sourceIndex: 0
                        };
                        var lastEncodedNameIndex = 0;
                        function encodeLastRecordedSourceMapSpan() {
                            if (!lastRecordedSourceMapSpan || lastRecordedSourceMapSpan === lastEncodedSourceMapSpan) {
                                return;
                            }
                            var prevEncodedEmittedColumn = lastEncodedSourceMapSpan.emittedColumn;
                            if (lastEncodedSourceMapSpan.emittedLine == lastRecordedSourceMapSpan.emittedLine) {
                                if (sourceMapData.sourceMapMappings) {
                                    sourceMapData.sourceMapMappings += ",";
                                }
                            }
                            else {
                                for (var encodedLine = lastEncodedSourceMapSpan.emittedLine; encodedLine < lastRecordedSourceMapSpan.emittedLine; encodedLine++) {
                                    sourceMapData.sourceMapMappings += ";";
                                }
                                prevEncodedEmittedColumn = 1;
                            }
                            sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.emittedColumn - prevEncodedEmittedColumn);
                            sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceIndex - lastEncodedSourceMapSpan.sourceIndex);
                            sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceLine - lastEncodedSourceMapSpan.sourceLine);
                            sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceColumn - lastEncodedSourceMapSpan.sourceColumn);
                            if (lastRecordedSourceMapSpan.nameIndex >= 0) {
                                sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.nameIndex - lastEncodedNameIndex);
                                lastEncodedNameIndex = lastRecordedSourceMapSpan.nameIndex;
                            }
                            lastEncodedSourceMapSpan = lastRecordedSourceMapSpan;
                            sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan);
                            function base64VLQFormatEncode(inValue) {
                                function base64FormatEncode(inValue) {
                                    if (inValue < 64) {
                                        return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.charAt(inValue);
                                    }
                                    throw TypeError(inValue + ": not a 64 based value");
                                }
                                if (inValue < 0) {
                                    inValue = ((-inValue) << 1) + 1;
                                }
                                else {
                                    inValue = inValue << 1;
                                }
                                var encodedStr = "";
                                do {
                                    var currentDigit = inValue & 31;
                                    inValue = inValue >> 5;
                                    if (inValue > 0) {
                                        currentDigit = currentDigit | 32;
                                    }
                                    encodedStr = encodedStr + base64FormatEncode(currentDigit);
                                } while (inValue > 0);
                                return encodedStr;
                            }
                        }
                        function recordSourceMapSpan(pos) {
                            var sourceLinePos = currentSourceFile.getLineAndCharacterFromPosition(pos);
                            var emittedLine = writer.getLine();
                            var emittedColumn = writer.getColumn();
                            if (!lastRecordedSourceMapSpan || lastRecordedSourceMapSpan.emittedLine != emittedLine || lastRecordedSourceMapSpan.emittedColumn != emittedColumn || (lastRecordedSourceMapSpan.sourceIndex === sourceMapSourceIndex && (lastRecordedSourceMapSpan.sourceLine > sourceLinePos.line || (lastRecordedSourceMapSpan.sourceLine === sourceLinePos.line && lastRecordedSourceMapSpan.sourceColumn > sourceLinePos.character)))) {
                                encodeLastRecordedSourceMapSpan();
                                lastRecordedSourceMapSpan = {
                                    emittedLine: emittedLine,
                                    emittedColumn: emittedColumn,
                                    sourceLine: sourceLinePos.line,
                                    sourceColumn: sourceLinePos.character,
                                    nameIndex: getSourceMapNameIndex(),
                                    sourceIndex: sourceMapSourceIndex
                                };
                            }
                            else {
                                lastRecordedSourceMapSpan.sourceLine = sourceLinePos.line;
                                lastRecordedSourceMapSpan.sourceColumn = sourceLinePos.character;
                                lastRecordedSourceMapSpan.sourceIndex = sourceMapSourceIndex;
                            }
                        }
                        function recordEmitNodeStartSpan(node) {
                            recordSourceMapSpan(ts.skipTrivia(currentSourceFile.text, node.pos));
                        }
                        function recordEmitNodeEndSpan(node) {
                            recordSourceMapSpan(node.end);
                        }
                        function writeTextWithSpanRecord(tokenKind, startPos, emitFn) {
                            var tokenStartPos = ts.skipTrivia(currentSourceFile.text, startPos);
                            recordSourceMapSpan(tokenStartPos);
                            var tokenEndPos = emitTokenText(tokenKind, tokenStartPos, emitFn);
                            recordSourceMapSpan(tokenEndPos);
                            return tokenEndPos;
                        }
                        function recordNewSourceFileStart(node) {
                            var sourcesDirectoryPath = compilerOptions.sourceRoot ? program.getCommonSourceDirectory() : sourceMapDir;
                            sourceMapData.sourceMapSources.push(ts.getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, node.filename, compilerHost.getCurrentDirectory(), compilerHost.getCanonicalFileName, true));
                            sourceMapSourceIndex = sourceMapData.sourceMapSources.length - 1;
                            sourceMapData.inputSourceFileNames.push(node.filename);
                        }
                        function recordScopeNameOfNode(node, scopeName) {
                            function recordScopeNameIndex(scopeNameIndex) {
                                sourceMapNameIndices.push(scopeNameIndex);
                            }
                            function recordScopeNameStart(scopeName) {
                                var scopeNameIndex = -1;
                                if (scopeName) {
                                    var parentIndex = getSourceMapNameIndex();
                                    if (parentIndex !== -1) {
                                        scopeName = sourceMapData.sourceMapNames[parentIndex] + "." + scopeName;
                                    }
                                    scopeNameIndex = ts.getProperty(sourceMapNameIndexMap, scopeName);
                                    if (scopeNameIndex === undefined) {
                                        scopeNameIndex = sourceMapData.sourceMapNames.length;
                                        sourceMapData.sourceMapNames.push(scopeName);
                                        sourceMapNameIndexMap[scopeName] = scopeNameIndex;
                                    }
                                }
                                recordScopeNameIndex(scopeNameIndex);
                            }
                            if (scopeName) {
                                recordScopeNameStart(scopeName);
                            }
                            else if (node.kind === 187 /* FunctionDeclaration */ || node.kind === 153 /* FunctionExpression */ || node.kind === 126 /* Method */ || node.kind === 128 /* GetAccessor */ || node.kind === 129 /* SetAccessor */ || node.kind === 193 /* ModuleDeclaration */ || node.kind === 189 /* ClassDeclaration */ || node.kind === 192 /* EnumDeclaration */) {
                                if (node.name) {
                                    scopeName = node.name.text;
                                }
                                recordScopeNameStart(scopeName);
                            }
                            else {
                                recordScopeNameIndex(getSourceMapNameIndex());
                            }
                        }
                        function recordScopeNameEnd() {
                            sourceMapNameIndices.pop();
                        }
                        ;
                        function writeCommentRangeWithMap(curentSourceFile, writer, comment, newLine) {
                            recordSourceMapSpan(comment.pos);
                            writeCommentRange(currentSourceFile, writer, comment, newLine);
                            recordSourceMapSpan(comment.end);
                        }
                        function serializeSourceMapContents(version, file, sourceRoot, sources, names, mappings) {
                            if (typeof JSON !== "undefined") {
                                return JSON.stringify({
                                    version: version,
                                    file: file,
                                    sourceRoot: sourceRoot,
                                    sources: sources,
                                    names: names,
                                    mappings: mappings
                                });
                            }
                            return "{\"version\":" + version + ",\"file\":\"" + ts.escapeString(file) + "\",\"sourceRoot\":\"" + ts.escapeString(sourceRoot) + "\",\"sources\":[" + serializeStringArray(sources) + "],\"names\":[" + serializeStringArray(names) + "],\"mappings\":\"" + ts.escapeString(mappings) + "\"}";
                            function serializeStringArray(list) {
                                var output = "";
                                for (var i = 0, n = list.length; i < n; i++) {
                                    if (i) {
                                        output += ",";
                                    }
                                    output += "\"" + ts.escapeString(list[i]) + "\"";
                                }
                                return output;
                            }
                        }
                        function writeJavaScriptAndSourceMapFile(emitOutput, writeByteOrderMark) {
                            encodeLastRecordedSourceMapSpan();
                            writeFile(compilerHost, diagnostics, sourceMapData.sourceMapFilePath, serializeSourceMapContents(3, sourceMapData.sourceMapFile, sourceMapData.sourceMapSourceRoot, sourceMapData.sourceMapSources, sourceMapData.sourceMapNames, sourceMapData.sourceMapMappings), false);
                            sourceMapDataList.push(sourceMapData);
                            writeJavaScriptFile(emitOutput + "//# sourceMappingURL=" + sourceMapData.jsSourceMappingURL, writeByteOrderMark);
                        }
                        var sourceMapJsFile = ts.getBaseFilename(ts.normalizeSlashes(jsFilePath));
                        sourceMapData = {
                            sourceMapFilePath: jsFilePath + ".map",
                            jsSourceMappingURL: sourceMapJsFile + ".map",
                            sourceMapFile: sourceMapJsFile,
                            sourceMapSourceRoot: compilerOptions.sourceRoot || "",
                            sourceMapSources: [],
                            inputSourceFileNames: [],
                            sourceMapNames: [],
                            sourceMapMappings: "",
                            sourceMapDecodedMappings: []
                        };
                        sourceMapData.sourceMapSourceRoot = ts.normalizeSlashes(sourceMapData.sourceMapSourceRoot);
                        if (sourceMapData.sourceMapSourceRoot.length && sourceMapData.sourceMapSourceRoot.charCodeAt(sourceMapData.sourceMapSourceRoot.length - 1) !== 47 /* slash */) {
                            sourceMapData.sourceMapSourceRoot += ts.directorySeparator;
                        }
                        if (compilerOptions.mapRoot) {
                            sourceMapDir = ts.normalizeSlashes(compilerOptions.mapRoot);
                            if (root) {
                                sourceMapDir = ts.getDirectoryPath(getSourceFilePathInNewDir(root, program, sourceMapDir));
                            }
                            if (!ts.isRootedDiskPath(sourceMapDir) && !ts.isUrl(sourceMapDir)) {
                                sourceMapDir = ts.combinePaths(program.getCommonSourceDirectory(), sourceMapDir);
                                sourceMapData.jsSourceMappingURL = ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizePath(jsFilePath)), ts.combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), compilerHost.getCurrentDirectory(), compilerHost.getCanonicalFileName, true);
                            }
                            else {
                                sourceMapData.jsSourceMappingURL = ts.combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL);
                            }
                        }
                        else {
                            sourceMapDir = ts.getDirectoryPath(ts.normalizePath(jsFilePath));
                        }
                        function emitNodeWithMap(node) {
                            if (node) {
                                if (node.kind != 198 /* SourceFile */) {
                                    recordEmitNodeStartSpan(node);
                                    emitNode(node);
                                    recordEmitNodeEndSpan(node);
                                }
                                else {
                                    recordNewSourceFileStart(node);
                                    emitNode(node);
                                }
                            }
                        }
                        writeEmittedFiles = writeJavaScriptAndSourceMapFile;
                        emit = emitNodeWithMap;
                        emitStart = recordEmitNodeStartSpan;
                        emitEnd = recordEmitNodeEndSpan;
                        emitToken = writeTextWithSpanRecord;
                        scopeEmitStart = recordScopeNameOfNode;
                        scopeEmitEnd = recordScopeNameEnd;
                        writeComment = writeCommentRangeWithMap;
                    }
                    function writeJavaScriptFile(emitOutput, writeByteOrderMark) {
                        writeFile(compilerHost, diagnostics, jsFilePath, emitOutput, writeByteOrderMark);
                    }
                    function emitTokenText(tokenKind, startPos, emitFn) {
                        var tokenString = ts.tokenToString(tokenKind);
                        if (emitFn) {
                            emitFn();
                        }
                        else {
                            write(tokenString);
                        }
                        return startPos + tokenString.length;
                    }
                    function emitOptional(prefix, node) {
                        if (node) {
                            write(prefix);
                            emit(node);
                        }
                    }
                    function emitTrailingCommaIfPresent(nodeList, isMultiline) {
                        if (nodeList.hasTrailingComma) {
                            write(",");
                            if (isMultiline) {
                                writeLine();
                            }
                        }
                    }
                    function emitCommaList(nodes, includeTrailingComma, count) {
                        if (!(count >= 0)) {
                            count = nodes.length;
                        }
                        if (nodes) {
                            for (var i = 0; i < count; i++) {
                                if (i) {
                                    write(", ");
                                }
                                emit(nodes[i]);
                            }
                            if (includeTrailingComma) {
                                emitTrailingCommaIfPresent(nodes, false);
                            }
                        }
                    }
                    function emitMultiLineList(nodes, includeTrailingComma) {
                        if (nodes) {
                            for (var i = 0; i < nodes.length; i++) {
                                if (i) {
                                    write(",");
                                }
                                writeLine();
                                emit(nodes[i]);
                            }
                            if (includeTrailingComma) {
                                emitTrailingCommaIfPresent(nodes, true);
                            }
                        }
                    }
                    function emitLines(nodes) {
                        emitLinesStartingAt(nodes, 0);
                    }
                    function emitLinesStartingAt(nodes, startIndex) {
                        for (var i = startIndex; i < nodes.length; i++) {
                            writeLine();
                            emit(nodes[i]);
                        }
                    }
                    function emitLiteral(node) {
                        var text = getLiteralText();
                        if (compilerOptions.sourceMap && (node.kind === 7 /* StringLiteral */ || ts.isTemplateLiteralKind(node.kind))) {
                            writer.writeLiteral(text);
                        }
                        else {
                            write(text);
                        }
                        function getLiteralText() {
                            if (compilerOptions.target < 2 /* ES6 */ && ts.isTemplateLiteralKind(node.kind)) {
                                return getTemplateLiteralAsStringLiteral(node);
                            }
                            return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
                        }
                    }
                    function getTemplateLiteralAsStringLiteral(node) {
                        return '"' + ts.escapeString(node.text) + '"';
                    }
                    function emitTemplateExpression(node) {
                        if (compilerOptions.target >= 2 /* ES6 */) {
                            ts.forEachChild(node, emit);
                            return;
                        }
                        ts.Debug.assert(node.parent.kind !== 150 /* TaggedTemplateExpression */);
                        var emitOuterParens = ts.isExpression(node.parent) && templateNeedsParens(node, node.parent);
                        if (emitOuterParens) {
                            write("(");
                        }
                        emitLiteral(node.head);
                        ts.forEach(node.templateSpans, function (templateSpan) {
                            var needsParens = templateSpan.expression.kind !== 152 /* ParenExpression */ && comparePrecedenceToBinaryPlus(templateSpan.expression) !== 1 /* GreaterThan */;
                            write(" + ");
                            if (needsParens) {
                                write("(");
                            }
                            emit(templateSpan.expression);
                            if (needsParens) {
                                write(")");
                            }
                            if (templateSpan.literal.text.length !== 0) {
                                write(" + ");
                                emitLiteral(templateSpan.literal);
                            }
                        });
                        if (emitOuterParens) {
                            write(")");
                        }
                        function templateNeedsParens(template, parent) {
                            switch (parent.kind) {
                                case 148 /* CallExpression */:
                                case 149 /* NewExpression */:
                                    return parent.func === template;
                                case 152 /* ParenExpression */:
                                    return false;
                                case 150 /* TaggedTemplateExpression */:
                                    ts.Debug.fail("Path should be unreachable; tagged templates not supported pre-ES6.");
                                default:
                                    return comparePrecedenceToBinaryPlus(parent) !== -1 /* LessThan */;
                            }
                        }
                        function comparePrecedenceToBinaryPlus(expression) {
                            ts.Debug.assert(compilerOptions.target <= 1 /* ES5 */);
                            switch (expression.kind) {
                                case 157 /* BinaryExpression */:
                                    switch (expression.operator) {
                                        case 34 /* AsteriskToken */:
                                        case 35 /* SlashToken */:
                                        case 36 /* PercentToken */:
                                            return 1 /* GreaterThan */;
                                        case 32 /* PlusToken */:
                                            return 0 /* EqualTo */;
                                        default:
                                            return -1 /* LessThan */;
                                    }
                                case 158 /* ConditionalExpression */:
                                    return -1 /* LessThan */;
                                default:
                                    return 1 /* GreaterThan */;
                            }
                        }
                    }
                    function emitTemplateSpan(span) {
                        emit(span.expression);
                        emit(span.literal);
                    }
                    function emitExpressionForPropertyName(node) {
                        if (node.kind === 7 /* StringLiteral */) {
                            emitLiteral(node);
                        }
                        else if (node.kind === 122 /* ComputedPropertyName */) {
                            emit(node.expression);
                        }
                        else {
                            write("\"");
                            if (node.kind === 6 /* NumericLiteral */) {
                                write(node.text);
                            }
                            else {
                                writeTextOfNode(currentSourceFile, node);
                            }
                            write("\"");
                        }
                    }
                    function isNotExpressionIdentifier(node) {
                        var parent = node.parent;
                        switch (parent.kind) {
                            case 124 /* Parameter */:
                            case 186 /* VariableDeclaration */:
                            case 125 /* Property */:
                            case 144 /* PropertyAssignment */:
                            case 145 /* ShorthandPropertyAssignment */:
                            case 197 /* EnumMember */:
                            case 126 /* Method */:
                            case 187 /* FunctionDeclaration */:
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                            case 153 /* FunctionExpression */:
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                            case 192 /* EnumDeclaration */:
                            case 193 /* ModuleDeclaration */:
                            case 195 /* ImportDeclaration */:
                                return parent.name === node;
                            case 173 /* BreakStatement */:
                            case 172 /* ContinueStatement */:
                            case 196 /* ExportAssignment */:
                                return false;
                            case 179 /* LabeledStatement */:
                                return node.parent.label === node;
                            case 183 /* CatchBlock */:
                                return node.parent.variable === node;
                        }
                    }
                    function emitExpressionIdentifier(node) {
                        var prefix = resolver.getExpressionNamePrefix(node);
                        if (prefix) {
                            write(prefix);
                            write(".");
                        }
                        writeTextOfNode(currentSourceFile, node);
                    }
                    function emitIdentifier(node) {
                        if (!isNotExpressionIdentifier(node)) {
                            emitExpressionIdentifier(node);
                        }
                        else {
                            writeTextOfNode(currentSourceFile, node);
                        }
                    }
                    function emitThis(node) {
                        if (resolver.getNodeCheckFlags(node) & 2 /* LexicalThis */) {
                            write("_this");
                        }
                        else {
                            write("this");
                        }
                    }
                    function emitSuper(node) {
                        var flags = resolver.getNodeCheckFlags(node);
                        if (flags & 16 /* SuperInstance */) {
                            write("_super.prototype");
                        }
                        else if (flags & 32 /* SuperStatic */) {
                            write("_super");
                        }
                        else {
                            write("super");
                        }
                    }
                    function emitArrayLiteral(node) {
                        if (node.flags & 256 /* MultiLine */) {
                            write("[");
                            increaseIndent();
                            emitMultiLineList(node.elements, true);
                            decreaseIndent();
                            writeLine();
                            write("]");
                        }
                        else {
                            write("[");
                            emitCommaList(node.elements, true);
                            write("]");
                        }
                    }
                    function emitObjectLiteral(node) {
                        if (!node.properties.length) {
                            write("{}");
                        }
                        else if (node.flags & 256 /* MultiLine */) {
                            write("{");
                            increaseIndent();
                            emitMultiLineList(node.properties, compilerOptions.target >= 1 /* ES5 */);
                            decreaseIndent();
                            writeLine();
                            write("}");
                        }
                        else {
                            write("{ ");
                            emitCommaList(node.properties, compilerOptions.target >= 1 /* ES5 */);
                            write(" }");
                        }
                    }
                    function emitComputedPropertyName(node) {
                        write("[");
                        emit(node.expression);
                        write("]");
                    }
                    function emitPropertyAssignment(node) {
                        emitLeadingComments(node);
                        emit(node.name);
                        write(": ");
                        emit(node.initializer);
                        emitTrailingComments(node);
                    }
                    function emitShortHandPropertyAssignment(node) {
                        function emitAsNormalPropertyAssignment() {
                            emitLeadingComments(node);
                            emit(node.name);
                            write(": ");
                            emitExpressionIdentifier(node.name);
                            emitTrailingComments(node);
                        }
                        if (compilerOptions.target < 2 /* ES6 */) {
                            emitAsNormalPropertyAssignment();
                        }
                        else if (compilerOptions.target >= 2 /* ES6 */) {
                            var prefix = resolver.getExpressionNamePrefix(node.name);
                            if (prefix) {
                                emitAsNormalPropertyAssignment();
                            }
                            else {
                                emitLeadingComments(node);
                                emit(node.name);
                                emitTrailingComments(node);
                            }
                        }
                    }
                    function tryEmitConstantValue(node) {
                        var constantValue = resolver.getConstantValue(node);
                        if (constantValue !== undefined) {
                            var propertyName = node.kind === 146 /* PropertyAccess */ ? ts.declarationNameToString(node.right) : ts.getTextOfNode(node.index);
                            write(constantValue.toString() + " /* " + propertyName + " */");
                            return true;
                        }
                        return false;
                    }
                    function emitPropertyAccess(node) {
                        if (tryEmitConstantValue(node)) {
                            return;
                        }
                        emit(node.left);
                        write(".");
                        emit(node.right);
                    }
                    function emitIndexedAccess(node) {
                        if (tryEmitConstantValue(node)) {
                            return;
                        }
                        emit(node.object);
                        write("[");
                        emit(node.index);
                        write("]");
                    }
                    function emitCallExpression(node) {
                        var superCall = false;
                        if (node.func.kind === 89 /* SuperKeyword */) {
                            write("_super");
                            superCall = true;
                        }
                        else {
                            emit(node.func);
                            superCall = node.func.kind === 146 /* PropertyAccess */ && node.func.left.kind === 89 /* SuperKeyword */;
                        }
                        if (superCall) {
                            write(".call(");
                            emitThis(node.func);
                            if (node.arguments.length) {
                                write(", ");
                                emitCommaList(node.arguments, false);
                            }
                            write(")");
                        }
                        else {
                            write("(");
                            emitCommaList(node.arguments, false);
                            write(")");
                        }
                    }
                    function emitNewExpression(node) {
                        write("new ");
                        emit(node.func);
                        if (node.arguments) {
                            write("(");
                            emitCommaList(node.arguments, false);
                            write(")");
                        }
                    }
                    function emitTaggedTemplateExpression(node) {
                        ts.Debug.assert(compilerOptions.target >= 2 /* ES6 */, "Trying to emit a tagged template in pre-ES6 mode.");
                        emit(node.tag);
                        write(" ");
                        emit(node.template);
                    }
                    function emitParenExpression(node) {
                        if (node.expression.kind === 151 /* TypeAssertion */) {
                            var operand = node.expression.operand;
                            while (operand.kind == 151 /* TypeAssertion */) {
                                operand = operand.operand;
                            }
                            if (operand.kind !== 155 /* PrefixOperator */ && operand.kind !== 156 /* PostfixOperator */ && operand.kind !== 149 /* NewExpression */ && !(operand.kind === 148 /* CallExpression */ && node.parent.kind === 149 /* NewExpression */) && !(operand.kind === 153 /* FunctionExpression */ && node.parent.kind === 148 /* CallExpression */)) {
                                emit(operand);
                                return;
                            }
                        }
                        write("(");
                        emit(node.expression);
                        write(")");
                    }
                    function emitUnaryExpression(node) {
                        if (node.kind === 155 /* PrefixOperator */) {
                            write(ts.tokenToString(node.operator));
                        }
                        if (node.operator >= 63 /* Identifier */) {
                            write(" ");
                        }
                        else if (node.kind === 155 /* PrefixOperator */ && node.operand.kind === 155 /* PrefixOperator */) {
                            var operand = node.operand;
                            if (node.operator === 32 /* PlusToken */ && (operand.operator === 32 /* PlusToken */ || operand.operator === 37 /* PlusPlusToken */)) {
                                write(" ");
                            }
                            else if (node.operator === 33 /* MinusToken */ && (operand.operator === 33 /* MinusToken */ || operand.operator === 38 /* MinusMinusToken */)) {
                                write(" ");
                            }
                        }
                        emit(node.operand);
                        if (node.kind === 156 /* PostfixOperator */) {
                            write(ts.tokenToString(node.operator));
                        }
                    }
                    function emitBinaryExpression(node) {
                        emit(node.left);
                        if (node.operator !== 22 /* CommaToken */)
                            write(" ");
                        write(ts.tokenToString(node.operator));
                        write(" ");
                        emit(node.right);
                    }
                    function emitConditionalExpression(node) {
                        emit(node.condition);
                        write(" ? ");
                        emit(node.whenTrue);
                        write(" : ");
                        emit(node.whenFalse);
                    }
                    function emitBlock(node) {
                        emitToken(13 /* OpenBraceToken */, node.pos);
                        increaseIndent();
                        scopeEmitStart(node.parent);
                        if (node.kind === 194 /* ModuleBlock */) {
                            ts.Debug.assert(node.parent.kind === 193 /* ModuleDeclaration */);
                            emitCaptureThisForNodeIfNecessary(node.parent);
                        }
                        emitLines(node.statements);
                        decreaseIndent();
                        writeLine();
                        emitToken(14 /* CloseBraceToken */, node.statements.end);
                        scopeEmitEnd();
                    }
                    function emitEmbeddedStatement(node) {
                        if (node.kind === 163 /* Block */) {
                            write(" ");
                            emit(node);
                        }
                        else {
                            increaseIndent();
                            writeLine();
                            emit(node);
                            decreaseIndent();
                        }
                    }
                    function emitExpressionStatement(node) {
                        var isArrowExpression = node.expression.kind === 154 /* ArrowFunction */;
                        emitLeadingComments(node);
                        if (isArrowExpression)
                            write("(");
                        emit(node.expression);
                        if (isArrowExpression)
                            write(")");
                        write(";");
                        emitTrailingComments(node);
                    }
                    function emitIfStatement(node) {
                        emitLeadingComments(node);
                        var endPos = emitToken(82 /* IfKeyword */, node.pos);
                        write(" ");
                        endPos = emitToken(15 /* OpenParenToken */, endPos);
                        emit(node.expression);
                        emitToken(16 /* CloseParenToken */, node.expression.end);
                        emitEmbeddedStatement(node.thenStatement);
                        if (node.elseStatement) {
                            writeLine();
                            emitToken(74 /* ElseKeyword */, node.thenStatement.end);
                            if (node.elseStatement.kind === 167 /* IfStatement */) {
                                write(" ");
                                emit(node.elseStatement);
                            }
                            else {
                                emitEmbeddedStatement(node.elseStatement);
                            }
                        }
                        emitTrailingComments(node);
                    }
                    function emitDoStatement(node) {
                        write("do");
                        emitEmbeddedStatement(node.statement);
                        if (node.statement.kind === 163 /* Block */) {
                            write(" ");
                        }
                        else {
                            writeLine();
                        }
                        write("while (");
                        emit(node.expression);
                        write(");");
                    }
                    function emitWhileStatement(node) {
                        write("while (");
                        emit(node.expression);
                        write(")");
                        emitEmbeddedStatement(node.statement);
                    }
                    function emitForStatement(node) {
                        var endPos = emitToken(80 /* ForKeyword */, node.pos);
                        write(" ");
                        endPos = emitToken(15 /* OpenParenToken */, endPos);
                        if (node.declarations) {
                            if (node.declarations[0] && ts.isLet(node.declarations[0])) {
                                emitToken(102 /* LetKeyword */, endPos);
                            }
                            else if (node.declarations[0] && ts.isConst(node.declarations[0])) {
                                emitToken(68 /* ConstKeyword */, endPos);
                            }
                            else {
                                emitToken(96 /* VarKeyword */, endPos);
                            }
                            write(" ");
                            emitCommaList(node.declarations, false);
                        }
                        if (node.initializer) {
                            emit(node.initializer);
                        }
                        write(";");
                        emitOptional(" ", node.condition);
                        write(";");
                        emitOptional(" ", node.iterator);
                        write(")");
                        emitEmbeddedStatement(node.statement);
                    }
                    function emitForInStatement(node) {
                        var endPos = emitToken(80 /* ForKeyword */, node.pos);
                        write(" ");
                        endPos = emitToken(15 /* OpenParenToken */, endPos);
                        if (node.declarations) {
                            if (node.declarations.length >= 1) {
                                var decl = node.declarations[0];
                                if (ts.isLet(decl)) {
                                    emitToken(102 /* LetKeyword */, endPos);
                                }
                                else {
                                    emitToken(96 /* VarKeyword */, endPos);
                                }
                                write(" ");
                                emit(decl);
                            }
                        }
                        else {
                            emit(node.variable);
                        }
                        write(" in ");
                        emit(node.expression);
                        emitToken(16 /* CloseParenToken */, node.expression.end);
                        emitEmbeddedStatement(node.statement);
                    }
                    function emitBreakOrContinueStatement(node) {
                        emitToken(node.kind === 173 /* BreakStatement */ ? 64 /* BreakKeyword */ : 69 /* ContinueKeyword */, node.pos);
                        emitOptional(" ", node.label);
                        write(";");
                    }
                    function emitReturnStatement(node) {
                        emitLeadingComments(node);
                        emitToken(88 /* ReturnKeyword */, node.pos);
                        emitOptional(" ", node.expression);
                        write(";");
                        emitTrailingComments(node);
                    }
                    function emitWithStatement(node) {
                        write("with (");
                        emit(node.expression);
                        write(")");
                        emitEmbeddedStatement(node.statement);
                    }
                    function emitSwitchStatement(node) {
                        var endPos = emitToken(90 /* SwitchKeyword */, node.pos);
                        write(" ");
                        emitToken(15 /* OpenParenToken */, endPos);
                        emit(node.expression);
                        endPos = emitToken(16 /* CloseParenToken */, node.expression.end);
                        write(" ");
                        emitToken(13 /* OpenBraceToken */, endPos);
                        increaseIndent();
                        emitLines(node.clauses);
                        decreaseIndent();
                        writeLine();
                        emitToken(14 /* CloseBraceToken */, node.clauses.end);
                    }
                    function isOnSameLine(node1, node2) {
                        return getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node1.pos)) === getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
                    }
                    function emitCaseOrDefaultClause(node) {
                        if (node.kind === 177 /* CaseClause */) {
                            write("case ");
                            emit(node.expression);
                            write(":");
                        }
                        else {
                            write("default:");
                        }
                        if (node.statements.length === 1 && isOnSameLine(node, node.statements[0])) {
                            write(" ");
                            emit(node.statements[0]);
                        }
                        else {
                            increaseIndent();
                            emitLines(node.statements);
                            decreaseIndent();
                        }
                    }
                    function emitThrowStatement(node) {
                        write("throw ");
                        emit(node.expression);
                        write(";");
                    }
                    function emitTryStatement(node) {
                        write("try ");
                        emit(node.tryBlock);
                        emit(node.catchBlock);
                        if (node.finallyBlock) {
                            writeLine();
                            write("finally ");
                            emit(node.finallyBlock);
                        }
                    }
                    function emitCatchBlock(node) {
                        writeLine();
                        var endPos = emitToken(66 /* CatchKeyword */, node.pos);
                        write(" ");
                        emitToken(15 /* OpenParenToken */, endPos);
                        emit(node.variable);
                        emitToken(16 /* CloseParenToken */, node.variable.end);
                        write(" ");
                        emitBlock(node);
                    }
                    function emitDebuggerStatement(node) {
                        emitToken(70 /* DebuggerKeyword */, node.pos);
                        write(";");
                    }
                    function emitLabelledStatement(node) {
                        emit(node.label);
                        write(": ");
                        emit(node.statement);
                    }
                    function getContainingModule(node) {
                        do {
                            node = node.parent;
                        } while (node && node.kind !== 193 /* ModuleDeclaration */);
                        return node;
                    }
                    function emitModuleMemberName(node) {
                        emitStart(node.name);
                        if (node.flags & 1 /* Export */) {
                            var container = getContainingModule(node);
                            write(container ? resolver.getLocalNameOfContainer(container) : "exports");
                            write(".");
                        }
                        emitNode(node.name);
                        emitEnd(node.name);
                    }
                    function emitVariableDeclaration(node) {
                        emitLeadingComments(node);
                        emitModuleMemberName(node);
                        emitOptional(" = ", node.initializer);
                        emitTrailingComments(node);
                    }
                    function emitVariableStatement(node) {
                        emitLeadingComments(node);
                        if (!(node.flags & 1 /* Export */)) {
                            if (ts.isLet(node)) {
                                write("let ");
                            }
                            else if (ts.isConst(node)) {
                                write("const ");
                            }
                            else {
                                write("var ");
                            }
                        }
                        emitCommaList(node.declarations, false);
                        write(";");
                        emitTrailingComments(node);
                    }
                    function emitParameter(node) {
                        emitLeadingComments(node);
                        emit(node.name);
                        emitTrailingComments(node);
                    }
                    function emitDefaultValueAssignments(node) {
                        ts.forEach(node.parameters, function (param) {
                            if (param.initializer) {
                                writeLine();
                                emitStart(param);
                                write("if (");
                                emitNode(param.name);
                                write(" === void 0)");
                                emitEnd(param);
                                write(" { ");
                                emitStart(param);
                                emitNode(param.name);
                                write(" = ");
                                emitNode(param.initializer);
                                emitEnd(param);
                                write("; }");
                            }
                        });
                    }
                    function emitRestParameter(node) {
                        if (ts.hasRestParameters(node)) {
                            var restIndex = node.parameters.length - 1;
                            var restParam = node.parameters[restIndex];
                            writeLine();
                            emitLeadingComments(restParam);
                            emitStart(restParam);
                            write("var ");
                            emitNode(restParam.name);
                            write(" = [];");
                            emitEnd(restParam);
                            emitTrailingComments(restParam);
                            writeLine();
                            write("for (");
                            emitStart(restParam);
                            write("var _i = " + restIndex + ";");
                            emitEnd(restParam);
                            write(" ");
                            emitStart(restParam);
                            write("_i < arguments.length;");
                            emitEnd(restParam);
                            write(" ");
                            emitStart(restParam);
                            write("_i++");
                            emitEnd(restParam);
                            write(") {");
                            increaseIndent();
                            writeLine();
                            emitStart(restParam);
                            emitNode(restParam.name);
                            write("[_i - " + restIndex + "] = arguments[_i];");
                            emitEnd(restParam);
                            decreaseIndent();
                            writeLine();
                            write("}");
                        }
                    }
                    function emitAccessor(node) {
                        emitLeadingComments(node);
                        write(node.kind === 128 /* GetAccessor */ ? "get " : "set ");
                        emit(node.name);
                        emitSignatureAndBody(node);
                        emitTrailingComments(node);
                    }
                    function emitFunctionDeclaration(node) {
                        if (!node.body) {
                            return emitPinnedOrTripleSlashComments(node);
                        }
                        if (node.kind !== 126 /* Method */) {
                            emitLeadingComments(node);
                        }
                        write("function ");
                        if (node.kind === 187 /* FunctionDeclaration */ || (node.kind === 153 /* FunctionExpression */ && node.name)) {
                            emit(node.name);
                        }
                        emitSignatureAndBody(node);
                        if (node.kind !== 126 /* Method */) {
                            emitTrailingComments(node);
                        }
                    }
                    function emitCaptureThisForNodeIfNecessary(node) {
                        if (resolver.getNodeCheckFlags(node) & 4 /* CaptureThis */) {
                            writeLine();
                            emitStart(node);
                            write("var _this = this;");
                            emitEnd(node);
                        }
                    }
                    function emitSignatureParameters(node) {
                        increaseIndent();
                        write("(");
                        if (node) {
                            emitCommaList(node.parameters, false, node.parameters.length - (ts.hasRestParameters(node) ? 1 : 0));
                        }
                        write(")");
                        decreaseIndent();
                    }
                    function emitSignatureAndBody(node) {
                        emitSignatureParameters(node);
                        write(" {");
                        scopeEmitStart(node);
                        increaseIndent();
                        emitDetachedComments(node.body.kind === 188 /* FunctionBlock */ ? node.body.statements : node.body);
                        var startIndex = 0;
                        if (node.body.kind === 188 /* FunctionBlock */) {
                            startIndex = emitDirectivePrologues(node.body.statements, true);
                        }
                        var outPos = writer.getTextPos();
                        emitCaptureThisForNodeIfNecessary(node);
                        emitDefaultValueAssignments(node);
                        emitRestParameter(node);
                        if (node.body.kind !== 188 /* FunctionBlock */ && outPos === writer.getTextPos()) {
                            decreaseIndent();
                            write(" ");
                            emitStart(node.body);
                            write("return ");
                            emitNode(node.body);
                            emitEnd(node.body);
                            write("; ");
                            emitStart(node.body);
                            write("}");
                            emitEnd(node.body);
                        }
                        else {
                            if (node.body.kind === 188 /* FunctionBlock */) {
                                emitLinesStartingAt(node.body.statements, startIndex);
                            }
                            else {
                                writeLine();
                                emitLeadingComments(node.body);
                                write("return ");
                                emit(node.body);
                                write(";");
                                emitTrailingComments(node.body);
                            }
                            writeLine();
                            if (node.body.kind === 188 /* FunctionBlock */) {
                                emitLeadingCommentsOfPosition(node.body.statements.end);
                                decreaseIndent();
                                emitToken(14 /* CloseBraceToken */, node.body.statements.end);
                            }
                            else {
                                decreaseIndent();
                                emitStart(node.body);
                                write("}");
                                emitEnd(node.body);
                            }
                        }
                        scopeEmitEnd();
                        if (node.flags & 1 /* Export */) {
                            writeLine();
                            emitStart(node);
                            emitModuleMemberName(node);
                            write(" = ");
                            emit(node.name);
                            emitEnd(node);
                            write(";");
                        }
                    }
                    function findInitialSuperCall(ctor) {
                        if (ctor.body) {
                            var statement = ctor.body.statements[0];
                            if (statement && statement.kind === 166 /* ExpressionStatement */) {
                                var expr = statement.expression;
                                if (expr && expr.kind === 148 /* CallExpression */) {
                                    var func = expr.func;
                                    if (func && func.kind === 89 /* SuperKeyword */) {
                                        return statement;
                                    }
                                }
                            }
                        }
                    }
                    function emitParameterPropertyAssignments(node) {
                        ts.forEach(node.parameters, function (param) {
                            if (param.flags & 112 /* AccessibilityModifier */) {
                                writeLine();
                                emitStart(param);
                                emitStart(param.name);
                                write("this.");
                                emitNode(param.name);
                                emitEnd(param.name);
                                write(" = ");
                                emit(param.name);
                                write(";");
                                emitEnd(param);
                            }
                        });
                    }
                    function emitMemberAccessForPropertyName(memberName) {
                        if (memberName.kind === 7 /* StringLiteral */ || memberName.kind === 6 /* NumericLiteral */) {
                            write("[");
                            emitNode(memberName);
                            write("]");
                        }
                        else if (memberName.kind === 122 /* ComputedPropertyName */) {
                            emitComputedPropertyName(memberName);
                        }
                        else {
                            write(".");
                            emitNode(memberName);
                        }
                    }
                    function emitMemberAssignments(node, staticFlag) {
                        ts.forEach(node.members, function (member) {
                            if (member.kind === 125 /* Property */ && (member.flags & 128 /* Static */) === staticFlag && member.initializer) {
                                writeLine();
                                emitLeadingComments(member);
                                emitStart(member);
                                emitStart(member.name);
                                if (staticFlag) {
                                    emitNode(node.name);
                                }
                                else {
                                    write("this");
                                }
                                emitMemberAccessForPropertyName(member.name);
                                emitEnd(member.name);
                                write(" = ");
                                emit(member.initializer);
                                write(";");
                                emitEnd(member);
                                emitTrailingComments(member);
                            }
                        });
                    }
                    function emitMemberFunctions(node) {
                        ts.forEach(node.members, function (member) {
                            if (member.kind === 126 /* Method */) {
                                if (!member.body) {
                                    return emitPinnedOrTripleSlashComments(member);
                                }
                                writeLine();
                                emitLeadingComments(member);
                                emitStart(member);
                                emitStart(member.name);
                                emitNode(node.name);
                                if (!(member.flags & 128 /* Static */)) {
                                    write(".prototype");
                                }
                                emitMemberAccessForPropertyName(member.name);
                                emitEnd(member.name);
                                write(" = ");
                                emitStart(member);
                                emitFunctionDeclaration(member);
                                emitEnd(member);
                                emitEnd(member);
                                write(";");
                                emitTrailingComments(member);
                            }
                            else if (member.kind === 128 /* GetAccessor */ || member.kind === 129 /* SetAccessor */) {
                                var accessors = getAllAccessorDeclarations(node, member);
                                if (member === accessors.firstAccessor) {
                                    writeLine();
                                    emitStart(member);
                                    write("Object.defineProperty(");
                                    emitStart(member.name);
                                    emitNode(node.name);
                                    if (!(member.flags & 128 /* Static */)) {
                                        write(".prototype");
                                    }
                                    write(", ");
                                    emitExpressionForPropertyName(member.name);
                                    emitEnd(member.name);
                                    write(", {");
                                    increaseIndent();
                                    if (accessors.getAccessor) {
                                        writeLine();
                                        emitLeadingComments(accessors.getAccessor);
                                        write("get: ");
                                        emitStart(accessors.getAccessor);
                                        write("function ");
                                        emitSignatureAndBody(accessors.getAccessor);
                                        emitEnd(accessors.getAccessor);
                                        emitTrailingComments(accessors.getAccessor);
                                        write(",");
                                    }
                                    if (accessors.setAccessor) {
                                        writeLine();
                                        emitLeadingComments(accessors.setAccessor);
                                        write("set: ");
                                        emitStart(accessors.setAccessor);
                                        write("function ");
                                        emitSignatureAndBody(accessors.setAccessor);
                                        emitEnd(accessors.setAccessor);
                                        emitTrailingComments(accessors.setAccessor);
                                        write(",");
                                    }
                                    writeLine();
                                    write("enumerable: true,");
                                    writeLine();
                                    write("configurable: true");
                                    decreaseIndent();
                                    writeLine();
                                    write("});");
                                    emitEnd(member);
                                }
                            }
                        });
                    }
                    function emitClassDeclaration(node) {
                        emitLeadingComments(node);
                        write("var ");
                        emit(node.name);
                        write(" = (function (");
                        if (node.baseType) {
                            write("_super");
                        }
                        write(") {");
                        increaseIndent();
                        scopeEmitStart(node);
                        if (node.baseType) {
                            writeLine();
                            emitStart(node.baseType);
                            write("__extends(");
                            emit(node.name);
                            write(", _super);");
                            emitEnd(node.baseType);
                        }
                        writeLine();
                        emitConstructorOfClass();
                        emitMemberFunctions(node);
                        emitMemberAssignments(node, 128 /* Static */);
                        writeLine();
                        function emitClassReturnStatement() {
                            write("return ");
                            emitNode(node.name);
                        }
                        emitToken(14 /* CloseBraceToken */, node.members.end, emitClassReturnStatement);
                        write(";");
                        decreaseIndent();
                        writeLine();
                        emitToken(14 /* CloseBraceToken */, node.members.end);
                        scopeEmitEnd();
                        emitStart(node);
                        write(")(");
                        if (node.baseType) {
                            emit(node.baseType.typeName);
                        }
                        write(");");
                        emitEnd(node);
                        if (node.flags & 1 /* Export */) {
                            writeLine();
                            emitStart(node);
                            emitModuleMemberName(node);
                            write(" = ");
                            emit(node.name);
                            emitEnd(node);
                            write(";");
                        }
                        emitTrailingComments(node);
                        function emitConstructorOfClass() {
                            ts.forEach(node.members, function (member) {
                                if (member.kind === 127 /* Constructor */ && !member.body) {
                                    emitPinnedOrTripleSlashComments(member);
                                }
                            });
                            var ctor = getFirstConstructorWithBody(node);
                            if (ctor) {
                                emitLeadingComments(ctor);
                            }
                            emitStart(ctor || node);
                            write("function ");
                            emit(node.name);
                            emitSignatureParameters(ctor);
                            write(" {");
                            scopeEmitStart(node, "constructor");
                            increaseIndent();
                            if (ctor) {
                                emitDetachedComments(ctor.body.statements);
                            }
                            emitCaptureThisForNodeIfNecessary(node);
                            if (ctor) {
                                emitDefaultValueAssignments(ctor);
                                emitRestParameter(ctor);
                                if (node.baseType) {
                                    var superCall = findInitialSuperCall(ctor);
                                    if (superCall) {
                                        writeLine();
                                        emit(superCall);
                                    }
                                }
                                emitParameterPropertyAssignments(ctor);
                            }
                            else {
                                if (node.baseType) {
                                    writeLine();
                                    emitStart(node.baseType);
                                    write("_super.apply(this, arguments);");
                                    emitEnd(node.baseType);
                                }
                            }
                            emitMemberAssignments(node, 0);
                            if (ctor) {
                                var statements = ctor.body.statements;
                                if (superCall)
                                    statements = statements.slice(1);
                                emitLines(statements);
                            }
                            writeLine();
                            if (ctor) {
                                emitLeadingCommentsOfPosition(ctor.body.statements.end);
                            }
                            decreaseIndent();
                            emitToken(14 /* CloseBraceToken */, ctor ? ctor.body.statements.end : node.members.end);
                            scopeEmitEnd();
                            emitEnd(ctor || node);
                            if (ctor) {
                                emitTrailingComments(ctor);
                            }
                        }
                    }
                    function emitInterfaceDeclaration(node) {
                        emitPinnedOrTripleSlashComments(node);
                    }
                    function emitEnumDeclaration(node) {
                        var isConstEnum = ts.isConst(node);
                        if (isConstEnum && !compilerOptions.preserveConstEnums) {
                            return;
                        }
                        emitLeadingComments(node);
                        if (!(node.flags & 1 /* Export */)) {
                            emitStart(node);
                            write("var ");
                            emit(node.name);
                            emitEnd(node);
                            write(";");
                        }
                        writeLine();
                        emitStart(node);
                        write("(function (");
                        emitStart(node.name);
                        write(resolver.getLocalNameOfContainer(node));
                        emitEnd(node.name);
                        write(") {");
                        increaseIndent();
                        scopeEmitStart(node);
                        emitEnumMemberDeclarations(isConstEnum);
                        decreaseIndent();
                        writeLine();
                        emitToken(14 /* CloseBraceToken */, node.members.end);
                        scopeEmitEnd();
                        write(")(");
                        emitModuleMemberName(node);
                        write(" || (");
                        emitModuleMemberName(node);
                        write(" = {}));");
                        emitEnd(node);
                        if (node.flags & 1 /* Export */) {
                            writeLine();
                            emitStart(node);
                            write("var ");
                            emit(node.name);
                            write(" = ");
                            emitModuleMemberName(node);
                            emitEnd(node);
                            write(";");
                        }
                        emitTrailingComments(node);
                        function emitEnumMemberDeclarations(isConstEnum) {
                            ts.forEach(node.members, function (member) {
                                writeLine();
                                emitLeadingComments(member);
                                emitStart(member);
                                write(resolver.getLocalNameOfContainer(node));
                                write("[");
                                write(resolver.getLocalNameOfContainer(node));
                                write("[");
                                emitExpressionForPropertyName(member.name);
                                write("] = ");
                                if (member.initializer && !isConstEnum) {
                                    emit(member.initializer);
                                }
                                else {
                                    write(resolver.getEnumMemberValue(member).toString());
                                }
                                write("] = ");
                                emitExpressionForPropertyName(member.name);
                                emitEnd(member);
                                write(";");
                                emitTrailingComments(member);
                            });
                        }
                    }
                    function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration) {
                        if (moduleDeclaration.body.kind === 193 /* ModuleDeclaration */) {
                            var recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body);
                            return recursiveInnerModule || moduleDeclaration.body;
                        }
                    }
                    function emitModuleDeclaration(node) {
                        var shouldEmit = ts.getModuleInstanceState(node) === 1 /* Instantiated */ || (ts.getModuleInstanceState(node) === 2 /* ConstEnumOnly */ && compilerOptions.preserveConstEnums);
                        if (!shouldEmit) {
                            return emitPinnedOrTripleSlashComments(node);
                        }
                        emitLeadingComments(node);
                        emitStart(node);
                        write("var ");
                        emit(node.name);
                        write(";");
                        emitEnd(node);
                        writeLine();
                        emitStart(node);
                        write("(function (");
                        emitStart(node.name);
                        write(resolver.getLocalNameOfContainer(node));
                        emitEnd(node.name);
                        write(") ");
                        if (node.body.kind === 194 /* ModuleBlock */) {
                            emit(node.body);
                        }
                        else {
                            write("{");
                            increaseIndent();
                            scopeEmitStart(node);
                            emitCaptureThisForNodeIfNecessary(node);
                            writeLine();
                            emit(node.body);
                            decreaseIndent();
                            writeLine();
                            var moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body;
                            emitToken(14 /* CloseBraceToken */, moduleBlock.statements.end);
                            scopeEmitEnd();
                        }
                        write(")(");
                        if (node.flags & 1 /* Export */) {
                            emit(node.name);
                            write(" = ");
                        }
                        emitModuleMemberName(node);
                        write(" || (");
                        emitModuleMemberName(node);
                        write(" = {}));");
                        emitEnd(node);
                        emitTrailingComments(node);
                    }
                    function emitImportDeclaration(node) {
                        var emitImportDeclaration = resolver.isReferencedImportDeclaration(node);
                        if (!emitImportDeclaration) {
                            emitImportDeclaration = !ts.isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportWithEntityName(node);
                        }
                        if (emitImportDeclaration) {
                            if (node.externalModuleName && node.parent.kind === 198 /* SourceFile */ && compilerOptions.module === 2 /* AMD */) {
                                if (node.flags & 1 /* Export */) {
                                    writeLine();
                                    emitLeadingComments(node);
                                    emitStart(node);
                                    emitModuleMemberName(node);
                                    write(" = ");
                                    emit(node.name);
                                    write(";");
                                    emitEnd(node);
                                    emitTrailingComments(node);
                                }
                            }
                            else {
                                writeLine();
                                emitLeadingComments(node);
                                emitStart(node);
                                if (!(node.flags & 1 /* Export */))
                                    write("var ");
                                emitModuleMemberName(node);
                                write(" = ");
                                if (node.entityName) {
                                    emit(node.entityName);
                                }
                                else {
                                    write("require(");
                                    emitStart(node.externalModuleName);
                                    emitLiteral(node.externalModuleName);
                                    emitEnd(node.externalModuleName);
                                    emitToken(16 /* CloseParenToken */, node.externalModuleName.end);
                                }
                                write(";");
                                emitEnd(node);
                                emitTrailingComments(node);
                            }
                        }
                    }
                    function getExternalImportDeclarations(node) {
                        var result = [];
                        ts.forEach(node.statements, function (stat) {
                            if (stat.kind === 195 /* ImportDeclaration */ && stat.externalModuleName && resolver.isReferencedImportDeclaration(stat)) {
                                result.push(stat);
                            }
                        });
                        return result;
                    }
                    function getFirstExportAssignment(sourceFile) {
                        return ts.forEach(sourceFile.statements, function (node) {
                            if (node.kind === 196 /* ExportAssignment */) {
                                return node;
                            }
                        });
                    }
                    function emitAMDModule(node, startIndex) {
                        var imports = getExternalImportDeclarations(node);
                        writeLine();
                        write("define(");
                        if (node.amdModuleName) {
                            write("\"" + node.amdModuleName + "\", ");
                        }
                        write("[\"require\", \"exports\"");
                        ts.forEach(imports, function (imp) {
                            write(", ");
                            emitLiteral(imp.externalModuleName);
                        });
                        ts.forEach(node.amdDependencies, function (amdDependency) {
                            var text = "\"" + amdDependency + "\"";
                            write(", ");
                            write(text);
                        });
                        write("], function (require, exports");
                        ts.forEach(imports, function (imp) {
                            write(", ");
                            emit(imp.name);
                        });
                        write(") {");
                        increaseIndent();
                        emitCaptureThisForNodeIfNecessary(node);
                        emitLinesStartingAt(node.statements, startIndex);
                        var exportName = resolver.getExportAssignmentName(node);
                        if (exportName) {
                            writeLine();
                            var exportAssignement = getFirstExportAssignment(node);
                            emitStart(exportAssignement);
                            write("return ");
                            emitStart(exportAssignement.exportName);
                            write(exportName);
                            emitEnd(exportAssignement.exportName);
                            write(";");
                            emitEnd(exportAssignement);
                        }
                        decreaseIndent();
                        writeLine();
                        write("});");
                    }
                    function emitCommonJSModule(node, startIndex) {
                        emitCaptureThisForNodeIfNecessary(node);
                        emitLinesStartingAt(node.statements, startIndex);
                        var exportName = resolver.getExportAssignmentName(node);
                        if (exportName) {
                            writeLine();
                            var exportAssignement = getFirstExportAssignment(node);
                            emitStart(exportAssignement);
                            write("module.exports = ");
                            emitStart(exportAssignement.exportName);
                            write(exportName);
                            emitEnd(exportAssignement.exportName);
                            write(";");
                            emitEnd(exportAssignement);
                        }
                    }
                    function emitDirectivePrologues(statements, startWithNewLine) {
                        for (var i = 0; i < statements.length; ++i) {
                            if (ts.isPrologueDirective(statements[i])) {
                                if (startWithNewLine || i > 0) {
                                    writeLine();
                                }
                                emit(statements[i]);
                            }
                            else {
                                return i;
                            }
                        }
                        return statements.length;
                    }
                    function emitSourceFile(node) {
                        currentSourceFile = node;
                        writeLine();
                        emitDetachedComments(node);
                        var startIndex = emitDirectivePrologues(node.statements, false);
                        if (!extendsEmitted && resolver.getNodeCheckFlags(node) & 8 /* EmitExtends */) {
                            writeLine();
                            write("var __extends = this.__extends || function (d, b) {");
                            increaseIndent();
                            writeLine();
                            write("for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];");
                            writeLine();
                            write("function __() { this.constructor = d; }");
                            writeLine();
                            write("__.prototype = b.prototype;");
                            writeLine();
                            write("d.prototype = new __();");
                            decreaseIndent();
                            writeLine();
                            write("};");
                            extendsEmitted = true;
                        }
                        if (ts.isExternalModule(node)) {
                            if (compilerOptions.module === 2 /* AMD */) {
                                emitAMDModule(node, startIndex);
                            }
                            else {
                                emitCommonJSModule(node, startIndex);
                            }
                        }
                        else {
                            emitCaptureThisForNodeIfNecessary(node);
                            emitLinesStartingAt(node.statements, startIndex);
                        }
                    }
                    function emitNode(node) {
                        if (!node) {
                            return;
                        }
                        if (node.flags & 2 /* Ambient */) {
                            return emitPinnedOrTripleSlashComments(node);
                        }
                        switch (node.kind) {
                            case 63 /* Identifier */:
                                return emitIdentifier(node);
                            case 124 /* Parameter */:
                                return emitParameter(node);
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                                return emitAccessor(node);
                            case 91 /* ThisKeyword */:
                                return emitThis(node);
                            case 89 /* SuperKeyword */:
                                return emitSuper(node);
                            case 87 /* NullKeyword */:
                                return write("null");
                            case 93 /* TrueKeyword */:
                                return write("true");
                            case 78 /* FalseKeyword */:
                                return write("false");
                            case 6 /* NumericLiteral */:
                            case 7 /* StringLiteral */:
                            case 8 /* RegularExpressionLiteral */:
                            case 9 /* NoSubstitutionTemplateLiteral */:
                            case 10 /* TemplateHead */:
                            case 11 /* TemplateMiddle */:
                            case 12 /* TemplateTail */:
                                return emitLiteral(node);
                            case 159 /* TemplateExpression */:
                                return emitTemplateExpression(node);
                            case 160 /* TemplateSpan */:
                                return emitTemplateSpan(node);
                            case 121 /* QualifiedName */:
                                return emitPropertyAccess(node);
                            case 142 /* ArrayLiteral */:
                                return emitArrayLiteral(node);
                            case 143 /* ObjectLiteral */:
                                return emitObjectLiteral(node);
                            case 144 /* PropertyAssignment */:
                                return emitPropertyAssignment(node);
                            case 145 /* ShorthandPropertyAssignment */:
                                return emitShortHandPropertyAssignment(node);
                            case 122 /* ComputedPropertyName */:
                                return emitComputedPropertyName(node);
                            case 146 /* PropertyAccess */:
                                return emitPropertyAccess(node);
                            case 147 /* IndexedAccess */:
                                return emitIndexedAccess(node);
                            case 148 /* CallExpression */:
                                return emitCallExpression(node);
                            case 149 /* NewExpression */:
                                return emitNewExpression(node);
                            case 150 /* TaggedTemplateExpression */:
                                return emitTaggedTemplateExpression(node);
                            case 151 /* TypeAssertion */:
                                return emit(node.operand);
                            case 152 /* ParenExpression */:
                                return emitParenExpression(node);
                            case 187 /* FunctionDeclaration */:
                            case 153 /* FunctionExpression */:
                            case 154 /* ArrowFunction */:
                                return emitFunctionDeclaration(node);
                            case 155 /* PrefixOperator */:
                            case 156 /* PostfixOperator */:
                                return emitUnaryExpression(node);
                            case 157 /* BinaryExpression */:
                                return emitBinaryExpression(node);
                            case 158 /* ConditionalExpression */:
                                return emitConditionalExpression(node);
                            case 162 /* OmittedExpression */:
                                return;
                            case 163 /* Block */:
                            case 182 /* TryBlock */:
                            case 184 /* FinallyBlock */:
                            case 188 /* FunctionBlock */:
                            case 194 /* ModuleBlock */:
                                return emitBlock(node);
                            case 164 /* VariableStatement */:
                                return emitVariableStatement(node);
                            case 165 /* EmptyStatement */:
                                return write(";");
                            case 166 /* ExpressionStatement */:
                                return emitExpressionStatement(node);
                            case 167 /* IfStatement */:
                                return emitIfStatement(node);
                            case 168 /* DoStatement */:
                                return emitDoStatement(node);
                            case 169 /* WhileStatement */:
                                return emitWhileStatement(node);
                            case 170 /* ForStatement */:
                                return emitForStatement(node);
                            case 171 /* ForInStatement */:
                                return emitForInStatement(node);
                            case 172 /* ContinueStatement */:
                            case 173 /* BreakStatement */:
                                return emitBreakOrContinueStatement(node);
                            case 174 /* ReturnStatement */:
                                return emitReturnStatement(node);
                            case 175 /* WithStatement */:
                                return emitWithStatement(node);
                            case 176 /* SwitchStatement */:
                                return emitSwitchStatement(node);
                            case 177 /* CaseClause */:
                            case 178 /* DefaultClause */:
                                return emitCaseOrDefaultClause(node);
                            case 179 /* LabeledStatement */:
                                return emitLabelledStatement(node);
                            case 180 /* ThrowStatement */:
                                return emitThrowStatement(node);
                            case 181 /* TryStatement */:
                                return emitTryStatement(node);
                            case 183 /* CatchBlock */:
                                return emitCatchBlock(node);
                            case 185 /* DebuggerStatement */:
                                return emitDebuggerStatement(node);
                            case 186 /* VariableDeclaration */:
                                return emitVariableDeclaration(node);
                            case 189 /* ClassDeclaration */:
                                return emitClassDeclaration(node);
                            case 190 /* InterfaceDeclaration */:
                                return emitInterfaceDeclaration(node);
                            case 192 /* EnumDeclaration */:
                                return emitEnumDeclaration(node);
                            case 193 /* ModuleDeclaration */:
                                return emitModuleDeclaration(node);
                            case 195 /* ImportDeclaration */:
                                return emitImportDeclaration(node);
                            case 198 /* SourceFile */:
                                return emitSourceFile(node);
                        }
                    }
                    function hasDetachedComments(pos) {
                        return detachedCommentsInfo !== undefined && detachedCommentsInfo[detachedCommentsInfo.length - 1].nodePos === pos;
                    }
                    function getLeadingCommentsWithoutDetachedComments() {
                        var leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, detachedCommentsInfo[detachedCommentsInfo.length - 1].detachedCommentEndPos);
                        if (detachedCommentsInfo.length - 1) {
                            detachedCommentsInfo.pop();
                        }
                        else {
                            detachedCommentsInfo = undefined;
                        }
                        return leadingComments;
                    }
                    function getLeadingCommentsToEmit(node) {
                        if (node.parent.kind === 198 /* SourceFile */ || node.pos !== node.parent.pos) {
                            var leadingComments;
                            if (hasDetachedComments(node.pos)) {
                                leadingComments = getLeadingCommentsWithoutDetachedComments();
                            }
                            else {
                                leadingComments = ts.getLeadingCommentRangesOfNode(node, currentSourceFile);
                            }
                            return leadingComments;
                        }
                    }
                    function emitLeadingDeclarationComments(node) {
                        var leadingComments = getLeadingCommentsToEmit(node);
                        emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
                        emitComments(currentSourceFile, writer, leadingComments, true, newLine, writeComment);
                    }
                    function emitTrailingDeclarationComments(node) {
                        if (node.parent.kind === 198 /* SourceFile */ || node.end !== node.parent.end) {
                            var trailingComments = ts.getTrailingCommentRanges(currentSourceFile.text, node.end);
                            emitComments(currentSourceFile, writer, trailingComments, false, newLine, writeComment);
                        }
                    }
                    function emitLeadingCommentsOfLocalPosition(pos) {
                        var leadingComments;
                        if (hasDetachedComments(pos)) {
                            leadingComments = getLeadingCommentsWithoutDetachedComments();
                        }
                        else {
                            leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, pos);
                        }
                        emitNewLineBeforeLeadingComments(currentSourceFile, writer, { pos: pos, end: pos }, leadingComments);
                        emitComments(currentSourceFile, writer, leadingComments, true, newLine, writeComment);
                    }
                    function emitDetachedCommentsAtPosition(node) {
                        var leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, node.pos);
                        if (leadingComments) {
                            var detachedComments = [];
                            var lastComment;
                            ts.forEach(leadingComments, function (comment) {
                                if (lastComment) {
                                    var lastCommentLine = getLineOfLocalPosition(currentSourceFile, lastComment.end);
                                    var commentLine = getLineOfLocalPosition(currentSourceFile, comment.pos);
                                    if (commentLine >= lastCommentLine + 2) {
                                        return detachedComments;
                                    }
                                }
                                detachedComments.push(comment);
                                lastComment = comment;
                            });
                            if (detachedComments.length) {
                                var lastCommentLine = getLineOfLocalPosition(currentSourceFile, detachedComments[detachedComments.length - 1].end);
                                var astLine = getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node.pos));
                                if (astLine >= lastCommentLine + 2) {
                                    emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
                                    emitComments(currentSourceFile, writer, detachedComments, true, newLine, writeComment);
                                    var currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: detachedComments[detachedComments.length - 1].end };
                                    if (detachedCommentsInfo) {
                                        detachedCommentsInfo.push(currentDetachedCommentInfo);
                                    }
                                    else {
                                        detachedCommentsInfo = [currentDetachedCommentInfo];
                                    }
                                }
                            }
                        }
                    }
                    function emitPinnedOrTripleSlashCommentsOfNode(node) {
                        var pinnedComments = ts.filter(getLeadingCommentsToEmit(node), isPinnedOrTripleSlashComment);
                        function isPinnedOrTripleSlashComment(comment) {
                            if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 42 /* asterisk */) {
                                return currentSourceFile.text.charCodeAt(comment.pos + 2) === 33 /* exclamation */;
                            }
                            else if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 47 /* slash */ && comment.pos + 2 < comment.end && currentSourceFile.text.charCodeAt(comment.pos + 2) === 47 /* slash */ && currentSourceFile.text.substring(comment.pos, comment.end).match(ts.fullTripleSlashReferencePathRegEx)) {
                                return true;
                            }
                        }
                        emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, pinnedComments);
                        emitComments(currentSourceFile, writer, pinnedComments, true, newLine, writeComment);
                    }
                    if (compilerOptions.sourceMap) {
                        initializeEmitterWithSourceMaps();
                    }
                    if (root) {
                        emit(root);
                    }
                    else {
                        ts.forEach(program.getSourceFiles(), function (sourceFile) {
                            if (!isExternalModuleOrDeclarationFile(sourceFile)) {
                                emit(sourceFile);
                            }
                        });
                    }
                    writeLine();
                    writeEmittedFiles(writer.getText(), compilerOptions.emitBOM);
                }
                function writeDeclarationFile(jsFilePath, sourceFile) {
                    var emitDeclarationResult = emitDeclarations(program, resolver, diagnostics, jsFilePath, sourceFile);
                    if (!emitDeclarationResult.reportedDeclarationError) {
                        var declarationOutput = emitDeclarationResult.referencePathsOutput;
                        var appliedSyncOutputPos = 0;
                        ts.forEach(emitDeclarationResult.aliasDeclarationEmitInfo, function (aliasEmitInfo) {
                            if (aliasEmitInfo.asynchronousOutput) {
                                declarationOutput += emitDeclarationResult.synchronousDeclarationOutput.substring(appliedSyncOutputPos, aliasEmitInfo.outputPos);
                                declarationOutput += aliasEmitInfo.asynchronousOutput;
                                appliedSyncOutputPos = aliasEmitInfo.outputPos;
                            }
                        });
                        declarationOutput += emitDeclarationResult.synchronousDeclarationOutput.substring(appliedSyncOutputPos);
                        writeFile(compilerHost, diagnostics, ts.removeFileExtension(jsFilePath) + ".d.ts", declarationOutput, compilerOptions.emitBOM);
                    }
                }
                var hasSemanticErrors = resolver.hasSemanticErrors();
                var isEmitBlocked = resolver.isEmitBlocked(targetSourceFile);
                function emitFile(jsFilePath, sourceFile) {
                    if (!isEmitBlocked) {
                        emitJavaScript(jsFilePath, sourceFile);
                        if (!hasSemanticErrors && compilerOptions.declaration) {
                            writeDeclarationFile(jsFilePath, sourceFile);
                        }
                    }
                }
                if (targetSourceFile === undefined) {
                    ts.forEach(program.getSourceFiles(), function (sourceFile) {
                        if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
                            var jsFilePath = getOwnEmitOutputFilePath(sourceFile, program, ".js");
                            emitFile(jsFilePath, sourceFile);
                        }
                    });
                    if (compilerOptions.out) {
                        emitFile(compilerOptions.out);
                    }
                }
                else {
                    if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
                        var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, program, ".js");
                        emitFile(jsFilePath, targetSourceFile);
                    }
                    else if (!ts.isDeclarationFile(targetSourceFile) && compilerOptions.out) {
                        emitFile(compilerOptions.out);
                    }
                }
                diagnostics.sort(ts.compareDiagnostics);
                diagnostics = ts.deduplicateSortedDiagnostics(diagnostics);
                var hasEmitterError = ts.forEach(diagnostics, function (diagnostic) { return diagnostic.category === 1 /* Error */; });
                var emitResultStatus;
                if (isEmitBlocked) {
                    emitResultStatus = 1 /* AllOutputGenerationSkipped */;
                }
                else if (hasEmitterError) {
                    emitResultStatus = 4 /* EmitErrorsEncountered */;
                }
                else if (hasSemanticErrors && compilerOptions.declaration) {
                    emitResultStatus = 3 /* DeclarationGenerationSkipped */;
                }
                else if (hasSemanticErrors && !compilerOptions.declaration) {
                    emitResultStatus = 2 /* JSGeneratedWithSemanticErrors */;
                }
                else {
                    emitResultStatus = 0 /* Succeeded */;
                }
                return {
                    emitResultStatus: emitResultStatus,
                    diagnostics: diagnostics,
                    sourceMaps: sourceMapDataList
                };
            }
            ts.emitFiles = emitFiles;
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var nextSymbolId = 1;
            var nextNodeId = 1;
            var nextMergeId = 1;
            function getDeclarationOfKind(symbol, kind) {
                var declarations = symbol.declarations;
                for (var i = 0; i < declarations.length; i++) {
                    var declaration = declarations[i];
                    if (declaration.kind === kind) {
                        return declaration;
                    }
                }
                return undefined;
            }
            ts.getDeclarationOfKind = getDeclarationOfKind;
            var stringWriters = [];
            function getSingleLineStringWriter() {
                if (stringWriters.length == 0) {
                    var str = "";
                    var writeText = function (text) { return str += text; };
                    return {
                        string: function () { return str; },
                        writeKeyword: writeText,
                        writeOperator: writeText,
                        writePunctuation: writeText,
                        writeSpace: writeText,
                        writeStringLiteral: writeText,
                        writeParameter: writeText,
                        writeSymbol: writeText,
                        writeLine: function () { return str += " "; },
                        increaseIndent: function () {
                        },
                        decreaseIndent: function () {
                        },
                        clear: function () { return str = ""; },
                        trackSymbol: function () {
                        }
                    };
                }
                return stringWriters.pop();
            }
            ts.getSingleLineStringWriter = getSingleLineStringWriter;
            function createTypeChecker(program, fullTypeCheck) {
                var Symbol = ts.objectAllocator.getSymbolConstructor();
                var Type = ts.objectAllocator.getTypeConstructor();
                var Signature = ts.objectAllocator.getSignatureConstructor();
                var typeCount = 0;
                var emptyArray = [];
                var emptySymbols = {};
                var compilerOptions = program.getCompilerOptions();
                var checker = {
                    getProgram: function () { return program; },
                    getNodeCount: function () { return ts.sum(program.getSourceFiles(), "nodeCount"); },
                    getIdentifierCount: function () { return ts.sum(program.getSourceFiles(), "identifierCount"); },
                    getSymbolCount: function () { return ts.sum(program.getSourceFiles(), "symbolCount"); },
                    getTypeCount: function () { return typeCount; },
                    isUndefinedSymbol: function (symbol) { return symbol === undefinedSymbol; },
                    isArgumentsSymbol: function (symbol) { return symbol === argumentsSymbol; },
                    emitFiles: invokeEmitter,
                    getDiagnostics: getDiagnostics,
                    getDeclarationDiagnostics: getDeclarationDiagnostics,
                    getGlobalDiagnostics: getGlobalDiagnostics,
                    checkProgram: checkProgram,
                    getParentOfSymbol: getParentOfSymbol,
                    getNarrowedTypeOfSymbol: getNarrowedTypeOfSymbol,
                    getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
                    getPropertiesOfType: getPropertiesOfType,
                    getPropertyOfType: getPropertyOfType,
                    getSignaturesOfType: getSignaturesOfType,
                    getIndexTypeOfType: getIndexTypeOfType,
                    getReturnTypeOfSignature: getReturnTypeOfSignature,
                    getSymbolsInScope: getSymbolsInScope,
                    getSymbolInfo: getSymbolInfo,
                    getShorthandAssignmentValueSymbol: getShorthandAssignmentValueSymbol,
                    getTypeOfNode: getTypeOfNode,
                    typeToString: typeToString,
                    getSymbolDisplayBuilder: getSymbolDisplayBuilder,
                    symbolToString: symbolToString,
                    getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
                    getRootSymbols: getRootSymbols,
                    getContextualType: getContextualType,
                    getFullyQualifiedName: getFullyQualifiedName,
                    getResolvedSignature: getResolvedSignature,
                    getEnumMemberValue: getEnumMemberValue,
                    isValidPropertyAccess: isValidPropertyAccess,
                    getSignatureFromDeclaration: getSignatureFromDeclaration,
                    isImplementationOfOverload: isImplementationOfOverload,
                    getAliasedSymbol: resolveImport,
                    hasEarlyErrors: hasEarlyErrors,
                    isEmitBlocked: isEmitBlocked
                };
                var undefinedSymbol = createSymbol(4 /* Property */ | 268435456 /* Transient */, "undefined");
                var argumentsSymbol = createSymbol(4 /* Property */ | 268435456 /* Transient */, "arguments");
                var unknownSymbol = createSymbol(4 /* Property */ | 268435456 /* Transient */, "unknown");
                var resolvingSymbol = createSymbol(268435456 /* Transient */, "__resolving__");
                var anyType = createIntrinsicType(1 /* Any */, "any");
                var stringType = createIntrinsicType(2 /* String */, "string");
                var numberType = createIntrinsicType(4 /* Number */, "number");
                var booleanType = createIntrinsicType(8 /* Boolean */, "boolean");
                var voidType = createIntrinsicType(16 /* Void */, "void");
                var undefinedType = createIntrinsicType(32 /* Undefined */, "undefined");
                var nullType = createIntrinsicType(64 /* Null */, "null");
                var unknownType = createIntrinsicType(1 /* Any */, "unknown");
                var resolvingType = createIntrinsicType(1 /* Any */, "__resolving__");
                var emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
                var anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
                var noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
                var inferenceFailureType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
                var anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false);
                var unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false);
                var globals = {};
                var globalArraySymbol;
                var globalObjectType;
                var globalFunctionType;
                var globalArrayType;
                var globalStringType;
                var globalNumberType;
                var globalBooleanType;
                var globalRegExpType;
                var globalTemplateStringsArrayType;
                var tupleTypes = {};
                var unionTypes = {};
                var stringLiteralTypes = {};
                var emitExtends = false;
                var mergedSymbols = [];
                var symbolLinks = [];
                var nodeLinks = [];
                var potentialThisCollisions = [];
                var diagnostics = [];
                var diagnosticsModified = false;
                function addDiagnostic(diagnostic) {
                    diagnostics.push(diagnostic);
                    diagnosticsModified = true;
                }
                function error(location, message, arg0, arg1, arg2) {
                    var diagnostic = location ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2) : ts.createCompilerDiagnostic(message, arg0, arg1, arg2);
                    addDiagnostic(diagnostic);
                }
                function createSymbol(flags, name) {
                    return new Symbol(flags, name);
                }
                function getExcludedSymbolFlags(flags) {
                    var result = 0;
                    if (flags & 2 /* BlockScopedVariable */)
                        result |= 107455 /* BlockScopedVariableExcludes */;
                    if (flags & 1 /* FunctionScopedVariable */)
                        result |= 107454 /* FunctionScopedVariableExcludes */;
                    if (flags & 4 /* Property */)
                        result |= 107455 /* PropertyExcludes */;
                    if (flags & 8 /* EnumMember */)
                        result |= 107455 /* EnumMemberExcludes */;
                    if (flags & 16 /* Function */)
                        result |= 106927 /* FunctionExcludes */;
                    if (flags & 32 /* Class */)
                        result |= 3258879 /* ClassExcludes */;
                    if (flags & 64 /* Interface */)
                        result |= 3152288 /* InterfaceExcludes */;
                    if (flags & 256 /* RegularEnum */)
                        result |= 3258623 /* RegularEnumExcludes */;
                    if (flags & 128 /* ConstEnum */)
                        result |= 3259263 /* ConstEnumExcludes */;
                    if (flags & 512 /* ValueModule */)
                        result |= 106639 /* ValueModuleExcludes */;
                    if (flags & 8192 /* Method */)
                        result |= 99263 /* MethodExcludes */;
                    if (flags & 32768 /* GetAccessor */)
                        result |= 41919 /* GetAccessorExcludes */;
                    if (flags & 65536 /* SetAccessor */)
                        result |= 74687 /* SetAccessorExcludes */;
                    if (flags & 1048576 /* TypeParameter */)
                        result |= 2103776 /* TypeParameterExcludes */;
                    if (flags & 2097152 /* TypeAlias */)
                        result |= 3152352 /* TypeAliasExcludes */;
                    if (flags & 33554432 /* Import */)
                        result |= 33554432 /* ImportExcludes */;
                    return result;
                }
                function recordMergedSymbol(target, source) {
                    if (!source.mergeId)
                        source.mergeId = nextMergeId++;
                    mergedSymbols[source.mergeId] = target;
                }
                function cloneSymbol(symbol) {
                    var result = createSymbol(symbol.flags | 134217728 /* Merged */, symbol.name);
                    result.declarations = symbol.declarations.slice(0);
                    result.parent = symbol.parent;
                    if (symbol.valueDeclaration)
                        result.valueDeclaration = symbol.valueDeclaration;
                    if (symbol.constEnumOnlyModule)
                        result.constEnumOnlyModule = true;
                    if (symbol.members)
                        result.members = cloneSymbolTable(symbol.members);
                    if (symbol.exports)
                        result.exports = cloneSymbolTable(symbol.exports);
                    recordMergedSymbol(result, symbol);
                    return result;
                }
                function extendSymbol(target, source) {
                    if (!(target.flags & getExcludedSymbolFlags(source.flags))) {
                        if (source.flags & 512 /* ValueModule */ && target.flags & 512 /* ValueModule */ && target.constEnumOnlyModule && !source.constEnumOnlyModule) {
                            target.constEnumOnlyModule = false;
                        }
                        target.flags |= source.flags;
                        if (!target.valueDeclaration && source.valueDeclaration)
                            target.valueDeclaration = source.valueDeclaration;
                        ts.forEach(source.declarations, function (node) {
                            target.declarations.push(node);
                        });
                        if (source.members) {
                            if (!target.members)
                                target.members = {};
                            extendSymbolTable(target.members, source.members);
                        }
                        if (source.exports) {
                            if (!target.exports)
                                target.exports = {};
                            extendSymbolTable(target.exports, source.exports);
                        }
                        recordMergedSymbol(target, source);
                    }
                    else {
                        var message = target.flags & 2 /* BlockScopedVariable */ || source.flags & 2 /* BlockScopedVariable */ ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 : ts.Diagnostics.Duplicate_identifier_0;
                        ts.forEach(source.declarations, function (node) {
                            error(node.name ? node.name : node, message, symbolToString(source));
                        });
                        ts.forEach(target.declarations, function (node) {
                            error(node.name ? node.name : node, message, symbolToString(source));
                        });
                    }
                }
                function cloneSymbolTable(symbolTable) {
                    var result = {};
                    for (var id in symbolTable) {
                        if (ts.hasProperty(symbolTable, id)) {
                            result[id] = symbolTable[id];
                        }
                    }
                    return result;
                }
                function extendSymbolTable(target, source) {
                    for (var id in source) {
                        if (ts.hasProperty(source, id)) {
                            if (!ts.hasProperty(target, id)) {
                                target[id] = source[id];
                            }
                            else {
                                var symbol = target[id];
                                if (!(symbol.flags & 134217728 /* Merged */)) {
                                    target[id] = symbol = cloneSymbol(symbol);
                                }
                                extendSymbol(symbol, source[id]);
                            }
                        }
                    }
                }
                function getSymbolLinks(symbol) {
                    if (symbol.flags & 268435456 /* Transient */)
                        return symbol;
                    if (!symbol.id)
                        symbol.id = nextSymbolId++;
                    return symbolLinks[symbol.id] || (symbolLinks[symbol.id] = {});
                }
                function getNodeLinks(node) {
                    if (!node.id)
                        node.id = nextNodeId++;
                    return nodeLinks[node.id] || (nodeLinks[node.id] = {});
                }
                function getSourceFile(node) {
                    return ts.getAncestor(node, 198 /* SourceFile */);
                }
                function isGlobalSourceFile(node) {
                    return node.kind === 198 /* SourceFile */ && !ts.isExternalModule(node);
                }
                function getSymbol(symbols, name, meaning) {
                    if (meaning && ts.hasProperty(symbols, name)) {
                        var symbol = symbols[name];
                        ts.Debug.assert((symbol.flags & 67108864 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
                        if (symbol.flags & meaning) {
                            return symbol;
                        }
                        if (symbol.flags & 33554432 /* Import */) {
                            var target = resolveImport(symbol);
                            if (target === unknownSymbol || target.flags & meaning) {
                                return symbol;
                            }
                        }
                    }
                }
                function isDefinedBefore(node1, node2) {
                    var file1 = ts.getSourceFileOfNode(node1);
                    var file2 = ts.getSourceFileOfNode(node2);
                    if (file1 === file2) {
                        return node1.pos <= node2.pos;
                    }
                    if (!compilerOptions.out) {
                        return true;
                    }
                    var sourceFiles = program.getSourceFiles();
                    return sourceFiles.indexOf(file1) <= sourceFiles.indexOf(file2);
                }
                function resolveName(location, name, meaning, nameNotFoundMessage, nameArg) {
                    var result;
                    var lastLocation;
                    var propertyWithInvalidInitializer;
                    var errorLocation = location;
                    loop: while (location) {
                        if (location.locals && !isGlobalSourceFile(location)) {
                            if (result = getSymbol(location.locals, name, meaning)) {
                                break loop;
                            }
                        }
                        switch (location.kind) {
                            case 198 /* SourceFile */:
                                if (!ts.isExternalModule(location))
                                    break;
                            case 193 /* ModuleDeclaration */:
                                if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & 35653619 /* ModuleMember */)) {
                                    break loop;
                                }
                                break;
                            case 192 /* EnumDeclaration */:
                                if (result = getSymbol(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) {
                                    break loop;
                                }
                                break;
                            case 125 /* Property */:
                                if (location.parent.kind === 189 /* ClassDeclaration */ && !(location.flags & 128 /* Static */)) {
                                    var ctor = findConstructorDeclaration(location.parent);
                                    if (ctor && ctor.locals) {
                                        if (getSymbol(ctor.locals, name, meaning & 107455 /* Value */)) {
                                            propertyWithInvalidInitializer = location;
                                        }
                                    }
                                }
                                break;
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                                if (result = getSymbol(getSymbolOfNode(location).members, name, meaning & 3152352 /* Type */)) {
                                    if (lastLocation && lastLocation.flags & 128 /* Static */) {
                                        error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters);
                                        return undefined;
                                    }
                                    break loop;
                                }
                                break;
                            case 126 /* Method */:
                            case 127 /* Constructor */:
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                            case 187 /* FunctionDeclaration */:
                            case 154 /* ArrowFunction */:
                                if (name === "arguments") {
                                    result = argumentsSymbol;
                                    break loop;
                                }
                                break;
                            case 153 /* FunctionExpression */:
                                if (name === "arguments") {
                                    result = argumentsSymbol;
                                    break loop;
                                }
                                var id = location.name;
                                if (id && name === id.text) {
                                    result = location.symbol;
                                    break loop;
                                }
                                break;
                            case 183 /* CatchBlock */:
                                var id = location.variable;
                                if (name === id.text) {
                                    result = location.symbol;
                                    break loop;
                                }
                                break;
                        }
                        lastLocation = location;
                        location = location.parent;
                    }
                    if (!result) {
                        result = getSymbol(globals, name, meaning);
                    }
                    if (!result) {
                        if (nameNotFoundMessage) {
                            error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : ts.declarationNameToString(nameArg));
                        }
                        return undefined;
                    }
                    if (nameNotFoundMessage) {
                        if (propertyWithInvalidInitializer) {
                            var propertyName = propertyWithInvalidInitializer.name;
                            error(errorLocation, ts.Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, ts.declarationNameToString(propertyName), typeof nameArg === "string" ? nameArg : ts.declarationNameToString(nameArg));
                            return undefined;
                        }
                        if (result.flags & 2 /* BlockScopedVariable */) {
                            var declaration = ts.forEach(result.declarations, function (d) { return d.flags & 6144 /* BlockScoped */ ? d : undefined; });
                            ts.Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined");
                            if (!isDefinedBefore(declaration, errorLocation)) {
                                error(errorLocation, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, ts.declarationNameToString(declaration.name));
                            }
                        }
                    }
                    return result;
                }
                function resolveImport(symbol) {
                    ts.Debug.assert((symbol.flags & 33554432 /* Import */) !== 0, "Should only get Imports here.");
                    var links = getSymbolLinks(symbol);
                    if (!links.target) {
                        links.target = resolvingSymbol;
                        var node = getDeclarationOfKind(symbol, 195 /* ImportDeclaration */);
                        var target = node.externalModuleName ? resolveExternalModuleName(node, node.externalModuleName) : getSymbolOfPartOfRightHandSideOfImport(node.entityName, node);
                        if (links.target === resolvingSymbol) {
                            links.target = target || unknownSymbol;
                        }
                        else {
                            error(node, ts.Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol));
                        }
                    }
                    else if (links.target === resolvingSymbol) {
                        links.target = unknownSymbol;
                    }
                    return links.target;
                }
                function getSymbolOfPartOfRightHandSideOfImport(entityName, importDeclaration) {
                    if (!importDeclaration) {
                        importDeclaration = ts.getAncestor(entityName, 195 /* ImportDeclaration */);
                        ts.Debug.assert(importDeclaration !== undefined);
                    }
                    if (entityName.kind === 63 /* Identifier */ && isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
                        entityName = entityName.parent;
                    }
                    if (entityName.kind === 63 /* Identifier */ || entityName.parent.kind === 121 /* QualifiedName */) {
                        return resolveEntityName(importDeclaration, entityName, 1536 /* Namespace */);
                    }
                    else {
                        ts.Debug.assert(entityName.parent.kind === 195 /* ImportDeclaration */);
                        return resolveEntityName(importDeclaration, entityName, 107455 /* Value */ | 3152352 /* Type */ | 1536 /* Namespace */);
                    }
                }
                function getFullyQualifiedName(symbol) {
                    return symbol.parent ? getFullyQualifiedName(symbol.parent) + "." + symbolToString(symbol) : symbolToString(symbol);
                }
                function resolveEntityName(location, name, meaning) {
                    if (name.kind === 63 /* Identifier */) {
                        var symbol = resolveName(location, name.text, meaning, ts.Diagnostics.Cannot_find_name_0, name);
                        if (!symbol) {
                            return;
                        }
                    }
                    else if (name.kind === 121 /* QualifiedName */) {
                        var namespace = resolveEntityName(location, name.left, 1536 /* Namespace */);
                        if (!namespace || namespace === unknownSymbol || name.right.kind === 120 /* Missing */)
                            return;
                        var symbol = getSymbol(namespace.exports, name.right.text, meaning);
                        if (!symbol) {
                            error(location, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(namespace), ts.declarationNameToString(name.right));
                            return;
                        }
                    }
                    else {
                        return;
                    }
                    ts.Debug.assert((symbol.flags & 67108864 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
                    return symbol.flags & meaning ? symbol : resolveImport(symbol);
                }
                function isExternalModuleNameRelative(moduleName) {
                    return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\";
                }
                function resolveExternalModuleName(location, moduleLiteral) {
                    var searchPath = ts.getDirectoryPath(getSourceFile(location).filename);
                    var moduleName = moduleLiteral.text;
                    if (!moduleName)
                        return;
                    var isRelative = isExternalModuleNameRelative(moduleName);
                    if (!isRelative) {
                        var symbol = getSymbol(globals, '"' + moduleName + '"', 512 /* ValueModule */);
                        if (symbol) {
                            return getResolvedExportSymbol(symbol);
                        }
                    }
                    while (true) {
                        var filename = ts.normalizePath(ts.combinePaths(searchPath, moduleName));
                        var sourceFile = program.getSourceFile(filename + ".ts") || program.getSourceFile(filename + ".d.ts");
                        if (sourceFile || isRelative)
                            break;
                        var parentPath = ts.getDirectoryPath(searchPath);
                        if (parentPath === searchPath)
                            break;
                        searchPath = parentPath;
                    }
                    if (sourceFile) {
                        if (sourceFile.symbol) {
                            return getResolvedExportSymbol(sourceFile.symbol);
                        }
                        error(moduleLiteral, ts.Diagnostics.File_0_is_not_an_external_module, sourceFile.filename);
                        return;
                    }
                    error(moduleLiteral, ts.Diagnostics.Cannot_find_external_module_0, moduleName);
                }
                function getResolvedExportSymbol(moduleSymbol) {
                    var symbol = getExportAssignmentSymbol(moduleSymbol);
                    if (symbol) {
                        if (symbol.flags & (107455 /* Value */ | 3152352 /* Type */ | 1536 /* Namespace */)) {
                            return symbol;
                        }
                        if (symbol.flags & 33554432 /* Import */) {
                            return resolveImport(symbol);
                        }
                    }
                    return moduleSymbol;
                }
                function getExportAssignmentSymbol(symbol) {
                    checkTypeOfExportAssignmentSymbol(symbol);
                    var symbolLinks = getSymbolLinks(symbol);
                    return symbolLinks.exportAssignSymbol === unknownSymbol ? undefined : symbolLinks.exportAssignSymbol;
                }
                function checkTypeOfExportAssignmentSymbol(containerSymbol) {
                    var symbolLinks = getSymbolLinks(containerSymbol);
                    if (!symbolLinks.exportAssignSymbol) {
                        var exportInformation = collectExportInformationForSourceFileOrModule(containerSymbol);
                        if (exportInformation.exportAssignments.length) {
                            if (exportInformation.exportAssignments.length > 1) {
                                ts.forEach(exportInformation.exportAssignments, function (node) { return error(node, ts.Diagnostics.A_module_cannot_have_more_than_one_export_assignment); });
                            }
                            var node = exportInformation.exportAssignments[0];
                            if (exportInformation.hasExportedMember) {
                                error(node, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements);
                            }
                            if (node.exportName.text) {
                                var meaning = 107455 /* Value */ | 3152352 /* Type */ | 1536 /* Namespace */;
                                var exportSymbol = resolveName(node, node.exportName.text, meaning, ts.Diagnostics.Cannot_find_name_0, node.exportName);
                            }
                        }
                        symbolLinks.exportAssignSymbol = exportSymbol || unknownSymbol;
                    }
                }
                function collectExportInformationForSourceFileOrModule(symbol) {
                    var seenExportedMember = false;
                    var result = [];
                    ts.forEach(symbol.declarations, function (declaration) {
                        var block = (declaration.kind === 198 /* SourceFile */ ? declaration : declaration.body);
                        ts.forEach(block.statements, function (node) {
                            if (node.kind === 196 /* ExportAssignment */) {
                                result.push(node);
                            }
                            else {
                                seenExportedMember = seenExportedMember || (node.flags & 1 /* Export */) !== 0;
                            }
                        });
                    });
                    return {
                        hasExportedMember: seenExportedMember,
                        exportAssignments: result
                    };
                }
                function getMergedSymbol(symbol) {
                    var merged;
                    return symbol && symbol.mergeId && (merged = mergedSymbols[symbol.mergeId]) ? merged : symbol;
                }
                function getSymbolOfNode(node) {
                    return getMergedSymbol(node.symbol);
                }
                function getParentOfSymbol(symbol) {
                    return getMergedSymbol(symbol.parent);
                }
                function getExportSymbolOfValueSymbolIfExported(symbol) {
                    return symbol && (symbol.flags & 4194304 /* ExportValue */) !== 0 ? getMergedSymbol(symbol.exportSymbol) : symbol;
                }
                function symbolIsValue(symbol) {
                    if (symbol.flags & 67108864 /* Instantiated */) {
                        return symbolIsValue(getSymbolLinks(symbol).target);
                    }
                    if (symbol.flags & 107455 /* Value */) {
                        return true;
                    }
                    if (symbol.flags & 33554432 /* Import */) {
                        return (resolveImport(symbol).flags & 107455 /* Value */) !== 0;
                    }
                    return false;
                }
                function findConstructorDeclaration(node) {
                    var members = node.members;
                    for (var i = 0; i < members.length; i++) {
                        var member = members[i];
                        if (member.kind === 127 /* Constructor */ && member.body) {
                            return member;
                        }
                    }
                }
                function createType(flags) {
                    var result = new Type(checker, flags);
                    result.id = typeCount++;
                    return result;
                }
                function createIntrinsicType(kind, intrinsicName) {
                    var type = createType(kind);
                    type.intrinsicName = intrinsicName;
                    return type;
                }
                function createObjectType(kind, symbol) {
                    var type = createType(kind);
                    type.symbol = symbol;
                    return type;
                }
                function isReservedMemberName(name) {
                    return name.charCodeAt(0) === 95 /* _ */ && name.charCodeAt(1) === 95 /* _ */ && name.charCodeAt(2) !== 95 /* _ */;
                }
                function getNamedMembers(members) {
                    var result;
                    for (var id in members) {
                        if (ts.hasProperty(members, id)) {
                            if (!isReservedMemberName(id)) {
                                if (!result)
                                    result = [];
                                var symbol = members[id];
                                if (symbolIsValue(symbol)) {
                                    result.push(symbol);
                                }
                            }
                        }
                    }
                    return result || emptyArray;
                }
                function setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexType, numberIndexType) {
                    type.members = members;
                    type.properties = getNamedMembers(members);
                    type.callSignatures = callSignatures;
                    type.constructSignatures = constructSignatures;
                    if (stringIndexType)
                        type.stringIndexType = stringIndexType;
                    if (numberIndexType)
                        type.numberIndexType = numberIndexType;
                    return type;
                }
                function createAnonymousType(symbol, members, callSignatures, constructSignatures, stringIndexType, numberIndexType) {
                    return setObjectTypeMembers(createObjectType(32768 /* Anonymous */, symbol), members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
                }
                function isOptionalProperty(propertySymbol) {
                    return propertySymbol.valueDeclaration && propertySymbol.valueDeclaration.flags & 4 /* QuestionMark */ && propertySymbol.valueDeclaration.kind !== 124 /* Parameter */;
                }
                function forEachSymbolTableInScope(enclosingDeclaration, callback) {
                    var result;
                    for (var location = enclosingDeclaration; location; location = location.parent) {
                        if (location.locals && !isGlobalSourceFile(location)) {
                            if (result = callback(location.locals)) {
                                return result;
                            }
                        }
                        switch (location.kind) {
                            case 198 /* SourceFile */:
                                if (!ts.isExternalModule(location)) {
                                    break;
                                }
                            case 193 /* ModuleDeclaration */:
                                if (result = callback(getSymbolOfNode(location).exports)) {
                                    return result;
                                }
                                break;
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                                if (result = callback(getSymbolOfNode(location).members)) {
                                    return result;
                                }
                                break;
                        }
                    }
                    return callback(globals);
                }
                function getQualifiedLeftMeaning(rightMeaning) {
                    return rightMeaning === 107455 /* Value */ ? 107455 /* Value */ : 1536 /* Namespace */;
                }
                function getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, useOnlyExternalAliasing) {
                    function getAccessibleSymbolChainFromSymbolTable(symbols) {
                        function canQualifySymbol(symbolFromSymbolTable, meaning) {
                            if (!needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning)) {
                                return true;
                            }
                            var accessibleParent = getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing);
                            return !!accessibleParent;
                        }
                        function isAccessible(symbolFromSymbolTable, resolvedAliasSymbol) {
                            if (symbol === (resolvedAliasSymbol || symbolFromSymbolTable)) {
                                return !ts.forEach(symbolFromSymbolTable.declarations, function (declaration) { return hasExternalModuleSymbol(declaration); }) && canQualifySymbol(symbolFromSymbolTable, meaning);
                            }
                        }
                        if (isAccessible(ts.lookUp(symbols, symbol.name))) {
                            return [symbol];
                        }
                        return ts.forEachValue(symbols, function (symbolFromSymbolTable) {
                            if (symbolFromSymbolTable.flags & 33554432 /* Import */) {
                                if (!useOnlyExternalAliasing || ts.forEach(symbolFromSymbolTable.declarations, function (declaration) { return declaration.kind === 195 /* ImportDeclaration */ && declaration.externalModuleName; })) {
                                    var resolvedImportedSymbol = resolveImport(symbolFromSymbolTable);
                                    if (isAccessible(symbolFromSymbolTable, resolveImport(symbolFromSymbolTable))) {
                                        return [symbolFromSymbolTable];
                                    }
                                    var accessibleSymbolsFromExports = resolvedImportedSymbol.exports ? getAccessibleSymbolChainFromSymbolTable(resolvedImportedSymbol.exports) : undefined;
                                    if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
                                        return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
                                    }
                                }
                            }
                        });
                    }
                    if (symbol) {
                        return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
                    }
                }
                function needsQualification(symbol, enclosingDeclaration, meaning) {
                    var qualify = false;
                    forEachSymbolTableInScope(enclosingDeclaration, function (symbolTable) {
                        if (!ts.hasProperty(symbolTable, symbol.name)) {
                            return false;
                        }
                        var symbolFromSymbolTable = symbolTable[symbol.name];
                        if (symbolFromSymbolTable === symbol) {
                            return true;
                        }
                        symbolFromSymbolTable = (symbolFromSymbolTable.flags & 33554432 /* Import */) ? resolveImport(symbolFromSymbolTable) : symbolFromSymbolTable;
                        if (symbolFromSymbolTable.flags & meaning) {
                            qualify = true;
                            return true;
                        }
                        return false;
                    });
                    return qualify;
                }
                function isSymbolAccessible(symbol, enclosingDeclaration, meaning) {
                    if (symbol && enclosingDeclaration && !(symbol.flags & 1048576 /* TypeParameter */)) {
                        var initialSymbol = symbol;
                        var meaningToLook = meaning;
                        while (symbol) {
                            var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaningToLook, false);
                            if (accessibleSymbolChain) {
                                var hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0]);
                                if (!hasAccessibleDeclarations) {
                                    return {
                                        accessibility: 1 /* NotAccessible */,
                                        errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
                                        errorModuleName: symbol !== initialSymbol ? symbolToString(symbol, enclosingDeclaration, 1536 /* Namespace */) : undefined
                                    };
                                }
                                return hasAccessibleDeclarations;
                            }
                            meaningToLook = getQualifiedLeftMeaning(meaning);
                            symbol = getParentOfSymbol(symbol);
                        }
                        var symbolExternalModule = ts.forEach(initialSymbol.declarations, function (declaration) { return getExternalModuleContainer(declaration); });
                        if (symbolExternalModule) {
                            var enclosingExternalModule = getExternalModuleContainer(enclosingDeclaration);
                            if (symbolExternalModule !== enclosingExternalModule) {
                                return {
                                    accessibility: 2 /* CannotBeNamed */,
                                    errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
                                    errorModuleName: symbolToString(symbolExternalModule)
                                };
                            }
                        }
                        return {
                            accessibility: 1 /* NotAccessible */,
                            errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning)
                        };
                    }
                    return { accessibility: 0 /* Accessible */ };
                    function getExternalModuleContainer(declaration) {
                        for (; declaration; declaration = declaration.parent) {
                            if (hasExternalModuleSymbol(declaration)) {
                                return getSymbolOfNode(declaration);
                            }
                        }
                    }
                }
                function hasExternalModuleSymbol(declaration) {
                    return (declaration.kind === 193 /* ModuleDeclaration */ && declaration.name.kind === 7 /* StringLiteral */) || (declaration.kind === 198 /* SourceFile */ && ts.isExternalModule(declaration));
                }
                function hasVisibleDeclarations(symbol) {
                    var aliasesToMakeVisible;
                    if (ts.forEach(symbol.declarations, function (declaration) { return !getIsDeclarationVisible(declaration); })) {
                        return undefined;
                    }
                    return { accessibility: 0 /* Accessible */, aliasesToMakeVisible: aliasesToMakeVisible };
                    function getIsDeclarationVisible(declaration) {
                        if (!isDeclarationVisible(declaration)) {
                            if (declaration.kind === 195 /* ImportDeclaration */ && !(declaration.flags & 1 /* Export */) && isDeclarationVisible(declaration.parent)) {
                                getNodeLinks(declaration).isVisible = true;
                                if (aliasesToMakeVisible) {
                                    if (!ts.contains(aliasesToMakeVisible, declaration)) {
                                        aliasesToMakeVisible.push(declaration);
                                    }
                                }
                                else {
                                    aliasesToMakeVisible = [declaration];
                                }
                                return true;
                            }
                            return false;
                        }
                        return true;
                    }
                }
                function isEntityNameVisible(entityName, enclosingDeclaration) {
                    var meaning;
                    if (entityName.parent.kind === 136 /* TypeQuery */) {
                        meaning = 107455 /* Value */ | 4194304 /* ExportValue */;
                    }
                    else if (entityName.kind === 121 /* QualifiedName */ || entityName.parent.kind === 195 /* ImportDeclaration */) {
                        meaning = 1536 /* Namespace */;
                    }
                    else {
                        meaning = 3152352 /* Type */;
                    }
                    var firstIdentifier = getFirstIdentifier(entityName);
                    var symbol = resolveName(enclosingDeclaration, firstIdentifier.text, meaning, undefined, undefined);
                    return hasVisibleDeclarations(symbol) || {
                        accessibility: 1 /* NotAccessible */,
                        errorSymbolName: ts.getTextOfNode(firstIdentifier),
                        errorNode: firstIdentifier
                    };
                }
                function releaseStringWriter(writer) {
                    writer.clear();
                    stringWriters.push(writer);
                }
                function writeKeyword(writer, kind) {
                    writer.writeKeyword(ts.tokenToString(kind));
                }
                function writePunctuation(writer, kind) {
                    writer.writePunctuation(ts.tokenToString(kind));
                }
                function writeOperator(writer, kind) {
                    writer.writeOperator(ts.tokenToString(kind));
                }
                function writeSpace(writer) {
                    writer.writeSpace(" ");
                }
                function symbolToString(symbol, enclosingDeclaration, meaning) {
                    var writer = getSingleLineStringWriter();
                    getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning);
                    var result = writer.string();
                    releaseStringWriter(writer);
                    return result;
                }
                function typeToString(type, enclosingDeclaration, flags) {
                    var writer = getSingleLineStringWriter();
                    getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
                    var result = writer.string();
                    releaseStringWriter(writer);
                    var maxLength = compilerOptions.noErrorTruncation || flags & 4 /* NoTruncation */ ? undefined : 100;
                    if (maxLength && result.length >= maxLength) {
                        result = result.substr(0, maxLength - "...".length) + "...";
                    }
                    return result;
                }
                function getTypeAliasForTypeLiteral(type) {
                    if (type.symbol && type.symbol.flags & 2048 /* TypeLiteral */) {
                        var node = type.symbol.declarations[0].parent;
                        while (node.kind === 141 /* ParenType */) {
                            node = node.parent;
                        }
                        if (node.kind === 191 /* TypeAliasDeclaration */) {
                            return getSymbolOfNode(node);
                        }
                    }
                    return undefined;
                }
                var _displayBuilder;
                function getSymbolDisplayBuilder() {
                    function appendSymbolNameOnly(symbol, writer) {
                        if (symbol.declarations && symbol.declarations.length > 0) {
                            var declaration = symbol.declarations[0];
                            if (declaration.name) {
                                writer.writeSymbol(ts.declarationNameToString(declaration.name), symbol);
                                return;
                            }
                        }
                        writer.writeSymbol(symbol.name, symbol);
                    }
                    function buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags) {
                        var parentSymbol;
                        function appendParentTypeArgumentsAndSymbolName(symbol) {
                            if (parentSymbol) {
                                if (flags & 1 /* WriteTypeParametersOrArguments */) {
                                    if (symbol.flags & 67108864 /* Instantiated */) {
                                        buildDisplayForTypeArgumentsAndDelimiters(getTypeParametersOfClassOrInterface(parentSymbol), symbol.mapper, writer, enclosingDeclaration);
                                    }
                                    else {
                                        buildTypeParameterDisplayFromSymbol(parentSymbol, writer, enclosingDeclaration);
                                    }
                                }
                                writePunctuation(writer, 19 /* DotToken */);
                            }
                            parentSymbol = symbol;
                            appendSymbolNameOnly(symbol, writer);
                        }
                        writer.trackSymbol(symbol, enclosingDeclaration, meaning);
                        function walkSymbol(symbol, meaning) {
                            if (symbol) {
                                var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, !!(flags & 2 /* UseOnlyExternalAliasing */));
                                if (!accessibleSymbolChain || needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
                                    walkSymbol(getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol), getQualifiedLeftMeaning(meaning));
                                }
                                if (accessibleSymbolChain) {
                                    for (var i = 0, n = accessibleSymbolChain.length; i < n; i++) {
                                        appendParentTypeArgumentsAndSymbolName(accessibleSymbolChain[i]);
                                    }
                                }
                                else {
                                    if (!parentSymbol && ts.forEach(symbol.declarations, function (declaration) { return hasExternalModuleSymbol(declaration); })) {
                                        return;
                                    }
                                    if (symbol.flags & 2048 /* TypeLiteral */ || symbol.flags & 4096 /* ObjectLiteral */) {
                                        return;
                                    }
                                    appendParentTypeArgumentsAndSymbolName(symbol);
                                }
                            }
                        }
                        if (enclosingDeclaration && !(symbol.flags & 1048576 /* TypeParameter */)) {
                            walkSymbol(symbol, meaning);
                            return;
                        }
                        return appendParentTypeArgumentsAndSymbolName(symbol);
                    }
                    function buildTypeDisplay(type, writer, enclosingDeclaration, globalFlags, typeStack) {
                        var globalFlagsToPass = globalFlags & 16 /* WriteOwnNameForAnyLike */;
                        return writeType(type, globalFlags);
                        function writeType(type, flags) {
                            if (type.flags & 127 /* Intrinsic */) {
                                writer.writeKeyword(!(globalFlags & 16 /* WriteOwnNameForAnyLike */) && (type.flags & 1 /* Any */) ? "any" : type.intrinsicName);
                            }
                            else if (type.flags & 4096 /* Reference */) {
                                writeTypeReference(type, flags);
                            }
                            else if (type.flags & (1024 /* Class */ | 2048 /* Interface */ | 128 /* Enum */ | 512 /* TypeParameter */)) {
                                buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 3152352 /* Type */);
                            }
                            else if (type.flags & 8192 /* Tuple */) {
                                writeTupleType(type);
                            }
                            else if (type.flags & 16384 /* Union */) {
                                writeUnionType(type, flags);
                            }
                            else if (type.flags & 32768 /* Anonymous */) {
                                writeAnonymousType(type, flags);
                            }
                            else if (type.flags & 256 /* StringLiteral */) {
                                writer.writeStringLiteral(type.text);
                            }
                            else {
                                writePunctuation(writer, 13 /* OpenBraceToken */);
                                writeSpace(writer);
                                writePunctuation(writer, 20 /* DotDotDotToken */);
                                writeSpace(writer);
                                writePunctuation(writer, 14 /* CloseBraceToken */);
                            }
                        }
                        function writeTypeList(types, union) {
                            for (var i = 0; i < types.length; i++) {
                                if (i > 0) {
                                    if (union) {
                                        writeSpace(writer);
                                    }
                                    writePunctuation(writer, union ? 43 /* BarToken */ : 22 /* CommaToken */);
                                    writeSpace(writer);
                                }
                                writeType(types[i], union ? 64 /* InElementType */ : 0 /* None */);
                            }
                        }
                        function writeTypeReference(type, flags) {
                            if (type.target === globalArrayType && !(flags & 1 /* WriteArrayAsGenericType */)) {
                                writeType(type.typeArguments[0], 64 /* InElementType */);
                                writePunctuation(writer, 17 /* OpenBracketToken */);
                                writePunctuation(writer, 18 /* CloseBracketToken */);
                            }
                            else {
                                buildSymbolDisplay(type.target.symbol, writer, enclosingDeclaration, 3152352 /* Type */);
                                writePunctuation(writer, 23 /* LessThanToken */);
                                writeTypeList(type.typeArguments, false);
                                writePunctuation(writer, 24 /* GreaterThanToken */);
                            }
                        }
                        function writeTupleType(type) {
                            writePunctuation(writer, 17 /* OpenBracketToken */);
                            writeTypeList(type.elementTypes, false);
                            writePunctuation(writer, 18 /* CloseBracketToken */);
                        }
                        function writeUnionType(type, flags) {
                            if (flags & 64 /* InElementType */) {
                                writePunctuation(writer, 15 /* OpenParenToken */);
                            }
                            writeTypeList(type.types, true);
                            if (flags & 64 /* InElementType */) {
                                writePunctuation(writer, 16 /* CloseParenToken */);
                            }
                        }
                        function writeAnonymousType(type, flags) {
                            if (type.symbol && type.symbol.flags & (32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) {
                                writeTypeofSymbol(type);
                            }
                            else if (shouldWriteTypeOfFunctionSymbol()) {
                                writeTypeofSymbol(type);
                            }
                            else if (typeStack && ts.contains(typeStack, type)) {
                                var typeAlias = getTypeAliasForTypeLiteral(type);
                                if (typeAlias) {
                                    buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, 3152352 /* Type */);
                                }
                                else {
                                    writeKeyword(writer, 109 /* AnyKeyword */);
                                }
                            }
                            else {
                                if (!typeStack) {
                                    typeStack = [];
                                }
                                typeStack.push(type);
                                writeLiteralType(type, flags);
                                typeStack.pop();
                            }
                            function shouldWriteTypeOfFunctionSymbol() {
                                if (type.symbol) {
                                    var isStaticMethodSymbol = !!(type.symbol.flags & 8192 /* Method */ && ts.forEach(type.symbol.declarations, function (declaration) { return declaration.flags & 128 /* Static */; }));
                                    var isNonLocalFunctionSymbol = !!(type.symbol.flags & 16 /* Function */) && (type.symbol.parent || ts.forEach(type.symbol.declarations, function (declaration) { return declaration.parent.kind === 198 /* SourceFile */ || declaration.parent.kind === 194 /* ModuleBlock */; }));
                                    if (isStaticMethodSymbol || isNonLocalFunctionSymbol) {
                                        return !!(flags & 2 /* UseTypeOfFunction */) || (typeStack && ts.contains(typeStack, type));
                                    }
                                }
                            }
                        }
                        function writeTypeofSymbol(type) {
                            writeKeyword(writer, 95 /* TypeOfKeyword */);
                            writeSpace(writer);
                            buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 107455 /* Value */);
                        }
                        function writeLiteralType(type, flags) {
                            var resolved = resolveObjectOrUnionTypeMembers(type);
                            if (!resolved.properties.length && !resolved.stringIndexType && !resolved.numberIndexType) {
                                if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
                                    writePunctuation(writer, 13 /* OpenBraceToken */);
                                    writePunctuation(writer, 14 /* CloseBraceToken */);
                                    return;
                                }
                                if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
                                    if (flags & 64 /* InElementType */) {
                                        writePunctuation(writer, 15 /* OpenParenToken */);
                                    }
                                    buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | 8 /* WriteArrowStyleSignature */, typeStack);
                                    if (flags & 64 /* InElementType */) {
                                        writePunctuation(writer, 16 /* CloseParenToken */);
                                    }
                                    return;
                                }
                                if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) {
                                    if (flags & 64 /* InElementType */) {
                                        writePunctuation(writer, 15 /* OpenParenToken */);
                                    }
                                    writeKeyword(writer, 86 /* NewKeyword */);
                                    writeSpace(writer);
                                    buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | 8 /* WriteArrowStyleSignature */, typeStack);
                                    if (flags & 64 /* InElementType */) {
                                        writePunctuation(writer, 16 /* CloseParenToken */);
                                    }
                                    return;
                                }
                            }
                            writePunctuation(writer, 13 /* OpenBraceToken */);
                            writer.writeLine();
                            writer.increaseIndent();
                            for (var i = 0; i < resolved.callSignatures.length; i++) {
                                buildSignatureDisplay(resolved.callSignatures[i], writer, enclosingDeclaration, globalFlagsToPass, typeStack);
                                writePunctuation(writer, 21 /* SemicolonToken */);
                                writer.writeLine();
                            }
                            for (var i = 0; i < resolved.constructSignatures.length; i++) {
                                writeKeyword(writer, 86 /* NewKeyword */);
                                writeSpace(writer);
                                buildSignatureDisplay(resolved.constructSignatures[i], writer, enclosingDeclaration, globalFlagsToPass, typeStack);
                                writePunctuation(writer, 21 /* SemicolonToken */);
                                writer.writeLine();
                            }
                            if (resolved.stringIndexType) {
                                writePunctuation(writer, 17 /* OpenBracketToken */);
                                writer.writeParameter("x");
                                writePunctuation(writer, 50 /* ColonToken */);
                                writeSpace(writer);
                                writeKeyword(writer, 118 /* StringKeyword */);
                                writePunctuation(writer, 18 /* CloseBracketToken */);
                                writePunctuation(writer, 50 /* ColonToken */);
                                writeSpace(writer);
                                writeType(resolved.stringIndexType, 0 /* None */);
                                writePunctuation(writer, 21 /* SemicolonToken */);
                                writer.writeLine();
                            }
                            if (resolved.numberIndexType) {
                                writePunctuation(writer, 17 /* OpenBracketToken */);
                                writer.writeParameter("x");
                                writePunctuation(writer, 50 /* ColonToken */);
                                writeSpace(writer);
                                writeKeyword(writer, 116 /* NumberKeyword */);
                                writePunctuation(writer, 18 /* CloseBracketToken */);
                                writePunctuation(writer, 50 /* ColonToken */);
                                writeSpace(writer);
                                writeType(resolved.numberIndexType, 0 /* None */);
                                writePunctuation(writer, 21 /* SemicolonToken */);
                                writer.writeLine();
                            }
                            for (var i = 0; i < resolved.properties.length; i++) {
                                var p = resolved.properties[i];
                                var t = getTypeOfSymbol(p);
                                if (p.flags & (16 /* Function */ | 8192 /* Method */) && !getPropertiesOfObjectType(t).length) {
                                    var signatures = getSignaturesOfType(t, 0 /* Call */);
                                    for (var j = 0; j < signatures.length; j++) {
                                        buildSymbolDisplay(p, writer);
                                        if (isOptionalProperty(p)) {
                                            writePunctuation(writer, 49 /* QuestionToken */);
                                        }
                                        buildSignatureDisplay(signatures[j], writer, enclosingDeclaration, globalFlagsToPass, typeStack);
                                        writePunctuation(writer, 21 /* SemicolonToken */);
                                        writer.writeLine();
                                    }
                                }
                                else {
                                    buildSymbolDisplay(p, writer);
                                    if (isOptionalProperty(p)) {
                                        writePunctuation(writer, 49 /* QuestionToken */);
                                    }
                                    writePunctuation(writer, 50 /* ColonToken */);
                                    writeSpace(writer);
                                    writeType(t, 0 /* None */);
                                    writePunctuation(writer, 21 /* SemicolonToken */);
                                    writer.writeLine();
                                }
                            }
                            writer.decreaseIndent();
                            writePunctuation(writer, 14 /* CloseBraceToken */);
                        }
                    }
                    function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaraiton, flags) {
                        var targetSymbol = getTargetSymbol(symbol);
                        if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */) {
                            buildDisplayForTypeParametersAndDelimiters(getTypeParametersOfClassOrInterface(symbol), writer, enclosingDeclaraiton, flags);
                        }
                    }
                    function buildTypeParameterDisplay(tp, writer, enclosingDeclaration, flags, typeStack) {
                        appendSymbolNameOnly(tp.symbol, writer);
                        var constraint = getConstraintOfTypeParameter(tp);
                        if (constraint) {
                            writeSpace(writer);
                            writeKeyword(writer, 77 /* ExtendsKeyword */);
                            writeSpace(writer);
                            buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, typeStack);
                        }
                    }
                    function buildParameterDisplay(p, writer, enclosingDeclaration, flags, typeStack) {
                        if (getDeclarationFlagsFromSymbol(p) & 8 /* Rest */) {
                            writePunctuation(writer, 20 /* DotDotDotToken */);
                        }
                        appendSymbolNameOnly(p, writer);
                        if (p.valueDeclaration.flags & 4 /* QuestionMark */ || p.valueDeclaration.initializer) {
                            writePunctuation(writer, 49 /* QuestionToken */);
                        }
                        writePunctuation(writer, 50 /* ColonToken */);
                        writeSpace(writer);
                        buildTypeDisplay(getTypeOfSymbol(p), writer, enclosingDeclaration, flags, typeStack);
                    }
                    function buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, flags, typeStack) {
                        if (typeParameters && typeParameters.length) {
                            writePunctuation(writer, 23 /* LessThanToken */);
                            for (var i = 0; i < typeParameters.length; i++) {
                                if (i > 0) {
                                    writePunctuation(writer, 22 /* CommaToken */);
                                    writeSpace(writer);
                                }
                                buildTypeParameterDisplay(typeParameters[i], writer, enclosingDeclaration, flags, typeStack);
                            }
                            writePunctuation(writer, 24 /* GreaterThanToken */);
                        }
                    }
                    function buildDisplayForTypeArgumentsAndDelimiters(typeParameters, mapper, writer, enclosingDeclaration, flags, typeStack) {
                        if (typeParameters && typeParameters.length) {
                            writePunctuation(writer, 23 /* LessThanToken */);
                            for (var i = 0; i < typeParameters.length; i++) {
                                if (i > 0) {
                                    writePunctuation(writer, 22 /* CommaToken */);
                                    writeSpace(writer);
                                }
                                buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, 0 /* None */);
                            }
                            writePunctuation(writer, 24 /* GreaterThanToken */);
                        }
                    }
                    function buildDisplayForParametersAndDelimiters(parameters, writer, enclosingDeclaration, flags, typeStack) {
                        writePunctuation(writer, 15 /* OpenParenToken */);
                        for (var i = 0; i < parameters.length; i++) {
                            if (i > 0) {
                                writePunctuation(writer, 22 /* CommaToken */);
                                writeSpace(writer);
                            }
                            buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, typeStack);
                        }
                        writePunctuation(writer, 16 /* CloseParenToken */);
                    }
                    function buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, typeStack) {
                        if (flags & 8 /* WriteArrowStyleSignature */) {
                            writeSpace(writer);
                            writePunctuation(writer, 31 /* EqualsGreaterThanToken */);
                        }
                        else {
                            writePunctuation(writer, 50 /* ColonToken */);
                        }
                        writeSpace(writer);
                        buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags, typeStack);
                    }
                    function buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, typeStack) {
                        if (signature.target && (flags & 32 /* WriteTypeArgumentsOfSignature */)) {
                            buildDisplayForTypeArgumentsAndDelimiters(signature.target.typeParameters, signature.mapper, writer, enclosingDeclaration);
                        }
                        else {
                            buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, typeStack);
                        }
                        buildDisplayForParametersAndDelimiters(signature.parameters, writer, enclosingDeclaration, flags, typeStack);
                        buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, typeStack);
                    }
                    return _displayBuilder || (_displayBuilder = {
                        symbolToString: symbolToString,
                        typeToString: typeToString,
                        buildSymbolDisplay: buildSymbolDisplay,
                        buildTypeDisplay: buildTypeDisplay,
                        buildTypeParameterDisplay: buildTypeParameterDisplay,
                        buildParameterDisplay: buildParameterDisplay,
                        buildDisplayForParametersAndDelimiters: buildDisplayForParametersAndDelimiters,
                        buildDisplayForTypeParametersAndDelimiters: buildDisplayForTypeParametersAndDelimiters,
                        buildDisplayForTypeArgumentsAndDelimiters: buildDisplayForTypeArgumentsAndDelimiters,
                        buildTypeParameterDisplayFromSymbol: buildTypeParameterDisplayFromSymbol,
                        buildSignatureDisplay: buildSignatureDisplay,
                        buildReturnTypeDisplay: buildReturnTypeDisplay
                    });
                }
                function isDeclarationVisible(node) {
                    function getContainingExternalModule(node) {
                        for (; node; node = node.parent) {
                            if (node.kind === 193 /* ModuleDeclaration */) {
                                if (node.name.kind === 7 /* StringLiteral */) {
                                    return node;
                                }
                            }
                            else if (node.kind === 198 /* SourceFile */) {
                                return ts.isExternalModule(node) ? node : undefined;
                            }
                        }
                        ts.Debug.fail("getContainingModule cant reach here");
                    }
                    function isUsedInExportAssignment(node) {
                        var externalModule = getContainingExternalModule(node);
                        if (externalModule) {
                            var externalModuleSymbol = getSymbolOfNode(externalModule);
                            var exportAssignmentSymbol = getExportAssignmentSymbol(externalModuleSymbol);
                            var resolvedExportSymbol;
                            var symbolOfNode = getSymbolOfNode(node);
                            if (isSymbolUsedInExportAssignment(symbolOfNode)) {
                                return true;
                            }
                            if (symbolOfNode.flags & 33554432 /* Import */) {
                                return isSymbolUsedInExportAssignment(resolveImport(symbolOfNode));
                            }
                        }
                        function isSymbolUsedInExportAssignment(symbol) {
                            if (exportAssignmentSymbol === symbol) {
                                return true;
                            }
                            if (exportAssignmentSymbol && !!(exportAssignmentSymbol.flags & 33554432 /* Import */)) {
                                resolvedExportSymbol = resolvedExportSymbol || resolveImport(exportAssignmentSymbol);
                                if (resolvedExportSymbol === symbol) {
                                    return true;
                                }
                                return ts.forEach(resolvedExportSymbol.declarations, function (declaration) {
                                    while (declaration) {
                                        if (declaration === node) {
                                            return true;
                                        }
                                        declaration = declaration.parent;
                                    }
                                });
                            }
                        }
                    }
                    function determineIfDeclarationIsVisible() {
                        switch (node.kind) {
                            case 186 /* VariableDeclaration */:
                            case 193 /* ModuleDeclaration */:
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                            case 191 /* TypeAliasDeclaration */:
                            case 187 /* FunctionDeclaration */:
                            case 192 /* EnumDeclaration */:
                            case 195 /* ImportDeclaration */:
                                var parent = node.kind === 186 /* VariableDeclaration */ ? node.parent.parent : node.parent;
                                if (!(node.flags & 1 /* Export */) && !(node.kind !== 195 /* ImportDeclaration */ && parent.kind !== 198 /* SourceFile */ && ts.isInAmbientContext(parent))) {
                                    return isGlobalSourceFile(parent) || isUsedInExportAssignment(node);
                                }
                                return isDeclarationVisible(parent);
                            case 125 /* Property */:
                            case 126 /* Method */:
                                if (node.flags & (32 /* Private */ | 64 /* Protected */)) {
                                    return false;
                                }
                            case 127 /* Constructor */:
                            case 131 /* ConstructSignature */:
                            case 130 /* CallSignature */:
                            case 132 /* IndexSignature */:
                            case 124 /* Parameter */:
                            case 194 /* ModuleBlock */:
                            case 123 /* TypeParameter */:
                                return isDeclarationVisible(node.parent);
                            case 198 /* SourceFile */:
                                return true;
                            default:
                                ts.Debug.fail("isDeclarationVisible unknown: SyntaxKind: " + node.kind);
                        }
                    }
                    if (node) {
                        var links = getNodeLinks(node);
                        if (links.isVisible === undefined) {
                            links.isVisible = !!determineIfDeclarationIsVisible();
                        }
                        return links.isVisible;
                    }
                }
                function getTypeOfPrototypeProperty(prototype) {
                    var classType = getDeclaredTypeOfSymbol(prototype.parent);
                    return classType.typeParameters ? createTypeReference(classType, ts.map(classType.typeParameters, function (_) { return anyType; })) : classType;
                }
                function getTypeOfVariableOrPropertyDeclaration(declaration) {
                    if (declaration.parent.kind === 171 /* ForInStatement */) {
                        return anyType;
                    }
                    if (declaration.type) {
                        return getTypeFromTypeNode(declaration.type);
                    }
                    if (declaration.kind === 124 /* Parameter */) {
                        var func = declaration.parent;
                        if (func.kind === 129 /* SetAccessor */ && !ts.hasComputedNameButNotSymbol(func)) {
                            var getter = getDeclarationOfKind(declaration.parent.symbol, 128 /* GetAccessor */);
                            if (getter) {
                                return getReturnTypeOfSignature(getSignatureFromDeclaration(getter));
                            }
                        }
                        var type = getContextuallyTypedParameterType(declaration);
                        if (type) {
                            return type;
                        }
                    }
                    if (declaration.initializer) {
                        var type = checkAndMarkExpression(declaration.initializer);
                        if (declaration.kind !== 144 /* PropertyAssignment */) {
                            var unwidenedType = type;
                            type = getWidenedType(type);
                            if (type !== unwidenedType) {
                                checkImplicitAny(type);
                            }
                        }
                        return type;
                    }
                    if (declaration.kind === 145 /* ShorthandPropertyAssignment */) {
                        var type = checkIdentifier(declaration.name);
                        return type;
                    }
                    var type = declaration.flags & 8 /* Rest */ ? createArrayType(anyType) : anyType;
                    checkImplicitAny(type);
                    return type;
                    function checkImplicitAny(type) {
                        if (!fullTypeCheck || !compilerOptions.noImplicitAny) {
                            return;
                        }
                        if (getInnermostTypeOfNestedArrayTypes(type) !== anyType) {
                            return;
                        }
                        if (isPrivateWithinAmbient(declaration) || (declaration.kind === 124 /* Parameter */ && isPrivateWithinAmbient(declaration.parent))) {
                            return;
                        }
                        switch (declaration.kind) {
                            case 125 /* Property */:
                                var diagnostic = ts.Diagnostics.Member_0_implicitly_has_an_1_type;
                                break;
                            case 124 /* Parameter */:
                                var diagnostic = declaration.flags & 8 /* Rest */ ? ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : ts.Diagnostics.Parameter_0_implicitly_has_an_1_type;
                                break;
                            default:
                                var diagnostic = ts.Diagnostics.Variable_0_implicitly_has_an_1_type;
                        }
                        error(declaration, diagnostic, ts.declarationNameToString(declaration.name), typeToString(type));
                    }
                }
                function getTypeOfVariableOrParameterOrProperty(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.type) {
                        if (symbol.flags & 536870912 /* Prototype */) {
                            return links.type = getTypeOfPrototypeProperty(symbol);
                        }
                        var declaration = symbol.valueDeclaration;
                        if (declaration.kind === 183 /* CatchBlock */) {
                            return links.type = anyType;
                        }
                        links.type = resolvingType;
                        var type = getTypeOfVariableOrPropertyDeclaration(declaration);
                        if (links.type === resolvingType) {
                            links.type = type;
                        }
                    }
                    else if (links.type === resolvingType) {
                        links.type = anyType;
                        if (compilerOptions.noImplicitAny) {
                            var diagnostic = symbol.valueDeclaration.type ? ts.Diagnostics._0_implicitly_has_type_any_because_it_is_referenced_directly_or_indirectly_in_its_own_type_annotation : ts.Diagnostics._0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer;
                            error(symbol.valueDeclaration, diagnostic, symbolToString(symbol));
                        }
                    }
                    return links.type;
                }
                function getSetAccessorTypeAnnotationNode(accessor) {
                    return accessor && accessor.parameters.length > 0 && accessor.parameters[0].type;
                }
                function getAnnotatedAccessorType(accessor) {
                    if (accessor) {
                        if (accessor.kind === 128 /* GetAccessor */) {
                            return accessor.type && getTypeFromTypeNode(accessor.type);
                        }
                        else {
                            var setterTypeAnnotation = getSetAccessorTypeAnnotationNode(accessor);
                            return setterTypeAnnotation && getTypeFromTypeNode(setterTypeAnnotation);
                        }
                    }
                    return undefined;
                }
                function getTypeOfAccessors(symbol) {
                    var links = getSymbolLinks(symbol);
                    checkAndStoreTypeOfAccessors(symbol, links);
                    return links.type;
                }
                function checkAndStoreTypeOfAccessors(symbol, links) {
                    links = links || getSymbolLinks(symbol);
                    if (!links.type) {
                        links.type = resolvingType;
                        var getter = getDeclarationOfKind(symbol, 128 /* GetAccessor */);
                        var setter = getDeclarationOfKind(symbol, 129 /* SetAccessor */);
                        var type;
                        var getterReturnType = getAnnotatedAccessorType(getter);
                        if (getterReturnType) {
                            type = getterReturnType;
                        }
                        else {
                            var setterParameterType = getAnnotatedAccessorType(setter);
                            if (setterParameterType) {
                                type = setterParameterType;
                            }
                            else {
                                if (getter && getter.body) {
                                    type = getReturnTypeFromBody(getter);
                                }
                                else {
                                    if (compilerOptions.noImplicitAny) {
                                        error(setter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_type_annotation, symbolToString(symbol));
                                    }
                                    type = anyType;
                                }
                            }
                        }
                        if (links.type === resolvingType) {
                            links.type = type;
                        }
                    }
                    else if (links.type === resolvingType) {
                        links.type = anyType;
                        if (compilerOptions.noImplicitAny) {
                            var getter = getDeclarationOfKind(symbol, 128 /* GetAccessor */);
                            error(getter, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol));
                        }
                    }
                }
                function getTypeOfFuncClassEnumModule(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.type) {
                        links.type = createObjectType(32768 /* Anonymous */, symbol);
                    }
                    return links.type;
                }
                function getTypeOfEnumMember(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.type) {
                        links.type = getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
                    }
                    return links.type;
                }
                function getTypeOfImport(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.type) {
                        links.type = getTypeOfSymbol(resolveImport(symbol));
                    }
                    return links.type;
                }
                function getTypeOfInstantiatedSymbol(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.type) {
                        links.type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
                    }
                    return links.type;
                }
                function getTypeOfSymbol(symbol) {
                    if (symbol.flags & 67108864 /* Instantiated */) {
                        return getTypeOfInstantiatedSymbol(symbol);
                    }
                    if (symbol.flags & (3 /* Variable */ | 4 /* Property */)) {
                        return getTypeOfVariableOrParameterOrProperty(symbol);
                    }
                    if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) {
                        return getTypeOfFuncClassEnumModule(symbol);
                    }
                    if (symbol.flags & 8 /* EnumMember */) {
                        return getTypeOfEnumMember(symbol);
                    }
                    if (symbol.flags & 98304 /* Accessor */) {
                        return getTypeOfAccessors(symbol);
                    }
                    if (symbol.flags & 33554432 /* Import */) {
                        return getTypeOfImport(symbol);
                    }
                    return unknownType;
                }
                function getTargetType(type) {
                    return type.flags & 4096 /* Reference */ ? type.target : type;
                }
                function hasBaseType(type, checkBase) {
                    return check(type);
                    function check(type) {
                        var target = getTargetType(type);
                        return target === checkBase || ts.forEach(target.baseTypes, check);
                    }
                }
                function getTypeParametersOfClassOrInterface(symbol) {
                    var result;
                    ts.forEach(symbol.declarations, function (node) {
                        if (node.kind === 190 /* InterfaceDeclaration */ || node.kind === 189 /* ClassDeclaration */) {
                            var declaration = node;
                            if (declaration.typeParameters && declaration.typeParameters.length) {
                                ts.forEach(declaration.typeParameters, function (node) {
                                    var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node));
                                    if (!result) {
                                        result = [tp];
                                    }
                                    else if (!ts.contains(result, tp)) {
                                        result.push(tp);
                                    }
                                });
                            }
                        }
                    });
                    return result;
                }
                function getDeclaredTypeOfClass(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.declaredType) {
                        var type = links.declaredType = createObjectType(1024 /* Class */, symbol);
                        var typeParameters = getTypeParametersOfClassOrInterface(symbol);
                        if (typeParameters) {
                            type.flags |= 4096 /* Reference */;
                            type.typeParameters = typeParameters;
                            type.instantiations = {};
                            type.instantiations[getTypeListId(type.typeParameters)] = type;
                            type.target = type;
                            type.typeArguments = type.typeParameters;
                        }
                        type.baseTypes = [];
                        var declaration = getDeclarationOfKind(symbol, 189 /* ClassDeclaration */);
                        if (declaration.baseType) {
                            var baseType = getTypeFromTypeReferenceNode(declaration.baseType);
                            if (baseType !== unknownType) {
                                if (getTargetType(baseType).flags & 1024 /* Class */) {
                                    if (type !== baseType && !hasBaseType(baseType, type)) {
                                        type.baseTypes.push(baseType);
                                    }
                                    else {
                                        error(declaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */));
                                    }
                                }
                                else {
                                    error(declaration.baseType, ts.Diagnostics.A_class_may_only_extend_another_class);
                                }
                            }
                        }
                        type.declaredProperties = getNamedMembers(symbol.members);
                        type.declaredCallSignatures = emptyArray;
                        type.declaredConstructSignatures = emptyArray;
                        type.declaredStringIndexType = getIndexTypeOfSymbol(symbol, 0 /* String */);
                        type.declaredNumberIndexType = getIndexTypeOfSymbol(symbol, 1 /* Number */);
                    }
                    return links.declaredType;
                }
                function getDeclaredTypeOfInterface(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.declaredType) {
                        var type = links.declaredType = createObjectType(2048 /* Interface */, symbol);
                        var typeParameters = getTypeParametersOfClassOrInterface(symbol);
                        if (typeParameters) {
                            type.flags |= 4096 /* Reference */;
                            type.typeParameters = typeParameters;
                            type.instantiations = {};
                            type.instantiations[getTypeListId(type.typeParameters)] = type;
                            type.target = type;
                            type.typeArguments = type.typeParameters;
                        }
                        type.baseTypes = [];
                        ts.forEach(symbol.declarations, function (declaration) {
                            if (declaration.kind === 190 /* InterfaceDeclaration */ && declaration.baseTypes) {
                                ts.forEach(declaration.baseTypes, function (node) {
                                    var baseType = getTypeFromTypeReferenceNode(node);
                                    if (baseType !== unknownType) {
                                        if (getTargetType(baseType).flags & (1024 /* Class */ | 2048 /* Interface */)) {
                                            if (type !== baseType && !hasBaseType(baseType, type)) {
                                                type.baseTypes.push(baseType);
                                            }
                                            else {
                                                error(declaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */));
                                            }
                                        }
                                        else {
                                            error(node, ts.Diagnostics.An_interface_may_only_extend_a_class_or_another_interface);
                                        }
                                    }
                                });
                            }
                        });
                        type.declaredProperties = getNamedMembers(symbol.members);
                        type.declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]);
                        type.declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]);
                        type.declaredStringIndexType = getIndexTypeOfSymbol(symbol, 0 /* String */);
                        type.declaredNumberIndexType = getIndexTypeOfSymbol(symbol, 1 /* Number */);
                    }
                    return links.declaredType;
                }
                function getDeclaredTypeOfTypeAlias(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.declaredType) {
                        links.declaredType = resolvingType;
                        var declaration = getDeclarationOfKind(symbol, 191 /* TypeAliasDeclaration */);
                        var type = getTypeFromTypeNode(declaration.type);
                        if (links.declaredType === resolvingType) {
                            links.declaredType = type;
                        }
                    }
                    else if (links.declaredType === resolvingType) {
                        links.declaredType = unknownType;
                        var declaration = getDeclarationOfKind(symbol, 191 /* TypeAliasDeclaration */);
                        error(declaration.name, ts.Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol));
                    }
                    return links.declaredType;
                }
                function getDeclaredTypeOfEnum(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.declaredType) {
                        var type = createType(128 /* Enum */);
                        type.symbol = symbol;
                        links.declaredType = type;
                    }
                    return links.declaredType;
                }
                function getDeclaredTypeOfTypeParameter(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.declaredType) {
                        var type = createType(512 /* TypeParameter */);
                        type.symbol = symbol;
                        if (!getDeclarationOfKind(symbol, 123 /* TypeParameter */).constraint) {
                            type.constraint = noConstraintType;
                        }
                        links.declaredType = type;
                    }
                    return links.declaredType;
                }
                function getDeclaredTypeOfImport(symbol) {
                    var links = getSymbolLinks(symbol);
                    if (!links.declaredType) {
                        links.declaredType = getDeclaredTypeOfSymbol(resolveImport(symbol));
                    }
                    return links.declaredType;
                }
                function getDeclaredTypeOfSymbol(symbol) {
                    ts.Debug.assert((symbol.flags & 67108864 /* Instantiated */) === 0);
                    if (symbol.flags & 32 /* Class */) {
                        return getDeclaredTypeOfClass(symbol);
                    }
                    if (symbol.flags & 64 /* Interface */) {
                        return getDeclaredTypeOfInterface(symbol);
                    }
                    if (symbol.flags & 2097152 /* TypeAlias */) {
                        return getDeclaredTypeOfTypeAlias(symbol);
                    }
                    if (symbol.flags & 384 /* Enum */) {
                        return getDeclaredTypeOfEnum(symbol);
                    }
                    if (symbol.flags & 1048576 /* TypeParameter */) {
                        return getDeclaredTypeOfTypeParameter(symbol);
                    }
                    if (symbol.flags & 33554432 /* Import */) {
                        return getDeclaredTypeOfImport(symbol);
                    }
                    return unknownType;
                }
                function createSymbolTable(symbols) {
                    var result = {};
                    for (var i = 0; i < symbols.length; i++) {
                        var symbol = symbols[i];
                        result[symbol.name] = symbol;
                    }
                    return result;
                }
                function createInstantiatedSymbolTable(symbols, mapper) {
                    var result = {};
                    for (var i = 0; i < symbols.length; i++) {
                        var symbol = symbols[i];
                        result[symbol.name] = instantiateSymbol(symbol, mapper);
                    }
                    return result;
                }
                function addInheritedMembers(symbols, baseSymbols) {
                    for (var i = 0; i < baseSymbols.length; i++) {
                        var s = baseSymbols[i];
                        if (!ts.hasProperty(symbols, s.name)) {
                            symbols[s.name] = s;
                        }
                    }
                }
                function addInheritedSignatures(signatures, baseSignatures) {
                    if (baseSignatures) {
                        for (var i = 0; i < baseSignatures.length; i++) {
                            signatures.push(baseSignatures[i]);
                        }
                    }
                }
                function resolveClassOrInterfaceMembers(type) {
                    var members = type.symbol.members;
                    var callSignatures = type.declaredCallSignatures;
                    var constructSignatures = type.declaredConstructSignatures;
                    var stringIndexType = type.declaredStringIndexType;
                    var numberIndexType = type.declaredNumberIndexType;
                    if (type.baseTypes.length) {
                        members = createSymbolTable(type.declaredProperties);
                        ts.forEach(type.baseTypes, function (baseType) {
                            addInheritedMembers(members, getPropertiesOfObjectType(baseType));
                            callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(baseType, 0 /* Call */));
                            constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(baseType, 1 /* Construct */));
                            stringIndexType = stringIndexType || getIndexTypeOfType(baseType, 0 /* String */);
                            numberIndexType = numberIndexType || getIndexTypeOfType(baseType, 1 /* Number */);
                        });
                    }
                    setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
                }
                function resolveTypeReferenceMembers(type) {
                    var target = type.target;
                    var mapper = createTypeMapper(target.typeParameters, type.typeArguments);
                    var members = createInstantiatedSymbolTable(target.declaredProperties, mapper);
                    var callSignatures = instantiateList(target.declaredCallSignatures, mapper, instantiateSignature);
                    var constructSignatures = instantiateList(target.declaredConstructSignatures, mapper, instantiateSignature);
                    var stringIndexType = target.declaredStringIndexType ? instantiateType(target.declaredStringIndexType, mapper) : undefined;
                    var numberIndexType = target.declaredNumberIndexType ? instantiateType(target.declaredNumberIndexType, mapper) : undefined;
                    ts.forEach(target.baseTypes, function (baseType) {
                        var instantiatedBaseType = instantiateType(baseType, mapper);
                        addInheritedMembers(members, getPropertiesOfObjectType(instantiatedBaseType));
                        callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, 0 /* Call */));
                        constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, 1 /* Construct */));
                        stringIndexType = stringIndexType || getIndexTypeOfType(instantiatedBaseType, 0 /* String */);
                        numberIndexType = numberIndexType || getIndexTypeOfType(instantiatedBaseType, 1 /* Number */);
                    });
                    setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
                }
                function createSignature(declaration, typeParameters, parameters, resolvedReturnType, minArgumentCount, hasRestParameter, hasStringLiterals) {
                    var sig = new Signature(checker);
                    sig.declaration = declaration;
                    sig.typeParameters = typeParameters;
                    sig.parameters = parameters;
                    sig.resolvedReturnType = resolvedReturnType;
                    sig.minArgumentCount = minArgumentCount;
                    sig.hasRestParameter = hasRestParameter;
                    sig.hasStringLiterals = hasStringLiterals;
                    return sig;
                }
                function cloneSignature(sig) {
                    return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals);
                }
                function getDefaultConstructSignatures(classType) {
                    if (classType.baseTypes.length) {
                        var baseType = classType.baseTypes[0];
                        var baseSignatures = getSignaturesOfType(getTypeOfSymbol(baseType.symbol), 1 /* Construct */);
                        return ts.map(baseSignatures, function (baseSignature) {
                            var signature = baseType.flags & 4096 /* Reference */ ? getSignatureInstantiation(baseSignature, baseType.typeArguments) : cloneSignature(baseSignature);
                            signature.typeParameters = classType.typeParameters;
                            signature.resolvedReturnType = classType;
                            return signature;
                        });
                    }
                    return [createSignature(undefined, classType.typeParameters, emptyArray, classType, 0, false, false)];
                }
                function createTupleTypeMemberSymbols(memberTypes) {
                    var members = {};
                    for (var i = 0; i < memberTypes.length; i++) {
                        var symbol = createSymbol(4 /* Property */ | 268435456 /* Transient */, "" + i);
                        symbol.type = memberTypes[i];
                        members[i] = symbol;
                    }
                    return members;
                }
                function resolveTupleTypeMembers(type) {
                    var arrayType = resolveObjectOrUnionTypeMembers(createArrayType(getUnionType(type.elementTypes)));
                    var members = createTupleTypeMemberSymbols(type.elementTypes);
                    addInheritedMembers(members, arrayType.properties);
                    setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexType, arrayType.numberIndexType);
                }
                function signatureListsIdentical(s, t) {
                    if (s.length !== t.length) {
                        return false;
                    }
                    for (var i = 0; i < s.length; i++) {
                        if (!compareSignatures(s[i], t[i], false, compareTypes)) {
                            return false;
                        }
                    }
                    return true;
                }
                function getUnionSignatures(types, kind) {
                    var signatureLists = ts.map(types, function (t) { return getSignaturesOfType(t, kind); });
                    var signatures = signatureLists[0];
                    for (var i = 0; i < signatures.length; i++) {
                        if (signatures[i].typeParameters) {
                            return emptyArray;
                        }
                    }
                    for (var i = 1; i < signatureLists.length; i++) {
                        if (!signatureListsIdentical(signatures, signatureLists[i])) {
                            return emptyArray;
                        }
                    }
                    var result = ts.map(signatures, cloneSignature);
                    for (var i = 0; i < result.length; i++) {
                        var s = result[i];
                        s.resolvedReturnType = undefined;
                        s.unionSignatures = ts.map(signatureLists, function (signatures) { return signatures[i]; });
                    }
                    return result;
                }
                function getUnionIndexType(types, kind) {
                    var indexTypes = [];
                    for (var i = 0; i < types.length; i++) {
                        var indexType = getIndexTypeOfType(types[i], kind);
                        if (!indexType) {
                            return undefined;
                        }
                        indexTypes.push(indexType);
                    }
                    return getUnionType(indexTypes);
                }
                function resolveUnionTypeMembers(type) {
                    var callSignatures = getUnionSignatures(type.types, 0 /* Call */);
                    var constructSignatures = getUnionSignatures(type.types, 1 /* Construct */);
                    var stringIndexType = getUnionIndexType(type.types, 0 /* String */);
                    var numberIndexType = getUnionIndexType(type.types, 1 /* Number */);
                    setObjectTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexType, numberIndexType);
                }
                function resolveAnonymousTypeMembers(type) {
                    var symbol = type.symbol;
                    if (symbol.flags & 2048 /* TypeLiteral */) {
                        var members = symbol.members;
                        var callSignatures = getSignaturesOfSymbol(members["__call"]);
                        var constructSignatures = getSignaturesOfSymbol(members["__new"]);
                        var stringIndexType = getIndexTypeOfSymbol(symbol, 0 /* String */);
                        var numberIndexType = getIndexTypeOfSymbol(symbol, 1 /* Number */);
                    }
                    else {
                        var members = emptySymbols;
                        var callSignatures = emptyArray;
                        var constructSignatures = emptyArray;
                        if (symbol.flags & 1952 /* HasExports */) {
                            members = symbol.exports;
                        }
                        if (symbol.flags & (16 /* Function */ | 8192 /* Method */)) {
                            callSignatures = getSignaturesOfSymbol(symbol);
                        }
                        if (symbol.flags & 32 /* Class */) {
                            var classType = getDeclaredTypeOfClass(symbol);
                            constructSignatures = getSignaturesOfSymbol(symbol.members["__constructor"]);
                            if (!constructSignatures.length) {
                                constructSignatures = getDefaultConstructSignatures(classType);
                            }
                            if (classType.baseTypes.length) {
                                members = createSymbolTable(getNamedMembers(members));
                                addInheritedMembers(members, getPropertiesOfObjectType(getTypeOfSymbol(classType.baseTypes[0].symbol)));
                            }
                        }
                        var stringIndexType = undefined;
                        var numberIndexType = (symbol.flags & 384 /* Enum */) ? stringType : undefined;
                    }
                    setObjectTypeMembers(type, members, callSignatures, constructSignatures, stringIndexType, numberIndexType);
                }
                function resolveObjectOrUnionTypeMembers(type) {
                    if (!type.members) {
                        if (type.flags & (1024 /* Class */ | 2048 /* Interface */)) {
                            resolveClassOrInterfaceMembers(type);
                        }
                        else if (type.flags & 32768 /* Anonymous */) {
                            resolveAnonymousTypeMembers(type);
                        }
                        else if (type.flags & 8192 /* Tuple */) {
                            resolveTupleTypeMembers(type);
                        }
                        else if (type.flags & 16384 /* Union */) {
                            resolveUnionTypeMembers(type);
                        }
                        else {
                            resolveTypeReferenceMembers(type);
                        }
                    }
                    return type;
                }
                function getPropertiesOfObjectType(type) {
                    if (type.flags & 48128 /* ObjectType */) {
                        return resolveObjectOrUnionTypeMembers(type).properties;
                    }
                    return emptyArray;
                }
                function getPropertyOfObjectType(type, name) {
                    if (type.flags & 48128 /* ObjectType */) {
                        var resolved = resolveObjectOrUnionTypeMembers(type);
                        if (ts.hasProperty(resolved.members, name)) {
                            var symbol = resolved.members[name];
                            if (symbolIsValue(symbol)) {
                                return symbol;
                            }
                        }
                    }
                }
                function getPropertiesOfUnionType(type) {
                    var result = [];
                    ts.forEach(getPropertiesOfType(type.types[0]), function (prop) {
                        var unionProp = getPropertyOfUnionType(type, prop.name);
                        if (unionProp) {
                            result.push(unionProp);
                        }
                    });
                    return result;
                }
                function getPropertiesOfType(type) {
                    if (type.flags & 16384 /* Union */) {
                        return getPropertiesOfUnionType(type);
                    }
                    return getPropertiesOfObjectType(getApparentType(type));
                }
                function getApparentType(type) {
                    if (type.flags & 512 /* TypeParameter */) {
                        do {
                            type = getConstraintOfTypeParameter(type);
                        } while (type && type.flags & 512 /* TypeParameter */);
                        if (!type) {
                            type = emptyObjectType;
                        }
                    }
                    if (type.flags & 258 /* StringLike */) {
                        type = globalStringType;
                    }
                    else if (type.flags & 132 /* NumberLike */) {
                        type = globalNumberType;
                    }
                    else if (type.flags & 8 /* Boolean */) {
                        type = globalBooleanType;
                    }
                    return type;
                }
                function createUnionProperty(unionType, name) {
                    var types = unionType.types;
                    var props;
                    for (var i = 0; i < types.length; i++) {
                        var type = getApparentType(types[i]);
                        if (type !== unknownType) {
                            var prop = getPropertyOfType(type, name);
                            if (!prop) {
                                return undefined;
                            }
                            if (!props) {
                                props = [prop];
                            }
                            else {
                                props.push(prop);
                            }
                        }
                    }
                    var propTypes = [];
                    var declarations = [];
                    for (var i = 0; i < props.length; i++) {
                        var prop = props[i];
                        if (prop.declarations) {
                            declarations.push.apply(declarations, prop.declarations);
                        }
                        propTypes.push(getTypeOfSymbol(prop));
                    }
                    var result = createSymbol(4 /* Property */ | 268435456 /* Transient */ | 1073741824 /* UnionProperty */, name);
                    result.unionType = unionType;
                    result.declarations = declarations;
                    result.type = getUnionType(propTypes);
                    return result;
                }
                function getPropertyOfUnionType(type, name) {
                    var properties = type.resolvedProperties || (type.resolvedProperties = {});
                    if (ts.hasProperty(properties, name)) {
                        return properties[name];
                    }
                    var property = createUnionProperty(type, name);
                    if (property) {
                        properties[name] = property;
                    }
                    return property;
                }
                function getPropertyOfType(type, name) {
                    if (type.flags & 16384 /* Union */) {
                        return getPropertyOfUnionType(type, name);
                    }
                    if (!(type.flags & 48128 /* ObjectType */)) {
                        type = getApparentType(type);
                        if (!(type.flags & 48128 /* ObjectType */)) {
                            return undefined;
                        }
                    }
                    var resolved = resolveObjectOrUnionTypeMembers(type);
                    if (ts.hasProperty(resolved.members, name)) {
                        var symbol = resolved.members[name];
                        if (symbolIsValue(symbol)) {
                            return symbol;
                        }
                    }
                    if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
                        var symbol = getPropertyOfObjectType(globalFunctionType, name);
                        if (symbol)
                            return symbol;
                    }
                    return getPropertyOfObjectType(globalObjectType, name);
                }
                function getSignaturesOfObjectOrUnionType(type, kind) {
                    if (type.flags & (48128 /* ObjectType */ | 16384 /* Union */)) {
                        var resolved = resolveObjectOrUnionTypeMembers(type);
                        return kind === 0 /* Call */ ? resolved.callSignatures : resolved.constructSignatures;
                    }
                    return emptyArray;
                }
                function getSignaturesOfType(type, kind) {
                    return getSignaturesOfObjectOrUnionType(getApparentType(type), kind);
                }
                function getIndexTypeOfObjectOrUnionType(type, kind) {
                    if (type.flags & (48128 /* ObjectType */ | 16384 /* Union */)) {
                        var resolved = resolveObjectOrUnionTypeMembers(type);
                        return kind === 0 /* String */ ? resolved.stringIndexType : resolved.numberIndexType;
                    }
                }
                function getIndexTypeOfType(type, kind) {
                    return getIndexTypeOfObjectOrUnionType(getApparentType(type), kind);
                }
                function getTypeParametersFromDeclaration(typeParameterDeclarations) {
                    var result = [];
                    ts.forEach(typeParameterDeclarations, function (node) {
                        var tp = getDeclaredTypeOfTypeParameter(node.symbol);
                        if (!ts.contains(result, tp)) {
                            result.push(tp);
                        }
                    });
                    return result;
                }
                function getSignatureFromDeclaration(declaration) {
                    var links = getNodeLinks(declaration);
                    if (!links.resolvedSignature) {
                        var classType = declaration.kind === 127 /* Constructor */ ? getDeclaredTypeOfClass(declaration.parent.symbol) : undefined;
                        var typeParameters = classType ? classType.typeParameters : declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) : undefined;
                        var parameters = [];
                        var hasStringLiterals = false;
                        var minArgumentCount = -1;
                        for (var i = 0, n = declaration.parameters.length; i < n; i++) {
                            var param = declaration.parameters[i];
                            parameters.push(param.symbol);
                            if (param.type && param.type.kind === 7 /* StringLiteral */) {
                                hasStringLiterals = true;
                            }
                            if (minArgumentCount < 0) {
                                if (param.initializer || param.flags & (4 /* QuestionMark */ | 8 /* Rest */)) {
                                    minArgumentCount = i;
                                }
                            }
                        }
                        if (minArgumentCount < 0) {
                            minArgumentCount = declaration.parameters.length;
                        }
                        var returnType;
                        if (classType) {
                            returnType = classType;
                        }
                        else if (declaration.type) {
                            returnType = getTypeFromTypeNode(declaration.type);
                        }
                        else {
                            if (declaration.kind === 128 /* GetAccessor */ && !ts.hasComputedNameButNotSymbol(declaration)) {
                                var setter = getDeclarationOfKind(declaration.symbol, 129 /* SetAccessor */);
                                returnType = getAnnotatedAccessorType(setter);
                            }
                            if (!returnType && !declaration.body) {
                                returnType = anyType;
                            }
                        }
                        links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, ts.hasRestParameters(declaration), hasStringLiterals);
                    }
                    return links.resolvedSignature;
                }
                function getSignaturesOfSymbol(symbol) {
                    if (!symbol)
                        return emptyArray;
                    var result = [];
                    for (var i = 0, len = symbol.declarations.length; i < len; i++) {
                        var node = symbol.declarations[i];
                        switch (node.kind) {
                            case 134 /* FunctionType */:
                            case 135 /* ConstructorType */:
                            case 187 /* FunctionDeclaration */:
                            case 126 /* Method */:
                            case 127 /* Constructor */:
                            case 130 /* CallSignature */:
                            case 131 /* ConstructSignature */:
                            case 132 /* IndexSignature */:
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                            case 153 /* FunctionExpression */:
                            case 154 /* ArrowFunction */:
                                if (i > 0 && node.body) {
                                    var previous = symbol.declarations[i - 1];
                                    if (node.parent === previous.parent && node.kind === previous.kind && node.pos === previous.end) {
                                        break;
                                    }
                                }
                                result.push(getSignatureFromDeclaration(node));
                        }
                    }
                    return result;
                }
                function getReturnTypeOfSignature(signature) {
                    if (!signature.resolvedReturnType) {
                        signature.resolvedReturnType = resolvingType;
                        if (signature.target) {
                            var type = instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper);
                        }
                        else if (signature.unionSignatures) {
                            var type = getUnionType(ts.map(signature.unionSignatures, getReturnTypeOfSignature));
                        }
                        else {
                            var type = getReturnTypeFromBody(signature.declaration);
                        }
                        if (signature.resolvedReturnType === resolvingType) {
                            signature.resolvedReturnType = type;
                        }
                    }
                    else if (signature.resolvedReturnType === resolvingType) {
                        signature.resolvedReturnType = anyType;
                        if (compilerOptions.noImplicitAny) {
                            var declaration = signature.declaration;
                            if (declaration.name) {
                                error(declaration.name, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, ts.declarationNameToString(declaration.name));
                            }
                            else {
                                error(declaration, ts.Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions);
                            }
                        }
                    }
                    return signature.resolvedReturnType;
                }
                function getRestTypeOfSignature(signature) {
                    if (signature.hasRestParameter) {
                        var type = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                        if (type.flags & 4096 /* Reference */ && type.target === globalArrayType) {
                            return type.typeArguments[0];
                        }
                    }
                    return anyType;
                }
                function getSignatureInstantiation(signature, typeArguments) {
                    return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), true);
                }
                function getErasedSignature(signature) {
                    if (!signature.typeParameters)
                        return signature;
                    if (!signature.erasedSignatureCache) {
                        if (signature.target) {
                            signature.erasedSignatureCache = instantiateSignature(getErasedSignature(signature.target), signature.mapper);
                        }
                        else {
                            signature.erasedSignatureCache = instantiateSignature(signature, createTypeEraser(signature.typeParameters), true);
                        }
                    }
                    return signature.erasedSignatureCache;
                }
                function getOrCreateTypeFromSignature(signature) {
                    if (!signature.isolatedSignatureType) {
                        var isConstructor = signature.declaration.kind === 127 /* Constructor */ || signature.declaration.kind === 131 /* ConstructSignature */;
                        var type = createObjectType(32768 /* Anonymous */ | 65536 /* FromSignature */);
                        type.members = emptySymbols;
                        type.properties = emptyArray;
                        type.callSignatures = !isConstructor ? [signature] : emptyArray;
                        type.constructSignatures = isConstructor ? [signature] : emptyArray;
                        signature.isolatedSignatureType = type;
                    }
                    return signature.isolatedSignatureType;
                }
                function getIndexSymbol(symbol) {
                    return symbol.members["__index"];
                }
                function getIndexDeclarationOfSymbol(symbol, kind) {
                    var syntaxKind = kind === 1 /* Number */ ? 116 /* NumberKeyword */ : 118 /* StringKeyword */;
                    var indexSymbol = getIndexSymbol(symbol);
                    if (indexSymbol) {
                        var len = indexSymbol.declarations.length;
                        for (var i = 0; i < len; i++) {
                            var node = indexSymbol.declarations[i];
                            if (node.parameters.length === 1) {
                                var parameter = node.parameters[0];
                                if (parameter && parameter.type && parameter.type.kind === syntaxKind) {
                                    return node;
                                }
                            }
                        }
                    }
                    return undefined;
                }
                function getIndexTypeOfSymbol(symbol, kind) {
                    var declaration = getIndexDeclarationOfSymbol(symbol, kind);
                    return declaration ? declaration.type ? getTypeFromTypeNode(declaration.type) : anyType : undefined;
                }
                function getConstraintOfTypeParameter(type) {
                    if (!type.constraint) {
                        if (type.target) {
                            var targetConstraint = getConstraintOfTypeParameter(type.target);
                            type.constraint = targetConstraint ? instantiateType(targetConstraint, type.mapper) : noConstraintType;
                        }
                        else {
                            type.constraint = getTypeFromTypeNode(getDeclarationOfKind(type.symbol, 123 /* TypeParameter */).constraint);
                        }
                    }
                    return type.constraint === noConstraintType ? undefined : type.constraint;
                }
                function getTypeListId(types) {
                    switch (types.length) {
                        case 1:
                            return "" + types[0].id;
                        case 2:
                            return types[0].id + "," + types[1].id;
                        default:
                            var result = "";
                            for (var i = 0; i < types.length; i++) {
                                if (i > 0)
                                    result += ",";
                                result += types[i].id;
                            }
                            return result;
                    }
                }
                function createTypeReference(target, typeArguments) {
                    var id = getTypeListId(typeArguments);
                    var type = target.instantiations[id];
                    if (!type) {
                        type = target.instantiations[id] = createObjectType(4096 /* Reference */, target.symbol);
                        type.target = target;
                        type.typeArguments = typeArguments;
                    }
                    return type;
                }
                function isTypeParameterReferenceIllegalInConstraint(typeReferenceNode, typeParameterSymbol) {
                    var links = getNodeLinks(typeReferenceNode);
                    if (links.isIllegalTypeReferenceInConstraint !== undefined) {
                        return links.isIllegalTypeReferenceInConstraint;
                    }
                    var currentNode = typeReferenceNode;
                    while (!ts.forEach(typeParameterSymbol.declarations, function (d) { return d.parent === currentNode.parent; })) {
                        currentNode = currentNode.parent;
                    }
                    links.isIllegalTypeReferenceInConstraint = currentNode.kind === 123 /* TypeParameter */;
                    return links.isIllegalTypeReferenceInConstraint;
                }
                function checkTypeParameterHasIllegalReferencesInConstraint(typeParameter) {
                    var typeParameterSymbol;
                    function check(n) {
                        if (n.kind === 133 /* TypeReference */ && n.typeName.kind === 63 /* Identifier */) {
                            var links = getNodeLinks(n);
                            if (links.isIllegalTypeReferenceInConstraint === undefined) {
                                var symbol = resolveName(typeParameter, n.typeName.text, 3152352 /* Type */, undefined, undefined);
                                if (symbol && (symbol.flags & 1048576 /* TypeParameter */)) {
                                    links.isIllegalTypeReferenceInConstraint = ts.forEach(symbol.declarations, function (d) { return d.parent == typeParameter.parent; });
                                }
                            }
                            if (links.isIllegalTypeReferenceInConstraint) {
                                error(typeParameter, ts.Diagnostics.Constraint_of_a_type_parameter_cannot_reference_any_type_parameter_from_the_same_type_parameter_list);
                            }
                        }
                        ts.forEachChild(n, check);
                    }
                    if (typeParameter.constraint) {
                        typeParameterSymbol = getSymbolOfNode(typeParameter);
                        check(typeParameter.constraint);
                    }
                }
                function getTypeFromTypeReferenceNode(node) {
                    var links = getNodeLinks(node);
                    if (!links.resolvedType) {
                        var symbol = resolveEntityName(node, node.typeName, 3152352 /* Type */);
                        if (symbol) {
                            var type;
                            if ((symbol.flags & 1048576 /* TypeParameter */) && isTypeParameterReferenceIllegalInConstraint(node, symbol)) {
                                type = unknownType;
                            }
                            else {
                                type = getDeclaredTypeOfSymbol(symbol);
                                if (type.flags & (1024 /* Class */ | 2048 /* Interface */) && type.flags & 4096 /* Reference */) {
                                    var typeParameters = type.typeParameters;
                                    if (node.typeArguments && node.typeArguments.length === typeParameters.length) {
                                        type = createTypeReference(type, ts.map(node.typeArguments, getTypeFromTypeNode));
                                    }
                                    else {
                                        error(node, ts.Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, undefined, 1 /* WriteArrayAsGenericType */), typeParameters.length);
                                        type = undefined;
                                    }
                                }
                                else {
                                    if (node.typeArguments) {
                                        error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type));
                                        type = undefined;
                                    }
                                }
                            }
                        }
                        links.resolvedType = type || unknownType;
                    }
                    return links.resolvedType;
                }
                function getTypeFromTypeQueryNode(node) {
                    var links = getNodeLinks(node);
                    if (!links.resolvedType) {
                        links.resolvedType = getWidenedType(checkExpression(node.exprName));
                    }
                    return links.resolvedType;
                }
                function getTypeOfGlobalSymbol(symbol, arity) {
                    function getTypeDeclaration(symbol) {
                        var declarations = symbol.declarations;
                        for (var i = 0; i < declarations.length; i++) {
                            var declaration = declarations[i];
                            switch (declaration.kind) {
                                case 189 /* ClassDeclaration */:
                                case 190 /* InterfaceDeclaration */:
                                case 192 /* EnumDeclaration */:
                                    return declaration;
                            }
                        }
                    }
                    if (!symbol) {
                        return emptyObjectType;
                    }
                    var type = getDeclaredTypeOfSymbol(symbol);
                    if (!(type.flags & 48128 /* ObjectType */)) {
                        error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, symbol.name);
                        return emptyObjectType;
                    }
                    if ((type.typeParameters ? type.typeParameters.length : 0) !== arity) {
                        error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, symbol.name, arity);
                        return emptyObjectType;
                    }
                    return type;
                }
                function getGlobalSymbol(name) {
                    return resolveName(undefined, name, 3152352 /* Type */, ts.Diagnostics.Cannot_find_global_type_0, name);
                }
                function getGlobalType(name) {
                    return getTypeOfGlobalSymbol(getGlobalSymbol(name), 0);
                }
                function createArrayType(elementType) {
                    var arrayType = globalArrayType || getDeclaredTypeOfSymbol(globalArraySymbol);
                    return arrayType !== emptyObjectType ? createTypeReference(arrayType, [elementType]) : emptyObjectType;
                }
                function getTypeFromArrayTypeNode(node) {
                    var links = getNodeLinks(node);
                    if (!links.resolvedType) {
                        links.resolvedType = createArrayType(getTypeFromTypeNode(node.elementType));
                    }
                    return links.resolvedType;
                }
                function createTupleType(elementTypes) {
                    var id = getTypeListId(elementTypes);
                    var type = tupleTypes[id];
                    if (!type) {
                        type = tupleTypes[id] = createObjectType(8192 /* Tuple */);
                        type.elementTypes = elementTypes;
                    }
                    return type;
                }
                function getTypeFromTupleTypeNode(node) {
                    var links = getNodeLinks(node);
                    if (!links.resolvedType) {
                        links.resolvedType = createTupleType(ts.map(node.elementTypes, getTypeFromTypeNode));
                    }
                    return links.resolvedType;
                }
                function addTypeToSortedSet(sortedSet, type) {
                    if (type.flags & 16384 /* Union */) {
                        addTypesToSortedSet(sortedSet, type.types);
                    }
                    else {
                        var i = 0;
                        var id = type.id;
                        while (i < sortedSet.length && sortedSet[i].id < id) {
                            i++;
                        }
                        if (i === sortedSet.length || sortedSet[i].id !== id) {
                            sortedSet.splice(i, 0, type);
                        }
                    }
                }
                function addTypesToSortedSet(sortedTypes, types) {
                    for (var i = 0, len = types.length; i < len; i++) {
                        addTypeToSortedSet(sortedTypes, types[i]);
                    }
                }
                function isSubtypeOfAny(candidate, types) {
                    for (var i = 0, len = types.length; i < len; i++) {
                        if (candidate !== types[i] && isTypeSubtypeOf(candidate, types[i])) {
                            return true;
                        }
                    }
                    return false;
                }
                function removeSubtypes(types) {
                    var i = types.length;
                    while (i > 0) {
                        i--;
                        if (isSubtypeOfAny(types[i], types)) {
                            types.splice(i, 1);
                        }
                    }
                }
                function containsAnyType(types) {
                    for (var i = 0; i < types.length; i++) {
                        if (types[i].flags & 1 /* Any */) {
                            return true;
                        }
                    }
                    return false;
                }
                function removeAllButLast(types, typeToRemove) {
                    var i = types.length;
                    while (i > 0 && types.length > 1) {
                        i--;
                        if (types[i] === typeToRemove) {
                            types.splice(i, 1);
                        }
                    }
                }
                function getUnionType(types, noSubtypeReduction) {
                    if (types.length === 0) {
                        return emptyObjectType;
                    }
                    var sortedTypes = [];
                    addTypesToSortedSet(sortedTypes, types);
                    if (noSubtypeReduction) {
                        if (containsAnyType(sortedTypes)) {
                            return anyType;
                        }
                        removeAllButLast(sortedTypes, undefinedType);
                        removeAllButLast(sortedTypes, nullType);
                    }
                    else {
                        removeSubtypes(sortedTypes);
                    }
                    if (sortedTypes.length === 1) {
                        return sortedTypes[0];
                    }
                    var id = getTypeListId(sortedTypes);
                    var type = unionTypes[id];
                    if (!type) {
                        type = unionTypes[id] = createObjectType(16384 /* Union */);
                        type.types = sortedTypes;
                    }
                    return type;
                }
                function getTypeFromUnionTypeNode(node) {
                    var links = getNodeLinks(node);
                    if (!links.resolvedType) {
                        links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), true);
                    }
                    return links.resolvedType;
                }
                function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node) {
                    var links = getNodeLinks(node);
                    if (!links.resolvedType) {
                        links.resolvedType = createObjectType(32768 /* Anonymous */, node.symbol);
                    }
                    return links.resolvedType;
                }
                function getStringLiteralType(node) {
                    if (ts.hasProperty(stringLiteralTypes, node.text))
                        return stringLiteralTypes[node.text];
                    var type = stringLiteralTypes[node.text] = createType(256 /* StringLiteral */);
                    type.text = ts.getTextOfNode(node);
                    return type;
                }
                function getTypeFromStringLiteral(node) {
                    var links = getNodeLinks(node);
                    if (!links.resolvedType) {
                        links.resolvedType = getStringLiteralType(node);
                    }
                    return links.resolvedType;
                }
                function getTypeFromTypeNode(node) {
                    switch (node.kind) {
                        case 109 /* AnyKeyword */:
                            return anyType;
                        case 118 /* StringKeyword */:
                            return stringType;
                        case 116 /* NumberKeyword */:
                            return numberType;
                        case 110 /* BooleanKeyword */:
                            return booleanType;
                        case 97 /* VoidKeyword */:
                            return voidType;
                        case 7 /* StringLiteral */:
                            return getTypeFromStringLiteral(node);
                        case 133 /* TypeReference */:
                            return getTypeFromTypeReferenceNode(node);
                        case 136 /* TypeQuery */:
                            return getTypeFromTypeQueryNode(node);
                        case 138 /* ArrayType */:
                            return getTypeFromArrayTypeNode(node);
                        case 139 /* TupleType */:
                            return getTypeFromTupleTypeNode(node);
                        case 140 /* UnionType */:
                            return getTypeFromUnionTypeNode(node);
                        case 141 /* ParenType */:
                            return getTypeFromTypeNode(node.type);
                        case 134 /* FunctionType */:
                        case 135 /* ConstructorType */:
                        case 137 /* TypeLiteral */:
                            return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                        case 63 /* Identifier */:
                        case 121 /* QualifiedName */:
                            var symbol = getSymbolInfo(node);
                            return symbol && getDeclaredTypeOfSymbol(symbol);
                        default:
                            return unknownType;
                    }
                }
                function instantiateList(items, mapper, instantiator) {
                    if (items && items.length) {
                        var result = [];
                        for (var i = 0; i < items.length; i++) {
                            result.push(instantiator(items[i], mapper));
                        }
                        return result;
                    }
                    return items;
                }
                function createUnaryTypeMapper(source, target) {
                    return function (t) { return t === source ? target : t; };
                }
                function createBinaryTypeMapper(source1, target1, source2, target2) {
                    return function (t) { return t === source1 ? target1 : t === source2 ? target2 : t; };
                }
                function createTypeMapper(sources, targets) {
                    switch (sources.length) {
                        case 1: return createUnaryTypeMapper(sources[0], targets[0]);
                        case 2: return createBinaryTypeMapper(sources[0], targets[0], sources[1], targets[1]);
                    }
                    return function (t) {
                        for (var i = 0; i < sources.length; i++) {
                            if (t === sources[i])
                                return targets[i];
                        }
                        return t;
                    };
                }
                function createUnaryTypeEraser(source) {
                    return function (t) { return t === source ? anyType : t; };
                }
                function createBinaryTypeEraser(source1, source2) {
                    return function (t) { return t === source1 || t === source2 ? anyType : t; };
                }
                function createTypeEraser(sources) {
                    switch (sources.length) {
                        case 1: return createUnaryTypeEraser(sources[0]);
                        case 2: return createBinaryTypeEraser(sources[0], sources[1]);
                    }
                    return function (t) {
                        for (var i = 0; i < sources.length; i++) {
                            if (t === sources[i])
                                return anyType;
                        }
                        return t;
                    };
                }
                function createInferenceMapper(context) {
                    return function (t) {
                        for (var i = 0; i < context.typeParameters.length; i++) {
                            if (t === context.typeParameters[i]) {
                                return getInferredType(context, i);
                            }
                        }
                        return t;
                    };
                }
                function identityMapper(type) {
                    return type;
                }
                function combineTypeMappers(mapper1, mapper2) {
                    return function (t) { return mapper2(mapper1(t)); };
                }
                function instantiateTypeParameter(typeParameter, mapper) {
                    var result = createType(512 /* TypeParameter */);
                    result.symbol = typeParameter.symbol;
                    if (typeParameter.constraint) {
                        result.constraint = instantiateType(typeParameter.constraint, mapper);
                    }
                    else {
                        result.target = typeParameter;
                        result.mapper = mapper;
                    }
                    return result;
                }
                function instantiateSignature(signature, mapper, eraseTypeParameters) {
                    if (signature.typeParameters && !eraseTypeParameters) {
                        var freshTypeParameters = instantiateList(signature.typeParameters, mapper, instantiateTypeParameter);
                        mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper);
                    }
                    var result = createSignature(signature.declaration, freshTypeParameters, instantiateList(signature.parameters, mapper, instantiateSymbol), signature.resolvedReturnType ? instantiateType(signature.resolvedReturnType, mapper) : undefined, signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals);
                    result.target = signature;
                    result.mapper = mapper;
                    return result;
                }
                function instantiateSymbol(symbol, mapper) {
                    if (symbol.flags & 67108864 /* Instantiated */) {
                        var links = getSymbolLinks(symbol);
                        symbol = links.target;
                        mapper = combineTypeMappers(links.mapper, mapper);
                    }
                    var result = createSymbol(67108864 /* Instantiated */ | 268435456 /* Transient */ | symbol.flags, symbol.name);
                    result.declarations = symbol.declarations;
                    result.parent = symbol.parent;
                    result.target = symbol;
                    result.mapper = mapper;
                    if (symbol.valueDeclaration) {
                        result.valueDeclaration = symbol.valueDeclaration;
                    }
                    return result;
                }
                function instantiateAnonymousType(type, mapper) {
                    var result = createObjectType(32768 /* Anonymous */, type.symbol);
                    result.properties = instantiateList(getPropertiesOfObjectType(type), mapper, instantiateSymbol);
                    result.members = createSymbolTable(result.properties);
                    result.callSignatures = instantiateList(getSignaturesOfType(type, 0 /* Call */), mapper, instantiateSignature);
                    result.constructSignatures = instantiateList(getSignaturesOfType(type, 1 /* Construct */), mapper, instantiateSignature);
                    var stringIndexType = getIndexTypeOfType(type, 0 /* String */);
                    var numberIndexType = getIndexTypeOfType(type, 1 /* Number */);
                    if (stringIndexType)
                        result.stringIndexType = instantiateType(stringIndexType, mapper);
                    if (numberIndexType)
                        result.numberIndexType = instantiateType(numberIndexType, mapper);
                    return result;
                }
                function instantiateType(type, mapper) {
                    if (mapper !== identityMapper) {
                        if (type.flags & 512 /* TypeParameter */) {
                            return mapper(type);
                        }
                        if (type.flags & 32768 /* Anonymous */) {
                            return type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) ? instantiateAnonymousType(type, mapper) : type;
                        }
                        if (type.flags & 4096 /* Reference */) {
                            return createTypeReference(type.target, instantiateList(type.typeArguments, mapper, instantiateType));
                        }
                        if (type.flags & 8192 /* Tuple */) {
                            return createTupleType(instantiateList(type.elementTypes, mapper, instantiateType));
                        }
                        if (type.flags & 16384 /* Union */) {
                            return getUnionType(instantiateList(type.types, mapper, instantiateType), true);
                        }
                    }
                    return type;
                }
                function isContextSensitiveExpression(node) {
                    switch (node.kind) {
                        case 153 /* FunctionExpression */:
                        case 154 /* ArrowFunction */:
                            return !node.typeParameters && !ts.forEach(node.parameters, function (p) { return p.type; });
                        case 143 /* ObjectLiteral */:
                            return ts.forEach(node.properties, function (p) { return p.kind === 144 /* PropertyAssignment */ && isContextSensitiveExpression(p.initializer); });
                        case 142 /* ArrayLiteral */:
                            return ts.forEach(node.elements, function (e) { return isContextSensitiveExpression(e); });
                        case 158 /* ConditionalExpression */:
                            return isContextSensitiveExpression(node.whenTrue) || isContextSensitiveExpression(node.whenFalse);
                        case 157 /* BinaryExpression */:
                            return node.operator === 48 /* BarBarToken */ && (isContextSensitiveExpression(node.left) || isContextSensitiveExpression(node.right));
                    }
                    return false;
                }
                function getTypeWithoutConstructors(type) {
                    if (type.flags & 48128 /* ObjectType */) {
                        var resolved = resolveObjectOrUnionTypeMembers(type);
                        if (resolved.constructSignatures.length) {
                            var result = createObjectType(32768 /* Anonymous */, type.symbol);
                            result.members = resolved.members;
                            result.properties = resolved.properties;
                            result.callSignatures = resolved.callSignatures;
                            result.constructSignatures = emptyArray;
                            type = result;
                        }
                    }
                    return type;
                }
                var subtypeRelation = {};
                var assignableRelation = {};
                var identityRelation = {};
                function isTypeIdenticalTo(source, target) {
                    return checkTypeRelatedTo(source, target, identityRelation, undefined);
                }
                function compareTypes(source, target) {
                    return checkTypeRelatedTo(source, target, identityRelation, undefined) ? -1 /* True */ : 0 /* False */;
                }
                function isTypeSubtypeOf(source, target) {
                    return checkTypeSubtypeOf(source, target, undefined);
                }
                function isTypeAssignableTo(source, target) {
                    return checkTypeAssignableTo(source, target, undefined);
                }
                function checkTypeSubtypeOf(source, target, errorNode, headMessage, containingMessageChain) {
                    return checkTypeRelatedTo(source, target, subtypeRelation, errorNode, headMessage, containingMessageChain);
                }
                function checkTypeAssignableTo(source, target, errorNode, headMessage) {
                    return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage);
                }
                function isSignatureAssignableTo(source, target) {
                    var sourceType = getOrCreateTypeFromSignature(source);
                    var targetType = getOrCreateTypeFromSignature(target);
                    return checkTypeRelatedTo(sourceType, targetType, assignableRelation, undefined);
                }
                function checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain) {
                    var errorInfo;
                    var sourceStack;
                    var targetStack;
                    var maybeStack;
                    var expandingFlags;
                    var depth = 0;
                    var overflow = false;
                    ts.Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
                    var result = isRelatedTo(source, target, errorNode !== undefined, headMessage);
                    if (overflow) {
                        error(errorNode, ts.Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
                    }
                    else if (errorInfo) {
                        if (containingMessageChain) {
                            errorInfo = ts.concatenateDiagnosticMessageChains(containingMessageChain, errorInfo);
                        }
                        addDiagnostic(ts.createDiagnosticForNodeFromMessageChain(errorNode, errorInfo, program.getCompilerHost().getNewLine()));
                    }
                    return result !== 0 /* False */;
                    function reportError(message, arg0, arg1, arg2) {
                        errorInfo = ts.chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2);
                    }
                    function isRelatedTo(source, target, reportErrors, headMessage) {
                        var result;
                        if (relation === identityRelation) {
                            if (source === target)
                                return -1 /* True */;
                        }
                        else {
                            if (source === target)
                                return -1 /* True */;
                            if (target.flags & 1 /* Any */)
                                return -1 /* True */;
                            if (source === undefinedType)
                                return -1 /* True */;
                            if (source === nullType && target !== undefinedType)
                                return -1 /* True */;
                            if (source.flags & 128 /* Enum */ && target === numberType)
                                return -1 /* True */;
                            if (source.flags & 256 /* StringLiteral */ && target === stringType)
                                return -1 /* True */;
                            if (relation === assignableRelation) {
                                if (source.flags & 1 /* Any */)
                                    return -1 /* True */;
                                if (source === numberType && target.flags & 128 /* Enum */)
                                    return -1 /* True */;
                            }
                        }
                        if (source.flags & 16384 /* Union */) {
                            if (result = unionTypeRelatedToType(source, target, reportErrors)) {
                                return result;
                            }
                        }
                        else if (target.flags & 16384 /* Union */) {
                            if (result = typeRelatedToUnionType(source, target, reportErrors)) {
                                return result;
                            }
                        }
                        else if (source.flags & 512 /* TypeParameter */ && target.flags & 512 /* TypeParameter */) {
                            if (result = typeParameterRelatedTo(source, target, reportErrors)) {
                                return result;
                            }
                        }
                        else {
                            var saveErrorInfo = errorInfo;
                            if (source.flags & 4096 /* Reference */ && target.flags & 4096 /* Reference */ && source.target === target.target) {
                                if (result = typesRelatedTo(source.typeArguments, target.typeArguments, reportErrors)) {
                                    return result;
                                }
                            }
                            var reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo;
                            var sourceOrApparentType = relation === identityRelation ? source : getApparentType(source);
                            if (sourceOrApparentType.flags & 48128 /* ObjectType */ && target.flags & 48128 /* ObjectType */ && (result = objectTypeRelatedTo(sourceOrApparentType, target, reportStructuralErrors))) {
                                errorInfo = saveErrorInfo;
                                return result;
                            }
                        }
                        if (reportErrors) {
                            headMessage = headMessage || ts.Diagnostics.Type_0_is_not_assignable_to_type_1;
                            reportError(headMessage, typeToString(source), typeToString(target));
                        }
                        return 0 /* False */;
                    }
                    function typeRelatedToUnionType(source, target, reportErrors) {
                        var targetTypes = target.types;
                        for (var i = 0, len = targetTypes.length; i < len; i++) {
                            var related = isRelatedTo(source, targetTypes[i], reportErrors && i === len - 1);
                            if (related) {
                                return related;
                            }
                        }
                        return 0 /* False */;
                    }
                    function unionTypeRelatedToType(source, target, reportErrors) {
                        var result = -1 /* True */;
                        var sourceTypes = source.types;
                        for (var i = 0, len = sourceTypes.length; i < len; i++) {
                            var related = isRelatedTo(sourceTypes[i], target, reportErrors);
                            if (!related) {
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                        return result;
                    }
                    function typesRelatedTo(sources, targets, reportErrors) {
                        var result = -1 /* True */;
                        for (var i = 0, len = sources.length; i < len; i++) {
                            var related = isRelatedTo(sources[i], targets[i], reportErrors);
                            if (!related) {
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                        return result;
                    }
                    function typeParameterRelatedTo(source, target, reportErrors) {
                        if (relation === identityRelation) {
                            if (source.symbol.name !== target.symbol.name) {
                                return 0 /* False */;
                            }
                            if (source.constraint === target.constraint) {
                                return -1 /* True */;
                            }
                            if (source.constraint === noConstraintType || target.constraint === noConstraintType) {
                                return 0 /* False */;
                            }
                            return isRelatedTo(source.constraint, target.constraint, reportErrors);
                        }
                        else {
                            while (true) {
                                var constraint = getConstraintOfTypeParameter(source);
                                if (constraint === target)
                                    return -1 /* True */;
                                if (!(constraint && constraint.flags & 512 /* TypeParameter */))
                                    break;
                                source = constraint;
                            }
                            return 0 /* False */;
                        }
                    }
                    function objectTypeRelatedTo(source, target, reportErrors) {
                        if (overflow) {
                            return 0 /* False */;
                        }
                        var id = source.id + "," + target.id;
                        var related = relation[id];
                        if (related !== undefined) {
                            return related ? -1 /* True */ : 0 /* False */;
                        }
                        if (depth > 0) {
                            for (var i = 0; i < depth; i++) {
                                if (maybeStack[i][id]) {
                                    return 1 /* Maybe */;
                                }
                            }
                            if (depth === 100) {
                                overflow = true;
                                return 0 /* False */;
                            }
                        }
                        else {
                            sourceStack = [];
                            targetStack = [];
                            maybeStack = [];
                            expandingFlags = 0;
                        }
                        sourceStack[depth] = source;
                        targetStack[depth] = target;
                        maybeStack[depth] = {};
                        maybeStack[depth][id] = true;
                        depth++;
                        var saveExpandingFlags = expandingFlags;
                        if (!(expandingFlags & 1) && isDeeplyNestedGeneric(source, sourceStack))
                            expandingFlags |= 1;
                        if (!(expandingFlags & 2) && isDeeplyNestedGeneric(target, targetStack))
                            expandingFlags |= 2;
                        if (expandingFlags === 3) {
                            var result = 1 /* Maybe */;
                        }
                        else {
                            var result = propertiesRelatedTo(source, target, reportErrors);
                            if (result) {
                                result &= signaturesRelatedTo(source, target, 0 /* Call */, reportErrors);
                                if (result) {
                                    result &= signaturesRelatedTo(source, target, 1 /* Construct */, reportErrors);
                                    if (result) {
                                        result &= stringIndexTypesRelatedTo(source, target, reportErrors);
                                        if (result) {
                                            result &= numberIndexTypesRelatedTo(source, target, reportErrors);
                                        }
                                    }
                                }
                            }
                        }
                        expandingFlags = saveExpandingFlags;
                        depth--;
                        if (result) {
                            var maybeCache = maybeStack[depth];
                            var destinationCache = result === -1 /* True */ || depth === 0 ? relation : maybeStack[depth - 1];
                            for (var p in maybeCache) {
                                destinationCache[p] = maybeCache[p];
                            }
                        }
                        else {
                            relation[id] = false;
                        }
                        return result;
                    }
                    function isDeeplyNestedGeneric(type, stack) {
                        if (type.flags & 4096 /* Reference */ && depth >= 10) {
                            var target = type.target;
                            var count = 0;
                            for (var i = 0; i < depth; i++) {
                                var t = stack[i];
                                if (t.flags & 4096 /* Reference */ && t.target === target) {
                                    count++;
                                    if (count >= 10)
                                        return true;
                                }
                            }
                        }
                        return false;
                    }
                    function propertiesRelatedTo(source, target, reportErrors) {
                        if (relation === identityRelation) {
                            return propertiesIdenticalTo(source, target);
                        }
                        var result = -1 /* True */;
                        var properties = getPropertiesOfObjectType(target);
                        for (var i = 0; i < properties.length; i++) {
                            var targetProp = properties[i];
                            var sourceProp = getPropertyOfType(source, targetProp.name);
                            if (sourceProp !== targetProp) {
                                if (!sourceProp) {
                                    if (relation === subtypeRelation || !isOptionalProperty(targetProp)) {
                                        if (reportErrors) {
                                            reportError(ts.Diagnostics.Property_0_is_missing_in_type_1, symbolToString(targetProp), typeToString(source));
                                        }
                                        return 0 /* False */;
                                    }
                                }
                                else if (!(targetProp.flags & 536870912 /* Prototype */)) {
                                    var sourceFlags = getDeclarationFlagsFromSymbol(sourceProp);
                                    var targetFlags = getDeclarationFlagsFromSymbol(targetProp);
                                    if (sourceFlags & 32 /* Private */ || targetFlags & 32 /* Private */) {
                                        if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) {
                                            if (reportErrors) {
                                                if (sourceFlags & 32 /* Private */ && targetFlags & 32 /* Private */) {
                                                    reportError(ts.Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
                                                }
                                                else {
                                                    reportError(ts.Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp), typeToString(sourceFlags & 32 /* Private */ ? source : target), typeToString(sourceFlags & 32 /* Private */ ? target : source));
                                                }
                                            }
                                            return 0 /* False */;
                                        }
                                    }
                                    else if (targetFlags & 64 /* Protected */) {
                                        var sourceDeclaredInClass = sourceProp.parent && sourceProp.parent.flags & 32 /* Class */;
                                        var sourceClass = sourceDeclaredInClass ? getDeclaredTypeOfSymbol(sourceProp.parent) : undefined;
                                        var targetClass = getDeclaredTypeOfSymbol(targetProp.parent);
                                        if (!sourceClass || !hasBaseType(sourceClass, targetClass)) {
                                            if (reportErrors) {
                                                reportError(ts.Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp), typeToString(sourceClass || source), typeToString(targetClass));
                                            }
                                            return 0 /* False */;
                                        }
                                    }
                                    else if (sourceFlags & 64 /* Protected */) {
                                        if (reportErrors) {
                                            reportError(ts.Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
                                        }
                                        return 0 /* False */;
                                    }
                                    var related = isRelatedTo(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp), reportErrors);
                                    if (!related) {
                                        if (reportErrors) {
                                            reportError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp));
                                        }
                                        return 0 /* False */;
                                    }
                                    result &= related;
                                    if (isOptionalProperty(sourceProp) && !isOptionalProperty(targetProp)) {
                                        if (reportErrors) {
                                            reportError(ts.Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
                                        }
                                        return 0 /* False */;
                                    }
                                }
                            }
                        }
                        return result;
                    }
                    function propertiesIdenticalTo(source, target) {
                        var sourceProperties = getPropertiesOfObjectType(source);
                        var targetProperties = getPropertiesOfObjectType(target);
                        if (sourceProperties.length !== targetProperties.length) {
                            return 0 /* False */;
                        }
                        var result = -1 /* True */;
                        for (var i = 0, len = sourceProperties.length; i < len; ++i) {
                            var sourceProp = sourceProperties[i];
                            var targetProp = getPropertyOfObjectType(target, sourceProp.name);
                            if (!targetProp) {
                                return 0 /* False */;
                            }
                            var related = compareProperties(sourceProp, targetProp, isRelatedTo);
                            if (!related) {
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                        return result;
                    }
                    function signaturesRelatedTo(source, target, kind, reportErrors) {
                        if (relation === identityRelation) {
                            return signaturesIdenticalTo(source, target, kind);
                        }
                        if (target === anyFunctionType || source === anyFunctionType) {
                            return -1 /* True */;
                        }
                        var sourceSignatures = getSignaturesOfType(source, kind);
                        var targetSignatures = getSignaturesOfType(target, kind);
                        var result = -1 /* True */;
                        var saveErrorInfo = errorInfo;
                        outer: for (var i = 0; i < targetSignatures.length; i++) {
                            var t = targetSignatures[i];
                            if (!t.hasStringLiterals || target.flags & 65536 /* FromSignature */) {
                                var localErrors = reportErrors;
                                for (var j = 0; j < sourceSignatures.length; j++) {
                                    var s = sourceSignatures[j];
                                    if (!s.hasStringLiterals || source.flags & 65536 /* FromSignature */) {
                                        var related = signatureRelatedTo(s, t, localErrors);
                                        if (related) {
                                            result &= related;
                                            errorInfo = saveErrorInfo;
                                            continue outer;
                                        }
                                        localErrors = false;
                                    }
                                }
                                return 0 /* False */;
                            }
                        }
                        return result;
                    }
                    function signatureRelatedTo(source, target, reportErrors) {
                        if (source === target) {
                            return -1 /* True */;
                        }
                        if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) {
                            return 0 /* False */;
                        }
                        var sourceMax = source.parameters.length;
                        var targetMax = target.parameters.length;
                        var checkCount;
                        if (source.hasRestParameter && target.hasRestParameter) {
                            checkCount = sourceMax > targetMax ? sourceMax : targetMax;
                            sourceMax--;
                            targetMax--;
                        }
                        else if (source.hasRestParameter) {
                            sourceMax--;
                            checkCount = targetMax;
                        }
                        else if (target.hasRestParameter) {
                            targetMax--;
                            checkCount = sourceMax;
                        }
                        else {
                            checkCount = sourceMax < targetMax ? sourceMax : targetMax;
                        }
                        source = getErasedSignature(source);
                        target = getErasedSignature(target);
                        var result = -1 /* True */;
                        for (var i = 0; i < checkCount; i++) {
                            var s = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source);
                            var t = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target);
                            var saveErrorInfo = errorInfo;
                            var related = isRelatedTo(s, t, reportErrors);
                            if (!related) {
                                related = isRelatedTo(t, s, false);
                                if (!related) {
                                    if (reportErrors) {
                                        reportError(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, source.parameters[i < sourceMax ? i : sourceMax].name, target.parameters[i < targetMax ? i : targetMax].name);
                                    }
                                    return 0 /* False */;
                                }
                                errorInfo = saveErrorInfo;
                            }
                            result &= related;
                        }
                        var t = getReturnTypeOfSignature(target);
                        if (t === voidType)
                            return result;
                        var s = getReturnTypeOfSignature(source);
                        return result & isRelatedTo(s, t, reportErrors);
                    }
                    function signaturesIdenticalTo(source, target, kind) {
                        var sourceSignatures = getSignaturesOfType(source, kind);
                        var targetSignatures = getSignaturesOfType(target, kind);
                        if (sourceSignatures.length !== targetSignatures.length) {
                            return 0 /* False */;
                        }
                        var result = -1 /* True */;
                        for (var i = 0, len = sourceSignatures.length; i < len; ++i) {
                            var related = compareSignatures(sourceSignatures[i], targetSignatures[i], true, isRelatedTo);
                            if (!related) {
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                        return result;
                    }
                    function stringIndexTypesRelatedTo(source, target, reportErrors) {
                        if (relation === identityRelation) {
                            return indexTypesIdenticalTo(0 /* String */, source, target);
                        }
                        var targetType = getIndexTypeOfType(target, 0 /* String */);
                        if (targetType) {
                            var sourceType = getIndexTypeOfType(source, 0 /* String */);
                            if (!sourceType) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Index_signature_is_missing_in_type_0, typeToString(source));
                                }
                                return 0 /* False */;
                            }
                            var related = isRelatedTo(sourceType, targetType, reportErrors);
                            if (!related) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Index_signatures_are_incompatible);
                                }
                                return 0 /* False */;
                            }
                            return related;
                        }
                        return -1 /* True */;
                    }
                    function numberIndexTypesRelatedTo(source, target, reportErrors) {
                        if (relation === identityRelation) {
                            return indexTypesIdenticalTo(1 /* Number */, source, target);
                        }
                        var targetType = getIndexTypeOfType(target, 1 /* Number */);
                        if (targetType) {
                            var sourceStringType = getIndexTypeOfType(source, 0 /* String */);
                            var sourceNumberType = getIndexTypeOfType(source, 1 /* Number */);
                            if (!(sourceStringType || sourceNumberType)) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Index_signature_is_missing_in_type_0, typeToString(source));
                                }
                                return 0 /* False */;
                            }
                            if (sourceStringType && sourceNumberType) {
                                var related = isRelatedTo(sourceStringType, targetType, false) || isRelatedTo(sourceNumberType, targetType, reportErrors);
                            }
                            else {
                                var related = isRelatedTo(sourceStringType || sourceNumberType, targetType, reportErrors);
                            }
                            if (!related) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Index_signatures_are_incompatible);
                                }
                                return 0 /* False */;
                            }
                            return related;
                        }
                        return -1 /* True */;
                    }
                    function indexTypesIdenticalTo(indexKind, source, target) {
                        var targetType = getIndexTypeOfType(target, indexKind);
                        var sourceType = getIndexTypeOfType(source, indexKind);
                        if (!sourceType && !targetType) {
                            return -1 /* True */;
                        }
                        if (sourceType && targetType) {
                            return isRelatedTo(sourceType, targetType);
                        }
                        return 0 /* False */;
                    }
                }
                function isPropertyIdenticalTo(sourceProp, targetProp) {
                    return compareProperties(sourceProp, targetProp, compareTypes) !== 0 /* False */;
                }
                function compareProperties(sourceProp, targetProp, compareTypes) {
                    if (sourceProp === targetProp) {
                        return -1 /* True */;
                    }
                    var sourcePropAccessibility = getDeclarationFlagsFromSymbol(sourceProp) & (32 /* Private */ | 64 /* Protected */);
                    var targetPropAccessibility = getDeclarationFlagsFromSymbol(targetProp) & (32 /* Private */ | 64 /* Protected */);
                    if (sourcePropAccessibility !== targetPropAccessibility) {
                        return 0 /* False */;
                    }
                    if (sourcePropAccessibility) {
                        if (getTargetSymbol(sourceProp) !== getTargetSymbol(targetProp)) {
                            return 0 /* False */;
                        }
                    }
                    else {
                        if (isOptionalProperty(sourceProp) !== isOptionalProperty(targetProp)) {
                            return 0 /* False */;
                        }
                    }
                    return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
                }
                function compareSignatures(source, target, compareReturnTypes, compareTypes) {
                    if (source === target) {
                        return -1 /* True */;
                    }
                    if (source.parameters.length !== target.parameters.length || source.minArgumentCount !== target.minArgumentCount || source.hasRestParameter !== target.hasRestParameter) {
                        return 0 /* False */;
                    }
                    var result = -1 /* True */;
                    if (source.typeParameters && target.typeParameters) {
                        if (source.typeParameters.length !== target.typeParameters.length) {
                            return 0 /* False */;
                        }
                        for (var i = 0, len = source.typeParameters.length; i < len; ++i) {
                            var related = compareTypes(source.typeParameters[i], target.typeParameters[i]);
                            if (!related) {
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                    }
                    else if (source.typeParameters || source.typeParameters) {
                        return 0 /* False */;
                    }
                    source = getErasedSignature(source);
                    target = getErasedSignature(target);
                    for (var i = 0, len = source.parameters.length; i < len; i++) {
                        var s = source.hasRestParameter && i === len - 1 ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]);
                        var t = target.hasRestParameter && i === len - 1 ? getRestTypeOfSignature(target) : getTypeOfSymbol(target.parameters[i]);
                        var related = compareTypes(s, t);
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                    if (compareReturnTypes) {
                        result &= compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
                    }
                    return result;
                }
                function isSupertypeOfEach(candidate, types) {
                    for (var i = 0, len = types.length; i < len; i++) {
                        if (candidate !== types[i] && !isTypeSubtypeOf(types[i], candidate))
                            return false;
                    }
                    return true;
                }
                function getCommonSupertype(types) {
                    return ts.forEach(types, function (t) { return isSupertypeOfEach(t, types) ? t : undefined; });
                }
                function reportNoCommonSupertypeError(types, errorLocation, errorMessageChainHead) {
                    var bestSupertype;
                    var bestSupertypeDownfallType;
                    var bestSupertypeScore = 0;
                    for (var i = 0; i < types.length; i++) {
                        var score = 0;
                        var downfallType = undefined;
                        for (var j = 0; j < types.length; j++) {
                            if (isTypeSubtypeOf(types[j], types[i])) {
                                score++;
                            }
                            else if (!downfallType) {
                                downfallType = types[j];
                            }
                        }
                        if (score > bestSupertypeScore) {
                            bestSupertype = types[i];
                            bestSupertypeDownfallType = downfallType;
                            bestSupertypeScore = score;
                        }
                        if (bestSupertypeScore === types.length - 1) {
                            break;
                        }
                    }
                    checkTypeSubtypeOf(bestSupertypeDownfallType, bestSupertype, errorLocation, ts.Diagnostics.Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0, errorMessageChainHead);
                }
                function isTypeOfObjectLiteral(type) {
                    return (type.flags & 32768 /* Anonymous */) && type.symbol && (type.symbol.flags & 4096 /* ObjectLiteral */) ? true : false;
                }
                function isArrayType(type) {
                    return type.flags & 4096 /* Reference */ && type.target === globalArrayType;
                }
                function getInnermostTypeOfNestedArrayTypes(type) {
                    while (isArrayType(type)) {
                        type = type.typeArguments[0];
                    }
                    return type;
                }
                function getWidenedType(type, suppressNoImplicitAnyErrors) {
                    if (type.flags & (32 /* Undefined */ | 64 /* Null */)) {
                        return anyType;
                    }
                    if (type.flags & 16384 /* Union */) {
                        return getWidenedTypeOfUnion(type);
                    }
                    if (isTypeOfObjectLiteral(type)) {
                        return getWidenedTypeOfObjectLiteral(type);
                    }
                    if (isArrayType(type)) {
                        return getWidenedTypeOfArrayLiteral(type);
                    }
                    return type;
                    function getWidenedTypeOfUnion(type) {
                        return getUnionType(ts.map(type.types, function (t) { return getWidenedType(t, suppressNoImplicitAnyErrors); }));
                    }
                    function getWidenedTypeOfObjectLiteral(type) {
                        var properties = getPropertiesOfObjectType(type);
                        if (properties.length) {
                            var widenedTypes = [];
                            var propTypeWasWidened = false;
                            ts.forEach(properties, function (p) {
                                var propType = getTypeOfSymbol(p);
                                var widenedType = getWidenedType(propType);
                                if (propType !== widenedType) {
                                    propTypeWasWidened = true;
                                    if (!suppressNoImplicitAnyErrors && compilerOptions.noImplicitAny && getInnermostTypeOfNestedArrayTypes(widenedType) === anyType) {
                                        error(p.valueDeclaration, ts.Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(widenedType));
                                    }
                                }
                                widenedTypes.push(widenedType);
                            });
                            if (propTypeWasWidened) {
                                var members = {};
                                var index = 0;
                                ts.forEach(properties, function (p) {
                                    var symbol = createSymbol(4 /* Property */ | 268435456 /* Transient */ | p.flags, p.name);
                                    symbol.declarations = p.declarations;
                                    symbol.parent = p.parent;
                                    symbol.type = widenedTypes[index++];
                                    symbol.target = p;
                                    if (p.valueDeclaration)
                                        symbol.valueDeclaration = p.valueDeclaration;
                                    members[symbol.name] = symbol;
                                });
                                var stringIndexType = getIndexTypeOfType(type, 0 /* String */);
                                var numberIndexType = getIndexTypeOfType(type, 1 /* Number */);
                                if (stringIndexType)
                                    stringIndexType = getWidenedType(stringIndexType);
                                if (numberIndexType)
                                    numberIndexType = getWidenedType(numberIndexType);
                                type = createAnonymousType(type.symbol, members, emptyArray, emptyArray, stringIndexType, numberIndexType);
                            }
                        }
                        return type;
                    }
                    function getWidenedTypeOfArrayLiteral(type) {
                        var elementType = type.typeArguments[0];
                        var widenedType = getWidenedType(elementType, suppressNoImplicitAnyErrors);
                        type = elementType !== widenedType ? createArrayType(widenedType) : type;
                        return type;
                    }
                }
                function forEachMatchingParameterType(source, target, callback) {
                    var sourceMax = source.parameters.length;
                    var targetMax = target.parameters.length;
                    var count;
                    if (source.hasRestParameter && target.hasRestParameter) {
                        count = sourceMax > targetMax ? sourceMax : targetMax;
                        sourceMax--;
                        targetMax--;
                    }
                    else if (source.hasRestParameter) {
                        sourceMax--;
                        count = targetMax;
                    }
                    else if (target.hasRestParameter) {
                        targetMax--;
                        count = sourceMax;
                    }
                    else {
                        count = sourceMax < targetMax ? sourceMax : targetMax;
                    }
                    for (var i = 0; i < count; i++) {
                        var s = i < sourceMax ? getTypeOfSymbol(source.parameters[i]) : getRestTypeOfSignature(source);
                        var t = i < targetMax ? getTypeOfSymbol(target.parameters[i]) : getRestTypeOfSignature(target);
                        callback(s, t);
                    }
                }
                function createInferenceContext(typeParameters, inferUnionTypes) {
                    var inferences = [];
                    for (var i = 0; i < typeParameters.length; i++) {
                        inferences.push({ primary: undefined, secondary: undefined });
                    }
                    return {
                        typeParameters: typeParameters,
                        inferUnionTypes: inferUnionTypes,
                        inferenceCount: 0,
                        inferences: inferences,
                        inferredTypes: new Array(typeParameters.length)
                    };
                }
                function inferTypes(context, source, target) {
                    var sourceStack;
                    var targetStack;
                    var depth = 0;
                    var inferiority = 0;
                    inferFromTypes(source, target);
                    function isInProcess(source, target) {
                        for (var i = 0; i < depth; i++) {
                            if (source === sourceStack[i] && target === targetStack[i])
                                return true;
                        }
                        return false;
                    }
                    function isWithinDepthLimit(type, stack) {
                        if (depth >= 5) {
                            var target = type.target;
                            var count = 0;
                            for (var i = 0; i < depth; i++) {
                                var t = stack[i];
                                if (t.flags & 4096 /* Reference */ && t.target === target)
                                    count++;
                            }
                            return count < 5;
                        }
                        return true;
                    }
                    function inferFromTypes(source, target) {
                        if (target.flags & 512 /* TypeParameter */) {
                            var typeParameters = context.typeParameters;
                            for (var i = 0; i < typeParameters.length; i++) {
                                if (target === typeParameters[i]) {
                                    var inferences = context.inferences[i];
                                    var candidates = inferiority ? inferences.secondary || (inferences.secondary = []) : inferences.primary || (inferences.primary = []);
                                    if (!ts.contains(candidates, source))
                                        candidates.push(source);
                                    break;
                                }
                            }
                        }
                        else if (source.flags & 4096 /* Reference */ && target.flags & 4096 /* Reference */ && source.target === target.target) {
                            var sourceTypes = source.typeArguments;
                            var targetTypes = target.typeArguments;
                            for (var i = 0; i < sourceTypes.length; i++) {
                                inferFromTypes(sourceTypes[i], targetTypes[i]);
                            }
                        }
                        else if (target.flags & 16384 /* Union */) {
                            var targetTypes = target.types;
                            var typeParameterCount = 0;
                            var typeParameter;
                            for (var i = 0; i < targetTypes.length; i++) {
                                var t = targetTypes[i];
                                if (t.flags & 512 /* TypeParameter */ && ts.contains(context.typeParameters, t)) {
                                    typeParameter = t;
                                    typeParameterCount++;
                                }
                                else {
                                    inferFromTypes(source, t);
                                }
                            }
                            if (typeParameterCount === 1) {
                                inferiority++;
                                inferFromTypes(source, typeParameter);
                                inferiority--;
                            }
                        }
                        else if (source.flags & 16384 /* Union */) {
                            var sourceTypes = source.types;
                            for (var i = 0; i < sourceTypes.length; i++) {
                                inferFromTypes(sourceTypes[i], target);
                            }
                        }
                        else if (source.flags & 48128 /* ObjectType */ && (target.flags & (4096 /* Reference */ | 8192 /* Tuple */) || (target.flags & 32768 /* Anonymous */) && target.symbol && target.symbol.flags & (8192 /* Method */ | 2048 /* TypeLiteral */))) {
                            if (!isInProcess(source, target) && isWithinDepthLimit(source, sourceStack) && isWithinDepthLimit(target, targetStack)) {
                                if (depth === 0) {
                                    sourceStack = [];
                                    targetStack = [];
                                }
                                sourceStack[depth] = source;
                                targetStack[depth] = target;
                                depth++;
                                inferFromProperties(source, target);
                                inferFromSignatures(source, target, 0 /* Call */);
                                inferFromSignatures(source, target, 1 /* Construct */);
                                inferFromIndexTypes(source, target, 0 /* String */, 0 /* String */);
                                inferFromIndexTypes(source, target, 1 /* Number */, 1 /* Number */);
                                inferFromIndexTypes(source, target, 0 /* String */, 1 /* Number */);
                                depth--;
                            }
                        }
                    }
                    function inferFromProperties(source, target) {
                        var properties = getPropertiesOfObjectType(target);
                        for (var i = 0; i < properties.length; i++) {
                            var targetProp = properties[i];
                            var sourceProp = getPropertyOfObjectType(source, targetProp.name);
                            if (sourceProp) {
                                inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
                            }
                        }
                    }
                    function inferFromSignatures(source, target, kind) {
                        var sourceSignatures = getSignaturesOfType(source, kind);
                        var targetSignatures = getSignaturesOfType(target, kind);
                        var sourceLen = sourceSignatures.length;
                        var targetLen = targetSignatures.length;
                        var len = sourceLen < targetLen ? sourceLen : targetLen;
                        for (var i = 0; i < len; i++) {
                            inferFromSignature(getErasedSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i]));
                        }
                    }
                    function inferFromSignature(source, target) {
                        forEachMatchingParameterType(source, target, inferFromTypes);
                        inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
                    }
                    function inferFromIndexTypes(source, target, sourceKind, targetKind) {
                        var targetIndexType = getIndexTypeOfType(target, targetKind);
                        if (targetIndexType) {
                            var sourceIndexType = getIndexTypeOfType(source, sourceKind);
                            if (sourceIndexType) {
                                inferFromTypes(sourceIndexType, targetIndexType);
                            }
                        }
                    }
                }
                function getInferenceCandidates(context, index) {
                    var inferences = context.inferences[index];
                    return inferences.primary || inferences.secondary || emptyArray;
                }
                function getInferredType(context, index) {
                    var inferredType = context.inferredTypes[index];
                    if (!inferredType) {
                        var inferences = getInferenceCandidates(context, index);
                        if (inferences.length) {
                            var unionOrSuperType = context.inferUnionTypes ? getUnionType(inferences) : getCommonSupertype(inferences);
                            inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : inferenceFailureType;
                        }
                        else {
                            inferredType = emptyObjectType;
                        }
                        if (inferredType !== inferenceFailureType) {
                            var constraint = getConstraintOfTypeParameter(context.typeParameters[index]);
                            inferredType = constraint && !isTypeAssignableTo(inferredType, constraint) ? constraint : inferredType;
                        }
                        context.inferredTypes[index] = inferredType;
                    }
                    return inferredType;
                }
                function getInferredTypes(context) {
                    for (var i = 0; i < context.inferredTypes.length; i++) {
                        getInferredType(context, i);
                    }
                    return context.inferredTypes;
                }
                function hasAncestor(node, kind) {
                    return ts.getAncestor(node, kind) !== undefined;
                }
                function getResolvedSymbol(node) {
                    var links = getNodeLinks(node);
                    if (!links.resolvedSymbol) {
                        links.resolvedSymbol = resolveName(node, node.text, 107455 /* Value */ | 4194304 /* ExportValue */, ts.Diagnostics.Cannot_find_name_0, node) || unknownSymbol;
                    }
                    return links.resolvedSymbol;
                }
                function isInTypeQuery(node) {
                    while (node) {
                        switch (node.kind) {
                            case 136 /* TypeQuery */:
                                return true;
                            case 63 /* Identifier */:
                            case 121 /* QualifiedName */:
                                node = node.parent;
                                continue;
                            default:
                                return false;
                        }
                    }
                    ts.Debug.fail("should not get here");
                }
                function subtractPrimitiveTypes(type, subtractMask) {
                    if (type.flags & 16384 /* Union */) {
                        var types = type.types;
                        if (ts.forEach(types, function (t) { return t.flags & subtractMask; })) {
                            return getUnionType(ts.filter(types, function (t) { return !(t.flags & subtractMask); }));
                        }
                    }
                    return type;
                }
                function isVariableAssignedWithin(symbol, node) {
                    var links = getNodeLinks(node);
                    if (links.assignmentChecks) {
                        var cachedResult = links.assignmentChecks[symbol.id];
                        if (cachedResult !== undefined) {
                            return cachedResult;
                        }
                    }
                    else {
                        links.assignmentChecks = {};
                    }
                    return links.assignmentChecks[symbol.id] = isAssignedIn(node);
                    function isAssignedInBinaryExpression(node) {
                        if (node.operator >= 51 /* FirstAssignment */ && node.operator <= 62 /* LastAssignment */) {
                            var n = node.left;
                            while (n.kind === 152 /* ParenExpression */) {
                                n = n.expression;
                            }
                            if (n.kind === 63 /* Identifier */ && getResolvedSymbol(n) === symbol) {
                                return true;
                            }
                        }
                        return ts.forEachChild(node, isAssignedIn);
                    }
                    function isAssignedInVariableDeclaration(node) {
                        if (getSymbolOfNode(node) === symbol && node.initializer) {
                            return true;
                        }
                        return ts.forEachChild(node, isAssignedIn);
                    }
                    function isAssignedIn(node) {
                        switch (node.kind) {
                            case 157 /* BinaryExpression */:
                                return isAssignedInBinaryExpression(node);
                            case 186 /* VariableDeclaration */:
                                return isAssignedInVariableDeclaration(node);
                            case 142 /* ArrayLiteral */:
                            case 143 /* ObjectLiteral */:
                            case 146 /* PropertyAccess */:
                            case 147 /* IndexedAccess */:
                            case 148 /* CallExpression */:
                            case 149 /* NewExpression */:
                            case 151 /* TypeAssertion */:
                            case 152 /* ParenExpression */:
                            case 155 /* PrefixOperator */:
                            case 156 /* PostfixOperator */:
                            case 158 /* ConditionalExpression */:
                            case 163 /* Block */:
                            case 164 /* VariableStatement */:
                            case 166 /* ExpressionStatement */:
                            case 167 /* IfStatement */:
                            case 168 /* DoStatement */:
                            case 169 /* WhileStatement */:
                            case 170 /* ForStatement */:
                            case 171 /* ForInStatement */:
                            case 174 /* ReturnStatement */:
                            case 175 /* WithStatement */:
                            case 176 /* SwitchStatement */:
                            case 177 /* CaseClause */:
                            case 178 /* DefaultClause */:
                            case 179 /* LabeledStatement */:
                            case 180 /* ThrowStatement */:
                            case 181 /* TryStatement */:
                            case 182 /* TryBlock */:
                            case 183 /* CatchBlock */:
                            case 184 /* FinallyBlock */:
                                return ts.forEachChild(node, isAssignedIn);
                        }
                        return false;
                    }
                }
                function getNarrowedTypeOfSymbol(symbol, node) {
                    var type = getTypeOfSymbol(symbol);
                    if (node && (symbol.flags & 3 /* Variable */ && type.flags & 65025 /* Structured */)) {
                        loop: while (true) {
                            var child = node;
                            node = node.parent;
                            var narrowedType = type;
                            switch (node.kind) {
                                case 167 /* IfStatement */:
                                    if (child !== node.expression) {
                                        narrowedType = narrowType(type, node.expression, child === node.thenStatement);
                                    }
                                    break;
                                case 158 /* ConditionalExpression */:
                                    if (child !== node.condition) {
                                        narrowedType = narrowType(type, node.condition, child === node.whenTrue);
                                    }
                                    break;
                                case 157 /* BinaryExpression */:
                                    if (child === node.right) {
                                        if (node.operator === 47 /* AmpersandAmpersandToken */) {
                                            narrowedType = narrowType(type, node.left, true);
                                        }
                                        else if (node.operator === 48 /* BarBarToken */) {
                                            narrowedType = narrowType(type, node.left, false);
                                        }
                                    }
                                    break;
                                case 198 /* SourceFile */:
                                case 193 /* ModuleDeclaration */:
                                case 187 /* FunctionDeclaration */:
                                case 126 /* Method */:
                                case 128 /* GetAccessor */:
                                case 129 /* SetAccessor */:
                                case 127 /* Constructor */:
                                    break loop;
                            }
                            if (narrowedType !== type && isTypeSubtypeOf(narrowedType, type)) {
                                if (isVariableAssignedWithin(symbol, node)) {
                                    break;
                                }
                                type = narrowedType;
                            }
                        }
                    }
                    return type;
                    function narrowTypeByEquality(type, expr, assumeTrue) {
                        var left = expr.left;
                        var right = expr.right;
                        if (left.kind !== 155 /* PrefixOperator */ || left.operator !== 95 /* TypeOfKeyword */ || left.operand.kind !== 63 /* Identifier */ || right.kind !== 7 /* StringLiteral */ || getResolvedSymbol(left.operand) !== symbol) {
                            return type;
                        }
                        var t = right.text;
                        var checkType = t === "string" ? stringType : t === "number" ? numberType : t === "boolean" ? booleanType : emptyObjectType;
                        if (expr.operator === 30 /* ExclamationEqualsEqualsToken */) {
                            assumeTrue = !assumeTrue;
                        }
                        if (assumeTrue) {
                            return checkType === emptyObjectType ? subtractPrimitiveTypes(type, 2 /* String */ | 4 /* Number */ | 8 /* Boolean */) : checkType;
                        }
                        else {
                            return checkType === emptyObjectType ? type : subtractPrimitiveTypes(type, checkType.flags);
                        }
                    }
                    function narrowTypeByAnd(type, expr, assumeTrue) {
                        if (assumeTrue) {
                            return narrowType(narrowType(type, expr.left, true), expr.right, true);
                        }
                        else {
                            return getUnionType([
                                narrowType(type, expr.left, false),
                                narrowType(narrowType(type, expr.left, true), expr.right, false)
                            ]);
                        }
                    }
                    function narrowTypeByOr(type, expr, assumeTrue) {
                        if (assumeTrue) {
                            return getUnionType([
                                narrowType(type, expr.left, true),
                                narrowType(narrowType(type, expr.left, false), expr.right, true)
                            ]);
                        }
                        else {
                            return narrowType(narrowType(type, expr.left, false), expr.right, false);
                        }
                    }
                    function narrowTypeByInstanceof(type, expr, assumeTrue) {
                        if (!assumeTrue || expr.left.kind !== 63 /* Identifier */ || getResolvedSymbol(expr.left) !== symbol) {
                            return type;
                        }
                        var rightType = checkExpression(expr.right);
                        if (!isTypeSubtypeOf(rightType, globalFunctionType)) {
                            return type;
                        }
                        var prototypeProperty = getPropertyOfType(rightType, "prototype");
                        if (!prototypeProperty) {
                            return type;
                        }
                        var prototypeType = getTypeOfSymbol(prototypeProperty);
                        return isTypeSubtypeOf(prototypeType, type) ? prototypeType : type;
                    }
                    function narrowType(type, expr, assumeTrue) {
                        switch (expr.kind) {
                            case 152 /* ParenExpression */:
                                return narrowType(type, expr.expression, assumeTrue);
                            case 157 /* BinaryExpression */:
                                var operator = expr.operator;
                                if (operator === 29 /* EqualsEqualsEqualsToken */ || operator === 30 /* ExclamationEqualsEqualsToken */) {
                                    return narrowTypeByEquality(type, expr, assumeTrue);
                                }
                                else if (operator === 47 /* AmpersandAmpersandToken */) {
                                    return narrowTypeByAnd(type, expr, assumeTrue);
                                }
                                else if (operator === 48 /* BarBarToken */) {
                                    return narrowTypeByOr(type, expr, assumeTrue);
                                }
                                else if (operator === 85 /* InstanceOfKeyword */) {
                                    return narrowTypeByInstanceof(type, expr, assumeTrue);
                                }
                                break;
                            case 155 /* PrefixOperator */:
                                if (expr.operator === 45 /* ExclamationToken */) {
                                    return narrowType(type, expr.operand, !assumeTrue);
                                }
                                break;
                        }
                        return type;
                    }
                }
                function checkIdentifier(node) {
                    var symbol = getResolvedSymbol(node);
                    if (symbol.flags & 33554432 /* Import */) {
                        getSymbolLinks(symbol).referenced = getSymbolLinks(symbol).referenced || (!isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveImport(symbol)));
                    }
                    checkCollisionWithCapturedSuperVariable(node, node);
                    checkCollisionWithCapturedThisVariable(node, node);
                    checkCollisionWithIndexVariableInGeneratedCode(node, node);
                    return getNarrowedTypeOfSymbol(getExportSymbolOfValueSymbolIfExported(symbol), node);
                }
                function captureLexicalThis(node, container) {
                    var classNode = container.parent && container.parent.kind === 189 /* ClassDeclaration */ ? container.parent : undefined;
                    getNodeLinks(node).flags |= 2 /* LexicalThis */;
                    if (container.kind === 125 /* Property */ || container.kind === 127 /* Constructor */) {
                        getNodeLinks(classNode).flags |= 4 /* CaptureThis */;
                    }
                    else {
                        getNodeLinks(container).flags |= 4 /* CaptureThis */;
                    }
                }
                function checkThisExpression(node) {
                    var container = ts.getThisContainer(node, true);
                    var needToCaptureLexicalThis = false;
                    if (container.kind === 154 /* ArrowFunction */) {
                        container = ts.getThisContainer(container, false);
                        needToCaptureLexicalThis = true;
                    }
                    switch (container.kind) {
                        case 193 /* ModuleDeclaration */:
                            error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_module_body);
                            break;
                        case 192 /* EnumDeclaration */:
                            error(node, ts.Diagnostics.this_cannot_be_referenced_in_current_location);
                            break;
                        case 127 /* Constructor */:
                            if (isInConstructorArgumentInitializer(node, container)) {
                                error(node, ts.Diagnostics.this_cannot_be_referenced_in_constructor_arguments);
                            }
                            break;
                        case 125 /* Property */:
                            if (container.flags & 128 /* Static */) {
                                error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
                            }
                            break;
                    }
                    if (needToCaptureLexicalThis) {
                        captureLexicalThis(node, container);
                    }
                    var classNode = container.parent && container.parent.kind === 189 /* ClassDeclaration */ ? container.parent : undefined;
                    if (classNode) {
                        var symbol = getSymbolOfNode(classNode);
                        return container.flags & 128 /* Static */ ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol);
                    }
                    return anyType;
                }
                function getSuperContainer(node) {
                    while (true) {
                        node = node.parent;
                        if (!node)
                            return node;
                        switch (node.kind) {
                            case 187 /* FunctionDeclaration */:
                            case 153 /* FunctionExpression */:
                            case 154 /* ArrowFunction */:
                            case 125 /* Property */:
                            case 126 /* Method */:
                            case 127 /* Constructor */:
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                                return node;
                        }
                    }
                }
                function isInConstructorArgumentInitializer(node, constructorDecl) {
                    for (var n = node; n && n !== constructorDecl; n = n.parent) {
                        if (n.kind === 124 /* Parameter */) {
                            return true;
                        }
                    }
                    return false;
                }
                function checkSuperExpression(node) {
                    var isCallExpression = node.parent.kind === 148 /* CallExpression */ && node.parent.func === node;
                    var enclosingClass = ts.getAncestor(node, 189 /* ClassDeclaration */);
                    var baseClass;
                    if (enclosingClass && enclosingClass.baseType) {
                        var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingClass));
                        baseClass = classType.baseTypes.length && classType.baseTypes[0];
                    }
                    if (!baseClass) {
                        error(node, ts.Diagnostics.super_can_only_be_referenced_in_a_derived_class);
                        return unknownType;
                    }
                    var container = getSuperContainer(node);
                    if (container) {
                        var canUseSuperExpression = false;
                        if (isCallExpression) {
                            canUseSuperExpression = container.kind === 127 /* Constructor */;
                        }
                        else {
                            var needToCaptureLexicalThis = false;
                            while (container && container.kind === 154 /* ArrowFunction */) {
                                container = getSuperContainer(container);
                                needToCaptureLexicalThis = true;
                            }
                            if (container && container.parent && container.parent.kind === 189 /* ClassDeclaration */) {
                                if (container.flags & 128 /* Static */) {
                                    canUseSuperExpression = container.kind === 126 /* Method */ || container.kind === 128 /* GetAccessor */ || container.kind === 129 /* SetAccessor */;
                                }
                                else {
                                    canUseSuperExpression = container.kind === 126 /* Method */ || container.kind === 128 /* GetAccessor */ || container.kind === 129 /* SetAccessor */ || container.kind === 125 /* Property */ || container.kind === 127 /* Constructor */;
                                }
                            }
                        }
                        if (canUseSuperExpression) {
                            var returnType;
                            if ((container.flags & 128 /* Static */) || isCallExpression) {
                                getNodeLinks(node).flags |= 32 /* SuperStatic */;
                                returnType = getTypeOfSymbol(baseClass.symbol);
                            }
                            else {
                                getNodeLinks(node).flags |= 16 /* SuperInstance */;
                                returnType = baseClass;
                            }
                            if (container.kind === 127 /* Constructor */ && isInConstructorArgumentInitializer(node, container)) {
                                error(node, ts.Diagnostics.super_cannot_be_referenced_in_constructor_arguments);
                                returnType = unknownType;
                            }
                            if (!isCallExpression && needToCaptureLexicalThis) {
                                captureLexicalThis(node.parent, container);
                            }
                            return returnType;
                        }
                    }
                    if (isCallExpression) {
                        error(node, ts.Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors);
                    }
                    else {
                        error(node, ts.Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class);
                    }
                    return unknownType;
                }
                function getContextuallyTypedParameterType(parameter) {
                    var func = parameter.parent;
                    if (func.kind === 153 /* FunctionExpression */ || func.kind === 154 /* ArrowFunction */) {
                        if (isContextSensitiveExpression(func)) {
                            var contextualSignature = getContextualSignature(func);
                            if (contextualSignature) {
                                var funcHasRestParameters = ts.hasRestParameters(func);
                                var len = func.parameters.length - (funcHasRestParameters ? 1 : 0);
                                var indexOfParameter = ts.indexOf(func.parameters, parameter);
                                if (indexOfParameter < len) {
                                    return getTypeAtPosition(contextualSignature, indexOfParameter);
                                }
                                if (indexOfParameter === (func.parameters.length - 1) && funcHasRestParameters && contextualSignature.hasRestParameter && func.parameters.length >= contextualSignature.parameters.length) {
                                    return getTypeOfSymbol(contextualSignature.parameters[contextualSignature.parameters.length - 1]);
                                }
                            }
                        }
                    }
                    return undefined;
                }
                function getContextualTypeForInitializerExpression(node) {
                    var declaration = node.parent;
                    if (node === declaration.initializer) {
                        if (declaration.type) {
                            return getTypeFromTypeNode(declaration.type);
                        }
                        if (declaration.kind === 124 /* Parameter */) {
                            return getContextuallyTypedParameterType(declaration);
                        }
                    }
                    return undefined;
                }
                function getContextualTypeForReturnExpression(node) {
                    var func = ts.getContainingFunction(node);
                    if (func) {
                        if (func.type || func.kind === 127 /* Constructor */ || func.kind === 128 /* GetAccessor */ && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(func.symbol, 129 /* SetAccessor */))) {
                            return getReturnTypeOfSignature(getSignatureFromDeclaration(func));
                        }
                        var signature = getContextualSignature(func);
                        if (signature) {
                            return getReturnTypeOfSignature(signature);
                        }
                    }
                    return undefined;
                }
                function getContextualTypeForArgument(node) {
                    var callExpression = node.parent;
                    var argIndex = ts.indexOf(callExpression.arguments, node);
                    if (argIndex >= 0) {
                        var signature = getResolvedSignature(callExpression);
                        return getTypeAtPosition(signature, argIndex);
                    }
                    return undefined;
                }
                function getContextualTypeForBinaryOperand(node) {
                    var binaryExpression = node.parent;
                    var operator = binaryExpression.operator;
                    if (operator >= 51 /* FirstAssignment */ && operator <= 62 /* LastAssignment */) {
                        if (node === binaryExpression.right) {
                            return checkExpression(binaryExpression.left);
                        }
                    }
                    else if (operator === 48 /* BarBarToken */) {
                        var type = getContextualType(binaryExpression);
                        if (!type && node === binaryExpression.right) {
                            type = checkExpression(binaryExpression.left);
                        }
                        return type;
                    }
                    return undefined;
                }
                function applyToContextualType(type, mapper) {
                    if (!(type.flags & 16384 /* Union */)) {
                        return mapper(type);
                    }
                    var types = type.types;
                    var mappedType;
                    var mappedTypes;
                    for (var i = 0; i < types.length; i++) {
                        var t = mapper(types[i]);
                        if (t) {
                            if (!mappedType) {
                                mappedType = t;
                            }
                            else if (!mappedTypes) {
                                mappedTypes = [mappedType, t];
                            }
                            else {
                                mappedTypes.push(t);
                            }
                        }
                    }
                    return mappedTypes ? getUnionType(mappedTypes) : mappedType;
                }
                function getTypeOfPropertyOfContextualType(type, name) {
                    return applyToContextualType(type, function (t) {
                        var prop = getPropertyOfObjectType(t, name);
                        return prop ? getTypeOfSymbol(prop) : undefined;
                    });
                }
                function getIndexTypeOfContextualType(type, kind) {
                    return applyToContextualType(type, function (t) { return getIndexTypeOfObjectOrUnionType(t, kind); });
                }
                function contextualTypeIsTupleType(type) {
                    return !!(type.flags & 16384 /* Union */ ? ts.forEach(type.types, function (t) { return getPropertyOfObjectType(t, "0"); }) : getPropertyOfObjectType(type, "0"));
                }
                function contextualTypeHasIndexSignature(type, kind) {
                    return !!(type.flags & 16384 /* Union */ ? ts.forEach(type.types, function (t) { return getIndexTypeOfObjectOrUnionType(t, kind); }) : getIndexTypeOfObjectOrUnionType(type, kind));
                }
                function getContextualTypeForPropertyExpression(node) {
                    var declaration = node.parent;
                    var objectLiteral = declaration.parent;
                    var type = getContextualType(objectLiteral);
                    var name = declaration.name.text;
                    if (type && name) {
                        return getTypeOfPropertyOfContextualType(type, name) || isNumericName(name) && getIndexTypeOfContextualType(type, 1 /* Number */) || getIndexTypeOfContextualType(type, 0 /* String */);
                    }
                    return undefined;
                }
                function getContextualTypeForElementExpression(node) {
                    var arrayLiteral = node.parent;
                    var type = getContextualType(arrayLiteral);
                    if (type) {
                        var index = ts.indexOf(arrayLiteral.elements, node);
                        return getTypeOfPropertyOfContextualType(type, "" + index) || getIndexTypeOfContextualType(type, 1 /* Number */);
                    }
                    return undefined;
                }
                function getContextualTypeForConditionalOperand(node) {
                    var conditional = node.parent;
                    return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined;
                }
                function getContextualType(node) {
                    if (isInsideWithStatementBody(node)) {
                        return undefined;
                    }
                    if (node.contextualType) {
                        return node.contextualType;
                    }
                    var parent = node.parent;
                    switch (parent.kind) {
                        case 186 /* VariableDeclaration */:
                        case 124 /* Parameter */:
                        case 125 /* Property */:
                            return getContextualTypeForInitializerExpression(node);
                        case 154 /* ArrowFunction */:
                        case 174 /* ReturnStatement */:
                            return getContextualTypeForReturnExpression(node);
                        case 148 /* CallExpression */:
                        case 149 /* NewExpression */:
                            return getContextualTypeForArgument(node);
                        case 151 /* TypeAssertion */:
                            return getTypeFromTypeNode(parent.type);
                        case 157 /* BinaryExpression */:
                            return getContextualTypeForBinaryOperand(node);
                        case 144 /* PropertyAssignment */:
                            return getContextualTypeForPropertyExpression(node);
                        case 142 /* ArrayLiteral */:
                            return getContextualTypeForElementExpression(node);
                        case 158 /* ConditionalExpression */:
                            return getContextualTypeForConditionalOperand(node);
                    }
                    return undefined;
                }
                function getNonGenericSignature(type) {
                    var signatures = getSignaturesOfObjectOrUnionType(type, 0 /* Call */);
                    if (signatures.length === 1) {
                        var signature = signatures[0];
                        if (!signature.typeParameters) {
                            return signature;
                        }
                    }
                }
                function getContextualSignature(node) {
                    var type = getContextualType(node);
                    if (!type) {
                        return undefined;
                    }
                    if (!(type.flags & 16384 /* Union */)) {
                        return getNonGenericSignature(type);
                    }
                    var signatureList;
                    var types = type.types;
                    for (var i = 0; i < types.length; i++) {
                        if (signatureList && getSignaturesOfObjectOrUnionType(types[i], 0 /* Call */).length > 1) {
                            return undefined;
                        }
                        var signature = getNonGenericSignature(types[i]);
                        if (signature) {
                            if (!signatureList) {
                                signatureList = [signature];
                            }
                            else if (!compareSignatures(signatureList[0], signature, false, compareTypes)) {
                                return undefined;
                            }
                            else {
                                signatureList.push(signature);
                            }
                        }
                    }
                    var result;
                    if (signatureList) {
                        result = cloneSignature(signatureList[0]);
                        result.resolvedReturnType = undefined;
                        result.unionSignatures = signatureList;
                    }
                    return result;
                }
                function isInferentialContext(mapper) {
                    return mapper && mapper !== identityMapper;
                }
                function checkArrayLiteral(node, contextualMapper) {
                    var elements = node.elements;
                    if (!elements.length) {
                        return createArrayType(undefinedType);
                    }
                    var elementTypes = ts.map(elements, function (e) { return checkExpression(e, contextualMapper); });
                    var contextualType = getContextualType(node);
                    if (contextualType && contextualTypeIsTupleType(contextualType)) {
                        return createTupleType(elementTypes);
                    }
                    return createArrayType(getUnionType(elementTypes));
                }
                function isNumericName(name) {
                    return (+name).toString() === name;
                }
                function checkObjectLiteral(node, contextualMapper) {
                    var members = node.symbol.members;
                    var properties = {};
                    var contextualType = getContextualType(node);
                    for (var id in members) {
                        if (ts.hasProperty(members, id)) {
                            var member = members[id];
                            if (member.flags & 4 /* Property */) {
                                var memberDecl = member.declarations[0];
                                var type;
                                if (memberDecl.kind === 144 /* PropertyAssignment */) {
                                    type = checkExpression(memberDecl.initializer, contextualMapper);
                                }
                                else {
                                    ts.Debug.assert(memberDecl.kind === 145 /* ShorthandPropertyAssignment */);
                                    type = checkExpression(memberDecl.name, contextualMapper);
                                }
                                var prop = createSymbol(4 /* Property */ | 268435456 /* Transient */ | member.flags, member.name);
                                prop.declarations = member.declarations;
                                prop.parent = member.parent;
                                if (member.valueDeclaration)
                                    prop.valueDeclaration = member.valueDeclaration;
                                prop.type = type;
                                prop.target = member;
                                member = prop;
                            }
                            else {
                                var getAccessor = getDeclarationOfKind(member, 128 /* GetAccessor */);
                                if (getAccessor) {
                                    checkAccessorDeclaration(getAccessor);
                                }
                                var setAccessor = getDeclarationOfKind(member, 129 /* SetAccessor */);
                                if (setAccessor) {
                                    checkAccessorDeclaration(setAccessor);
                                }
                            }
                            properties[member.name] = member;
                        }
                    }
                    var stringIndexType = getIndexType(0 /* String */);
                    var numberIndexType = getIndexType(1 /* Number */);
                    return createAnonymousType(node.symbol, properties, emptyArray, emptyArray, stringIndexType, numberIndexType);
                    function getIndexType(kind) {
                        if (contextualType && contextualTypeHasIndexSignature(contextualType, kind)) {
                            var propTypes = [];
                            for (var id in properties) {
                                if (ts.hasProperty(properties, id)) {
                                    if (kind === 0 /* String */ || isNumericName(id)) {
                                        var type = getTypeOfSymbol(properties[id]);
                                        if (!ts.contains(propTypes, type)) {
                                            propTypes.push(type);
                                        }
                                    }
                                }
                            }
                            return propTypes.length ? getUnionType(propTypes) : undefinedType;
                        }
                        return undefined;
                    }
                }
                function getDeclarationKindFromSymbol(s) {
                    return s.valueDeclaration ? s.valueDeclaration.kind : 125 /* Property */;
                }
                function getDeclarationFlagsFromSymbol(s) {
                    return s.valueDeclaration ? s.valueDeclaration.flags : s.flags & 536870912 /* Prototype */ ? 16 /* Public */ | 128 /* Static */ : 0;
                }
                function checkClassPropertyAccess(node, type, prop) {
                    var flags = getDeclarationFlagsFromSymbol(prop);
                    if (!(flags & (32 /* Private */ | 64 /* Protected */))) {
                        return;
                    }
                    var enclosingClassDeclaration = ts.getAncestor(node, 189 /* ClassDeclaration */);
                    var enclosingClass = enclosingClassDeclaration ? getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingClassDeclaration)) : undefined;
                    var declaringClass = getDeclaredTypeOfSymbol(prop.parent);
                    if (flags & 32 /* Private */) {
                        if (declaringClass !== enclosingClass) {
                            error(node, ts.Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(declaringClass));
                        }
                        return;
                    }
                    if (node.left.kind === 89 /* SuperKeyword */) {
                        return;
                    }
                    if (!enclosingClass || !hasBaseType(enclosingClass, declaringClass)) {
                        error(node, ts.Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(declaringClass));
                        return;
                    }
                    if (flags & 128 /* Static */) {
                        return;
                    }
                    if (!(getTargetType(type).flags & (1024 /* Class */ | 2048 /* Interface */) && hasBaseType(type, enclosingClass))) {
                        error(node, ts.Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
                    }
                }
                function checkPropertyAccess(node) {
                    var type = checkExpression(node.left);
                    if (type === unknownType)
                        return type;
                    if (type !== anyType) {
                        var apparentType = getApparentType(getWidenedType(type));
                        if (apparentType === unknownType) {
                            return unknownType;
                        }
                        var prop = getPropertyOfType(apparentType, node.right.text);
                        if (!prop) {
                            if (node.right.text) {
                                error(node.right, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(node.right), typeToString(type));
                            }
                            return unknownType;
                        }
                        getNodeLinks(node).resolvedSymbol = prop;
                        if (prop.parent && prop.parent.flags & 32 /* Class */) {
                            if (node.left.kind === 89 /* SuperKeyword */ && getDeclarationKindFromSymbol(prop) !== 126 /* Method */) {
                                error(node.right, ts.Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
                            }
                            else {
                                checkClassPropertyAccess(node, type, prop);
                            }
                        }
                        return getTypeOfSymbol(prop);
                    }
                    return anyType;
                }
                function isValidPropertyAccess(node, propertyName) {
                    var type = checkExpression(node.left);
                    if (type !== unknownType && type !== anyType) {
                        var prop = getPropertyOfType(getWidenedType(type), propertyName);
                        if (prop && prop.parent && prop.parent.flags & 32 /* Class */) {
                            if (node.left.kind === 89 /* SuperKeyword */ && getDeclarationKindFromSymbol(prop) !== 126 /* Method */) {
                                return false;
                            }
                            else {
                                var diagnosticsCount = diagnostics.length;
                                checkClassPropertyAccess(node, type, prop);
                                return diagnostics.length === diagnosticsCount;
                            }
                        }
                    }
                    return true;
                }
                function checkIndexedAccess(node) {
                    var objectType = getApparentType(checkExpression(node.object));
                    var indexType = checkExpression(node.index);
                    if (objectType === unknownType)
                        return unknownType;
                    if (isConstEnumObjectType(objectType) && node.index.kind !== 7 /* StringLiteral */) {
                        error(node.index, ts.Diagnostics.Index_expression_arguments_in_const_enums_must_be_of_type_string);
                    }
                    if (node.index.kind === 7 /* StringLiteral */ || node.index.kind === 6 /* NumericLiteral */) {
                        var name = node.index.text;
                        var prop = getPropertyOfType(objectType, name);
                        if (prop) {
                            getNodeLinks(node).resolvedSymbol = prop;
                            return getTypeOfSymbol(prop);
                        }
                    }
                    if (indexType.flags & (1 /* Any */ | 258 /* StringLike */ | 132 /* NumberLike */)) {
                        if (indexType.flags & (1 /* Any */ | 132 /* NumberLike */)) {
                            var numberIndexType = getIndexTypeOfType(objectType, 1 /* Number */);
                            if (numberIndexType) {
                                return numberIndexType;
                            }
                        }
                        var stringIndexType = getIndexTypeOfType(objectType, 0 /* String */);
                        if (stringIndexType) {
                            return stringIndexType;
                        }
                        if (compilerOptions.noImplicitAny && objectType !== anyType) {
                            error(node, ts.Diagnostics.Index_signature_of_object_type_implicitly_has_an_any_type);
                        }
                        return anyType;
                    }
                    error(node, ts.Diagnostics.An_index_expression_argument_must_be_of_type_string_number_or_any);
                    return unknownType;
                }
                function resolveUntypedCall(node) {
                    if (node.kind === 150 /* TaggedTemplateExpression */) {
                        checkExpression(node.template);
                    }
                    else {
                        ts.forEach(node.arguments, function (argument) {
                            checkExpression(argument);
                        });
                    }
                    return anySignature;
                }
                function resolveErrorCall(node) {
                    resolveUntypedCall(node);
                    return unknownSignature;
                }
                function hasCorrectArity(node, args, signature) {
                    var adjustedArgCount;
                    var typeArguments;
                    var callIsIncomplete;
                    if (node.kind === 150 /* TaggedTemplateExpression */) {
                        var tagExpression = node;
                        adjustedArgCount = args.length;
                        typeArguments = undefined;
                        if (tagExpression.template.kind === 159 /* TemplateExpression */) {
                            var templateExpression = tagExpression.template;
                            var lastSpan = ts.lastOrUndefined(templateExpression.templateSpans);
                            ts.Debug.assert(lastSpan !== undefined);
                            callIsIncomplete = lastSpan.literal.kind === 120 /* Missing */ || ts.isUnterminatedTemplateEnd(lastSpan.literal);
                        }
                        else {
                            var templateLiteral = tagExpression.template;
                            ts.Debug.assert(templateLiteral.kind === 9 /* NoSubstitutionTemplateLiteral */);
                            callIsIncomplete = ts.isUnterminatedTemplateEnd(templateLiteral);
                        }
                    }
                    else {
                        var callExpression = node;
                        if (!callExpression.arguments) {
                            ts.Debug.assert(callExpression.kind === 149 /* NewExpression */);
                            return signature.minArgumentCount === 0;
                        }
                        adjustedArgCount = callExpression.arguments.hasTrailingComma ? args.length + 1 : args.length;
                        callIsIncomplete = callExpression.arguments.end === callExpression.end;
                        typeArguments = callExpression.typeArguments;
                    }
                    ts.Debug.assert(adjustedArgCount !== undefined, "'adjustedArgCount' undefined");
                    ts.Debug.assert(callIsIncomplete !== undefined, "'callIsIncomplete' undefined");
                    return checkArity(adjustedArgCount, typeArguments, callIsIncomplete, signature);
                    function checkArity(adjustedArgCount, typeArguments, callIsIncomplete, signature) {
                        if (!signature.hasRestParameter && adjustedArgCount > signature.parameters.length) {
                            return false;
                        }
                        var hasRightNumberOfTypeArgs = !typeArguments || (signature.typeParameters && typeArguments.length === signature.typeParameters.length);
                        if (!hasRightNumberOfTypeArgs) {
                            return false;
                        }
                        var hasEnoughArguments = adjustedArgCount >= signature.minArgumentCount;
                        return callIsIncomplete || hasEnoughArguments;
                    }
                }
                function getSingleCallSignature(type) {
                    if (type.flags & 48128 /* ObjectType */) {
                        var resolved = resolveObjectOrUnionTypeMembers(type);
                        if (resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0 && resolved.properties.length === 0 && !resolved.stringIndexType && !resolved.numberIndexType) {
                            return resolved.callSignatures[0];
                        }
                    }
                    return undefined;
                }
                function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper) {
                    var context = createInferenceContext(signature.typeParameters, true);
                    forEachMatchingParameterType(contextualSignature, signature, function (source, target) {
                        inferTypes(context, instantiateType(source, contextualMapper), target);
                    });
                    return getSignatureInstantiation(signature, getInferredTypes(context));
                }
                function inferTypeArguments(signature, args, excludeArgument) {
                    var typeParameters = signature.typeParameters;
                    var context = createInferenceContext(typeParameters, false);
                    var mapper = createInferenceMapper(context);
                    for (var i = 0; i < args.length; i++) {
                        if (args[i].kind === 162 /* OmittedExpression */) {
                            continue;
                        }
                        if (!excludeArgument || excludeArgument[i] === undefined) {
                            var parameterType = getTypeAtPosition(signature, i);
                            if (i === 0 && args[i].parent.kind === 150 /* TaggedTemplateExpression */) {
                                inferTypes(context, globalTemplateStringsArrayType, parameterType);
                                continue;
                            }
                            inferTypes(context, checkExpressionWithContextualType(args[i], parameterType, mapper), parameterType);
                        }
                    }
                    if (excludeArgument) {
                        for (var i = 0; i < args.length; i++) {
                            if (args[i].kind === 162 /* OmittedExpression */) {
                                continue;
                            }
                            if (excludeArgument[i] === false) {
                                var parameterType = getTypeAtPosition(signature, i);
                                inferTypes(context, checkExpressionWithContextualType(args[i], parameterType, mapper), parameterType);
                            }
                        }
                    }
                    var inferredTypes = getInferredTypes(context);
                    context.failedTypeParameterIndex = ts.indexOf(inferredTypes, inferenceFailureType);
                    for (var i = 0; i < inferredTypes.length; i++) {
                        if (inferredTypes[i] === inferenceFailureType) {
                            inferredTypes[i] = unknownType;
                        }
                    }
                    return context;
                }
                function checkTypeArguments(signature, typeArguments, typeArgumentResultTypes, reportErrors) {
                    var typeParameters = signature.typeParameters;
                    var typeArgumentsAreAssignable = true;
                    for (var i = 0; i < typeParameters.length; i++) {
                        var typeArgNode = typeArguments[i];
                        var typeArgument = getTypeFromTypeNode(typeArgNode);
                        typeArgumentResultTypes[i] = typeArgument;
                        if (typeArgumentsAreAssignable) {
                            var constraint = getConstraintOfTypeParameter(typeParameters[i]);
                            if (constraint) {
                                typeArgumentsAreAssignable = checkTypeAssignableTo(typeArgument, constraint, reportErrors ? typeArgNode : undefined, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
                            }
                        }
                    }
                    return typeArgumentsAreAssignable;
                }
                function checkApplicableSignature(node, args, signature, relation, excludeArgument, reportErrors) {
                    for (var i = 0; i < args.length; i++) {
                        var arg = args[i];
                        var argType;
                        if (arg.kind === 162 /* OmittedExpression */) {
                            continue;
                        }
                        var paramType = getTypeAtPosition(signature, i);
                        if (i === 0 && node.kind === 150 /* TaggedTemplateExpression */) {
                            argType = globalTemplateStringsArrayType;
                        }
                        else {
                            argType = arg.kind === 7 /* StringLiteral */ && !reportErrors ? getStringLiteralType(arg) : checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
                        }
                        var isValidArgument = checkTypeRelatedTo(argType, paramType, relation, reportErrors ? arg : undefined, ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1);
                        if (!isValidArgument) {
                            return false;
                        }
                    }
                    return true;
                }
                function getEffectiveCallArguments(node) {
                    var args;
                    if (node.kind === 150 /* TaggedTemplateExpression */) {
                        var template = node.template;
                        args = [template];
                        if (template.kind === 159 /* TemplateExpression */) {
                            ts.forEach(template.templateSpans, function (span) {
                                args.push(span.expression);
                            });
                        }
                    }
                    else {
                        args = node.arguments || emptyArray;
                    }
                    return args;
                }
                function resolveCall(node, signatures, candidatesOutArray) {
                    var isTaggedTemplate = node.kind === 150 /* TaggedTemplateExpression */;
                    var typeArguments = isTaggedTemplate ? undefined : node.typeArguments;
                    ts.forEach(typeArguments, checkSourceElement);
                    var candidates = candidatesOutArray || [];
                    collectCandidates();
                    if (!candidates.length) {
                        error(node, ts.Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target);
                        return resolveErrorCall(node);
                    }
                    var args = getEffectiveCallArguments(node);
                    var excludeArgument;
                    for (var i = isTaggedTemplate ? 1 : 0; i < args.length; i++) {
                        if (isContextSensitiveExpression(args[i])) {
                            if (!excludeArgument) {
                                excludeArgument = new Array(args.length);
                            }
                            excludeArgument[i] = true;
                        }
                    }
                    var candidateForArgumentError;
                    var candidateForTypeArgumentError;
                    var resultOfFailedInference;
                    var result;
                    if (candidates.length > 1) {
                        result = chooseOverload(candidates, subtypeRelation);
                    }
                    if (!result) {
                        candidateForArgumentError = undefined;
                        candidateForTypeArgumentError = undefined;
                        resultOfFailedInference = undefined;
                        result = chooseOverload(candidates, assignableRelation);
                    }
                    if (result) {
                        return result;
                    }
                    if (candidateForArgumentError) {
                        checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, undefined, true);
                    }
                    else if (candidateForTypeArgumentError) {
                        if (!isTaggedTemplate && node.typeArguments) {
                            checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, [], true);
                        }
                        else {
                            ts.Debug.assert(resultOfFailedInference.failedTypeParameterIndex >= 0);
                            var failedTypeParameter = candidateForTypeArgumentError.typeParameters[resultOfFailedInference.failedTypeParameterIndex];
                            var inferenceCandidates = getInferenceCandidates(resultOfFailedInference, resultOfFailedInference.failedTypeParameterIndex);
                            var diagnosticChainHead = ts.chainDiagnosticMessages(undefined, ts.Diagnostics.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly, typeToString(failedTypeParameter));
                            reportNoCommonSupertypeError(inferenceCandidates, node.func || node.tag, diagnosticChainHead);
                        }
                    }
                    else {
                        error(node, ts.Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target);
                    }
                    if (!fullTypeCheck) {
                        for (var i = 0, n = candidates.length; i < n; i++) {
                            if (hasCorrectArity(node, args, candidates[i])) {
                                return candidates[i];
                            }
                        }
                    }
                    return resolveErrorCall(node);
                    function chooseOverload(candidates, relation) {
                        for (var i = 0; i < candidates.length; i++) {
                            if (!hasCorrectArity(node, args, candidates[i])) {
                                continue;
                            }
                            var originalCandidate = candidates[i];
                            var inferenceResult;
                            while (true) {
                                var candidate = originalCandidate;
                                if (candidate.typeParameters) {
                                    var typeArgumentTypes;
                                    var typeArgumentsAreValid;
                                    if (typeArguments) {
                                        typeArgumentTypes = new Array(candidate.typeParameters.length);
                                        typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, false);
                                    }
                                    else {
                                        inferenceResult = inferTypeArguments(candidate, args, excludeArgument);
                                        typeArgumentsAreValid = inferenceResult.failedTypeParameterIndex < 0;
                                        typeArgumentTypes = inferenceResult.inferredTypes;
                                    }
                                    if (!typeArgumentsAreValid) {
                                        break;
                                    }
                                    candidate = getSignatureInstantiation(candidate, typeArgumentTypes);
                                }
                                if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, false)) {
                                    break;
                                }
                                var index = excludeArgument ? ts.indexOf(excludeArgument, true) : -1;
                                if (index < 0) {
                                    return candidate;
                                }
                                excludeArgument[index] = false;
                            }
                            if (originalCandidate.typeParameters) {
                                var instantiatedCandidate = candidate;
                                if (typeArgumentsAreValid) {
                                    candidateForArgumentError = instantiatedCandidate;
                                }
                                else {
                                    candidateForTypeArgumentError = originalCandidate;
                                    if (!typeArguments) {
                                        resultOfFailedInference = inferenceResult;
                                    }
                                }
                            }
                            else {
                                ts.Debug.assert(originalCandidate === candidate);
                                candidateForArgumentError = originalCandidate;
                            }
                        }
                        return undefined;
                    }
                    function collectCandidates() {
                        var result = candidates;
                        var lastParent;
                        var lastSymbol;
                        var cutoffPos = 0;
                        var pos;
                        ts.Debug.assert(!result.length);
                        for (var i = 0; i < signatures.length; i++) {
                            var signature = signatures[i];
                            var symbol = signature.declaration && getSymbolOfNode(signature.declaration);
                            var parent = signature.declaration && signature.declaration.parent;
                            if (!lastSymbol || symbol === lastSymbol) {
                                if (lastParent && parent === lastParent) {
                                    pos++;
                                }
                                else {
                                    lastParent = parent;
                                    pos = cutoffPos;
                                }
                            }
                            else {
                                pos = cutoffPos = result.length;
                                lastParent = parent;
                            }
                            lastSymbol = symbol;
                            for (var j = result.length; j > pos; j--) {
                                result[j] = result[j - 1];
                            }
                            result[pos] = signature;
                        }
                    }
                }
                function resolveCallExpression(node, candidatesOutArray) {
                    if (node.func.kind === 89 /* SuperKeyword */) {
                        var superType = checkSuperExpression(node.func);
                        if (superType !== unknownType) {
                            return resolveCall(node, getSignaturesOfType(superType, 1 /* Construct */), candidatesOutArray);
                        }
                        return resolveUntypedCall(node);
                    }
                    var funcType = checkExpression(node.func);
                    var apparentType = getApparentType(funcType);
                    if (apparentType === unknownType) {
                        return resolveErrorCall(node);
                    }
                    var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
                    var constructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */);
                    if (funcType === anyType || (!callSignatures.length && !constructSignatures.length && !(funcType.flags & 16384 /* Union */) && isTypeAssignableTo(funcType, globalFunctionType))) {
                        if (node.typeArguments) {
                            error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
                        }
                        return resolveUntypedCall(node);
                    }
                    if (!callSignatures.length) {
                        if (constructSignatures.length) {
                            error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
                        }
                        else {
                            error(node, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature);
                        }
                        return resolveErrorCall(node);
                    }
                    return resolveCall(node, callSignatures, candidatesOutArray);
                }
                function resolveNewExpression(node, candidatesOutArray) {
                    var expressionType = checkExpression(node.func);
                    if (expressionType === anyType) {
                        if (node.typeArguments) {
                            error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
                        }
                        return resolveUntypedCall(node);
                    }
                    expressionType = getApparentType(expressionType);
                    if (expressionType === unknownType) {
                        return resolveErrorCall(node);
                    }
                    var constructSignatures = getSignaturesOfType(expressionType, 1 /* Construct */);
                    if (constructSignatures.length) {
                        return resolveCall(node, constructSignatures, candidatesOutArray);
                    }
                    var callSignatures = getSignaturesOfType(expressionType, 0 /* Call */);
                    if (callSignatures.length) {
                        var signature = resolveCall(node, callSignatures, candidatesOutArray);
                        if (getReturnTypeOfSignature(signature) !== voidType) {
                            error(node, ts.Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
                        }
                        return signature;
                    }
                    error(node, ts.Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature);
                    return resolveErrorCall(node);
                }
                function resolveTaggedTemplateExpression(node, candidatesOutArray) {
                    var tagType = checkExpression(node.tag);
                    var apparentType = getApparentType(tagType);
                    if (apparentType === unknownType) {
                        return resolveErrorCall(node);
                    }
                    var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
                    if (tagType === anyType || (!callSignatures.length && !(tagType.flags & 16384 /* Union */) && isTypeAssignableTo(tagType, globalFunctionType))) {
                        return resolveUntypedCall(node);
                    }
                    if (!callSignatures.length) {
                        error(node, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature);
                        return resolveErrorCall(node);
                    }
                    return resolveCall(node, callSignatures, candidatesOutArray);
                }
                function getResolvedSignature(node, candidatesOutArray) {
                    var links = getNodeLinks(node);
                    if (!links.resolvedSignature || candidatesOutArray) {
                        links.resolvedSignature = anySignature;
                        if (node.kind === 148 /* CallExpression */) {
                            links.resolvedSignature = resolveCallExpression(node, candidatesOutArray);
                        }
                        else if (node.kind === 149 /* NewExpression */) {
                            links.resolvedSignature = resolveNewExpression(node, candidatesOutArray);
                        }
                        else if (node.kind === 150 /* TaggedTemplateExpression */) {
                            links.resolvedSignature = resolveTaggedTemplateExpression(node, candidatesOutArray);
                        }
                        else {
                            ts.Debug.fail("Branch in 'getResolvedSignature' should be unreachable.");
                        }
                    }
                    return links.resolvedSignature;
                }
                function checkCallExpression(node) {
                    var signature = getResolvedSignature(node);
                    if (node.func.kind === 89 /* SuperKeyword */) {
                        return voidType;
                    }
                    if (node.kind === 149 /* NewExpression */) {
                        var declaration = signature.declaration;
                        if (declaration && declaration.kind !== 127 /* Constructor */ && declaration.kind !== 131 /* ConstructSignature */ && declaration.kind !== 135 /* ConstructorType */) {
                            if (compilerOptions.noImplicitAny) {
                                error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                            }
                            return anyType;
                        }
                    }
                    return getReturnTypeOfSignature(signature);
                }
                function checkTaggedTemplateExpression(node) {
                    return getReturnTypeOfSignature(getResolvedSignature(node));
                }
                function checkTypeAssertion(node) {
                    var exprType = checkExpression(node.operand);
                    var targetType = getTypeFromTypeNode(node.type);
                    if (fullTypeCheck && targetType !== unknownType) {
                        var widenedType = getWidenedType(exprType, true);
                        if (!(isTypeAssignableTo(targetType, widenedType))) {
                            checkTypeAssignableTo(exprType, targetType, node, ts.Diagnostics.Neither_type_0_nor_type_1_is_assignable_to_the_other);
                        }
                    }
                    return targetType;
                }
                function getTypeAtPosition(signature, pos) {
                    return signature.hasRestParameter ? pos < signature.parameters.length - 1 ? getTypeOfSymbol(signature.parameters[pos]) : getRestTypeOfSignature(signature) : pos < signature.parameters.length ? getTypeOfSymbol(signature.parameters[pos]) : anyType;
                }
                function assignContextualParameterTypes(signature, context, mapper) {
                    var len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
                    for (var i = 0; i < len; i++) {
                        var parameter = signature.parameters[i];
                        var links = getSymbolLinks(parameter);
                        links.type = instantiateType(getTypeAtPosition(context, i), mapper);
                    }
                    if (signature.hasRestParameter && context.hasRestParameter && signature.parameters.length >= context.parameters.length) {
                        var parameter = signature.parameters[signature.parameters.length - 1];
                        var links = getSymbolLinks(parameter);
                        links.type = instantiateType(getTypeOfSymbol(context.parameters[context.parameters.length - 1]), mapper);
                    }
                }
                function getReturnTypeFromBody(func, contextualMapper) {
                    var contextualSignature = getContextualSignature(func);
                    if (func.body.kind !== 188 /* FunctionBlock */) {
                        var unwidenedType = checkAndMarkExpression(func.body, contextualMapper);
                        var widenedType = getWidenedType(unwidenedType);
                        if (fullTypeCheck && compilerOptions.noImplicitAny && !contextualSignature && widenedType !== unwidenedType && getInnermostTypeOfNestedArrayTypes(widenedType) === anyType) {
                            error(func, ts.Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeToString(widenedType));
                        }
                        return widenedType;
                    }
                    var types = checkAndAggregateReturnExpressionTypes(func.body, contextualMapper);
                    if (types.length > 0) {
                        var commonType = contextualSignature ? getUnionType(types) : getCommonSupertype(types);
                        if (!commonType) {
                            error(func, ts.Diagnostics.No_best_common_type_exists_among_return_expressions);
                            return unknownType;
                        }
                        var widenedType = getWidenedType(commonType);
                        if (fullTypeCheck && compilerOptions.noImplicitAny && !contextualSignature && widenedType !== commonType && getInnermostTypeOfNestedArrayTypes(widenedType) === anyType) {
                            var typeName = typeToString(widenedType);
                            if (func.name) {
                                error(func, ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type, ts.declarationNameToString(func.name), typeName);
                            }
                            else {
                                error(func, ts.Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeName);
                            }
                        }
                        return widenedType;
                    }
                    return voidType;
                }
                function checkAndAggregateReturnExpressionTypes(body, contextualMapper) {
                    var aggregatedTypes = [];
                    ts.forEachReturnStatement(body, function (returnStatement) {
                        var expr = returnStatement.expression;
                        if (expr) {
                            var type = checkAndMarkExpression(expr, contextualMapper);
                            if (!ts.contains(aggregatedTypes, type)) {
                                aggregatedTypes.push(type);
                            }
                        }
                    });
                    return aggregatedTypes;
                }
                function bodyContainsAReturnStatement(funcBody) {
                    return ts.forEachReturnStatement(funcBody, function (returnStatement) {
                        return true;
                    });
                }
                function bodyContainsSingleThrowStatement(body) {
                    return (body.statements.length === 1) && (body.statements[0].kind === 180 /* ThrowStatement */);
                }
                function checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(func, returnType) {
                    if (!fullTypeCheck) {
                        return;
                    }
                    if (returnType === voidType || returnType === anyType) {
                        return;
                    }
                    if (!func.body || func.body.kind !== 188 /* FunctionBlock */) {
                        return;
                    }
                    var bodyBlock = func.body;
                    if (bodyContainsAReturnStatement(bodyBlock)) {
                        return;
                    }
                    if (bodyContainsSingleThrowStatement(bodyBlock)) {
                        return;
                    }
                    error(func.type, ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_or_consist_of_a_single_throw_statement);
                }
                function checkFunctionExpression(node, contextualMapper) {
                    if (contextualMapper === identityMapper) {
                        return anyFunctionType;
                    }
                    var links = getNodeLinks(node);
                    var type = getTypeOfSymbol(node.symbol);
                    if (!(links.flags & 64 /* ContextChecked */)) {
                        var contextualSignature = getContextualSignature(node);
                        if (!(links.flags & 64 /* ContextChecked */)) {
                            links.flags |= 64 /* ContextChecked */;
                            if (contextualSignature) {
                                var signature = getSignaturesOfType(type, 0 /* Call */)[0];
                                if (isContextSensitiveExpression(node)) {
                                    assignContextualParameterTypes(signature, contextualSignature, contextualMapper || identityMapper);
                                }
                                if (!node.type) {
                                    signature.resolvedReturnType = resolvingType;
                                    var returnType = getReturnTypeFromBody(node, contextualMapper);
                                    if (signature.resolvedReturnType === resolvingType) {
                                        signature.resolvedReturnType = returnType;
                                    }
                                }
                            }
                            checkSignatureDeclaration(node);
                        }
                    }
                    if (fullTypeCheck) {
                        checkCollisionWithCapturedSuperVariable(node, node.name);
                        checkCollisionWithCapturedThisVariable(node, node.name);
                    }
                    return type;
                }
                function checkFunctionExpressionBody(node) {
                    if (node.type) {
                        checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type));
                    }
                    if (node.body.kind === 188 /* FunctionBlock */) {
                        checkSourceElement(node.body);
                    }
                    else {
                        var exprType = checkExpression(node.body);
                        if (node.type) {
                            checkTypeAssignableTo(exprType, getTypeFromTypeNode(node.type), node.body, undefined);
                        }
                        checkFunctionExpressionBodies(node.body);
                    }
                }
                function checkArithmeticOperandType(operand, type, diagnostic) {
                    if (!(type.flags & (1 /* Any */ | 132 /* NumberLike */))) {
                        error(operand, diagnostic);
                        return false;
                    }
                    return true;
                }
                function checkReferenceExpression(n, invalidReferenceMessage, constantVarianleMessage) {
                    function findSymbol(n) {
                        var symbol = getNodeLinks(n).resolvedSymbol;
                        return symbol && getExportSymbolOfValueSymbolIfExported(symbol);
                    }
                    function isReferenceOrErrorExpression(n) {
                        switch (n.kind) {
                            case 63 /* Identifier */:
                                var symbol = findSymbol(n);
                                return !symbol || symbol === unknownSymbol || symbol === argumentsSymbol || (symbol.flags & 3 /* Variable */) !== 0;
                            case 146 /* PropertyAccess */:
                                var symbol = findSymbol(n);
                                return !symbol || symbol === unknownSymbol || (symbol.flags & ~8 /* EnumMember */) !== 0;
                            case 147 /* IndexedAccess */:
                                return true;
                            case 152 /* ParenExpression */:
                                return isReferenceOrErrorExpression(n.expression);
                            default:
                                return false;
                        }
                    }
                    function isConstVariableReference(n) {
                        switch (n.kind) {
                            case 63 /* Identifier */:
                            case 146 /* PropertyAccess */:
                                var symbol = findSymbol(n);
                                return symbol && (symbol.flags & 3 /* Variable */) !== 0 && (getDeclarationFlagsFromSymbol(symbol) & 4096 /* Const */) !== 0;
                            case 147 /* IndexedAccess */:
                                var index = n.index;
                                var symbol = findSymbol(n.object);
                                if (symbol && index.kind === 7 /* StringLiteral */) {
                                    var name = index.text;
                                    var prop = getPropertyOfType(getTypeOfSymbol(symbol), name);
                                    return prop && (prop.flags & 3 /* Variable */) !== 0 && (getDeclarationFlagsFromSymbol(prop) & 4096 /* Const */) !== 0;
                                }
                                return false;
                            case 152 /* ParenExpression */:
                                return isConstVariableReference(n.expression);
                            default:
                                return false;
                        }
                    }
                    if (!isReferenceOrErrorExpression(n)) {
                        error(n, invalidReferenceMessage);
                        return false;
                    }
                    if (isConstVariableReference(n)) {
                        error(n, constantVarianleMessage);
                        return false;
                    }
                    return true;
                }
                function checkPrefixExpression(node) {
                    var operandType = checkExpression(node.operand);
                    switch (node.operator) {
                        case 32 /* PlusToken */:
                        case 33 /* MinusToken */:
                        case 46 /* TildeToken */:
                            return numberType;
                        case 45 /* ExclamationToken */:
                        case 72 /* DeleteKeyword */:
                            return booleanType;
                        case 95 /* TypeOfKeyword */:
                            return stringType;
                        case 97 /* VoidKeyword */:
                            return undefinedType;
                        case 37 /* PlusPlusToken */:
                        case 38 /* MinusMinusToken */:
                            var ok = checkArithmeticOperandType(node.operand, operandType, ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
                            if (ok) {
                                checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant);
                            }
                            return numberType;
                    }
                    return unknownType;
                }
                function checkPostfixExpression(node) {
                    var operandType = checkExpression(node.operand);
                    var ok = checkArithmeticOperandType(node.operand, operandType, ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type);
                    if (ok) {
                        checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant);
                    }
                    return numberType;
                }
                function isStructuredType(type) {
                    if (type.flags & 16384 /* Union */) {
                        return !ts.forEach(type.types, function (t) { return !isStructuredType(t); });
                    }
                    return (type.flags & 65025 /* Structured */) !== 0;
                }
                function isConstEnumObjectType(type) {
                    return type.flags & (48128 /* ObjectType */ | 32768 /* Anonymous */) && type.symbol && isConstEnumSymbol(type.symbol);
                }
                function isConstEnumSymbol(symbol) {
                    return (symbol.flags & 128 /* ConstEnum */) !== 0;
                }
                function checkInstanceOfExpression(node, leftType, rightType) {
                    if (leftType !== unknownType && !isStructuredType(leftType)) {
                        error(node.left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
                    }
                    if (rightType !== unknownType && rightType !== anyType && !isTypeSubtypeOf(rightType, globalFunctionType)) {
                        error(node.right, ts.Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type);
                    }
                    return booleanType;
                }
                function checkInExpression(node, leftType, rightType) {
                    if (leftType !== anyType && leftType !== stringType && leftType !== numberType) {
                        error(node.left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number);
                    }
                    if (!isStructuredType(rightType)) {
                        error(node.right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
                    }
                    return booleanType;
                }
                function checkBinaryExpression(node, contextualMapper) {
                    var operator = node.operator;
                    var leftType = checkExpression(node.left, contextualMapper);
                    var rightType = checkExpression(node.right, contextualMapper);
                    switch (operator) {
                        case 34 /* AsteriskToken */:
                        case 54 /* AsteriskEqualsToken */:
                        case 35 /* SlashToken */:
                        case 55 /* SlashEqualsToken */:
                        case 36 /* PercentToken */:
                        case 56 /* PercentEqualsToken */:
                        case 33 /* MinusToken */:
                        case 53 /* MinusEqualsToken */:
                        case 39 /* LessThanLessThanToken */:
                        case 57 /* LessThanLessThanEqualsToken */:
                        case 40 /* GreaterThanGreaterThanToken */:
                        case 58 /* GreaterThanGreaterThanEqualsToken */:
                        case 41 /* GreaterThanGreaterThanGreaterThanToken */:
                        case 59 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                        case 43 /* BarToken */:
                        case 61 /* BarEqualsToken */:
                        case 44 /* CaretToken */:
                        case 62 /* CaretEqualsToken */:
                        case 42 /* AmpersandToken */:
                        case 60 /* AmpersandEqualsToken */:
                            if (leftType.flags & (32 /* Undefined */ | 64 /* Null */))
                                leftType = rightType;
                            if (rightType.flags & (32 /* Undefined */ | 64 /* Null */))
                                rightType = leftType;
                            var suggestedOperator;
                            if ((leftType.flags & 8 /* Boolean */) && (rightType.flags & 8 /* Boolean */) && (suggestedOperator = getSuggestedBooleanOperator(node.operator)) !== undefined) {
                                error(node, ts.Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, ts.tokenToString(node.operator), ts.tokenToString(suggestedOperator));
                            }
                            else {
                                var leftOk = checkArithmeticOperandType(node.left, leftType, ts.Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
                                var rightOk = checkArithmeticOperandType(node.right, rightType, ts.Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
                                if (leftOk && rightOk) {
                                    checkAssignmentOperator(numberType);
                                }
                            }
                            return numberType;
                        case 32 /* PlusToken */:
                        case 52 /* PlusEqualsToken */:
                            if (leftType.flags & (32 /* Undefined */ | 64 /* Null */))
                                leftType = rightType;
                            if (rightType.flags & (32 /* Undefined */ | 64 /* Null */))
                                rightType = leftType;
                            var resultType;
                            if (leftType.flags & 132 /* NumberLike */ && rightType.flags & 132 /* NumberLike */) {
                                resultType = numberType;
                            }
                            else if (leftType.flags & 258 /* StringLike */ || rightType.flags & 258 /* StringLike */) {
                                resultType = stringType;
                            }
                            else if (leftType.flags & 1 /* Any */ || leftType === unknownType || rightType.flags & 1 /* Any */ || rightType === unknownType) {
                                resultType = anyType;
                            }
                            if (!resultType) {
                                reportOperatorError();
                                return anyType;
                            }
                            if (operator === 52 /* PlusEqualsToken */) {
                                checkAssignmentOperator(resultType);
                            }
                            return resultType;
                        case 27 /* EqualsEqualsToken */:
                        case 28 /* ExclamationEqualsToken */:
                        case 29 /* EqualsEqualsEqualsToken */:
                        case 30 /* ExclamationEqualsEqualsToken */:
                        case 23 /* LessThanToken */:
                        case 24 /* GreaterThanToken */:
                        case 25 /* LessThanEqualsToken */:
                        case 26 /* GreaterThanEqualsToken */:
                            if (!isTypeAssignableTo(leftType, rightType) && !isTypeAssignableTo(rightType, leftType)) {
                                reportOperatorError();
                            }
                            return booleanType;
                        case 85 /* InstanceOfKeyword */:
                            return checkInstanceOfExpression(node, leftType, rightType);
                        case 84 /* InKeyword */:
                            return checkInExpression(node, leftType, rightType);
                        case 47 /* AmpersandAmpersandToken */:
                            return rightType;
                        case 48 /* BarBarToken */:
                            return getUnionType([leftType, rightType]);
                        case 51 /* EqualsToken */:
                            checkAssignmentOperator(rightType);
                            return rightType;
                        case 22 /* CommaToken */:
                            return rightType;
                    }
                    function getSuggestedBooleanOperator(operator) {
                        switch (operator) {
                            case 43 /* BarToken */:
                            case 61 /* BarEqualsToken */:
                                return 48 /* BarBarToken */;
                            case 44 /* CaretToken */:
                            case 62 /* CaretEqualsToken */:
                                return 30 /* ExclamationEqualsEqualsToken */;
                            case 42 /* AmpersandToken */:
                            case 60 /* AmpersandEqualsToken */:
                                return 47 /* AmpersandAmpersandToken */;
                            default:
                                return undefined;
                        }
                    }
                    function checkAssignmentOperator(valueType) {
                        if (fullTypeCheck && operator >= 51 /* FirstAssignment */ && operator <= 62 /* LastAssignment */) {
                            var ok = checkReferenceExpression(node.left, ts.Diagnostics.Invalid_left_hand_side_of_assignment_expression, ts.Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant);
                            if (ok) {
                                checkTypeAssignableTo(valueType, leftType, node.left, undefined);
                            }
                        }
                    }
                    function reportOperatorError() {
                        error(node, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(node.operator), typeToString(leftType), typeToString(rightType));
                    }
                }
                function checkConditionalExpression(node, contextualMapper) {
                    checkExpression(node.condition);
                    var type1 = checkExpression(node.whenTrue, contextualMapper);
                    var type2 = checkExpression(node.whenFalse, contextualMapper);
                    return getUnionType([type1, type2]);
                }
                function checkTemplateExpression(node) {
                    ts.forEach(node.templateSpans, function (templateSpan) {
                        checkExpression(templateSpan.expression);
                    });
                    return stringType;
                }
                function checkExpressionWithContextualType(node, contextualType, contextualMapper) {
                    var saveContextualType = node.contextualType;
                    node.contextualType = contextualType;
                    var result = checkExpression(node, contextualMapper);
                    node.contextualType = saveContextualType;
                    return result;
                }
                function checkAndMarkExpression(node, contextualMapper) {
                    var result = checkExpression(node, contextualMapper);
                    getNodeLinks(node).flags |= 1 /* TypeChecked */;
                    return result;
                }
                function checkExpression(node, contextualMapper) {
                    var type = checkExpressionNode(node, contextualMapper);
                    if (contextualMapper && contextualMapper !== identityMapper) {
                        var signature = getSingleCallSignature(type);
                        if (signature && signature.typeParameters) {
                            var contextualType = getContextualType(node);
                            if (contextualType) {
                                var contextualSignature = getSingleCallSignature(contextualType);
                                if (contextualSignature && !contextualSignature.typeParameters) {
                                    type = getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper));
                                }
                            }
                        }
                    }
                    if (isConstEnumObjectType(type)) {
                        var ok = (node.parent.kind === 146 /* PropertyAccess */ && node.parent.left === node) || (node.parent.kind === 147 /* IndexedAccess */ && node.parent.object === node) || ((node.kind === 63 /* Identifier */ || node.kind === 121 /* QualifiedName */) && isInRightSideOfImportOrExportAssignment(node));
                        if (!ok) {
                            error(node, ts.Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment);
                        }
                    }
                    return type;
                }
                function checkExpressionNode(node, contextualMapper) {
                    switch (node.kind) {
                        case 63 /* Identifier */:
                            return checkIdentifier(node);
                        case 91 /* ThisKeyword */:
                            return checkThisExpression(node);
                        case 89 /* SuperKeyword */:
                            return checkSuperExpression(node);
                        case 87 /* NullKeyword */:
                            return nullType;
                        case 93 /* TrueKeyword */:
                        case 78 /* FalseKeyword */:
                            return booleanType;
                        case 6 /* NumericLiteral */:
                            return numberType;
                        case 159 /* TemplateExpression */:
                            return checkTemplateExpression(node);
                        case 7 /* StringLiteral */:
                        case 9 /* NoSubstitutionTemplateLiteral */:
                            return stringType;
                        case 8 /* RegularExpressionLiteral */:
                            return globalRegExpType;
                        case 121 /* QualifiedName */:
                            return checkPropertyAccess(node);
                        case 142 /* ArrayLiteral */:
                            return checkArrayLiteral(node, contextualMapper);
                        case 143 /* ObjectLiteral */:
                            return checkObjectLiteral(node, contextualMapper);
                        case 146 /* PropertyAccess */:
                            return checkPropertyAccess(node);
                        case 147 /* IndexedAccess */:
                            return checkIndexedAccess(node);
                        case 148 /* CallExpression */:
                        case 149 /* NewExpression */:
                            return checkCallExpression(node);
                        case 150 /* TaggedTemplateExpression */:
                            return checkTaggedTemplateExpression(node);
                        case 151 /* TypeAssertion */:
                            return checkTypeAssertion(node);
                        case 152 /* ParenExpression */:
                            return checkExpression(node.expression);
                        case 153 /* FunctionExpression */:
                        case 154 /* ArrowFunction */:
                            return checkFunctionExpression(node, contextualMapper);
                        case 155 /* PrefixOperator */:
                            return checkPrefixExpression(node);
                        case 156 /* PostfixOperator */:
                            return checkPostfixExpression(node);
                        case 157 /* BinaryExpression */:
                            return checkBinaryExpression(node, contextualMapper);
                        case 158 /* ConditionalExpression */:
                            return checkConditionalExpression(node, contextualMapper);
                        case 162 /* OmittedExpression */:
                            return undefinedType;
                    }
                    return unknownType;
                }
                function checkTypeParameter(node) {
                    checkSourceElement(node.constraint);
                    if (fullTypeCheck) {
                        checkTypeParameterHasIllegalReferencesInConstraint(node);
                        checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_parameter_name_cannot_be_0);
                    }
                }
                function checkParameter(parameterDeclaration) {
                    checkVariableDeclaration(parameterDeclaration);
                    if (fullTypeCheck) {
                        checkCollisionWithIndexVariableInGeneratedCode(parameterDeclaration, parameterDeclaration.name);
                        if (parameterDeclaration.flags & (16 /* Public */ | 32 /* Private */ | 64 /* Protected */) && !(parameterDeclaration.parent.kind === 127 /* Constructor */ && parameterDeclaration.parent.body)) {
                            error(parameterDeclaration, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
                        }
                        if (parameterDeclaration.flags & 8 /* Rest */) {
                            if (!isArrayType(getTypeOfSymbol(parameterDeclaration.symbol))) {
                                error(parameterDeclaration, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type);
                            }
                        }
                        else {
                            if (parameterDeclaration.initializer && !parameterDeclaration.parent.body) {
                                error(parameterDeclaration, ts.Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation);
                            }
                        }
                    }
                    function checkReferencesInInitializer(n) {
                        if (n.kind === 63 /* Identifier */) {
                            var referencedSymbol = getNodeLinks(n).resolvedSymbol;
                            if (referencedSymbol && referencedSymbol !== unknownSymbol && getSymbol(parameterDeclaration.parent.locals, referencedSymbol.name, 107455 /* Value */) === referencedSymbol) {
                                if (referencedSymbol.valueDeclaration.kind === 124 /* Parameter */) {
                                    if (referencedSymbol.valueDeclaration === parameterDeclaration) {
                                        error(n, ts.Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, ts.declarationNameToString(parameterDeclaration.name));
                                        return;
                                    }
                                    var enclosingOrReferencedParameter = ts.forEach(parameterDeclaration.parent.parameters, function (p) { return p === parameterDeclaration || p === referencedSymbol.valueDeclaration ? p : undefined; });
                                    if (enclosingOrReferencedParameter === referencedSymbol.valueDeclaration) {
                                        return;
                                    }
                                }
                                error(n, ts.Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, ts.declarationNameToString(parameterDeclaration.name), ts.declarationNameToString(n));
                            }
                        }
                        else {
                            ts.forEachChild(n, checkReferencesInInitializer);
                        }
                    }
                    if (parameterDeclaration.initializer) {
                        checkReferencesInInitializer(parameterDeclaration.initializer);
                    }
                }
                function checkSignatureDeclaration(node) {
                    checkTypeParameters(node.typeParameters);
                    ts.forEach(node.parameters, checkParameter);
                    if (node.type) {
                        checkSourceElement(node.type);
                    }
                    if (fullTypeCheck) {
                        checkCollisionWithArgumentsInGeneratedCode(node);
                        if (compilerOptions.noImplicitAny && !node.type) {
                            switch (node.kind) {
                                case 131 /* ConstructSignature */:
                                    error(node, ts.Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                                    break;
                                case 130 /* CallSignature */:
                                    error(node, ts.Diagnostics.Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                                    break;
                            }
                        }
                    }
                    checkSpecializedSignatureDeclaration(node);
                }
                function checkTypeForDuplicateIndexSignatures(node) {
                    if (node.kind === 190 /* InterfaceDeclaration */) {
                        var nodeSymbol = getSymbolOfNode(node);
                        if (nodeSymbol.declarations.length > 0 && nodeSymbol.declarations[0] !== node) {
                            return;
                        }
                    }
                    var indexSymbol = getIndexSymbol(getSymbolOfNode(node));
                    if (indexSymbol) {
                        var seenNumericIndexer = false;
                        var seenStringIndexer = false;
                        for (var i = 0, len = indexSymbol.declarations.length; i < len; ++i) {
                            var declaration = indexSymbol.declarations[i];
                            if (declaration.parameters.length == 1 && declaration.parameters[0].type) {
                                switch (declaration.parameters[0].type.kind) {
                                    case 118 /* StringKeyword */:
                                        if (!seenStringIndexer) {
                                            seenStringIndexer = true;
                                        }
                                        else {
                                            error(declaration, ts.Diagnostics.Duplicate_string_index_signature);
                                        }
                                        break;
                                    case 116 /* NumberKeyword */:
                                        if (!seenNumericIndexer) {
                                            seenNumericIndexer = true;
                                        }
                                        else {
                                            error(declaration, ts.Diagnostics.Duplicate_number_index_signature);
                                        }
                                        break;
                                }
                            }
                        }
                    }
                }
                function checkPropertyDeclaration(node) {
                    if (fullTypeCheck) {
                        checkVariableOrPropertyInFullTypeCheck(node);
                    }
                }
                function checkMethodDeclaration(node) {
                    checkFunctionLikeDeclaration(node);
                }
                function checkConstructorDeclaration(node) {
                    checkSignatureDeclaration(node);
                    checkSourceElement(node.body);
                    var symbol = getSymbolOfNode(node);
                    var firstDeclaration = getDeclarationOfKind(symbol, node.kind);
                    if (node === firstDeclaration) {
                        checkFunctionOrConstructorSymbol(symbol);
                    }
                    if (!node.body) {
                        return;
                    }
                    if (!fullTypeCheck) {
                        return;
                    }
                    function isSuperCallExpression(n) {
                        return n.kind === 148 /* CallExpression */ && n.func.kind === 89 /* SuperKeyword */;
                    }
                    function containsSuperCall(n) {
                        if (isSuperCallExpression(n)) {
                            return true;
                        }
                        switch (n.kind) {
                            case 153 /* FunctionExpression */:
                            case 187 /* FunctionDeclaration */:
                            case 154 /* ArrowFunction */:
                            case 143 /* ObjectLiteral */: return false;
                            default: return ts.forEachChild(n, containsSuperCall);
                        }
                    }
                    function markThisReferencesAsErrors(n) {
                        if (n.kind === 91 /* ThisKeyword */) {
                            error(n, ts.Diagnostics.this_cannot_be_referenced_in_current_location);
                        }
                        else if (n.kind !== 153 /* FunctionExpression */ && n.kind !== 187 /* FunctionDeclaration */) {
                            ts.forEachChild(n, markThisReferencesAsErrors);
                        }
                    }
                    function isInstancePropertyWithInitializer(n) {
                        return n.kind === 125 /* Property */ && !(n.flags & 128 /* Static */) && !!n.initializer;
                    }
                    if (node.parent.baseType) {
                        if (containsSuperCall(node.body)) {
                            var superCallShouldBeFirst = ts.forEach(node.parent.members, isInstancePropertyWithInitializer) || ts.forEach(node.parameters, function (p) { return p.flags & (16 /* Public */ | 32 /* Private */ | 64 /* Protected */); });
                            if (superCallShouldBeFirst) {
                                var statements = node.body.statements;
                                if (!statements.length || statements[0].kind !== 166 /* ExpressionStatement */ || !isSuperCallExpression(statements[0].expression)) {
                                    error(node, ts.Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties);
                                }
                                else {
                                    markThisReferencesAsErrors(statements[0].expression);
                                }
                            }
                        }
                        else {
                            error(node, ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call);
                        }
                    }
                }
                function checkAccessorDeclaration(node) {
                    if (fullTypeCheck) {
                        if (node.kind === 128 /* GetAccessor */) {
                            if (!ts.isInAmbientContext(node) && node.body && !(bodyContainsAReturnStatement(node.body) || bodyContainsSingleThrowStatement(node.body))) {
                                error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value_or_consist_of_a_single_throw_statement);
                            }
                        }
                        if (!ts.hasComputedNameButNotSymbol(node)) {
                            var otherKind = node.kind === 128 /* GetAccessor */ ? 129 /* SetAccessor */ : 128 /* GetAccessor */;
                            var otherAccessor = getDeclarationOfKind(node.symbol, otherKind);
                            if (otherAccessor) {
                                if (((node.flags & 112 /* AccessibilityModifier */) !== (otherAccessor.flags & 112 /* AccessibilityModifier */))) {
                                    error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
                                }
                                var currentAccessorType = getAnnotatedAccessorType(node);
                                var otherAccessorType = getAnnotatedAccessorType(otherAccessor);
                                if (currentAccessorType && otherAccessorType) {
                                    if (!isTypeIdenticalTo(currentAccessorType, otherAccessorType)) {
                                        error(node, ts.Diagnostics.get_and_set_accessor_must_have_the_same_type);
                                    }
                                }
                            }
                            checkAndStoreTypeOfAccessors(getSymbolOfNode(node));
                        }
                    }
                    checkFunctionLikeDeclaration(node);
                }
                function checkTypeReference(node) {
                    var type = getTypeFromTypeReferenceNode(node);
                    if (type !== unknownType && node.typeArguments) {
                        var len = node.typeArguments.length;
                        for (var i = 0; i < len; i++) {
                            checkSourceElement(node.typeArguments[i]);
                            var constraint = getConstraintOfTypeParameter(type.target.typeParameters[i]);
                            if (fullTypeCheck && constraint) {
                                var typeArgument = type.typeArguments[i];
                                checkTypeAssignableTo(typeArgument, constraint, node, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
                            }
                        }
                    }
                }
                function checkTypeQuery(node) {
                    getTypeFromTypeQueryNode(node);
                }
                function checkTypeLiteral(node) {
                    ts.forEach(node.members, checkSourceElement);
                    if (fullTypeCheck) {
                        var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                        checkIndexConstraints(type);
                        checkTypeForDuplicateIndexSignatures(node);
                    }
                }
                function checkArrayType(node) {
                    checkSourceElement(node.elementType);
                }
                function checkTupleType(node) {
                    ts.forEach(node.elementTypes, checkSourceElement);
                }
                function checkUnionType(node) {
                    ts.forEach(node.types, checkSourceElement);
                }
                function isPrivateWithinAmbient(node) {
                    return (node.flags & 32 /* Private */) && ts.isInAmbientContext(node);
                }
                function checkSpecializedSignatureDeclaration(signatureDeclarationNode) {
                    if (!fullTypeCheck) {
                        return;
                    }
                    var signature = getSignatureFromDeclaration(signatureDeclarationNode);
                    if (!signature.hasStringLiterals) {
                        return;
                    }
                    if (signatureDeclarationNode.body) {
                        error(signatureDeclarationNode, ts.Diagnostics.A_signature_with_an_implementation_cannot_use_a_string_literal_type);
                        return;
                    }
                    var signaturesToCheck;
                    if (!signatureDeclarationNode.name && signatureDeclarationNode.parent && signatureDeclarationNode.parent.kind === 190 /* InterfaceDeclaration */) {
                        ts.Debug.assert(signatureDeclarationNode.kind === 130 /* CallSignature */ || signatureDeclarationNode.kind === 131 /* ConstructSignature */);
                        var signatureKind = signatureDeclarationNode.kind === 130 /* CallSignature */ ? 0 /* Call */ : 1 /* Construct */;
                        var containingSymbol = getSymbolOfNode(signatureDeclarationNode.parent);
                        var containingType = getDeclaredTypeOfSymbol(containingSymbol);
                        signaturesToCheck = getSignaturesOfType(containingType, signatureKind);
                    }
                    else {
                        signaturesToCheck = getSignaturesOfSymbol(getSymbolOfNode(signatureDeclarationNode));
                    }
                    for (var i = 0; i < signaturesToCheck.length; i++) {
                        var otherSignature = signaturesToCheck[i];
                        if (!otherSignature.hasStringLiterals && isSignatureAssignableTo(signature, otherSignature)) {
                            return;
                        }
                    }
                    error(signatureDeclarationNode, ts.Diagnostics.Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature);
                }
                function getEffectiveDeclarationFlags(n, flagsToCheck) {
                    var flags = n.flags;
                    if (n.parent.kind !== 190 /* InterfaceDeclaration */ && ts.isInAmbientContext(n)) {
                        if (!(flags & 2 /* Ambient */)) {
                            flags |= 1 /* Export */;
                        }
                        flags |= 2 /* Ambient */;
                    }
                    return flags & flagsToCheck;
                }
                function checkFunctionOrConstructorSymbol(symbol) {
                    if (!fullTypeCheck) {
                        return;
                    }
                    function checkFlagAgreementBetweenOverloads(overloads, implementation, flagsToCheck, someOverloadFlags, allOverloadFlags) {
                        var someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags;
                        if (someButNotAllOverloadFlags !== 0) {
                            var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent;
                            var canonicalFlags = implementationSharesContainerWithFirstOverload ? getEffectiveDeclarationFlags(implementation, flagsToCheck) : getEffectiveDeclarationFlags(overloads[0], flagsToCheck);
                            ts.forEach(overloads, function (o) {
                                var deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags;
                                if (deviation & 1 /* Export */) {
                                    error(o.name, ts.Diagnostics.Overload_signatures_must_all_be_exported_or_not_exported);
                                }
                                else if (deviation & 2 /* Ambient */) {
                                    error(o.name, ts.Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
                                }
                                else if (deviation & (32 /* Private */ | 64 /* Protected */)) {
                                    error(o.name, ts.Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
                                }
                                else if (deviation & 4 /* QuestionMark */) {
                                    error(o.name, ts.Diagnostics.Overload_signatures_must_all_be_optional_or_required);
                                }
                            });
                        }
                    }
                    var flagsToCheck = 1 /* Export */ | 2 /* Ambient */ | 32 /* Private */ | 64 /* Protected */ | 4 /* QuestionMark */;
                    var someNodeFlags = 0;
                    var allNodeFlags = flagsToCheck;
                    var hasOverloads = false;
                    var bodyDeclaration;
                    var lastSeenNonAmbientDeclaration;
                    var previousDeclaration;
                    var declarations = symbol.declarations;
                    var isConstructor = (symbol.flags & 16384 /* Constructor */) !== 0;
                    function reportImplementationExpectedError(node) {
                        if (node.name && node.name.kind === 120 /* Missing */) {
                            return;
                        }
                        var seen = false;
                        var subsequentNode = ts.forEachChild(node.parent, function (c) {
                            if (seen) {
                                return c;
                            }
                            else {
                                seen = c === node;
                            }
                        });
                        if (subsequentNode) {
                            if (subsequentNode.kind === node.kind) {
                                var errorNode = subsequentNode.name || subsequentNode;
                                if (node.name && subsequentNode.name && node.name.text === subsequentNode.name.text) {
                                    ts.Debug.assert(node.kind === 126 /* Method */);
                                    ts.Debug.assert((node.flags & 128 /* Static */) !== (subsequentNode.flags & 128 /* Static */));
                                    var diagnostic = node.flags & 128 /* Static */ ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static;
                                    error(errorNode, diagnostic);
                                    return;
                                }
                                else if (subsequentNode.body) {
                                    error(errorNode, ts.Diagnostics.Function_implementation_name_must_be_0, ts.declarationNameToString(node.name));
                                    return;
                                }
                            }
                        }
                        var errorNode = node.name || node;
                        if (isConstructor) {
                            error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing);
                        }
                        else {
                            error(errorNode, ts.Diagnostics.Function_implementation_is_missing_or_not_immediately_following_the_declaration);
                        }
                    }
                    var isExportSymbolInsideModule = symbol.parent && symbol.parent.flags & 1536 /* Module */;
                    var duplicateFunctionDeclaration = false;
                    var multipleConstructorImplementation = false;
                    for (var i = 0; i < declarations.length; i++) {
                        var node = declarations[i];
                        var inAmbientContext = ts.isInAmbientContext(node);
                        var inAmbientContextOrInterface = node.parent.kind === 190 /* InterfaceDeclaration */ || node.parent.kind === 137 /* TypeLiteral */ || inAmbientContext;
                        if (inAmbientContextOrInterface) {
                            previousDeclaration = undefined;
                        }
                        if (node.kind === 187 /* FunctionDeclaration */ || node.kind === 126 /* Method */ || node.kind === 127 /* Constructor */) {
                            var currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
                            someNodeFlags |= currentNodeFlags;
                            allNodeFlags &= currentNodeFlags;
                            if (node.body && bodyDeclaration) {
                                if (isConstructor) {
                                    multipleConstructorImplementation = true;
                                }
                                else {
                                    duplicateFunctionDeclaration = true;
                                }
                            }
                            else if (!isExportSymbolInsideModule && previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) {
                                reportImplementationExpectedError(previousDeclaration);
                            }
                            if (node.body) {
                                if (!bodyDeclaration) {
                                    bodyDeclaration = node;
                                }
                            }
                            else {
                                hasOverloads = true;
                            }
                            previousDeclaration = node;
                            if (!inAmbientContextOrInterface) {
                                lastSeenNonAmbientDeclaration = node;
                            }
                        }
                    }
                    if (multipleConstructorImplementation) {
                        ts.forEach(declarations, function (declaration) {
                            error(declaration, ts.Diagnostics.Multiple_constructor_implementations_are_not_allowed);
                        });
                    }
                    if (duplicateFunctionDeclaration) {
                        ts.forEach(declarations, function (declaration) {
                            error(declaration.name, ts.Diagnostics.Duplicate_function_implementation);
                        });
                    }
                    if (!isExportSymbolInsideModule && lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body) {
                        reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
                    }
                    if (hasOverloads) {
                        checkFlagAgreementBetweenOverloads(declarations, bodyDeclaration, flagsToCheck, someNodeFlags, allNodeFlags);
                        if (bodyDeclaration) {
                            var signatures = getSignaturesOfSymbol(symbol);
                            var bodySignature = getSignatureFromDeclaration(bodyDeclaration);
                            if (!bodySignature.hasStringLiterals) {
                                for (var i = 0, len = signatures.length; i < len; ++i) {
                                    if (!signatures[i].hasStringLiterals && !isSignatureAssignableTo(bodySignature, signatures[i])) {
                                        error(signatures[i].declaration, ts.Diagnostics.Overload_signature_is_not_compatible_with_function_implementation);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                function checkExportsOnMergedDeclarations(node) {
                    if (!fullTypeCheck) {
                        return;
                    }
                    var symbol;
                    var symbol = node.localSymbol;
                    if (!symbol) {
                        symbol = getSymbolOfNode(node);
                        if (!(symbol.flags & 29360128 /* Export */)) {
                            return;
                        }
                    }
                    if (getDeclarationOfKind(symbol, node.kind) !== node) {
                        return;
                    }
                    var exportedDeclarationSpaces = 0;
                    var nonExportedDeclarationSpaces = 0;
                    ts.forEach(symbol.declarations, function (d) {
                        var declarationSpaces = getDeclarationSpaces(d);
                        if (getEffectiveDeclarationFlags(d, 1 /* Export */)) {
                            exportedDeclarationSpaces |= declarationSpaces;
                        }
                        else {
                            nonExportedDeclarationSpaces |= declarationSpaces;
                        }
                    });
                    var commonDeclarationSpace = exportedDeclarationSpaces & nonExportedDeclarationSpaces;
                    if (commonDeclarationSpace) {
                        ts.forEach(symbol.declarations, function (d) {
                            if (getDeclarationSpaces(d) & commonDeclarationSpace) {
                                error(d.name, ts.Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, ts.declarationNameToString(d.name));
                            }
                        });
                    }
                    function getDeclarationSpaces(d) {
                        switch (d.kind) {
                            case 190 /* InterfaceDeclaration */:
                                return 8388608 /* ExportType */;
                            case 193 /* ModuleDeclaration */:
                                return d.name.kind === 7 /* StringLiteral */ || ts.getModuleInstanceState(d) !== 0 /* NonInstantiated */ ? 16777216 /* ExportNamespace */ | 4194304 /* ExportValue */ : 16777216 /* ExportNamespace */;
                            case 189 /* ClassDeclaration */:
                            case 192 /* EnumDeclaration */:
                                return 8388608 /* ExportType */ | 4194304 /* ExportValue */;
                            case 195 /* ImportDeclaration */:
                                var result = 0;
                                var target = resolveImport(getSymbolOfNode(d));
                                ts.forEach(target.declarations, function (d) {
                                    result |= getDeclarationSpaces(d);
                                });
                                return result;
                            default:
                                return 4194304 /* ExportValue */;
                        }
                    }
                }
                function checkFunctionDeclaration(node) {
                    checkFunctionLikeDeclaration(node);
                    if (fullTypeCheck) {
                        checkCollisionWithCapturedSuperVariable(node, node.name);
                        checkCollisionWithCapturedThisVariable(node, node.name);
                        checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                    }
                }
                function checkFunctionLikeDeclaration(node) {
                    checkSignatureDeclaration(node);
                    if (!ts.hasComputedNameButNotSymbol(node)) {
                        var symbol = getSymbolOfNode(node);
                        var localSymbol = node.localSymbol || symbol;
                        var firstDeclaration = getDeclarationOfKind(localSymbol, node.kind);
                        if (node === firstDeclaration) {
                            checkFunctionOrConstructorSymbol(localSymbol);
                        }
                        if (symbol.parent) {
                            if (getDeclarationOfKind(symbol, node.kind) === node) {
                                checkFunctionOrConstructorSymbol(symbol);
                            }
                        }
                    }
                    checkSourceElement(node.body);
                    if (node.type && !isAccessor(node.kind)) {
                        checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type));
                    }
                    if (fullTypeCheck && compilerOptions.noImplicitAny && !node.body && !node.type) {
                        if (!isPrivateWithinAmbient(node)) {
                            var typeName = typeToString(anyType);
                            if (node.name) {
                                error(node, ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type, ts.declarationNameToString(node.name), typeName);
                            }
                            else {
                                error(node, ts.Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeName);
                            }
                        }
                    }
                }
                function checkBlock(node) {
                    ts.forEach(node.statements, checkSourceElement);
                }
                function checkCollisionWithArgumentsInGeneratedCode(node) {
                    if (!ts.hasRestParameters(node) || ts.isInAmbientContext(node) || !node.body) {
                        return;
                    }
                    ts.forEach(node.parameters, function (p) {
                        if (p.name && p.name.text === argumentsSymbol.name) {
                            error(p, ts.Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters);
                        }
                    });
                }
                function checkCollisionWithIndexVariableInGeneratedCode(node, name) {
                    if (!(name && name.text === "_i")) {
                        return;
                    }
                    if (node.kind === 124 /* Parameter */) {
                        if (node.parent.body && ts.hasRestParameters(node.parent) && !ts.isInAmbientContext(node)) {
                            error(node, ts.Diagnostics.Duplicate_identifier_i_Compiler_uses_i_to_initialize_rest_parameter);
                        }
                        return;
                    }
                    var symbol = getNodeLinks(node).resolvedSymbol;
                    if (symbol === unknownSymbol) {
                        return;
                    }
                    var current = node;
                    while (current) {
                        var definedOnCurrentLevel = ts.forEach(symbol.declarations, function (d) { return d.parent === current ? d : undefined; });
                        if (definedOnCurrentLevel) {
                            return;
                        }
                        switch (current.kind) {
                            case 187 /* FunctionDeclaration */:
                            case 153 /* FunctionExpression */:
                            case 126 /* Method */:
                            case 154 /* ArrowFunction */:
                            case 127 /* Constructor */:
                                if (ts.hasRestParameters(current)) {
                                    error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_i_that_compiler_uses_to_initialize_rest_parameter);
                                    return;
                                }
                                break;
                        }
                        current = current.parent;
                    }
                }
                function needCollisionCheckForIdentifier(node, identifier, name) {
                    if (!identifier || identifier.text !== name) {
                        return false;
                    }
                    if (node.kind === 125 /* Property */ || node.kind === 126 /* Method */ || node.kind === 128 /* GetAccessor */ || node.kind === 129 /* SetAccessor */) {
                        return false;
                    }
                    if (ts.isInAmbientContext(node)) {
                        return false;
                    }
                    if (node.kind === 124 /* Parameter */ && !node.parent.body) {
                        return false;
                    }
                    return true;
                }
                function checkCollisionWithCapturedThisVariable(node, name) {
                    if (needCollisionCheckForIdentifier(node, name, "_this")) {
                        potentialThisCollisions.push(node);
                    }
                }
                function checkIfThisIsCapturedInEnclosingScope(node) {
                    var current = node;
                    while (current) {
                        if (getNodeCheckFlags(current) & 4 /* CaptureThis */) {
                            var isDeclaration = node.kind !== 63 /* Identifier */;
                            if (isDeclaration) {
                                error(node.name, ts.Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference);
                            }
                            else {
                                error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference);
                            }
                            return;
                        }
                        current = current.parent;
                    }
                }
                function checkCollisionWithCapturedSuperVariable(node, name) {
                    if (!needCollisionCheckForIdentifier(node, name, "_super")) {
                        return;
                    }
                    var enclosingClass = ts.getAncestor(node, 189 /* ClassDeclaration */);
                    if (!enclosingClass || ts.isInAmbientContext(enclosingClass)) {
                        return;
                    }
                    if (enclosingClass.baseType) {
                        var isDeclaration = node.kind !== 63 /* Identifier */;
                        if (isDeclaration) {
                            error(node, ts.Diagnostics.Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference);
                        }
                        else {
                            error(node, ts.Diagnostics.Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference);
                        }
                    }
                }
                function checkCollisionWithRequireExportsInGeneratedCode(node, name) {
                    if (!needCollisionCheckForIdentifier(node, name, "require") && !needCollisionCheckForIdentifier(node, name, "exports")) {
                        return;
                    }
                    if (node.kind === 193 /* ModuleDeclaration */ && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                        return;
                    }
                    var parent = node.kind === 186 /* VariableDeclaration */ ? node.parent.parent : node.parent;
                    if (parent.kind === 198 /* SourceFile */ && ts.isExternalModule(parent)) {
                        error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_an_external_module, ts.declarationNameToString(name), ts.declarationNameToString(name));
                    }
                }
                function checkCollisionWithConstDeclarations(node) {
                    if (node.initializer && (node.flags & 6144 /* BlockScoped */) === 0) {
                        var symbol = getSymbolOfNode(node);
                        if (symbol.flags & 1 /* FunctionScopedVariable */) {
                            var localDeclarationSymbol = resolveName(node, node.name.text, 3 /* Variable */, undefined, undefined);
                            if (localDeclarationSymbol && localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & 2 /* BlockScopedVariable */) {
                                if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & 4096 /* Const */) {
                                    error(node, ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0, symbolToString(localDeclarationSymbol));
                                }
                            }
                        }
                    }
                }
                function checkVariableOrPropertyInFullTypeCheck(node) {
                    ts.Debug.assert(fullTypeCheck);
                    checkSourceElement(node.type);
                    if (ts.hasComputedNameButNotSymbol(node)) {
                        return node.initializer ? checkAndMarkExpression(node.initializer) : anyType;
                    }
                    var symbol = getSymbolOfNode(node);
                    var type;
                    if (symbol.valueDeclaration !== node) {
                        type = getTypeOfVariableOrPropertyDeclaration(node);
                    }
                    else {
                        type = getTypeOfVariableOrParameterOrProperty(symbol);
                    }
                    if (node.initializer && !(getNodeLinks(node.initializer).flags & 1 /* TypeChecked */)) {
                        checkTypeAssignableTo(checkAndMarkExpression(node.initializer), type, node, undefined);
                    }
                    return type;
                }
                function checkVariableDeclaration(node) {
                    if (fullTypeCheck) {
                        var type = checkVariableOrPropertyInFullTypeCheck(node);
                        checkExportsOnMergedDeclarations(node);
                        if (node.initializer) {
                            checkCollisionWithConstDeclarations(node);
                        }
                        checkCollisionWithCapturedSuperVariable(node, node.name);
                        checkCollisionWithCapturedThisVariable(node, node.name);
                        checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                        var symbol = getSymbolOfNode(node);
                        if (node !== symbol.valueDeclaration) {
                            var typeOfValueDeclaration = getTypeOfVariableOrParameterOrProperty(symbol);
                            if (typeOfValueDeclaration !== unknownType && type !== unknownType && !isTypeIdenticalTo(typeOfValueDeclaration, type)) {
                                error(node.name, ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, ts.declarationNameToString(node.name), typeToString(typeOfValueDeclaration), typeToString(type));
                            }
                        }
                    }
                }
                function checkVariableStatement(node) {
                    ts.forEach(node.declarations, checkVariableDeclaration);
                }
                function checkExpressionStatement(node) {
                    checkExpression(node.expression);
                }
                function checkIfStatement(node) {
                    checkExpression(node.expression);
                    checkSourceElement(node.thenStatement);
                    checkSourceElement(node.elseStatement);
                }
                function checkDoStatement(node) {
                    checkSourceElement(node.statement);
                    checkExpression(node.expression);
                }
                function checkWhileStatement(node) {
                    checkExpression(node.expression);
                    checkSourceElement(node.statement);
                }
                function checkForStatement(node) {
                    if (node.declarations)
                        ts.forEach(node.declarations, checkVariableDeclaration);
                    if (node.initializer)
                        checkExpression(node.initializer);
                    if (node.condition)
                        checkExpression(node.condition);
                    if (node.iterator)
                        checkExpression(node.iterator);
                    checkSourceElement(node.statement);
                }
                function checkForInStatement(node) {
                    if (node.declarations) {
                        if (node.declarations.length >= 1) {
                            var decl = node.declarations[0];
                            checkVariableDeclaration(decl);
                            if (decl.type) {
                                error(decl, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation);
                            }
                        }
                    }
                    if (node.variable) {
                        var exprType = checkExpression(node.variable);
                        if (exprType !== anyType && exprType !== stringType) {
                            error(node.variable, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
                        }
                        else {
                            checkReferenceExpression(node.variable, ts.Diagnostics.Invalid_left_hand_side_in_for_in_statement, ts.Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant);
                        }
                    }
                    var exprType = checkExpression(node.expression);
                    if (!isStructuredType(exprType) && exprType !== unknownType) {
                        error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
                    }
                    checkSourceElement(node.statement);
                }
                function checkBreakOrContinueStatement(node) {
                }
                function checkReturnStatement(node) {
                    if (node.expression && !(getNodeLinks(node.expression).flags & 1 /* TypeChecked */)) {
                        var func = ts.getContainingFunction(node);
                        if (func) {
                            if (func.kind === 129 /* SetAccessor */) {
                                if (node.expression) {
                                    error(node.expression, ts.Diagnostics.Setters_cannot_return_a_value);
                                }
                            }
                            else {
                                var returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func));
                                var checkAssignability = func.type || (func.kind === 128 /* GetAccessor */ && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(func.symbol, 129 /* SetAccessor */)));
                                if (checkAssignability) {
                                    checkTypeAssignableTo(checkExpression(node.expression), returnType, node.expression, undefined);
                                }
                                else if (func.kind == 127 /* Constructor */) {
                                    if (!isTypeAssignableTo(checkExpression(node.expression), returnType)) {
                                        error(node.expression, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
                                    }
                                }
                            }
                        }
                    }
                }
                function checkWithStatement(node) {
                    checkExpression(node.expression);
                    error(node.expression, ts.Diagnostics.All_symbols_within_a_with_block_will_be_resolved_to_any);
                }
                function checkSwitchStatement(node) {
                    var expressionType = checkExpression(node.expression);
                    ts.forEach(node.clauses, function (clause) {
                        if (fullTypeCheck && clause.expression) {
                            var caseType = checkExpression(clause.expression);
                            if (!isTypeAssignableTo(expressionType, caseType)) {
                                checkTypeAssignableTo(caseType, expressionType, clause.expression, undefined);
                            }
                        }
                        checkBlock(clause);
                    });
                }
                function checkLabeledStatement(node) {
                    checkSourceElement(node.statement);
                }
                function checkThrowStatement(node) {
                    checkExpression(node.expression);
                }
                function checkTryStatement(node) {
                    checkBlock(node.tryBlock);
                    if (node.catchBlock)
                        checkBlock(node.catchBlock);
                    if (node.finallyBlock)
                        checkBlock(node.finallyBlock);
                }
                function checkIndexConstraints(type) {
                    function checkIndexConstraintForProperty(prop, propertyType, indexDeclaration, indexType, indexKind) {
                        if (!indexType) {
                            return;
                        }
                        if (indexKind === 1 /* Number */ && !isNumericName(prop.name)) {
                            return;
                        }
                        var errorNode;
                        if (prop.parent === type.symbol) {
                            errorNode = prop.valueDeclaration;
                        }
                        else if (indexDeclaration) {
                            errorNode = indexDeclaration;
                        }
                        else if (type.flags & 2048 /* Interface */) {
                            var someBaseClassHasBothPropertyAndIndexer = ts.forEach(type.baseTypes, function (base) { return getPropertyOfObjectType(base, prop.name) && getIndexTypeOfType(base, indexKind); });
                            errorNode = someBaseClassHasBothPropertyAndIndexer ? undefined : type.symbol.declarations[0];
                        }
                        if (errorNode && !isTypeAssignableTo(propertyType, indexType)) {
                            var errorMessage = indexKind === 0 /* String */ ? ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2 : ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2;
                            error(errorNode, errorMessage, symbolToString(prop), typeToString(propertyType), typeToString(indexType));
                        }
                    }
                    var declaredNumberIndexer = getIndexDeclarationOfSymbol(type.symbol, 1 /* Number */);
                    var declaredStringIndexer = getIndexDeclarationOfSymbol(type.symbol, 0 /* String */);
                    var stringIndexType = getIndexTypeOfType(type, 0 /* String */);
                    var numberIndexType = getIndexTypeOfType(type, 1 /* Number */);
                    if (stringIndexType || numberIndexType) {
                        ts.forEach(getPropertiesOfObjectType(type), function (prop) {
                            var propType = getTypeOfSymbol(prop);
                            checkIndexConstraintForProperty(prop, propType, declaredStringIndexer, stringIndexType, 0 /* String */);
                            checkIndexConstraintForProperty(prop, propType, declaredNumberIndexer, numberIndexType, 1 /* Number */);
                        });
                    }
                    var errorNode;
                    if (stringIndexType && numberIndexType) {
                        errorNode = declaredNumberIndexer || declaredStringIndexer;
                        if (!errorNode && (type.flags & 2048 /* Interface */)) {
                            var someBaseTypeHasBothIndexers = ts.forEach(type.baseTypes, function (base) { return getIndexTypeOfType(base, 0 /* String */) && getIndexTypeOfType(base, 1 /* Number */); });
                            errorNode = someBaseTypeHasBothIndexers ? undefined : type.symbol.declarations[0];
                        }
                    }
                    if (errorNode && !isTypeAssignableTo(numberIndexType, stringIndexType)) {
                        error(errorNode, ts.Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1, typeToString(numberIndexType), typeToString(stringIndexType));
                    }
                }
                function checkTypeNameIsReserved(name, message) {
                    switch (name.text) {
                        case "any":
                        case "number":
                        case "boolean":
                        case "string":
                        case "void":
                            error(name, message, name.text);
                    }
                }
                function checkTypeParameters(typeParameterDeclarations) {
                    if (typeParameterDeclarations) {
                        for (var i = 0; i < typeParameterDeclarations.length; i++) {
                            var node = typeParameterDeclarations[i];
                            checkTypeParameter(node);
                            if (fullTypeCheck) {
                                for (var j = 0; j < i; j++) {
                                    if (typeParameterDeclarations[j].symbol === node.symbol) {
                                        error(node.name, ts.Diagnostics.Duplicate_identifier_0, ts.declarationNameToString(node.name));
                                    }
                                }
                            }
                        }
                    }
                }
                function checkClassDeclaration(node) {
                    checkTypeNameIsReserved(node.name, ts.Diagnostics.Class_name_cannot_be_0);
                    checkTypeParameters(node.typeParameters);
                    checkCollisionWithCapturedThisVariable(node, node.name);
                    checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                    checkExportsOnMergedDeclarations(node);
                    var symbol = getSymbolOfNode(node);
                    var type = getDeclaredTypeOfSymbol(symbol);
                    var staticType = getTypeOfSymbol(symbol);
                    if (node.baseType) {
                        emitExtends = emitExtends || !ts.isInAmbientContext(node);
                        checkTypeReference(node.baseType);
                    }
                    if (type.baseTypes.length) {
                        if (fullTypeCheck) {
                            var baseType = type.baseTypes[0];
                            checkTypeAssignableTo(type, baseType, node.name, ts.Diagnostics.Class_0_incorrectly_extends_base_class_1);
                            var staticBaseType = getTypeOfSymbol(baseType.symbol);
                            checkTypeAssignableTo(staticType, getTypeWithoutConstructors(staticBaseType), node.name, ts.Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
                            if (baseType.symbol !== resolveEntityName(node, node.baseType.typeName, 107455 /* Value */)) {
                                error(node.baseType, ts.Diagnostics.Type_name_0_in_extends_clause_does_not_reference_constructor_function_for_0, typeToString(baseType));
                            }
                            checkKindsOfPropertyMemberOverrides(type, baseType);
                        }
                        checkExpression(node.baseType.typeName);
                    }
                    if (node.implementedTypes) {
                        ts.forEach(node.implementedTypes, function (typeRefNode) {
                            checkTypeReference(typeRefNode);
                            if (fullTypeCheck) {
                                var t = getTypeFromTypeReferenceNode(typeRefNode);
                                if (t !== unknownType) {
                                    var declaredType = (t.flags & 4096 /* Reference */) ? t.target : t;
                                    if (declaredType.flags & (1024 /* Class */ | 2048 /* Interface */)) {
                                        checkTypeAssignableTo(type, t, node.name, ts.Diagnostics.Class_0_incorrectly_implements_interface_1);
                                    }
                                    else {
                                        error(typeRefNode, ts.Diagnostics.A_class_may_only_implement_another_class_or_interface);
                                    }
                                }
                            }
                        });
                    }
                    ts.forEach(node.members, checkSourceElement);
                    if (fullTypeCheck) {
                        checkIndexConstraints(type);
                        checkTypeForDuplicateIndexSignatures(node);
                    }
                }
                function getTargetSymbol(s) {
                    return s.flags & 67108864 /* Instantiated */ ? getSymbolLinks(s).target : s;
                }
                function checkKindsOfPropertyMemberOverrides(type, baseType) {
                    var baseProperties = getPropertiesOfObjectType(baseType);
                    for (var i = 0, len = baseProperties.length; i < len; ++i) {
                        var base = getTargetSymbol(baseProperties[i]);
                        if (base.flags & 536870912 /* Prototype */) {
                            continue;
                        }
                        var derived = getTargetSymbol(getPropertyOfObjectType(type, base.name));
                        if (derived) {
                            var baseDeclarationFlags = getDeclarationFlagsFromSymbol(base);
                            var derivedDeclarationFlags = getDeclarationFlagsFromSymbol(derived);
                            if ((baseDeclarationFlags & 32 /* Private */) || (derivedDeclarationFlags & 32 /* Private */)) {
                                continue;
                            }
                            if ((baseDeclarationFlags & 128 /* Static */) !== (derivedDeclarationFlags & 128 /* Static */)) {
                                continue;
                            }
                            if ((base.flags & derived.flags & 8192 /* Method */) || ((base.flags & 98308 /* PropertyOrAccessor */) && (derived.flags & 98308 /* PropertyOrAccessor */))) {
                                continue;
                            }
                            var errorMessage;
                            if (base.flags & 8192 /* Method */) {
                                if (derived.flags & 98304 /* Accessor */) {
                                    errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
                                }
                                else {
                                    ts.Debug.assert((derived.flags & 4 /* Property */) !== 0);
                                    errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property;
                                }
                            }
                            else if (base.flags & 4 /* Property */) {
                                ts.Debug.assert((derived.flags & 8192 /* Method */) !== 0);
                                errorMessage = ts.Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
                            }
                            else {
                                ts.Debug.assert((base.flags & 98304 /* Accessor */) !== 0);
                                ts.Debug.assert((derived.flags & 8192 /* Method */) !== 0);
                                errorMessage = ts.Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
                            }
                            error(derived.valueDeclaration.name, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
                        }
                    }
                }
                function isAccessor(kind) {
                    return kind === 128 /* GetAccessor */ || kind === 129 /* SetAccessor */;
                }
                function areTypeParametersIdentical(list1, list2) {
                    if (!list1 && !list2) {
                        return true;
                    }
                    if (!list1 || !list2 || list1.length !== list2.length) {
                        return false;
                    }
                    for (var i = 0, len = list1.length; i < len; i++) {
                        var tp1 = list1[i];
                        var tp2 = list2[i];
                        if (tp1.name.text !== tp2.name.text) {
                            return false;
                        }
                        if (!tp1.constraint && !tp2.constraint) {
                            continue;
                        }
                        if (!tp1.constraint || !tp2.constraint) {
                            return false;
                        }
                        if (!isTypeIdenticalTo(getTypeFromTypeNode(tp1.constraint), getTypeFromTypeNode(tp2.constraint))) {
                            return false;
                        }
                    }
                    return true;
                }
                function checkInheritedPropertiesAreIdentical(type, typeNode) {
                    if (!type.baseTypes.length || type.baseTypes.length === 1) {
                        return true;
                    }
                    var seen = {};
                    ts.forEach(type.declaredProperties, function (p) {
                        seen[p.name] = { prop: p, containingType: type };
                    });
                    var ok = true;
                    for (var i = 0, len = type.baseTypes.length; i < len; ++i) {
                        var base = type.baseTypes[i];
                        var properties = getPropertiesOfObjectType(base);
                        for (var j = 0, proplen = properties.length; j < proplen; ++j) {
                            var prop = properties[j];
                            if (!ts.hasProperty(seen, prop.name)) {
                                seen[prop.name] = { prop: prop, containingType: base };
                            }
                            else {
                                var existing = seen[prop.name];
                                var isInheritedProperty = existing.containingType !== type;
                                if (isInheritedProperty && !isPropertyIdenticalTo(existing.prop, prop)) {
                                    ok = false;
                                    var typeName1 = typeToString(existing.containingType);
                                    var typeName2 = typeToString(base);
                                    var errorInfo = ts.chainDiagnosticMessages(undefined, ts.Diagnostics.Named_properties_0_of_types_1_and_2_are_not_identical, prop.name, typeName1, typeName2);
                                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2);
                                    addDiagnostic(ts.createDiagnosticForNodeFromMessageChain(typeNode, errorInfo, program.getCompilerHost().getNewLine()));
                                }
                            }
                        }
                    }
                    return ok;
                }
                function checkInterfaceDeclaration(node) {
                    checkTypeParameters(node.typeParameters);
                    if (fullTypeCheck) {
                        checkTypeNameIsReserved(node.name, ts.Diagnostics.Interface_name_cannot_be_0);
                        checkExportsOnMergedDeclarations(node);
                        var symbol = getSymbolOfNode(node);
                        var firstInterfaceDecl = getDeclarationOfKind(symbol, 190 /* InterfaceDeclaration */);
                        if (symbol.declarations.length > 1) {
                            if (node !== firstInterfaceDecl && !areTypeParametersIdentical(firstInterfaceDecl.typeParameters, node.typeParameters)) {
                                error(node.name, ts.Diagnostics.All_declarations_of_an_interface_must_have_identical_type_parameters);
                            }
                        }
                        if (node === firstInterfaceDecl) {
                            var type = getDeclaredTypeOfSymbol(symbol);
                            if (checkInheritedPropertiesAreIdentical(type, node.name)) {
                                ts.forEach(type.baseTypes, function (baseType) {
                                    checkTypeAssignableTo(type, baseType, node.name, ts.Diagnostics.Interface_0_incorrectly_extends_interface_1);
                                });
                                checkIndexConstraints(type);
                            }
                        }
                    }
                    ts.forEach(node.baseTypes, checkTypeReference);
                    ts.forEach(node.members, checkSourceElement);
                    if (fullTypeCheck) {
                        checkTypeForDuplicateIndexSignatures(node);
                    }
                }
                function checkTypeAliasDeclaration(node) {
                    checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0);
                    checkSourceElement(node.type);
                }
                function computeEnumMemberValues(node) {
                    var nodeLinks = getNodeLinks(node);
                    if (!(nodeLinks.flags & 128 /* EnumValuesComputed */)) {
                        var enumSymbol = getSymbolOfNode(node);
                        var enumType = getDeclaredTypeOfSymbol(enumSymbol);
                        var autoValue = 0;
                        var ambient = ts.isInAmbientContext(node);
                        var enumIsConst = ts.isConst(node);
                        ts.forEach(node.members, function (member) {
                            if (isNumericName(member.name.text)) {
                                error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
                            }
                            var initializer = member.initializer;
                            if (initializer) {
                                autoValue = getConstantValueForEnumMemberInitializer(initializer, enumIsConst);
                                if (autoValue === undefined) {
                                    if (enumIsConst) {
                                        error(initializer, ts.Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression);
                                    }
                                    else if (!ambient) {
                                        checkTypeAssignableTo(checkExpression(initializer), enumType, initializer, undefined);
                                    }
                                }
                                else if (enumIsConst) {
                                    if (isNaN(autoValue)) {
                                        error(initializer, ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN);
                                    }
                                    else if (!isFinite(autoValue)) {
                                        error(initializer, ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
                                    }
                                }
                            }
                            else if (ambient && !enumIsConst) {
                                autoValue = undefined;
                            }
                            if (autoValue !== undefined) {
                                getNodeLinks(member).enumMemberValue = autoValue++;
                            }
                        });
                        nodeLinks.flags |= 128 /* EnumValuesComputed */;
                    }
                    function getConstantValueForEnumMemberInitializer(initializer, enumIsConst) {
                        return evalConstant(initializer);
                        function evalConstant(e) {
                            switch (e.kind) {
                                case 155 /* PrefixOperator */:
                                    var value = evalConstant(e.operand);
                                    if (value === undefined) {
                                        return undefined;
                                    }
                                    switch (e.operator) {
                                        case 32 /* PlusToken */: return value;
                                        case 33 /* MinusToken */: return -value;
                                        case 46 /* TildeToken */: return enumIsConst ? ~value : undefined;
                                    }
                                    return undefined;
                                case 157 /* BinaryExpression */:
                                    if (!enumIsConst) {
                                        return undefined;
                                    }
                                    var left = evalConstant(e.left);
                                    if (left === undefined) {
                                        return undefined;
                                    }
                                    var right = evalConstant(e.right);
                                    if (right === undefined) {
                                        return undefined;
                                    }
                                    switch (e.operator) {
                                        case 43 /* BarToken */: return left | right;
                                        case 42 /* AmpersandToken */: return left & right;
                                        case 40 /* GreaterThanGreaterThanToken */: return left >> right;
                                        case 41 /* GreaterThanGreaterThanGreaterThanToken */: return left >>> right;
                                        case 39 /* LessThanLessThanToken */: return left << right;
                                        case 44 /* CaretToken */: return left ^ right;
                                        case 34 /* AsteriskToken */: return left * right;
                                        case 35 /* SlashToken */: return left / right;
                                        case 32 /* PlusToken */: return left + right;
                                        case 33 /* MinusToken */: return left - right;
                                        case 36 /* PercentToken */: return left % right;
                                    }
                                    return undefined;
                                case 6 /* NumericLiteral */:
                                    return +e.text;
                                case 152 /* ParenExpression */:
                                    return enumIsConst ? evalConstant(e.expression) : undefined;
                                case 63 /* Identifier */:
                                case 147 /* IndexedAccess */:
                                case 146 /* PropertyAccess */:
                                    if (!enumIsConst) {
                                        return undefined;
                                    }
                                    var member = initializer.parent;
                                    var currentType = getTypeOfSymbol(getSymbolOfNode(member.parent));
                                    var enumType;
                                    var propertyName;
                                    if (e.kind === 63 /* Identifier */) {
                                        enumType = currentType;
                                        propertyName = e.text;
                                    }
                                    else {
                                        if (e.kind === 147 /* IndexedAccess */) {
                                            if (e.index.kind !== 7 /* StringLiteral */) {
                                                return undefined;
                                            }
                                            var enumType = getTypeOfNode(e.object);
                                            propertyName = e.index.text;
                                        }
                                        else {
                                            var enumType = getTypeOfNode(e.left);
                                            propertyName = e.right.text;
                                        }
                                        if (enumType !== currentType) {
                                            return undefined;
                                        }
                                    }
                                    if (propertyName === undefined) {
                                        return undefined;
                                    }
                                    var property = getPropertyOfObjectType(enumType, propertyName);
                                    if (!property || !(property.flags & 8 /* EnumMember */)) {
                                        return undefined;
                                    }
                                    var propertyDecl = property.valueDeclaration;
                                    if (member === propertyDecl) {
                                        return undefined;
                                    }
                                    if (!isDefinedBefore(propertyDecl, member)) {
                                        return undefined;
                                    }
                                    return getNodeLinks(propertyDecl).enumMemberValue;
                            }
                        }
                    }
                }
                function checkEnumDeclaration(node) {
                    if (!fullTypeCheck) {
                        return;
                    }
                    checkTypeNameIsReserved(node.name, ts.Diagnostics.Enum_name_cannot_be_0);
                    checkCollisionWithCapturedThisVariable(node, node.name);
                    checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                    checkExportsOnMergedDeclarations(node);
                    computeEnumMemberValues(node);
                    var enumSymbol = getSymbolOfNode(node);
                    var firstDeclaration = getDeclarationOfKind(enumSymbol, node.kind);
                    if (node === firstDeclaration) {
                        if (enumSymbol.declarations.length > 1) {
                            var enumIsConst = ts.isConst(node);
                            ts.forEach(enumSymbol.declarations, function (decl) {
                                if (ts.isConstEnumDeclaration(decl) !== enumIsConst) {
                                    error(decl.name, ts.Diagnostics.Enum_declarations_must_all_be_const_or_non_const);
                                }
                            });
                        }
                        var seenEnumMissingInitialInitializer = false;
                        ts.forEach(enumSymbol.declarations, function (declaration) {
                            if (declaration.kind !== 192 /* EnumDeclaration */) {
                                return false;
                            }
                            var enumDeclaration = declaration;
                            if (!enumDeclaration.members.length) {
                                return false;
                            }
                            var firstEnumMember = enumDeclaration.members[0];
                            if (!firstEnumMember.initializer) {
                                if (seenEnumMissingInitialInitializer) {
                                    error(firstEnumMember.name, ts.Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element);
                                }
                                else {
                                    seenEnumMissingInitialInitializer = true;
                                }
                            }
                        });
                    }
                }
                function getFirstNonAmbientClassOrFunctionDeclaration(symbol) {
                    var declarations = symbol.declarations;
                    for (var i = 0; i < declarations.length; i++) {
                        var declaration = declarations[i];
                        if ((declaration.kind === 189 /* ClassDeclaration */ || (declaration.kind === 187 /* FunctionDeclaration */ && declaration.body)) && !ts.isInAmbientContext(declaration)) {
                            return declaration;
                        }
                    }
                    return undefined;
                }
                function checkModuleDeclaration(node) {
                    if (fullTypeCheck) {
                        checkCollisionWithCapturedThisVariable(node, node.name);
                        checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                        checkExportsOnMergedDeclarations(node);
                        var symbol = getSymbolOfNode(node);
                        if (symbol.flags & 512 /* ValueModule */ && symbol.declarations.length > 1 && !ts.isInAmbientContext(node)) {
                            var classOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol);
                            if (classOrFunc) {
                                if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(classOrFunc)) {
                                    error(node.name, ts.Diagnostics.A_module_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged);
                                }
                                else if (node.pos < classOrFunc.pos) {
                                    error(node.name, ts.Diagnostics.A_module_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged);
                                }
                            }
                        }
                        if (node.name.kind === 7 /* StringLiteral */) {
                            if (!isGlobalSourceFile(node.parent)) {
                                error(node.name, ts.Diagnostics.Ambient_external_modules_cannot_be_nested_in_other_modules);
                            }
                            if (isExternalModuleNameRelative(node.name.text)) {
                                error(node.name, ts.Diagnostics.Ambient_external_module_declaration_cannot_specify_relative_module_name);
                            }
                        }
                    }
                    checkSourceElement(node.body);
                }
                function getFirstIdentifier(node) {
                    while (node.kind === 121 /* QualifiedName */) {
                        node = node.left;
                    }
                    return node;
                }
                function checkImportDeclaration(node) {
                    checkCollisionWithCapturedThisVariable(node, node.name);
                    checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                    var symbol = getSymbolOfNode(node);
                    var target;
                    if (node.entityName) {
                        target = resolveImport(symbol);
                        if (target !== unknownSymbol) {
                            if (target.flags & 107455 /* Value */) {
                                var moduleName = getFirstIdentifier(node.entityName);
                                if (resolveEntityName(node, moduleName, 107455 /* Value */ | 1536 /* Namespace */).flags & 1536 /* Namespace */) {
                                    checkExpression(node.entityName);
                                }
                                else {
                                    error(moduleName, ts.Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, ts.declarationNameToString(moduleName));
                                }
                            }
                            if (target.flags & 3152352 /* Type */) {
                                checkTypeNameIsReserved(node.name, ts.Diagnostics.Import_name_cannot_be_0);
                            }
                        }
                    }
                    else {
                        if (node.parent.kind === 198 /* SourceFile */) {
                            target = resolveImport(symbol);
                        }
                        else if (node.parent.kind === 194 /* ModuleBlock */ && node.parent.parent.name.kind === 7 /* StringLiteral */) {
                            if (isExternalModuleNameRelative(node.externalModuleName.text)) {
                                error(node, ts.Diagnostics.Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name);
                                target = unknownSymbol;
                            }
                            else {
                                target = resolveImport(symbol);
                            }
                        }
                        else {
                            target = unknownSymbol;
                        }
                    }
                    if (target !== unknownSymbol) {
                        var excludedMeanings = (symbol.flags & 107455 /* Value */ ? 107455 /* Value */ : 0) | (symbol.flags & 3152352 /* Type */ ? 3152352 /* Type */ : 0) | (symbol.flags & 1536 /* Namespace */ ? 1536 /* Namespace */ : 0);
                        if (target.flags & excludedMeanings) {
                            error(node, ts.Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0, symbolToString(symbol));
                        }
                    }
                }
                function checkExportAssignment(node) {
                    var container = node.parent;
                    if (container.kind !== 198 /* SourceFile */) {
                        container = container.parent;
                    }
                    checkTypeOfExportAssignmentSymbol(getSymbolOfNode(container));
                }
                function checkSourceElement(node) {
                    if (!node)
                        return;
                    switch (node.kind) {
                        case 123 /* TypeParameter */:
                            return checkTypeParameter(node);
                        case 124 /* Parameter */:
                            return checkParameter(node);
                        case 125 /* Property */:
                            return checkPropertyDeclaration(node);
                        case 134 /* FunctionType */:
                        case 135 /* ConstructorType */:
                        case 130 /* CallSignature */:
                        case 131 /* ConstructSignature */:
                        case 132 /* IndexSignature */:
                            return checkSignatureDeclaration(node);
                        case 126 /* Method */:
                            return checkMethodDeclaration(node);
                        case 127 /* Constructor */:
                            return checkConstructorDeclaration(node);
                        case 128 /* GetAccessor */:
                        case 129 /* SetAccessor */:
                            return checkAccessorDeclaration(node);
                        case 133 /* TypeReference */:
                            return checkTypeReference(node);
                        case 136 /* TypeQuery */:
                            return checkTypeQuery(node);
                        case 137 /* TypeLiteral */:
                            return checkTypeLiteral(node);
                        case 138 /* ArrayType */:
                            return checkArrayType(node);
                        case 139 /* TupleType */:
                            return checkTupleType(node);
                        case 140 /* UnionType */:
                            return checkUnionType(node);
                        case 141 /* ParenType */:
                            return checkSourceElement(node.type);
                        case 187 /* FunctionDeclaration */:
                            return checkFunctionDeclaration(node);
                        case 163 /* Block */:
                            return checkBlock(node);
                        case 188 /* FunctionBlock */:
                        case 194 /* ModuleBlock */:
                            return checkBody(node);
                        case 164 /* VariableStatement */:
                            return checkVariableStatement(node);
                        case 166 /* ExpressionStatement */:
                            return checkExpressionStatement(node);
                        case 167 /* IfStatement */:
                            return checkIfStatement(node);
                        case 168 /* DoStatement */:
                            return checkDoStatement(node);
                        case 169 /* WhileStatement */:
                            return checkWhileStatement(node);
                        case 170 /* ForStatement */:
                            return checkForStatement(node);
                        case 171 /* ForInStatement */:
                            return checkForInStatement(node);
                        case 172 /* ContinueStatement */:
                        case 173 /* BreakStatement */:
                            return checkBreakOrContinueStatement(node);
                        case 174 /* ReturnStatement */:
                            return checkReturnStatement(node);
                        case 175 /* WithStatement */:
                            return checkWithStatement(node);
                        case 176 /* SwitchStatement */:
                            return checkSwitchStatement(node);
                        case 179 /* LabeledStatement */:
                            return checkLabeledStatement(node);
                        case 180 /* ThrowStatement */:
                            return checkThrowStatement(node);
                        case 181 /* TryStatement */:
                            return checkTryStatement(node);
                        case 186 /* VariableDeclaration */:
                            return ts.Debug.fail("Checker encountered variable declaration");
                        case 189 /* ClassDeclaration */:
                            return checkClassDeclaration(node);
                        case 190 /* InterfaceDeclaration */:
                            return checkInterfaceDeclaration(node);
                        case 191 /* TypeAliasDeclaration */:
                            return checkTypeAliasDeclaration(node);
                        case 192 /* EnumDeclaration */:
                            return checkEnumDeclaration(node);
                        case 193 /* ModuleDeclaration */:
                            return checkModuleDeclaration(node);
                        case 195 /* ImportDeclaration */:
                            return checkImportDeclaration(node);
                        case 196 /* ExportAssignment */:
                            return checkExportAssignment(node);
                    }
                }
                function checkFunctionExpressionBodies(node) {
                    switch (node.kind) {
                        case 153 /* FunctionExpression */:
                        case 154 /* ArrowFunction */:
                            ts.forEach(node.parameters, checkFunctionExpressionBodies);
                            checkFunctionExpressionBody(node);
                            break;
                        case 126 /* Method */:
                        case 127 /* Constructor */:
                        case 128 /* GetAccessor */:
                        case 129 /* SetAccessor */:
                        case 187 /* FunctionDeclaration */:
                            ts.forEach(node.parameters, checkFunctionExpressionBodies);
                            break;
                        case 175 /* WithStatement */:
                            checkFunctionExpressionBodies(node.expression);
                            break;
                        case 124 /* Parameter */:
                        case 125 /* Property */:
                        case 142 /* ArrayLiteral */:
                        case 143 /* ObjectLiteral */:
                        case 144 /* PropertyAssignment */:
                        case 146 /* PropertyAccess */:
                        case 147 /* IndexedAccess */:
                        case 148 /* CallExpression */:
                        case 149 /* NewExpression */:
                        case 150 /* TaggedTemplateExpression */:
                        case 151 /* TypeAssertion */:
                        case 152 /* ParenExpression */:
                        case 155 /* PrefixOperator */:
                        case 156 /* PostfixOperator */:
                        case 157 /* BinaryExpression */:
                        case 158 /* ConditionalExpression */:
                        case 163 /* Block */:
                        case 188 /* FunctionBlock */:
                        case 194 /* ModuleBlock */:
                        case 164 /* VariableStatement */:
                        case 166 /* ExpressionStatement */:
                        case 167 /* IfStatement */:
                        case 168 /* DoStatement */:
                        case 169 /* WhileStatement */:
                        case 170 /* ForStatement */:
                        case 171 /* ForInStatement */:
                        case 172 /* ContinueStatement */:
                        case 173 /* BreakStatement */:
                        case 174 /* ReturnStatement */:
                        case 176 /* SwitchStatement */:
                        case 177 /* CaseClause */:
                        case 178 /* DefaultClause */:
                        case 179 /* LabeledStatement */:
                        case 180 /* ThrowStatement */:
                        case 181 /* TryStatement */:
                        case 182 /* TryBlock */:
                        case 183 /* CatchBlock */:
                        case 184 /* FinallyBlock */:
                        case 186 /* VariableDeclaration */:
                        case 189 /* ClassDeclaration */:
                        case 192 /* EnumDeclaration */:
                        case 197 /* EnumMember */:
                        case 198 /* SourceFile */:
                            ts.forEachChild(node, checkFunctionExpressionBodies);
                            break;
                    }
                }
                function checkBody(node) {
                    checkBlock(node);
                    checkFunctionExpressionBodies(node);
                }
                function checkSourceFile(node) {
                    var links = getNodeLinks(node);
                    if (!(links.flags & 1 /* TypeChecked */)) {
                        emitExtends = false;
                        potentialThisCollisions.length = 0;
                        checkBody(node);
                        if (ts.isExternalModule(node)) {
                            var symbol = getExportAssignmentSymbol(node.symbol);
                            if (symbol && symbol.flags & 33554432 /* Import */) {
                                getSymbolLinks(symbol).referenced = true;
                            }
                        }
                        if (potentialThisCollisions.length) {
                            ts.forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope);
                            potentialThisCollisions.length = 0;
                        }
                        if (emitExtends)
                            links.flags |= 8 /* EmitExtends */;
                        links.flags |= 1 /* TypeChecked */;
                    }
                }
                function checkProgram() {
                    ts.forEach(program.getSourceFiles(), checkSourceFile);
                }
                function getSortedDiagnostics() {
                    ts.Debug.assert(fullTypeCheck, "diagnostics are available only in the full typecheck mode");
                    if (diagnosticsModified) {
                        diagnostics.sort(ts.compareDiagnostics);
                        diagnostics = ts.deduplicateSortedDiagnostics(diagnostics);
                        diagnosticsModified = false;
                    }
                    return diagnostics;
                }
                function getDiagnostics(sourceFile) {
                    if (sourceFile) {
                        checkSourceFile(sourceFile);
                        return ts.filter(getSortedDiagnostics(), function (d) { return d.file === sourceFile; });
                    }
                    checkProgram();
                    return getSortedDiagnostics();
                }
                function getDeclarationDiagnostics(targetSourceFile) {
                    var resolver = createResolver();
                    checkSourceFile(targetSourceFile);
                    return ts.getDeclarationDiagnostics(program, resolver, targetSourceFile);
                }
                function getGlobalDiagnostics() {
                    return ts.filter(getSortedDiagnostics(), function (d) { return !d.file; });
                }
                function getNodeAtPosition(sourceFile, position) {
                    function findChildAtPosition(parent) {
                        var child = ts.forEachChild(parent, function (node) {
                            if (position >= node.pos && position <= node.end && position >= ts.getTokenPosOfNode(node)) {
                                return findChildAtPosition(node);
                            }
                        });
                        return child || parent;
                    }
                    if (position < sourceFile.pos)
                        position = sourceFile.pos;
                    if (position > sourceFile.end)
                        position = sourceFile.end;
                    return findChildAtPosition(sourceFile);
                }
                function isInsideWithStatementBody(node) {
                    if (node) {
                        while (node.parent) {
                            if (node.parent.kind === 175 /* WithStatement */ && node.parent.statement === node) {
                                return true;
                            }
                            node = node.parent;
                        }
                    }
                    return false;
                }
                function getSymbolsInScope(location, meaning) {
                    var symbols = {};
                    var memberFlags = 0;
                    function copySymbol(symbol, meaning) {
                        if (symbol.flags & meaning) {
                            var id = symbol.name;
                            if (!isReservedMemberName(id) && !ts.hasProperty(symbols, id)) {
                                symbols[id] = symbol;
                            }
                        }
                    }
                    function copySymbols(source, meaning) {
                        if (meaning) {
                            for (var id in source) {
                                if (ts.hasProperty(source, id)) {
                                    copySymbol(source[id], meaning);
                                }
                            }
                        }
                    }
                    if (isInsideWithStatementBody(location)) {
                        return [];
                    }
                    while (location) {
                        if (location.locals && !isGlobalSourceFile(location)) {
                            copySymbols(location.locals, meaning);
                        }
                        switch (location.kind) {
                            case 198 /* SourceFile */:
                                if (!ts.isExternalModule(location))
                                    break;
                            case 193 /* ModuleDeclaration */:
                                copySymbols(getSymbolOfNode(location).exports, meaning & 35653619 /* ModuleMember */);
                                break;
                            case 192 /* EnumDeclaration */:
                                copySymbols(getSymbolOfNode(location).exports, meaning & 8 /* EnumMember */);
                                break;
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                                if (!(memberFlags & 128 /* Static */)) {
                                    copySymbols(getSymbolOfNode(location).members, meaning & 3152352 /* Type */);
                                }
                                break;
                            case 153 /* FunctionExpression */:
                                if (location.name) {
                                    copySymbol(location.symbol, meaning);
                                }
                                break;
                            case 183 /* CatchBlock */:
                                if (location.variable.text) {
                                    copySymbol(location.symbol, meaning);
                                }
                                break;
                        }
                        memberFlags = location.flags;
                        location = location.parent;
                    }
                    copySymbols(globals, meaning);
                    return ts.mapToArray(symbols);
                }
                function isTypeDeclarationName(name) {
                    return name.kind == 63 /* Identifier */ && isTypeDeclaration(name.parent) && name.parent.name === name;
                }
                function isTypeDeclaration(node) {
                    switch (node.kind) {
                        case 123 /* TypeParameter */:
                        case 189 /* ClassDeclaration */:
                        case 190 /* InterfaceDeclaration */:
                        case 191 /* TypeAliasDeclaration */:
                        case 192 /* EnumDeclaration */:
                            return true;
                    }
                }
                function isTypeReferenceIdentifier(entityName) {
                    var node = entityName;
                    while (node.parent && node.parent.kind === 121 /* QualifiedName */)
                        node = node.parent;
                    return node.parent && node.parent.kind === 133 /* TypeReference */;
                }
                function isTypeNode(node) {
                    if (133 /* FirstTypeNode */ <= node.kind && node.kind <= 141 /* LastTypeNode */) {
                        return true;
                    }
                    switch (node.kind) {
                        case 109 /* AnyKeyword */:
                        case 116 /* NumberKeyword */:
                        case 118 /* StringKeyword */:
                        case 110 /* BooleanKeyword */:
                            return true;
                        case 97 /* VoidKeyword */:
                            return node.parent.kind !== 155 /* PrefixOperator */;
                        case 7 /* StringLiteral */:
                            return node.parent.kind === 124 /* Parameter */;
                        case 63 /* Identifier */:
                            if (node.parent.kind === 121 /* QualifiedName */ && node.parent.right === node) {
                                node = node.parent;
                            }
                        case 121 /* QualifiedName */:
                            ts.Debug.assert(node.kind === 63 /* Identifier */ || node.kind === 121 /* QualifiedName */, "'node' was expected to be a qualified name or identifier in 'isTypeNode'.");
                            var parent = node.parent;
                            if (parent.kind === 136 /* TypeQuery */) {
                                return false;
                            }
                            if (133 /* FirstTypeNode */ <= parent.kind && parent.kind <= 141 /* LastTypeNode */) {
                                return true;
                            }
                            switch (parent.kind) {
                                case 123 /* TypeParameter */:
                                    return node === parent.constraint;
                                case 125 /* Property */:
                                case 124 /* Parameter */:
                                case 186 /* VariableDeclaration */:
                                    return node === parent.type;
                                case 187 /* FunctionDeclaration */:
                                case 153 /* FunctionExpression */:
                                case 154 /* ArrowFunction */:
                                case 127 /* Constructor */:
                                case 126 /* Method */:
                                case 128 /* GetAccessor */:
                                case 129 /* SetAccessor */:
                                    return node === parent.type;
                                case 130 /* CallSignature */:
                                case 131 /* ConstructSignature */:
                                case 132 /* IndexSignature */:
                                    return node === parent.type;
                                case 151 /* TypeAssertion */:
                                    return node === parent.type;
                                case 148 /* CallExpression */:
                                case 149 /* NewExpression */:
                                    return parent.typeArguments && parent.typeArguments.indexOf(node) >= 0;
                                case 150 /* TaggedTemplateExpression */:
                                    return false;
                            }
                    }
                    return false;
                }
                function isInRightSideOfImportOrExportAssignment(node) {
                    while (node.parent.kind === 121 /* QualifiedName */) {
                        node = node.parent;
                    }
                    if (node.parent.kind === 195 /* ImportDeclaration */) {
                        return node.parent.entityName === node;
                    }
                    if (node.parent.kind === 196 /* ExportAssignment */) {
                        return node.parent.exportName === node;
                    }
                    return false;
                }
                function isRightSideOfQualifiedNameOrPropertyAccess(node) {
                    return (node.parent.kind === 121 /* QualifiedName */ || node.parent.kind === 146 /* PropertyAccess */) && node.parent.right === node;
                }
                function getSymbolOfEntityName(entityName) {
                    if (ts.isDeclarationOrFunctionExpressionOrCatchVariableName(entityName)) {
                        return getSymbolOfNode(entityName.parent);
                    }
                    if (entityName.parent.kind === 196 /* ExportAssignment */) {
                        return resolveEntityName(entityName.parent.parent, entityName, 107455 /* Value */ | 3152352 /* Type */ | 1536 /* Namespace */ | 33554432 /* Import */);
                    }
                    if (isInRightSideOfImportOrExportAssignment(entityName)) {
                        return getSymbolOfPartOfRightHandSideOfImport(entityName);
                    }
                    if (isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
                        entityName = entityName.parent;
                    }
                    if (ts.isExpression(entityName)) {
                        if (entityName.kind === 63 /* Identifier */) {
                            var meaning = 107455 /* Value */ | 33554432 /* Import */;
                            return resolveEntityName(entityName, entityName, meaning);
                        }
                        else if (entityName.kind === 121 /* QualifiedName */ || entityName.kind === 146 /* PropertyAccess */) {
                            var symbol = getNodeLinks(entityName).resolvedSymbol;
                            if (!symbol) {
                                checkPropertyAccess(entityName);
                            }
                            return getNodeLinks(entityName).resolvedSymbol;
                        }
                        else {
                            return;
                        }
                    }
                    else if (isTypeReferenceIdentifier(entityName)) {
                        var meaning = entityName.parent.kind === 133 /* TypeReference */ ? 3152352 /* Type */ : 1536 /* Namespace */;
                        meaning |= 33554432 /* Import */;
                        return resolveEntityName(entityName, entityName, meaning);
                    }
                    return undefined;
                }
                function getSymbolInfo(node) {
                    if (isInsideWithStatementBody(node)) {
                        return undefined;
                    }
                    if (ts.isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
                        return getSymbolOfNode(node.parent);
                    }
                    if (node.kind === 63 /* Identifier */ && isInRightSideOfImportOrExportAssignment(node)) {
                        return node.parent.kind === 196 /* ExportAssignment */ ? getSymbolOfEntityName(node) : getSymbolOfPartOfRightHandSideOfImport(node);
                    }
                    switch (node.kind) {
                        case 63 /* Identifier */:
                        case 146 /* PropertyAccess */:
                        case 121 /* QualifiedName */:
                            return getSymbolOfEntityName(node);
                        case 91 /* ThisKeyword */:
                        case 89 /* SuperKeyword */:
                            var type = checkExpression(node);
                            return type.symbol;
                        case 111 /* ConstructorKeyword */:
                            var constructorDeclaration = node.parent;
                            if (constructorDeclaration && constructorDeclaration.kind === 127 /* Constructor */) {
                                return constructorDeclaration.parent.symbol;
                            }
                            return undefined;
                        case 7 /* StringLiteral */:
                            if (node.parent.kind === 195 /* ImportDeclaration */ && node.parent.externalModuleName === node) {
                                var importSymbol = getSymbolOfNode(node.parent);
                                var moduleType = getTypeOfSymbol(importSymbol);
                                return moduleType ? moduleType.symbol : undefined;
                            }
                        case 6 /* NumericLiteral */:
                            if (node.parent.kind == 147 /* IndexedAccess */ && node.parent.index === node) {
                                var objectType = checkExpression(node.parent.object);
                                if (objectType === unknownType)
                                    return undefined;
                                var apparentType = getApparentType(objectType);
                                if (apparentType === unknownType)
                                    return undefined;
                                return getPropertyOfType(apparentType, node.text);
                            }
                            break;
                    }
                    return undefined;
                }
                function getShorthandAssignmentValueSymbol(location) {
                    if (location && location.kind === 145 /* ShorthandPropertyAssignment */) {
                        return resolveEntityName(location, location.name, 107455 /* Value */);
                    }
                    return undefined;
                }
                function getTypeOfNode(node) {
                    if (isInsideWithStatementBody(node)) {
                        return unknownType;
                    }
                    if (ts.isExpression(node)) {
                        return getTypeOfExpression(node);
                    }
                    if (isTypeNode(node)) {
                        return getTypeFromTypeNode(node);
                    }
                    if (isTypeDeclaration(node)) {
                        var symbol = getSymbolOfNode(node);
                        return getDeclaredTypeOfSymbol(symbol);
                    }
                    if (isTypeDeclarationName(node)) {
                        var symbol = getSymbolInfo(node);
                        return symbol && getDeclaredTypeOfSymbol(symbol);
                    }
                    if (ts.isDeclaration(node)) {
                        var symbol = getSymbolOfNode(node);
                        return getTypeOfSymbol(symbol);
                    }
                    if (ts.isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
                        var symbol = getSymbolInfo(node);
                        return symbol && getTypeOfSymbol(symbol);
                    }
                    if (isInRightSideOfImportOrExportAssignment(node)) {
                        var symbol = getSymbolInfo(node);
                        var declaredType = symbol && getDeclaredTypeOfSymbol(symbol);
                        return declaredType !== unknownType ? declaredType : getTypeOfSymbol(symbol);
                    }
                    return unknownType;
                }
                function getTypeOfExpression(expr) {
                    if (isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
                        expr = expr.parent;
                    }
                    return checkExpression(expr);
                }
                function getAugmentedPropertiesOfType(type) {
                    var type = getApparentType(type);
                    var propsByName = createSymbolTable(getPropertiesOfType(type));
                    if (getSignaturesOfType(type, 0 /* Call */).length || getSignaturesOfType(type, 1 /* Construct */).length) {
                        ts.forEach(getPropertiesOfType(globalFunctionType), function (p) {
                            if (!ts.hasProperty(propsByName, p.name)) {
                                propsByName[p.name] = p;
                            }
                        });
                    }
                    return getNamedMembers(propsByName);
                }
                function getRootSymbols(symbol) {
                    if (symbol.flags & 1073741824 /* UnionProperty */) {
                        var symbols = [];
                        var name = symbol.name;
                        ts.forEach(getSymbolLinks(symbol).unionType.types, function (t) {
                            symbols.push(getPropertyOfType(t, name));
                        });
                        return symbols;
                    }
                    else if (symbol.flags & 268435456 /* Transient */) {
                        var target = getSymbolLinks(symbol).target;
                        if (target) {
                            return [target];
                        }
                    }
                    return [symbol];
                }
                function isExternalModuleSymbol(symbol) {
                    return symbol.flags & 512 /* ValueModule */ && symbol.declarations.length === 1 && symbol.declarations[0].kind === 198 /* SourceFile */;
                }
                function isNodeDescendentOf(node, ancestor) {
                    while (node) {
                        if (node === ancestor)
                            return true;
                        node = node.parent;
                    }
                    return false;
                }
                function isUniqueLocalName(name, container) {
                    for (var node = container; isNodeDescendentOf(node, container); node = node.nextContainer) {
                        if (node.locals && ts.hasProperty(node.locals, name) && node.locals[name].flags & (107455 /* Value */ | 4194304 /* ExportValue */)) {
                            return false;
                        }
                    }
                    return true;
                }
                function getLocalNameOfContainer(container) {
                    var links = getNodeLinks(container);
                    if (!links.localModuleName) {
                        var prefix = "";
                        var name = ts.unescapeIdentifier(container.name.text);
                        while (!isUniqueLocalName(ts.escapeIdentifier(prefix + name), container)) {
                            prefix += "_";
                        }
                        links.localModuleName = prefix + ts.getTextOfNode(container.name);
                    }
                    return links.localModuleName;
                }
                function getLocalNameForSymbol(symbol, location) {
                    var node = location;
                    while (node) {
                        if ((node.kind === 193 /* ModuleDeclaration */ || node.kind === 192 /* EnumDeclaration */) && getSymbolOfNode(node) === symbol) {
                            return getLocalNameOfContainer(node);
                        }
                        node = node.parent;
                    }
                    ts.Debug.fail("getLocalNameForSymbol failed");
                }
                function getExpressionNamePrefix(node) {
                    var symbol = getNodeLinks(node).resolvedSymbol;
                    if (symbol) {
                        var exportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
                        if (symbol !== exportSymbol && !(exportSymbol.flags & 944 /* ExportHasLocal */)) {
                            symbol = exportSymbol;
                        }
                        if (symbol.parent) {
                            return isExternalModuleSymbol(symbol.parent) ? "exports" : getLocalNameForSymbol(getParentOfSymbol(symbol), node.parent);
                        }
                    }
                }
                function getExportAssignmentName(node) {
                    var symbol = getExportAssignmentSymbol(getSymbolOfNode(node));
                    return symbol && symbolIsValue(symbol) && !isConstEnumSymbol(symbol) ? symbolToString(symbol) : undefined;
                }
                function isTopLevelValueImportWithEntityName(node) {
                    if (node.parent.kind !== 198 /* SourceFile */ || !node.entityName) {
                        return false;
                    }
                    return isImportResolvedToValue(getSymbolOfNode(node));
                }
                function hasSemanticErrors() {
                    return getDiagnostics().length > 0 || getGlobalDiagnostics().length > 0;
                }
                function isEmitBlocked(sourceFile) {
                    return program.getDiagnostics(sourceFile).length !== 0 || hasEarlyErrors(sourceFile) || (compilerOptions.noEmitOnError && getDiagnostics(sourceFile).length !== 0);
                }
                function hasEarlyErrors(sourceFile) {
                    return ts.forEach(getDiagnostics(sourceFile), function (d) { return d.isEarly; });
                }
                function isImportResolvedToValue(symbol) {
                    var target = resolveImport(symbol);
                    return target !== unknownSymbol && target.flags & 107455 /* Value */ && !isConstEnumOrConstEnumOnlyModule(target);
                }
                function isConstEnumOrConstEnumOnlyModule(s) {
                    return isConstEnumSymbol(s) || s.constEnumOnlyModule;
                }
                function isReferencedImportDeclaration(node) {
                    var symbol = getSymbolOfNode(node);
                    if (getSymbolLinks(symbol).referenced) {
                        return true;
                    }
                    if (node.flags & 1 /* Export */) {
                        return isImportResolvedToValue(symbol);
                    }
                    return false;
                }
                function isImplementationOfOverload(node) {
                    if (node.body) {
                        var symbol = getSymbolOfNode(node);
                        var signaturesOfSymbol = getSignaturesOfSymbol(symbol);
                        return signaturesOfSymbol.length > 1 || (signaturesOfSymbol.length === 1 && signaturesOfSymbol[0].declaration !== node);
                    }
                    return false;
                }
                function getNodeCheckFlags(node) {
                    return getNodeLinks(node).flags;
                }
                function getEnumMemberValue(node) {
                    computeEnumMemberValues(node.parent);
                    return getNodeLinks(node).enumMemberValue;
                }
                function getConstantValue(node) {
                    var symbol = getNodeLinks(node).resolvedSymbol;
                    if (symbol && (symbol.flags & 8 /* EnumMember */)) {
                        var declaration = symbol.valueDeclaration;
                        var constantValue;
                        if (declaration.kind === 197 /* EnumMember */ && (constantValue = getNodeLinks(declaration).enumMemberValue) !== undefined) {
                            return constantValue;
                        }
                    }
                    return undefined;
                }
                function writeTypeAtLocation(location, enclosingDeclaration, flags, writer) {
                    var symbol = getSymbolOfNode(location);
                    var type = symbol && !(symbol.flags & (2048 /* TypeLiteral */ | 131072 /* CallSignature */ | 262144 /* ConstructSignature */)) ? getTypeOfSymbol(symbol) : getTypeFromTypeNode(location);
                    getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
                }
                function writeReturnTypeOfSignatureDeclaration(signatureDeclaration, enclosingDeclaration, flags, writer) {
                    var signature = getSignatureFromDeclaration(signatureDeclaration);
                    getSymbolDisplayBuilder().buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags);
                }
                function createResolver() {
                    return {
                        getProgram: function () { return program; },
                        getLocalNameOfContainer: getLocalNameOfContainer,
                        getExpressionNamePrefix: getExpressionNamePrefix,
                        getExportAssignmentName: getExportAssignmentName,
                        isReferencedImportDeclaration: isReferencedImportDeclaration,
                        getNodeCheckFlags: getNodeCheckFlags,
                        getEnumMemberValue: getEnumMemberValue,
                        isTopLevelValueImportWithEntityName: isTopLevelValueImportWithEntityName,
                        hasSemanticErrors: hasSemanticErrors,
                        isEmitBlocked: isEmitBlocked,
                        isDeclarationVisible: isDeclarationVisible,
                        isImplementationOfOverload: isImplementationOfOverload,
                        writeTypeAtLocation: writeTypeAtLocation,
                        writeReturnTypeOfSignatureDeclaration: writeReturnTypeOfSignatureDeclaration,
                        isSymbolAccessible: isSymbolAccessible,
                        isEntityNameVisible: isEntityNameVisible,
                        getConstantValue: getConstantValue
                    };
                }
                function invokeEmitter(targetSourceFile) {
                    var resolver = createResolver();
                    checkProgram();
                    return ts.emitFiles(resolver, targetSourceFile);
                }
                function initializeTypeChecker() {
                    ts.forEach(program.getSourceFiles(), function (file) {
                        ts.bindSourceFile(file);
                        ts.forEach(file.semanticDiagnostics, addDiagnostic);
                    });
                    ts.forEach(program.getSourceFiles(), function (file) {
                        if (!ts.isExternalModule(file)) {
                            extendSymbolTable(globals, file.locals);
                        }
                    });
                    getSymbolLinks(undefinedSymbol).type = undefinedType;
                    getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments");
                    getSymbolLinks(unknownSymbol).type = unknownType;
                    globals[undefinedSymbol.name] = undefinedSymbol;
                    globalArraySymbol = getGlobalSymbol("Array");
                    globalArrayType = getTypeOfGlobalSymbol(globalArraySymbol, 1);
                    globalObjectType = getGlobalType("Object");
                    globalFunctionType = getGlobalType("Function");
                    globalStringType = getGlobalType("String");
                    globalNumberType = getGlobalType("Number");
                    globalBooleanType = getGlobalType("Boolean");
                    globalRegExpType = getGlobalType("RegExp");
                    globalTemplateStringsArrayType = compilerOptions.target >= 2 /* ES6 */ ? getGlobalType("TemplateStringsArray") : unknownType;
                }
                initializeTypeChecker();
                return checker;
            }
            ts.createTypeChecker = createTypeChecker;
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var TextSpan = (function () {
                function TextSpan(start, length) {
                    ts.Debug.assert(start >= 0, "start");
                    ts.Debug.assert(length >= 0, "length");
                    this._start = start;
                    this._length = length;
                }
                TextSpan.prototype.toJSON = function (key) {
                    return { start: this._start, length: this._length };
                };
                TextSpan.prototype.start = function () {
                    return this._start;
                };
                TextSpan.prototype.length = function () {
                    return this._length;
                };
                TextSpan.prototype.end = function () {
                    return this._start + this._length;
                };
                TextSpan.prototype.isEmpty = function () {
                    return this._length === 0;
                };
                TextSpan.prototype.containsPosition = function (position) {
                    return position >= this._start && position < this.end();
                };
                TextSpan.prototype.containsTextSpan = function (span) {
                    return span._start >= this._start && span.end() <= this.end();
                };
                TextSpan.prototype.overlapsWith = function (span) {
                    var overlapStart = Math.max(this._start, span._start);
                    var overlapEnd = Math.min(this.end(), span.end());
                    return overlapStart < overlapEnd;
                };
                TextSpan.prototype.overlap = function (span) {
                    var overlapStart = Math.max(this._start, span._start);
                    var overlapEnd = Math.min(this.end(), span.end());
                    if (overlapStart < overlapEnd) {
                        return TextSpan.fromBounds(overlapStart, overlapEnd);
                    }
                    return undefined;
                };
                TextSpan.prototype.intersectsWithTextSpan = function (span) {
                    return span._start <= this.end() && span.end() >= this._start;
                };
                TextSpan.prototype.intersectsWith = function (start, length) {
                    var end = start + length;
                    return start <= this.end() && end >= this._start;
                };
                TextSpan.prototype.intersectsWithPosition = function (position) {
                    return position <= this.end() && position >= this._start;
                };
                TextSpan.prototype.intersection = function (span) {
                    var intersectStart = Math.max(this._start, span._start);
                    var intersectEnd = Math.min(this.end(), span.end());
                    if (intersectStart <= intersectEnd) {
                        return TextSpan.fromBounds(intersectStart, intersectEnd);
                    }
                    return undefined;
                };
                TextSpan.fromBounds = function (start, end) {
                    ts.Debug.assert(start >= 0);
                    ts.Debug.assert(end - start >= 0);
                    return new TextSpan(start, end - start);
                };
                return TextSpan;
            })();
            ts.TextSpan = TextSpan;
            var TextChangeRange = (function () {
                function TextChangeRange(span, newLength) {
                    ts.Debug.assert(newLength >= 0, "newLength");
                    this._span = span;
                    this._newLength = newLength;
                }
                TextChangeRange.prototype.span = function () {
                    return this._span;
                };
                TextChangeRange.prototype.newLength = function () {
                    return this._newLength;
                };
                TextChangeRange.prototype.newSpan = function () {
                    return new TextSpan(this.span().start(), this.newLength());
                };
                TextChangeRange.prototype.isUnchanged = function () {
                    return this.span().isEmpty() && this.newLength() === 0;
                };
                TextChangeRange.collapseChangesAcrossMultipleVersions = function (changes) {
                    if (changes.length === 0) {
                        return TextChangeRange.unchanged;
                    }
                    if (changes.length === 1) {
                        return changes[0];
                    }
                    var change0 = changes[0];
                    var oldStartN = change0.span().start();
                    var oldEndN = change0.span().end();
                    var newEndN = oldStartN + change0.newLength();
                    for (var i = 1; i < changes.length; i++) {
                        var nextChange = changes[i];
                        var oldStart1 = oldStartN;
                        var oldEnd1 = oldEndN;
                        var newEnd1 = newEndN;
                        var oldStart2 = nextChange.span().start();
                        var oldEnd2 = nextChange.span().end();
                        var newEnd2 = oldStart2 + nextChange.newLength();
                        oldStartN = Math.min(oldStart1, oldStart2);
                        oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
                        newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2));
                    }
                    return new TextChangeRange(TextSpan.fromBounds(oldStartN, oldEndN), newEndN - oldStartN);
                };
                TextChangeRange.unchanged = new TextChangeRange(new TextSpan(0, 0), 0);
                return TextChangeRange;
            })();
            ts.TextChangeRange = TextChangeRange;
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var OutliningElementsCollector;
            (function (OutliningElementsCollector) {
                function collectElements(sourceFile) {
                    var elements = [];
                    var collapseText = "...";
                    function addOutliningSpan(hintSpanNode, startElement, endElement, autoCollapse) {
                        if (hintSpanNode && startElement && endElement) {
                            var span = {
                                textSpan: ts.TextSpan.fromBounds(startElement.pos, endElement.end),
                                hintSpan: ts.TextSpan.fromBounds(hintSpanNode.getStart(), hintSpanNode.end),
                                bannerText: collapseText,
                                autoCollapse: autoCollapse
                            };
                            elements.push(span);
                        }
                    }
                    function autoCollapse(node) {
                        switch (node.kind) {
                            case 194 /* ModuleBlock */:
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                            case 192 /* EnumDeclaration */:
                                return false;
                        }
                        return true;
                    }
                    var depth = 0;
                    var maxDepth = 20;
                    function walk(n) {
                        if (depth > maxDepth) {
                            return;
                        }
                        switch (n.kind) {
                            case 163 /* Block */:
                                var parent = n.parent;
                                var openBrace = ts.findChildOfKind(n, 13 /* OpenBraceToken */, sourceFile);
                                var closeBrace = ts.findChildOfKind(n, 14 /* CloseBraceToken */, sourceFile);
                                if (parent.kind === 168 /* DoStatement */ || parent.kind === 171 /* ForInStatement */ || parent.kind === 170 /* ForStatement */ || parent.kind === 167 /* IfStatement */ || parent.kind === 169 /* WhileStatement */ || parent.kind === 175 /* WithStatement */) {
                                    addOutliningSpan(parent, openBrace, closeBrace, autoCollapse(n));
                                }
                                else {
                                    var span = ts.TextSpan.fromBounds(n.getStart(), n.end);
                                    elements.push({
                                        textSpan: span,
                                        hintSpan: span,
                                        bannerText: collapseText,
                                        autoCollapse: autoCollapse(n)
                                    });
                                }
                                break;
                            case 188 /* FunctionBlock */:
                            case 194 /* ModuleBlock */:
                            case 182 /* TryBlock */:
                            case 183 /* CatchBlock */:
                            case 184 /* FinallyBlock */:
                                var openBrace = ts.findChildOfKind(n, 13 /* OpenBraceToken */, sourceFile);
                                var closeBrace = ts.findChildOfKind(n, 14 /* CloseBraceToken */, sourceFile);
                                addOutliningSpan(n.parent, openBrace, closeBrace, autoCollapse(n));
                                break;
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                            case 192 /* EnumDeclaration */:
                            case 143 /* ObjectLiteral */:
                            case 176 /* SwitchStatement */:
                                var openBrace = ts.findChildOfKind(n, 13 /* OpenBraceToken */, sourceFile);
                                var closeBrace = ts.findChildOfKind(n, 14 /* CloseBraceToken */, sourceFile);
                                addOutliningSpan(n, openBrace, closeBrace, autoCollapse(n));
                                break;
                            case 142 /* ArrayLiteral */:
                                var openBracket = ts.findChildOfKind(n, 17 /* OpenBracketToken */, sourceFile);
                                var closeBracket = ts.findChildOfKind(n, 18 /* CloseBracketToken */, sourceFile);
                                addOutliningSpan(n, openBracket, closeBracket, autoCollapse(n));
                                break;
                        }
                        depth++;
                        ts.forEachChild(n, walk);
                        depth--;
                    }
                    walk(sourceFile);
                    return elements;
                }
                OutliningElementsCollector.collectElements = collectElements;
            })(OutliningElementsCollector = ts.OutliningElementsCollector || (ts.OutliningElementsCollector = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var NavigationBar;
            (function (NavigationBar) {
                function getNavigationBarItems(sourceFile) {
                    var hasGlobalNode = false;
                    return getItemsWorker(getTopLevelNodes(sourceFile), createTopLevelItem);
                    function getIndent(node) {
                        var indent = hasGlobalNode ? 1 : 0;
                        var current = node.parent;
                        while (current) {
                            switch (current.kind) {
                                case 193 /* ModuleDeclaration */:
                                    do {
                                        current = current.parent;
                                    } while (current.kind === 193 /* ModuleDeclaration */);
                                case 189 /* ClassDeclaration */:
                                case 192 /* EnumDeclaration */:
                                case 190 /* InterfaceDeclaration */:
                                case 187 /* FunctionDeclaration */:
                                    indent++;
                            }
                            current = current.parent;
                        }
                        return indent;
                    }
                    function getChildNodes(nodes) {
                        var childNodes = [];
                        for (var i = 0, n = nodes.length; i < n; i++) {
                            var node = nodes[i];
                            if (node.kind === 189 /* ClassDeclaration */ || node.kind === 192 /* EnumDeclaration */ || node.kind === 190 /* InterfaceDeclaration */ || node.kind === 193 /* ModuleDeclaration */ || node.kind === 187 /* FunctionDeclaration */) {
                                childNodes.push(node);
                            }
                            else if (node.kind === 164 /* VariableStatement */) {
                                childNodes.push.apply(childNodes, node.declarations);
                            }
                        }
                        return sortNodes(childNodes);
                    }
                    function getTopLevelNodes(node) {
                        var topLevelNodes = [];
                        topLevelNodes.push(node);
                        addTopLevelNodes(node.statements, topLevelNodes);
                        return topLevelNodes;
                    }
                    function sortNodes(nodes) {
                        return nodes.slice(0).sort(function (n1, n2) {
                            if (n1.name && n2.name) {
                                return n1.name.text.localeCompare(n2.name.text);
                            }
                            else if (n1.name) {
                                return 1;
                            }
                            else if (n2.name) {
                                return -1;
                            }
                            else {
                                return n1.kind - n2.kind;
                            }
                        });
                    }
                    function addTopLevelNodes(nodes, topLevelNodes) {
                        nodes = sortNodes(nodes);
                        for (var i = 0, n = nodes.length; i < n; i++) {
                            var node = nodes[i];
                            switch (node.kind) {
                                case 189 /* ClassDeclaration */:
                                case 192 /* EnumDeclaration */:
                                case 190 /* InterfaceDeclaration */:
                                    topLevelNodes.push(node);
                                    break;
                                case 193 /* ModuleDeclaration */:
                                    var moduleDeclaration = node;
                                    topLevelNodes.push(node);
                                    addTopLevelNodes(getInnermostModule(moduleDeclaration).body.statements, topLevelNodes);
                                    break;
                                case 187 /* FunctionDeclaration */:
                                    var functionDeclaration = node;
                                    if (isTopLevelFunctionDeclaration(functionDeclaration)) {
                                        topLevelNodes.push(node);
                                        addTopLevelNodes(functionDeclaration.body.statements, topLevelNodes);
                                    }
                                    break;
                            }
                        }
                    }
                    function isTopLevelFunctionDeclaration(functionDeclaration) {
                        if (functionDeclaration.kind === 187 /* FunctionDeclaration */) {
                            if (functionDeclaration.body && functionDeclaration.body.kind === 188 /* FunctionBlock */) {
                                if (ts.forEach(functionDeclaration.body.statements, function (s) { return s.kind === 187 /* FunctionDeclaration */ && !isEmpty(s.name.text); })) {
                                    return true;
                                }
                                if (functionDeclaration.parent.kind !== 188 /* FunctionBlock */) {
                                    return true;
                                }
                            }
                        }
                        return false;
                    }
                    function getItemsWorker(nodes, createItem) {
                        var items = [];
                        var keyToItem = {};
                        for (var i = 0, n = nodes.length; i < n; i++) {
                            var child = nodes[i];
                            var item = createItem(child);
                            if (item !== undefined) {
                                if (item.text.length > 0) {
                                    var key = item.text + "-" + item.kind + "-" + item.indent;
                                    var itemWithSameName = keyToItem[key];
                                    if (itemWithSameName) {
                                        merge(itemWithSameName, item);
                                    }
                                    else {
                                        keyToItem[key] = item;
                                        items.push(item);
                                    }
                                }
                            }
                        }
                        return items;
                    }
                    function merge(target, source) {
                        target.spans.push.apply(target.spans, source.spans);
                        if (source.childItems) {
                            if (!target.childItems) {
                                target.childItems = [];
                            }
                            outer: for (var i = 0, n = source.childItems.length; i < n; i++) {
                                var sourceChild = source.childItems[i];
                                for (var j = 0, m = target.childItems.length; j < m; j++) {
                                    var targetChild = target.childItems[j];
                                    if (targetChild.text === sourceChild.text && targetChild.kind === sourceChild.kind) {
                                        merge(targetChild, sourceChild);
                                        continue outer;
                                    }
                                }
                                target.childItems.push(sourceChild);
                            }
                        }
                    }
                    function createChildItem(node) {
                        switch (node.kind) {
                            case 124 /* Parameter */:
                                if ((node.flags & 243 /* Modifier */) === 0) {
                                    return undefined;
                                }
                                return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberVariableElement);
                            case 126 /* Method */:
                                return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberFunctionElement);
                            case 128 /* GetAccessor */:
                                return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberGetAccessorElement);
                            case 129 /* SetAccessor */:
                                return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberSetAccessorElement);
                            case 132 /* IndexSignature */:
                                return createItem(node, "[]", ts.ScriptElementKind.indexSignatureElement);
                            case 197 /* EnumMember */:
                                return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberVariableElement);
                            case 130 /* CallSignature */:
                                return createItem(node, "()", ts.ScriptElementKind.callSignatureElement);
                            case 131 /* ConstructSignature */:
                                return createItem(node, "new()", ts.ScriptElementKind.constructSignatureElement);
                            case 125 /* Property */:
                                return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.memberVariableElement);
                            case 187 /* FunctionDeclaration */:
                                return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.functionElement);
                            case 186 /* VariableDeclaration */:
                                if (ts.isConst(node)) {
                                    return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.constElement);
                                }
                                else if (ts.isLet(node)) {
                                    return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.letElement);
                                }
                                else {
                                    return createItem(node, getTextOfNode(node.name), ts.ScriptElementKind.variableElement);
                                }
                            case 127 /* Constructor */:
                                return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement);
                        }
                        return undefined;
                        function createItem(node, name, scriptElementKind) {
                            return getNavigationBarItem(name, scriptElementKind, ts.getNodeModifiers(node), [getNodeSpan(node)]);
                        }
                    }
                    function isEmpty(text) {
                        return !text || text.trim() === "";
                    }
                    function getNavigationBarItem(text, kind, kindModifiers, spans, childItems, indent) {
                        if (childItems === void 0) { childItems = []; }
                        if (indent === void 0) { indent = 0; }
                        if (isEmpty(text)) {
                            return undefined;
                        }
                        return {
                            text: text,
                            kind: kind,
                            kindModifiers: kindModifiers,
                            spans: spans,
                            childItems: childItems,
                            indent: indent,
                            bolded: false,
                            grayed: false
                        };
                    }
                    function createTopLevelItem(node) {
                        switch (node.kind) {
                            case 198 /* SourceFile */:
                                return createSourceFileItem(node);
                            case 189 /* ClassDeclaration */:
                                return createClassItem(node);
                            case 192 /* EnumDeclaration */:
                                return createEnumItem(node);
                            case 190 /* InterfaceDeclaration */:
                                return createIterfaceItem(node);
                            case 193 /* ModuleDeclaration */:
                                return createModuleItem(node);
                            case 187 /* FunctionDeclaration */:
                                return createFunctionItem(node);
                        }
                        return undefined;
                        function getModuleName(moduleDeclaration) {
                            if (moduleDeclaration.name.kind === 7 /* StringLiteral */) {
                                return getTextOfNode(moduleDeclaration.name);
                            }
                            var result = [];
                            result.push(moduleDeclaration.name.text);
                            while (moduleDeclaration.body && moduleDeclaration.body.kind === 193 /* ModuleDeclaration */) {
                                moduleDeclaration = moduleDeclaration.body;
                                result.push(moduleDeclaration.name.text);
                            }
                            return result.join(".");
                        }
                        function createModuleItem(node) {
                            var moduleName = getModuleName(node);
                            var childItems = getItemsWorker(getChildNodes(getInnermostModule(node).body.statements), createChildItem);
                            return getNavigationBarItem(moduleName, ts.ScriptElementKind.moduleElement, ts.getNodeModifiers(node), [getNodeSpan(node)], childItems, getIndent(node));
                        }
                        function createFunctionItem(node) {
                            if (node.name && node.body && node.body.kind === 188 /* FunctionBlock */) {
                                var childItems = getItemsWorker(sortNodes(node.body.statements), createChildItem);
                                return getNavigationBarItem(node.name.text, ts.ScriptElementKind.functionElement, ts.getNodeModifiers(node), [getNodeSpan(node)], childItems, getIndent(node));
                            }
                            return undefined;
                        }
                        function createSourceFileItem(node) {
                            var childItems = getItemsWorker(getChildNodes(node.statements), createChildItem);
                            if (childItems === undefined || childItems.length === 0) {
                                return undefined;
                            }
                            hasGlobalNode = true;
                            var rootName = ts.isExternalModule(node) ? "\"" + ts.escapeString(ts.getBaseFilename(ts.removeFileExtension(ts.normalizePath(node.filename)))) + "\"" : "<global>";
                            return getNavigationBarItem(rootName, ts.ScriptElementKind.moduleElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)], childItems);
                        }
                        function createClassItem(node) {
                            var childItems;
                            if (node.members) {
                                var constructor = ts.forEach(node.members, function (member) {
                                    return member.kind === 127 /* Constructor */ && member;
                                });
                                var nodes = removeComputedProperties(node);
                                if (constructor) {
                                    nodes.push.apply(nodes, constructor.parameters);
                                }
                                var childItems = getItemsWorker(sortNodes(nodes), createChildItem);
                            }
                            return getNavigationBarItem(node.name.text, ts.ScriptElementKind.classElement, ts.getNodeModifiers(node), [getNodeSpan(node)], childItems, getIndent(node));
                        }
                        function createEnumItem(node) {
                            var childItems = getItemsWorker(sortNodes(removeComputedProperties(node)), createChildItem);
                            return getNavigationBarItem(node.name.text, ts.ScriptElementKind.enumElement, ts.getNodeModifiers(node), [getNodeSpan(node)], childItems, getIndent(node));
                        }
                        function createIterfaceItem(node) {
                            var childItems = getItemsWorker(sortNodes(removeComputedProperties(node)), createChildItem);
                            return getNavigationBarItem(node.name.text, ts.ScriptElementKind.interfaceElement, ts.getNodeModifiers(node), [getNodeSpan(node)], childItems, getIndent(node));
                        }
                    }
                    function removeComputedProperties(node) {
                        return ts.filter(node.members, function (member) { return member.name === undefined || member.name.kind !== 122 /* ComputedPropertyName */; });
                    }
                    function getInnermostModule(node) {
                        while (node.body.kind === 193 /* ModuleDeclaration */) {
                            node = node.body;
                        }
                        return node;
                    }
                    function getNodeSpan(node) {
                        return node.kind === 198 /* SourceFile */ ? ts.TextSpan.fromBounds(node.getFullStart(), node.getEnd()) : ts.TextSpan.fromBounds(node.getStart(), node.getEnd());
                    }
                    function getTextOfNode(node) {
                        return ts.getTextOfNodeFromSourceText(sourceFile.text, node);
                    }
                }
                NavigationBar.getNavigationBarItems = getNavigationBarItems;
            })(NavigationBar = ts.NavigationBar || (ts.NavigationBar = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var SignatureHelp;
            (function (SignatureHelp) {
                var emptyArray = [];
                var ArgumentListKind;
                (function (ArgumentListKind) {
                    ArgumentListKind[ArgumentListKind["TypeArguments"] = 0] = "TypeArguments";
                    ArgumentListKind[ArgumentListKind["CallArguments"] = 1] = "CallArguments";
                    ArgumentListKind[ArgumentListKind["TaggedTemplateArguments"] = 2] = "TaggedTemplateArguments";
                })(ArgumentListKind || (ArgumentListKind = {}));
                function getSignatureHelpItems(sourceFile, position, typeInfoResolver, cancellationToken) {
                    var startingToken = ts.findTokenOnLeftOfPosition(sourceFile, position);
                    if (!startingToken) {
                        return undefined;
                    }
                    var argumentInfo = getContainingArgumentInfo(startingToken);
                    cancellationToken.throwIfCancellationRequested();
                    if (!argumentInfo) {
                        return undefined;
                    }
                    var call = argumentInfo.invocation;
                    var candidates = [];
                    var resolvedSignature = typeInfoResolver.getResolvedSignature(call, candidates);
                    cancellationToken.throwIfCancellationRequested();
                    if (!candidates.length) {
                        return undefined;
                    }
                    return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo);
                    function getImmediatelyContainingArgumentInfo(node) {
                        if (node.parent.kind === 148 /* CallExpression */ || node.parent.kind === 149 /* NewExpression */) {
                            var callExpression = node.parent;
                            if (node.kind === 23 /* LessThanToken */ || node.kind === 15 /* OpenParenToken */) {
                                var list = getChildListThatStartsWithOpenerToken(callExpression, node, sourceFile);
                                var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos;
                                ts.Debug.assert(list !== undefined);
                                return {
                                    kind: isTypeArgList ? 0 /* TypeArguments */ : 1 /* CallArguments */,
                                    invocation: callExpression,
                                    argumentsSpan: getApplicableSpanForArguments(list),
                                    argumentIndex: 0,
                                    argumentCount: getCommaBasedArgCount(list)
                                };
                            }
                            var listItemInfo = ts.findListItemInfo(node);
                            if (listItemInfo) {
                                var list = listItemInfo.list;
                                var isTypeArgList = callExpression.typeArguments && callExpression.typeArguments.pos === list.pos;
                                var argumentIndex = (listItemInfo.listItemIndex + 1) >> 1;
                                return {
                                    kind: isTypeArgList ? 0 /* TypeArguments */ : 1 /* CallArguments */,
                                    invocation: callExpression,
                                    argumentsSpan: getApplicableSpanForArguments(list),
                                    argumentIndex: argumentIndex,
                                    argumentCount: getCommaBasedArgCount(list)
                                };
                            }
                        }
                        else if (node.kind === 9 /* NoSubstitutionTemplateLiteral */ && node.parent.kind === 150 /* TaggedTemplateExpression */) {
                            if (ts.isInsideTemplateLiteral(node, position)) {
                                return getArgumentListInfoForTemplate(node.parent, 0);
                            }
                        }
                        else if (node.kind === 10 /* TemplateHead */ && node.parent.parent.kind === 150 /* TaggedTemplateExpression */) {
                            var templateExpression = node.parent;
                            var tagExpression = templateExpression.parent;
                            ts.Debug.assert(templateExpression.kind === 159 /* TemplateExpression */);
                            var argumentIndex = ts.isInsideTemplateLiteral(node, position) ? 0 : 1;
                            return getArgumentListInfoForTemplate(tagExpression, argumentIndex);
                        }
                        else if (node.parent.kind === 160 /* TemplateSpan */ && node.parent.parent.parent.kind === 150 /* TaggedTemplateExpression */) {
                            var templateSpan = node.parent;
                            var templateExpression = templateSpan.parent;
                            var tagExpression = templateExpression.parent;
                            ts.Debug.assert(templateExpression.kind === 159 /* TemplateExpression */);
                            if (node.kind === 12 /* TemplateTail */ && position >= node.getEnd() && !ts.isUnterminatedTemplateEnd(node)) {
                                return undefined;
                            }
                            var spanIndex = templateExpression.templateSpans.indexOf(templateSpan);
                            var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node);
                            return getArgumentListInfoForTemplate(tagExpression, argumentIndex);
                        }
                        return undefined;
                    }
                    function getCommaBasedArgCount(argumentsList) {
                        return argumentsList.getChildCount() === 0 ? 0 : 1 + ts.countWhere(argumentsList.getChildren(), function (arg) { return arg.kind === 22 /* CommaToken */; });
                    }
                    function getArgumentIndexForTemplatePiece(spanIndex, node) {
                        ts.Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node.");
                        if (ts.isTemplateLiteralKind(node.kind)) {
                            if (ts.isInsideTemplateLiteral(node, position)) {
                                return 0;
                            }
                            return spanIndex + 2;
                        }
                        return spanIndex + 1;
                    }
                    function getArgumentListInfoForTemplate(tagExpression, argumentIndex) {
                        var argumentCount = tagExpression.template.kind === 9 /* NoSubstitutionTemplateLiteral */ ? 1 : tagExpression.template.templateSpans.length + 1;
                        return {
                            kind: 2 /* TaggedTemplateArguments */,
                            invocation: tagExpression,
                            argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression),
                            argumentIndex: argumentIndex,
                            argumentCount: argumentCount
                        };
                    }
                    function getApplicableSpanForArguments(argumentsList) {
                        var applicableSpanStart = argumentsList.getFullStart();
                        var applicableSpanEnd = ts.skipTrivia(sourceFile.text, argumentsList.getEnd(), false);
                        return new ts.TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
                    }
                    function getApplicableSpanForTaggedTemplate(taggedTemplate) {
                        var template = taggedTemplate.template;
                        var applicableSpanStart = template.getStart();
                        var applicableSpanEnd = template.getEnd();
                        if (template.kind === 159 /* TemplateExpression */) {
                            var lastSpan = ts.lastOrUndefined(template.templateSpans);
                            if (lastSpan.literal.kind === 120 /* Missing */) {
                                applicableSpanEnd = ts.skipTrivia(sourceFile.text, applicableSpanEnd, false);
                            }
                        }
                        return new ts.TextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart);
                    }
                    function getContainingArgumentInfo(node) {
                        for (var n = node; n.kind !== 198 /* SourceFile */; n = n.parent) {
                            if (n.kind === 188 /* FunctionBlock */) {
                                return undefined;
                            }
                            if (n.pos < n.parent.pos || n.end > n.parent.end) {
                                ts.Debug.fail("Node of kind " + n.kind + " is not a subspan of its parent of kind " + n.parent.kind);
                            }
                            var argumentInfo = getImmediatelyContainingArgumentInfo(n);
                            if (argumentInfo) {
                                return argumentInfo;
                            }
                        }
                        return undefined;
                    }
                    function getChildListThatStartsWithOpenerToken(parent, openerToken, sourceFile) {
                        var children = parent.getChildren(sourceFile);
                        var indexOfOpenerToken = children.indexOf(openerToken);
                        ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1);
                        return children[indexOfOpenerToken + 1];
                    }
                    function selectBestInvalidOverloadIndex(candidates, argumentCount) {
                        var maxParamsSignatureIndex = -1;
                        var maxParams = -1;
                        for (var i = 0; i < candidates.length; i++) {
                            var candidate = candidates[i];
                            if (candidate.hasRestParameter || candidate.parameters.length >= argumentCount) {
                                return i;
                            }
                            if (candidate.parameters.length > maxParams) {
                                maxParams = candidate.parameters.length;
                                maxParamsSignatureIndex = i;
                            }
                        }
                        return maxParamsSignatureIndex;
                    }
                    function createSignatureHelpItems(candidates, bestSignature, argumentListInfo) {
                        var applicableSpan = argumentListInfo.argumentsSpan;
                        var isTypeParameterList = argumentListInfo.kind === 0 /* TypeArguments */;
                        var invocation = argumentListInfo.invocation;
                        var callTarget = ts.getInvokedExpression(invocation);
                        var callTargetSymbol = typeInfoResolver.getSymbolInfo(callTarget);
                        var callTargetDisplayParts = callTargetSymbol && ts.symbolToDisplayParts(typeInfoResolver, callTargetSymbol, undefined, undefined);
                        var items = ts.map(candidates, function (candidateSignature) {
                            var signatureHelpParameters;
                            var prefixDisplayParts = [];
                            var suffixDisplayParts = [];
                            if (callTargetDisplayParts) {
                                prefixDisplayParts.push.apply(prefixDisplayParts, callTargetDisplayParts);
                            }
                            if (isTypeParameterList) {
                                prefixDisplayParts.push(ts.punctuationPart(23 /* LessThanToken */));
                                var typeParameters = candidateSignature.typeParameters;
                                signatureHelpParameters = typeParameters && typeParameters.length > 0 ? ts.map(typeParameters, createSignatureHelpParameterForTypeParameter) : emptyArray;
                                suffixDisplayParts.push(ts.punctuationPart(24 /* GreaterThanToken */));
                                var parameterParts = ts.mapToDisplayParts(function (writer) { return typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.parameters, writer, invocation); });
                                suffixDisplayParts.push.apply(suffixDisplayParts, parameterParts);
                            }
                            else {
                                var typeParameterParts = ts.mapToDisplayParts(function (writer) { return typeInfoResolver.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation); });
                                prefixDisplayParts.push.apply(prefixDisplayParts, typeParameterParts);
                                prefixDisplayParts.push(ts.punctuationPart(15 /* OpenParenToken */));
                                var parameters = candidateSignature.parameters;
                                signatureHelpParameters = parameters.length > 0 ? ts.map(parameters, createSignatureHelpParameterForParameter) : emptyArray;
                                suffixDisplayParts.push(ts.punctuationPart(16 /* CloseParenToken */));
                            }
                            var returnTypeParts = ts.mapToDisplayParts(function (writer) { return typeInfoResolver.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation); });
                            suffixDisplayParts.push.apply(suffixDisplayParts, returnTypeParts);
                            return {
                                isVariadic: candidateSignature.hasRestParameter,
                                prefixDisplayParts: prefixDisplayParts,
                                suffixDisplayParts: suffixDisplayParts,
                                separatorDisplayParts: [ts.punctuationPart(22 /* CommaToken */), ts.spacePart()],
                                parameters: signatureHelpParameters,
                                documentation: candidateSignature.getDocumentationComment()
                            };
                        });
                        var argumentIndex = argumentListInfo.argumentIndex;
                        var argumentCount = argumentListInfo.argumentCount;
                        var selectedItemIndex = candidates.indexOf(bestSignature);
                        if (selectedItemIndex < 0) {
                            selectedItemIndex = selectBestInvalidOverloadIndex(candidates, argumentCount);
                        }
                        return {
                            items: items,
                            applicableSpan: applicableSpan,
                            selectedItemIndex: selectedItemIndex,
                            argumentIndex: argumentIndex,
                            argumentCount: argumentCount
                        };
                        function createSignatureHelpParameterForParameter(parameter) {
                            var displayParts = ts.mapToDisplayParts(function (writer) { return typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation); });
                            var isOptional = !!(parameter.valueDeclaration.flags & 4 /* QuestionMark */);
                            return {
                                name: parameter.name,
                                documentation: parameter.getDocumentationComment(),
                                displayParts: displayParts,
                                isOptional: isOptional
                            };
                        }
                        function createSignatureHelpParameterForTypeParameter(typeParameter) {
                            var displayParts = ts.mapToDisplayParts(function (writer) { return typeInfoResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation); });
                            return {
                                name: typeParameter.symbol.name,
                                documentation: emptyArray,
                                displayParts: displayParts,
                                isOptional: false
                            };
                        }
                    }
                }
                SignatureHelp.getSignatureHelpItems = getSignatureHelpItems;
            })(SignatureHelp = ts.SignatureHelp || (ts.SignatureHelp = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            function getEndLinePosition(line, sourceFile) {
                ts.Debug.assert(line >= 1);
                var lineStarts = sourceFile.getLineStarts();
                var lineIndex = line - 1;
                if (lineIndex === lineStarts.length - 1) {
                    return sourceFile.text.length - 1;
                }
                else {
                    var start = lineStarts[lineIndex];
                    var pos = lineStarts[lineIndex + 1] - 1;
                    ts.Debug.assert(ts.isLineBreak(sourceFile.text.charCodeAt(pos)));
                    while (start <= pos && ts.isLineBreak(sourceFile.text.charCodeAt(pos))) {
                        pos--;
                    }
                    return pos;
                }
            }
            ts.getEndLinePosition = getEndLinePosition;
            function getStartPositionOfLine(line, sourceFile) {
                ts.Debug.assert(line >= 1);
                return sourceFile.getLineStarts()[line - 1];
            }
            ts.getStartPositionOfLine = getStartPositionOfLine;
            function getStartLinePositionForPosition(position, sourceFile) {
                var lineStarts = sourceFile.getLineStarts();
                var line = sourceFile.getLineAndCharacterFromPosition(position).line;
                return lineStarts[line - 1];
            }
            ts.getStartLinePositionForPosition = getStartLinePositionForPosition;
            function rangeContainsRange(r1, r2) {
                return startEndContainsRange(r1.pos, r1.end, r2);
            }
            ts.rangeContainsRange = rangeContainsRange;
            function startEndContainsRange(start, end, range) {
                return start <= range.pos && end >= range.end;
            }
            ts.startEndContainsRange = startEndContainsRange;
            function rangeContainsStartEnd(range, start, end) {
                return range.pos <= start && range.end >= end;
            }
            ts.rangeContainsStartEnd = rangeContainsStartEnd;
            function rangeOverlapsWithStartEnd(r1, start, end) {
                return startEndOverlapsWithStartEnd(r1.pos, r1.end, start, end);
            }
            ts.rangeOverlapsWithStartEnd = rangeOverlapsWithStartEnd;
            function startEndOverlapsWithStartEnd(start1, end1, start2, end2) {
                var start = Math.max(start1, start2);
                var end = Math.min(end1, end2);
                return start < end;
            }
            ts.startEndOverlapsWithStartEnd = startEndOverlapsWithStartEnd;
            function findListItemInfo(node) {
                var list = findContainingList(node);
                if (!list) {
                    return undefined;
                }
                var children = list.getChildren();
                var listItemIndex = ts.indexOf(children, node);
                return {
                    listItemIndex: listItemIndex,
                    list: list
                };
            }
            ts.findListItemInfo = findListItemInfo;
            function findChildOfKind(n, kind, sourceFile) {
                return ts.forEach(n.getChildren(sourceFile), function (c) { return c.kind === kind && c; });
            }
            ts.findChildOfKind = findChildOfKind;
            function findContainingList(node) {
                var syntaxList = ts.forEach(node.parent.getChildren(), function (c) {
                    if (c.kind === 200 /* SyntaxList */ && c.pos <= node.pos && c.end >= node.end) {
                        return c;
                    }
                });
                return syntaxList;
            }
            ts.findContainingList = findContainingList;
            function findListItemIndexContainingPosition(list, position) {
                ts.Debug.assert(list.kind === 200 /* SyntaxList */);
                var children = list.getChildren();
                for (var i = 0; i < children.length; i++) {
                    if (children[i].pos <= position && children[i].end > position) {
                        return i;
                    }
                }
                return -1;
            }
            ts.findListItemIndexContainingPosition = findListItemIndexContainingPosition;
            function getTouchingWord(sourceFile, position) {
                return getTouchingToken(sourceFile, position, function (n) { return isWord(n.kind); });
            }
            ts.getTouchingWord = getTouchingWord;
            function getTouchingPropertyName(sourceFile, position) {
                return getTouchingToken(sourceFile, position, function (n) { return isPropertyName(n.kind); });
            }
            ts.getTouchingPropertyName = getTouchingPropertyName;
            function getTouchingToken(sourceFile, position, includeItemAtEndPosition) {
                return getTokenAtPositionWorker(sourceFile, position, false, includeItemAtEndPosition);
            }
            ts.getTouchingToken = getTouchingToken;
            function getTokenAtPosition(sourceFile, position) {
                return getTokenAtPositionWorker(sourceFile, position, true, undefined);
            }
            ts.getTokenAtPosition = getTokenAtPosition;
            function getTokenAtPositionWorker(sourceFile, position, allowPositionInLeadingTrivia, includeItemAtEndPosition) {
                var current = sourceFile;
                outer: while (true) {
                    if (isToken(current)) {
                        return current;
                    }
                    for (var i = 0, n = current.getChildCount(sourceFile); i < n; i++) {
                        var child = current.getChildAt(i);
                        var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile);
                        if (start <= position) {
                            var end = child.getEnd();
                            if (position < end || (position === end && child.kind === 1 /* EndOfFileToken */)) {
                                current = child;
                                continue outer;
                            }
                            else if (includeItemAtEndPosition && end === position) {
                                var previousToken = findPrecedingToken(position, sourceFile, child);
                                if (previousToken && includeItemAtEndPosition(previousToken)) {
                                    return previousToken;
                                }
                            }
                        }
                    }
                    return current;
                }
            }
            function findTokenOnLeftOfPosition(file, position) {
                var tokenAtPosition = getTokenAtPosition(file, position);
                if (isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) {
                    return tokenAtPosition;
                }
                return findPrecedingToken(position, file);
            }
            ts.findTokenOnLeftOfPosition = findTokenOnLeftOfPosition;
            function findNextToken(previousToken, parent) {
                return find(parent);
                function find(n) {
                    if (isToken(n) && n.pos === previousToken.end) {
                        return n;
                    }
                    var children = n.getChildren();
                    for (var i = 0, len = children.length; i < len; ++i) {
                        var child = children[i];
                        var shouldDiveInChildNode = (child.pos <= previousToken.pos && child.end > previousToken.end) || (child.pos === previousToken.end);
                        if (shouldDiveInChildNode && nodeHasTokens(child)) {
                            return find(child);
                        }
                    }
                    return undefined;
                }
            }
            ts.findNextToken = findNextToken;
            function findPrecedingToken(position, sourceFile, startNode) {
                return find(startNode || sourceFile);
                function findRightmostToken(n) {
                    if (isToken(n)) {
                        return n;
                    }
                    var children = n.getChildren();
                    var candidate = findRightmostChildNodeWithTokens(children, children.length);
                    return candidate && findRightmostToken(candidate);
                }
                function find(n) {
                    if (isToken(n)) {
                        return n;
                    }
                    var children = n.getChildren();
                    for (var i = 0, len = children.length; i < len; ++i) {
                        var child = children[i];
                        if (nodeHasTokens(child)) {
                            if (position <= child.end) {
                                if (child.getStart(sourceFile) >= position) {
                                    var candidate = findRightmostChildNodeWithTokens(children, i);
                                    return candidate && findRightmostToken(candidate);
                                }
                                else {
                                    return find(child);
                                }
                            }
                        }
                    }
                    ts.Debug.assert(startNode !== undefined || n.kind === 198 /* SourceFile */);
                    if (children.length) {
                        var candidate = findRightmostChildNodeWithTokens(children, children.length);
                        return candidate && findRightmostToken(candidate);
                    }
                }
                function findRightmostChildNodeWithTokens(children, exclusiveStartPosition) {
                    for (var i = exclusiveStartPosition - 1; i >= 0; --i) {
                        if (nodeHasTokens(children[i])) {
                            return children[i];
                        }
                    }
                }
            }
            ts.findPrecedingToken = findPrecedingToken;
            function nodeHasTokens(n) {
                if (n.kind === 0 /* Unknown */) {
                    return false;
                }
                return n.getWidth() !== 0;
            }
            function getTypeArgumentOrTypeParameterList(node) {
                if (node.kind === 133 /* TypeReference */ || node.kind === 148 /* CallExpression */) {
                    return node.typeArguments;
                }
                if (ts.isAnyFunction(node) || node.kind === 189 /* ClassDeclaration */ || node.kind === 190 /* InterfaceDeclaration */) {
                    return node.typeParameters;
                }
                return undefined;
            }
            ts.getTypeArgumentOrTypeParameterList = getTypeArgumentOrTypeParameterList;
            function isToken(n) {
                return n.kind >= 1 /* FirstToken */ && n.kind <= 119 /* LastToken */;
            }
            ts.isToken = isToken;
            function isWord(kind) {
                return kind === 63 /* Identifier */ || ts.isKeyword(kind);
            }
            function isPropertyName(kind) {
                return kind === 7 /* StringLiteral */ || kind === 6 /* NumericLiteral */ || isWord(kind);
            }
            function isComment(kind) {
                return kind === 2 /* SingleLineCommentTrivia */ || kind === 3 /* MultiLineCommentTrivia */;
            }
            ts.isComment = isComment;
            function isPunctuation(kind) {
                return 13 /* FirstPunctuation */ <= kind && kind <= 62 /* LastPunctuation */;
            }
            ts.isPunctuation = isPunctuation;
            function isInsideTemplateLiteral(node, position) {
                return (node.getStart() < position && position < node.getEnd()) || (ts.isUnterminatedTemplateEnd(node) && position === node.getEnd());
            }
            ts.isInsideTemplateLiteral = isInsideTemplateLiteral;
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var SmartIndenter;
                (function (SmartIndenter) {
                    function getIndentation(position, sourceFile, options) {
                        if (position > sourceFile.text.length) {
                            return 0;
                        }
                        var precedingToken = ts.findPrecedingToken(position, sourceFile);
                        if (!precedingToken) {
                            return 0;
                        }
                        if ((precedingToken.kind === 7 /* StringLiteral */ || precedingToken.kind === 8 /* RegularExpressionLiteral */) && precedingToken.getStart(sourceFile) <= position && precedingToken.end > position) {
                            return 0;
                        }
                        var lineAtPosition = sourceFile.getLineAndCharacterFromPosition(position).line;
                        if (precedingToken.kind === 22 /* CommaToken */ && precedingToken.parent.kind !== 157 /* BinaryExpression */) {
                            var actualIndentation = getActualIndentationForListItemBeforeComma(precedingToken, sourceFile, options);
                            if (actualIndentation !== -1) {
                                return actualIndentation;
                            }
                        }
                        var previous;
                        var current = precedingToken;
                        var currentStart;
                        var indentationDelta;
                        while (current) {
                            if (positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current.kind, previous ? previous.kind : 0 /* Unknown */)) {
                                currentStart = getStartLineAndCharacterForNode(current, sourceFile);
                                if (nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile)) {
                                    indentationDelta = 0;
                                }
                                else {
                                    indentationDelta = lineAtPosition !== currentStart.line ? options.IndentSize : 0;
                                }
                                break;
                            }
                            var actualIndentation = getActualIndentationForListItem(current, sourceFile, options);
                            if (actualIndentation !== -1) {
                                return actualIndentation;
                            }
                            previous = current;
                            current = current.parent;
                        }
                        if (!current) {
                            return 0;
                        }
                        return getIndentationForNodeWorker(current, currentStart, undefined, indentationDelta, sourceFile, options);
                    }
                    SmartIndenter.getIndentation = getIndentation;
                    function getIndentationForNode(n, ignoreActualIndentationRange, sourceFile, options) {
                        var start = sourceFile.getLineAndCharacterFromPosition(n.getStart(sourceFile));
                        return getIndentationForNodeWorker(n, start, ignoreActualIndentationRange, 0, sourceFile, options);
                    }
                    SmartIndenter.getIndentationForNode = getIndentationForNode;
                    function getIndentationForNodeWorker(current, currentStart, ignoreActualIndentationRange, indentationDelta, sourceFile, options) {
                        var parent = current.parent;
                        var parentStart;
                        while (parent) {
                            var useActualIndentation = true;
                            if (ignoreActualIndentationRange) {
                                var start = current.getStart(sourceFile);
                                useActualIndentation = start < ignoreActualIndentationRange.pos || start > ignoreActualIndentationRange.end;
                            }
                            if (useActualIndentation) {
                                var actualIndentation = getActualIndentationForListItem(current, sourceFile, options);
                                if (actualIndentation !== -1) {
                                    return actualIndentation + indentationDelta;
                                }
                            }
                            parentStart = getParentStart(parent, current, sourceFile);
                            var parentAndChildShareLine = parentStart.line === currentStart.line || childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile);
                            if (useActualIndentation) {
                                var actualIndentation = getActualIndentationForNode(current, parent, currentStart, parentAndChildShareLine, sourceFile, options);
                                if (actualIndentation !== -1) {
                                    return actualIndentation + indentationDelta;
                                }
                            }
                            if (shouldIndentChildNode(parent.kind, current.kind) && !parentAndChildShareLine) {
                                indentationDelta += options.IndentSize;
                            }
                            current = parent;
                            currentStart = parentStart;
                            parent = current.parent;
                        }
                        return indentationDelta;
                    }
                    function getParentStart(parent, child, sourceFile) {
                        var containingList = getContainingList(child, sourceFile);
                        if (containingList) {
                            return sourceFile.getLineAndCharacterFromPosition(containingList.pos);
                        }
                        return sourceFile.getLineAndCharacterFromPosition(parent.getStart(sourceFile));
                    }
                    function getActualIndentationForListItemBeforeComma(commaToken, sourceFile, options) {
                        var commaItemInfo = ts.findListItemInfo(commaToken);
                        ts.Debug.assert(commaItemInfo && commaItemInfo.listItemIndex > 0);
                        return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options);
                    }
                    function getActualIndentationForNode(current, parent, currentLineAndChar, parentAndChildShareLine, sourceFile, options) {
                        var useActualIndentation = (ts.isDeclaration(current) || ts.isStatement(current)) && (parent.kind === 198 /* SourceFile */ || !parentAndChildShareLine);
                        if (!useActualIndentation) {
                            return -1;
                        }
                        return findColumnForFirstNonWhitespaceCharacterInLine(currentLineAndChar, sourceFile, options);
                    }
                    function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile) {
                        var nextToken = ts.findNextToken(precedingToken, current);
                        if (!nextToken) {
                            return false;
                        }
                        if (nextToken.kind === 13 /* OpenBraceToken */) {
                            return true;
                        }
                        else if (nextToken.kind === 14 /* CloseBraceToken */) {
                            var nextTokenStartLine = getStartLineAndCharacterForNode(nextToken, sourceFile).line;
                            return lineAtPosition === nextTokenStartLine;
                        }
                        return false;
                    }
                    function getStartLineAndCharacterForNode(n, sourceFile) {
                        return sourceFile.getLineAndCharacterFromPosition(n.getStart(sourceFile));
                    }
                    function positionBelongsToNode(candidate, position, sourceFile) {
                        return candidate.end > position || !isCompletedNode(candidate, sourceFile);
                    }
                    function childStartsOnTheSameLineWithElseInIfStatement(parent, child, childStartLine, sourceFile) {
                        if (parent.kind === 167 /* IfStatement */ && parent.elseStatement === child) {
                            var elseKeyword = ts.findChildOfKind(parent, 74 /* ElseKeyword */, sourceFile);
                            ts.Debug.assert(elseKeyword !== undefined);
                            var elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line;
                            return elseKeywordStartLine === childStartLine;
                        }
                        return false;
                    }
                    SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement = childStartsOnTheSameLineWithElseInIfStatement;
                    function getContainingList(node, sourceFile) {
                        if (node.parent) {
                            switch (node.parent.kind) {
                                case 133 /* TypeReference */:
                                    if (node.parent.typeArguments && ts.rangeContainsStartEnd(node.parent.typeArguments, node.getStart(sourceFile), node.getEnd())) {
                                        return node.parent.typeArguments;
                                    }
                                    break;
                                case 143 /* ObjectLiteral */:
                                    return node.parent.properties;
                                case 142 /* ArrayLiteral */:
                                    return node.parent.elements;
                                case 187 /* FunctionDeclaration */:
                                case 153 /* FunctionExpression */:
                                case 154 /* ArrowFunction */:
                                case 126 /* Method */:
                                case 130 /* CallSignature */:
                                case 131 /* ConstructSignature */:
                                    var start = node.getStart(sourceFile);
                                    if (node.parent.typeParameters && ts.rangeContainsStartEnd(node.parent.typeParameters, start, node.getEnd())) {
                                        return node.parent.typeParameters;
                                    }
                                    if (ts.rangeContainsStartEnd(node.parent.parameters, start, node.getEnd())) {
                                        return node.parent.parameters;
                                    }
                                    break;
                                case 149 /* NewExpression */:
                                case 148 /* CallExpression */:
                                    var start = node.getStart(sourceFile);
                                    if (node.parent.typeArguments && ts.rangeContainsStartEnd(node.parent.typeArguments, start, node.getEnd())) {
                                        return node.parent.typeArguments;
                                    }
                                    if (ts.rangeContainsStartEnd(node.parent.arguments, start, node.getEnd())) {
                                        return node.parent.arguments;
                                    }
                                    break;
                            }
                        }
                        return undefined;
                    }
                    function getActualIndentationForListItem(node, sourceFile, options) {
                        var containingList = getContainingList(node, sourceFile);
                        return containingList ? getActualIndentationFromList(containingList) : -1;
                        function getActualIndentationFromList(list) {
                            var index = ts.indexOf(list, node);
                            return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : -1;
                        }
                    }
                    function deriveActualIndentationFromList(list, index, sourceFile, options) {
                        ts.Debug.assert(index >= 0 && index < list.length);
                        var node = list[index];
                        var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile);
                        for (var i = index - 1; i >= 0; --i) {
                            if (list[i].kind === 22 /* CommaToken */) {
                                continue;
                            }
                            var prevEndLine = sourceFile.getLineAndCharacterFromPosition(list[i].end).line;
                            if (prevEndLine !== lineAndCharacter.line) {
                                return findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options);
                            }
                            lineAndCharacter = getStartLineAndCharacterForNode(list[i], sourceFile);
                        }
                        return -1;
                    }
                    function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options) {
                        var lineStart = sourceFile.getPositionFromLineAndCharacter(lineAndCharacter.line, 1);
                        return findFirstNonWhitespaceColumn(lineStart, lineStart + lineAndCharacter.character, sourceFile, options);
                    }
                    function findFirstNonWhitespaceColumn(startPos, endPos, sourceFile, options) {
                        var column = 0;
                        for (var pos = startPos; pos < endPos; ++pos) {
                            var ch = sourceFile.text.charCodeAt(pos);
                            if (!ts.isWhiteSpace(ch)) {
                                return column;
                            }
                            if (ch === 9 /* tab */) {
                                column += options.TabSize + (column % options.TabSize);
                            }
                            else {
                                column++;
                            }
                        }
                        return column;
                    }
                    SmartIndenter.findFirstNonWhitespaceColumn = findFirstNonWhitespaceColumn;
                    function nodeContentIsAlwaysIndented(kind) {
                        switch (kind) {
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                            case 192 /* EnumDeclaration */:
                            case 142 /* ArrayLiteral */:
                            case 163 /* Block */:
                            case 188 /* FunctionBlock */:
                            case 182 /* TryBlock */:
                            case 183 /* CatchBlock */:
                            case 184 /* FinallyBlock */:
                            case 194 /* ModuleBlock */:
                            case 143 /* ObjectLiteral */:
                            case 137 /* TypeLiteral */:
                            case 176 /* SwitchStatement */:
                            case 178 /* DefaultClause */:
                            case 177 /* CaseClause */:
                            case 152 /* ParenExpression */:
                            case 148 /* CallExpression */:
                            case 149 /* NewExpression */:
                            case 164 /* VariableStatement */:
                            case 186 /* VariableDeclaration */:
                            case 196 /* ExportAssignment */:
                            case 174 /* ReturnStatement */:
                                return true;
                        }
                        return false;
                    }
                    function shouldIndentChildNode(parent, child) {
                        if (nodeContentIsAlwaysIndented(parent)) {
                            return true;
                        }
                        switch (parent) {
                            case 168 /* DoStatement */:
                            case 169 /* WhileStatement */:
                            case 171 /* ForInStatement */:
                            case 170 /* ForStatement */:
                            case 167 /* IfStatement */:
                                return child !== 163 /* Block */;
                            case 187 /* FunctionDeclaration */:
                            case 153 /* FunctionExpression */:
                            case 126 /* Method */:
                            case 154 /* ArrowFunction */:
                            case 127 /* Constructor */:
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                                return child !== 188 /* FunctionBlock */;
                            default:
                                return false;
                        }
                    }
                    SmartIndenter.shouldIndentChildNode = shouldIndentChildNode;
                    function nodeEndsWith(n, expectedLastToken, sourceFile) {
                        var children = n.getChildren(sourceFile);
                        if (children.length) {
                            var last = children[children.length - 1];
                            if (last.kind === expectedLastToken) {
                                return true;
                            }
                            else if (last.kind === 21 /* SemicolonToken */ && children.length !== 1) {
                                return children[children.length - 2].kind === expectedLastToken;
                            }
                        }
                        return false;
                    }
                    function isCompletedNode(n, sourceFile) {
                        switch (n.kind) {
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                            case 192 /* EnumDeclaration */:
                            case 143 /* ObjectLiteral */:
                            case 163 /* Block */:
                            case 183 /* CatchBlock */:
                            case 184 /* FinallyBlock */:
                            case 188 /* FunctionBlock */:
                            case 194 /* ModuleBlock */:
                            case 176 /* SwitchStatement */:
                                return nodeEndsWith(n, 14 /* CloseBraceToken */, sourceFile);
                            case 152 /* ParenExpression */:
                            case 130 /* CallSignature */:
                            case 148 /* CallExpression */:
                            case 131 /* ConstructSignature */:
                                return nodeEndsWith(n, 16 /* CloseParenToken */, sourceFile);
                            case 187 /* FunctionDeclaration */:
                            case 153 /* FunctionExpression */:
                            case 126 /* Method */:
                            case 154 /* ArrowFunction */:
                                return !n.body || isCompletedNode(n.body, sourceFile);
                            case 193 /* ModuleDeclaration */:
                                return n.body && isCompletedNode(n.body, sourceFile);
                            case 167 /* IfStatement */:
                                if (n.elseStatement) {
                                    return isCompletedNode(n.elseStatement, sourceFile);
                                }
                                return isCompletedNode(n.thenStatement, sourceFile);
                            case 166 /* ExpressionStatement */:
                                return isCompletedNode(n.expression, sourceFile);
                            case 142 /* ArrayLiteral */:
                                return nodeEndsWith(n, 18 /* CloseBracketToken */, sourceFile);
                            case 120 /* Missing */:
                                return false;
                            case 177 /* CaseClause */:
                            case 178 /* DefaultClause */:
                                return false;
                            case 169 /* WhileStatement */:
                                return isCompletedNode(n.statement, sourceFile);
                            case 168 /* DoStatement */:
                                var hasWhileKeyword = ts.findChildOfKind(n, 98 /* WhileKeyword */, sourceFile);
                                if (hasWhileKeyword) {
                                    return nodeEndsWith(n, 16 /* CloseParenToken */, sourceFile);
                                }
                                return isCompletedNode(n.statement, sourceFile);
                            default:
                                return true;
                        }
                    }
                })(SmartIndenter = formatting.SmartIndenter || (formatting.SmartIndenter = {}));
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var internedTabsIndentation;
                var internedSpacesIndentation;
                function getIndentationString(indentation, options) {
                    if (!options.ConvertTabsToSpaces) {
                        var tabs = Math.floor(indentation / options.TabSize);
                        var spaces = indentation - tabs * options.TabSize;
                        var tabString;
                        if (!internedTabsIndentation) {
                            internedTabsIndentation = [];
                        }
                        if (internedTabsIndentation[tabs] === undefined) {
                            internedTabsIndentation[tabs] = tabString = repeat('\t', tabs);
                        }
                        else {
                            tabString = internedTabsIndentation[tabs];
                        }
                        return spaces ? tabString + repeat(" ", spaces) : tabString;
                    }
                    else {
                        var spacesString;
                        var quotient = Math.floor(indentation / options.IndentSize);
                        var remainder = indentation % options.IndentSize;
                        if (!internedSpacesIndentation) {
                            internedSpacesIndentation = [];
                        }
                        if (internedSpacesIndentation[quotient] === undefined) {
                            spacesString = repeat(" ", options.IndentSize * quotient);
                            internedSpacesIndentation[quotient] = spacesString;
                        }
                        else {
                            spacesString = internedSpacesIndentation[quotient];
                        }
                        return remainder ? spacesString + repeat(" ", remainder) : spacesString;
                    }
                    function repeat(value, count) {
                        var s = "";
                        for (var i = 0; i < count; ++i) {
                            s += value;
                        }
                        return s;
                    }
                }
                formatting.getIndentationString = getIndentationString;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var scanner = ts.createScanner(2 /* Latest */, false);
                var ScanAction;
                (function (ScanAction) {
                    ScanAction[ScanAction["Scan"] = 0] = "Scan";
                    ScanAction[ScanAction["RescanGreaterThanToken"] = 1] = "RescanGreaterThanToken";
                    ScanAction[ScanAction["RescanSlashToken"] = 2] = "RescanSlashToken";
                    ScanAction[ScanAction["RescanTemplateToken"] = 3] = "RescanTemplateToken";
                })(ScanAction || (ScanAction = {}));
                function getFormattingScanner(sourceFile, startPos, endPos) {
                    scanner.setText(sourceFile.text);
                    scanner.setTextPos(startPos);
                    var wasNewLine = true;
                    var leadingTrivia;
                    var trailingTrivia;
                    var savedPos;
                    var lastScanAction;
                    var lastTokenInfo;
                    return {
                        advance: advance,
                        readTokenInfo: readTokenInfo,
                        isOnToken: isOnToken,
                        lastTrailingTriviaWasNewLine: function () { return wasNewLine; },
                        close: function () {
                            lastTokenInfo = undefined;
                            scanner.setText(undefined);
                        }
                    };
                    function advance() {
                        lastTokenInfo = undefined;
                        var isStarted = scanner.getStartPos() !== startPos;
                        if (isStarted) {
                            if (trailingTrivia) {
                                ts.Debug.assert(trailingTrivia.length !== 0);
                                wasNewLine = trailingTrivia[trailingTrivia.length - 1].kind === 4 /* NewLineTrivia */;
                            }
                            else {
                                wasNewLine = false;
                            }
                        }
                        leadingTrivia = undefined;
                        trailingTrivia = undefined;
                        if (!isStarted) {
                            scanner.scan();
                        }
                        var t;
                        var pos = scanner.getStartPos();
                        while (pos < endPos) {
                            var t = scanner.getToken();
                            if (!ts.isTrivia(t)) {
                                break;
                            }
                            scanner.scan();
                            var item = {
                                pos: pos,
                                end: scanner.getStartPos(),
                                kind: t
                            };
                            pos = scanner.getStartPos();
                            if (!leadingTrivia) {
                                leadingTrivia = [];
                            }
                            leadingTrivia.push(item);
                        }
                        savedPos = scanner.getStartPos();
                    }
                    function shouldRescanGreaterThanToken(container) {
                        if (container.kind !== 157 /* BinaryExpression */) {
                            return false;
                        }
                        switch (container.operator) {
                            case 26 /* GreaterThanEqualsToken */:
                            case 58 /* GreaterThanGreaterThanEqualsToken */:
                            case 59 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                            case 41 /* GreaterThanGreaterThanGreaterThanToken */:
                            case 40 /* GreaterThanGreaterThanToken */:
                                return true;
                        }
                        return false;
                    }
                    function shouldRescanSlashToken(container) {
                        return container.kind === 8 /* RegularExpressionLiteral */;
                    }
                    function shouldRescanTemplateToken(container) {
                        return container.kind === 11 /* TemplateMiddle */ || container.kind === 12 /* TemplateTail */;
                    }
                    function startsWithSlashToken(t) {
                        return t === 35 /* SlashToken */ || t === 55 /* SlashEqualsToken */;
                    }
                    function readTokenInfo(n) {
                        if (!isOnToken()) {
                            return {
                                leadingTrivia: leadingTrivia,
                                trailingTrivia: undefined,
                                token: undefined
                            };
                        }
                        var expectedScanAction = shouldRescanGreaterThanToken(n) ? 1 /* RescanGreaterThanToken */ : shouldRescanSlashToken(n) ? 2 /* RescanSlashToken */ : shouldRescanTemplateToken(n) ? 3 /* RescanTemplateToken */ : 0 /* Scan */;
                        if (lastTokenInfo && expectedScanAction === lastScanAction) {
                            return lastTokenInfo;
                        }
                        if (scanner.getStartPos() !== savedPos) {
                            ts.Debug.assert(lastTokenInfo !== undefined);
                            scanner.setTextPos(savedPos);
                            scanner.scan();
                        }
                        var currentToken = scanner.getToken();
                        if (expectedScanAction === 1 /* RescanGreaterThanToken */ && currentToken === 24 /* GreaterThanToken */) {
                            currentToken = scanner.reScanGreaterToken();
                            ts.Debug.assert(n.operator === currentToken);
                            lastScanAction = 1 /* RescanGreaterThanToken */;
                        }
                        else if (expectedScanAction === 2 /* RescanSlashToken */ && startsWithSlashToken(currentToken)) {
                            currentToken = scanner.reScanSlashToken();
                            ts.Debug.assert(n.kind === currentToken);
                            lastScanAction = 2 /* RescanSlashToken */;
                        }
                        else if (expectedScanAction === 3 /* RescanTemplateToken */ && currentToken === 14 /* CloseBraceToken */) {
                            currentToken = scanner.reScanTemplateToken();
                            lastScanAction = 3 /* RescanTemplateToken */;
                        }
                        else {
                            lastScanAction = 0 /* Scan */;
                        }
                        var token = {
                            pos: scanner.getStartPos(),
                            end: scanner.getTextPos(),
                            kind: currentToken
                        };
                        while (scanner.getStartPos() < endPos) {
                            currentToken = scanner.scan();
                            if (!ts.isTrivia(currentToken)) {
                                break;
                            }
                            var trivia = {
                                pos: scanner.getStartPos(),
                                end: scanner.getTextPos(),
                                kind: currentToken
                            };
                            if (!trailingTrivia) {
                                trailingTrivia = [];
                            }
                            trailingTrivia.push(trivia);
                            if (currentToken === 4 /* NewLineTrivia */) {
                                scanner.scan();
                                break;
                            }
                        }
                        return lastTokenInfo = {
                            leadingTrivia: leadingTrivia,
                            trailingTrivia: trailingTrivia,
                            token: token
                        };
                    }
                    function isOnToken() {
                        var current = (lastTokenInfo && lastTokenInfo.token.kind) || scanner.getToken();
                        var startPos = (lastTokenInfo && lastTokenInfo.token.pos) || scanner.getStartPos();
                        return startPos < endPos && current !== 1 /* EndOfFileToken */ && !ts.isTrivia(current);
                    }
                }
                formatting.getFormattingScanner = getFormattingScanner;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var FormattingContext = (function () {
                    function FormattingContext(sourceFile, formattingRequestKind) {
                        this.sourceFile = sourceFile;
                        this.formattingRequestKind = formattingRequestKind;
                    }
                    FormattingContext.prototype.updateContext = function (currentRange, currentTokenParent, nextRange, nextTokenParent, commonParent) {
                        ts.Debug.assert(currentRange !== undefined, "currentTokenSpan is null");
                        ts.Debug.assert(currentTokenParent !== undefined, "currentTokenParent is null");
                        ts.Debug.assert(nextRange !== undefined, "nextTokenSpan is null");
                        ts.Debug.assert(nextTokenParent !== undefined, "nextTokenParent is null");
                        ts.Debug.assert(commonParent !== undefined, "commonParent is null");
                        this.currentTokenSpan = currentRange;
                        this.currentTokenParent = currentTokenParent;
                        this.nextTokenSpan = nextRange;
                        this.nextTokenParent = nextTokenParent;
                        this.contextNode = commonParent;
                        this.contextNodeAllOnSameLine = undefined;
                        this.nextNodeAllOnSameLine = undefined;
                        this.tokensAreOnSameLine = undefined;
                        this.contextNodeBlockIsOnOneLine = undefined;
                        this.nextNodeBlockIsOnOneLine = undefined;
                    };
                    FormattingContext.prototype.ContextNodeAllOnSameLine = function () {
                        if (this.contextNodeAllOnSameLine === undefined) {
                            this.contextNodeAllOnSameLine = this.NodeIsOnOneLine(this.contextNode);
                        }
                        return this.contextNodeAllOnSameLine;
                    };
                    FormattingContext.prototype.NextNodeAllOnSameLine = function () {
                        if (this.nextNodeAllOnSameLine === undefined) {
                            this.nextNodeAllOnSameLine = this.NodeIsOnOneLine(this.nextTokenParent);
                        }
                        return this.nextNodeAllOnSameLine;
                    };
                    FormattingContext.prototype.TokensAreOnSameLine = function () {
                        if (this.tokensAreOnSameLine === undefined) {
                            var startLine = this.sourceFile.getLineAndCharacterFromPosition(this.currentTokenSpan.pos).line;
                            var endLine = this.sourceFile.getLineAndCharacterFromPosition(this.nextTokenSpan.pos).line;
                            this.tokensAreOnSameLine = (startLine == endLine);
                        }
                        return this.tokensAreOnSameLine;
                    };
                    FormattingContext.prototype.ContextNodeBlockIsOnOneLine = function () {
                        if (this.contextNodeBlockIsOnOneLine === undefined) {
                            this.contextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.contextNode);
                        }
                        return this.contextNodeBlockIsOnOneLine;
                    };
                    FormattingContext.prototype.NextNodeBlockIsOnOneLine = function () {
                        if (this.nextNodeBlockIsOnOneLine === undefined) {
                            this.nextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.nextTokenParent);
                        }
                        return this.nextNodeBlockIsOnOneLine;
                    };
                    FormattingContext.prototype.NodeIsOnOneLine = function (node) {
                        var startLine = this.sourceFile.getLineAndCharacterFromPosition(node.getStart(this.sourceFile)).line;
                        var endLine = this.sourceFile.getLineAndCharacterFromPosition(node.getEnd()).line;
                        return startLine == endLine;
                    };
                    FormattingContext.prototype.BlockIsOnOneLine = function (node) {
                        var openBrace = ts.findChildOfKind(node, 13 /* OpenBraceToken */, this.sourceFile);
                        var closeBrace = ts.findChildOfKind(node, 14 /* CloseBraceToken */, this.sourceFile);
                        if (openBrace && closeBrace) {
                            var startLine = this.sourceFile.getLineAndCharacterFromPosition(openBrace.getEnd()).line;
                            var endLine = this.sourceFile.getLineAndCharacterFromPosition(closeBrace.getStart(this.sourceFile)).line;
                            return startLine === endLine;
                        }
                        return false;
                    };
                    return FormattingContext;
                })();
                formatting.FormattingContext = FormattingContext;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                (function (FormattingRequestKind) {
                    FormattingRequestKind[FormattingRequestKind["FormatDocument"] = 0] = "FormatDocument";
                    FormattingRequestKind[FormattingRequestKind["FormatSelection"] = 1] = "FormatSelection";
                    FormattingRequestKind[FormattingRequestKind["FormatOnEnter"] = 2] = "FormatOnEnter";
                    FormattingRequestKind[FormattingRequestKind["FormatOnSemicolon"] = 3] = "FormatOnSemicolon";
                    FormattingRequestKind[FormattingRequestKind["FormatOnClosingCurlyBrace"] = 4] = "FormatOnClosingCurlyBrace";
                })(formatting.FormattingRequestKind || (formatting.FormattingRequestKind = {}));
                var FormattingRequestKind = formatting.FormattingRequestKind;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var Rule = (function () {
                    function Rule(Descriptor, Operation, Flag) {
                        if (Flag === void 0) { Flag = 0 /* None */; }
                        this.Descriptor = Descriptor;
                        this.Operation = Operation;
                        this.Flag = Flag;
                    }
                    Rule.prototype.toString = function () {
                        return "[desc=" + this.Descriptor + "," + "operation=" + this.Operation + "," + "flag=" + this.Flag + "]";
                    };
                    return Rule;
                })();
                formatting.Rule = Rule;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                (function (RuleAction) {
                    RuleAction[RuleAction["Ignore"] = 1] = "Ignore";
                    RuleAction[RuleAction["Space"] = 2] = "Space";
                    RuleAction[RuleAction["NewLine"] = 4] = "NewLine";
                    RuleAction[RuleAction["Delete"] = 8] = "Delete";
                })(formatting.RuleAction || (formatting.RuleAction = {}));
                var RuleAction = formatting.RuleAction;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var RuleDescriptor = (function () {
                    function RuleDescriptor(LeftTokenRange, RightTokenRange) {
                        this.LeftTokenRange = LeftTokenRange;
                        this.RightTokenRange = RightTokenRange;
                    }
                    RuleDescriptor.prototype.toString = function () {
                        return "[leftRange=" + this.LeftTokenRange + "," + "rightRange=" + this.RightTokenRange + "]";
                    };
                    RuleDescriptor.create1 = function (left, right) {
                        return RuleDescriptor.create4(formatting.Shared.TokenRange.FromToken(left), formatting.Shared.TokenRange.FromToken(right));
                    };
                    RuleDescriptor.create2 = function (left, right) {
                        return RuleDescriptor.create4(left, formatting.Shared.TokenRange.FromToken(right));
                    };
                    RuleDescriptor.create3 = function (left, right) {
                        return RuleDescriptor.create4(formatting.Shared.TokenRange.FromToken(left), right);
                    };
                    RuleDescriptor.create4 = function (left, right) {
                        return new RuleDescriptor(left, right);
                    };
                    return RuleDescriptor;
                })();
                formatting.RuleDescriptor = RuleDescriptor;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                (function (RuleFlags) {
                    RuleFlags[RuleFlags["None"] = 0] = "None";
                    RuleFlags[RuleFlags["CanDeleteNewLines"] = 1] = "CanDeleteNewLines";
                })(formatting.RuleFlags || (formatting.RuleFlags = {}));
                var RuleFlags = formatting.RuleFlags;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var RuleOperation = (function () {
                    function RuleOperation() {
                        this.Context = null;
                        this.Action = null;
                    }
                    RuleOperation.prototype.toString = function () {
                        return "[context=" + this.Context + "," + "action=" + this.Action + "]";
                    };
                    RuleOperation.create1 = function (action) {
                        return RuleOperation.create2(formatting.RuleOperationContext.Any, action);
                    };
                    RuleOperation.create2 = function (context, action) {
                        var result = new RuleOperation();
                        result.Context = context;
                        result.Action = action;
                        return result;
                    };
                    return RuleOperation;
                })();
                formatting.RuleOperation = RuleOperation;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var RuleOperationContext = (function () {
                    function RuleOperationContext() {
                        var funcs = [];
                        for (var _i = 0; _i < arguments.length; _i++) {
                            funcs[_i - 0] = arguments[_i];
                        }
                        this.customContextChecks = funcs;
                    }
                    RuleOperationContext.prototype.IsAny = function () {
                        return this == RuleOperationContext.Any;
                    };
                    RuleOperationContext.prototype.InContext = function (context) {
                        if (this.IsAny()) {
                            return true;
                        }
                        for (var i = 0, len = this.customContextChecks.length; i < len; i++) {
                            if (!this.customContextChecks[i](context)) {
                                return false;
                            }
                        }
                        return true;
                    };
                    RuleOperationContext.Any = new RuleOperationContext();
                    return RuleOperationContext;
                })();
                formatting.RuleOperationContext = RuleOperationContext;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var Rules = (function () {
                    function Rules() {
                        this.IgnoreBeforeComment = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.Comments), formatting.RuleOperation.create1(1 /* Ignore */));
                        this.IgnoreAfterLineComment = new formatting.Rule(formatting.RuleDescriptor.create3(2 /* SingleLineCommentTrivia */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create1(1 /* Ignore */));
                        this.NoSpaceBeforeSemicolon = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 21 /* SemicolonToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceBeforeColon = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 50 /* ColonToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
                        this.NoSpaceBeforeQMark = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 49 /* QuestionToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
                        this.SpaceAfterColon = new formatting.Rule(formatting.RuleDescriptor.create3(50 /* ColonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), 2 /* Space */));
                        this.SpaceAfterQMark = new formatting.Rule(formatting.RuleDescriptor.create3(49 /* QuestionToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), 2 /* Space */));
                        this.SpaceAfterSemicolon = new formatting.Rule(formatting.RuleDescriptor.create3(21 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.SpaceAfterCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create3(14 /* CloseBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsAfterCodeBlockContext), 2 /* Space */));
                        this.SpaceBetweenCloseBraceAndElse = new formatting.Rule(formatting.RuleDescriptor.create1(14 /* CloseBraceToken */, 74 /* ElseKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.SpaceBetweenCloseBraceAndWhile = new formatting.Rule(formatting.RuleDescriptor.create1(14 /* CloseBraceToken */, 98 /* WhileKeyword */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.NoSpaceAfterCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create3(14 /* CloseBraceToken */, formatting.Shared.TokenRange.FromTokens([16 /* CloseParenToken */, 18 /* CloseBracketToken */, 22 /* CommaToken */, 21 /* SemicolonToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceBeforeDot = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 19 /* DotToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceAfterDot = new formatting.Rule(formatting.RuleDescriptor.create3(19 /* DotToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceBeforeOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 17 /* OpenBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceAfterOpenBracket = new formatting.Rule(formatting.RuleDescriptor.create3(17 /* OpenBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceBeforeCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 18 /* CloseBracketToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceAfterCloseBracket = new formatting.Rule(formatting.RuleDescriptor.create3(18 /* CloseBracketToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.FunctionOpenBraceLeftTokenRange = formatting.Shared.TokenRange.AnyIncludingMultilineComments;
                        this.SpaceBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 13 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */);
                        this.TypeScriptOpenBraceLeftTokenRange = formatting.Shared.TokenRange.FromTokens([63 /* Identifier */, 3 /* MultiLineCommentTrivia */]);
                        this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock = new formatting.Rule(formatting.RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, 13 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsTypeScriptDeclWithBlockContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */);
                        this.ControlOpenBraceLeftTokenRange = formatting.Shared.TokenRange.FromTokens([16 /* CloseParenToken */, 3 /* MultiLineCommentTrivia */, 73 /* DoKeyword */, 94 /* TryKeyword */, 79 /* FinallyKeyword */, 74 /* ElseKeyword */]);
                        this.SpaceBeforeOpenBraceInControl = new formatting.Rule(formatting.RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, 13 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext, Rules.IsNotFormatOnEnter, Rules.IsSameLineTokenOrBeforeMultilineBlockContext), 2 /* Space */), 1 /* CanDeleteNewLines */);
                        this.SpaceAfterOpenBrace = new formatting.Rule(formatting.RuleDescriptor.create3(13 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSingleLineBlockContext), 2 /* Space */));
                        this.SpaceBeforeCloseBrace = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 14 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSingleLineBlockContext), 2 /* Space */));
                        this.NoSpaceBetweenEmptyBraceBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(13 /* OpenBraceToken */, 14 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsObjectContext), 8 /* Delete */));
                        this.NewLineAfterOpenBraceInBlockContext = new formatting.Rule(formatting.RuleDescriptor.create3(13 /* OpenBraceToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsMultilineBlockContext), 4 /* NewLine */));
                        this.NewLineBeforeCloseBraceInBlockContext = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.AnyIncludingMultilineComments, 14 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsMultilineBlockContext), 4 /* NewLine */));
                        this.NoSpaceAfterUnaryPrefixOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.UnaryPrefixOperators, formatting.Shared.TokenRange.UnaryPrefixExpressions), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
                        this.NoSpaceAfterUnaryPreincrementOperator = new formatting.Rule(formatting.RuleDescriptor.create3(37 /* PlusPlusToken */, formatting.Shared.TokenRange.UnaryPreincrementExpressions), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceAfterUnaryPredecrementOperator = new formatting.Rule(formatting.RuleDescriptor.create3(38 /* MinusMinusToken */, formatting.Shared.TokenRange.UnaryPredecrementExpressions), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceBeforeUnaryPostincrementOperator = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.UnaryPostincrementExpressions, 37 /* PlusPlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceBeforeUnaryPostdecrementOperator = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.UnaryPostdecrementExpressions, 38 /* MinusMinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.SpaceAfterPostincrementWhenFollowedByAdd = new formatting.Rule(formatting.RuleDescriptor.create1(37 /* PlusPlusToken */, 32 /* PlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                        this.SpaceAfterAddWhenFollowedByUnaryPlus = new formatting.Rule(formatting.RuleDescriptor.create1(32 /* PlusToken */, 32 /* PlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                        this.SpaceAfterAddWhenFollowedByPreincrement = new formatting.Rule(formatting.RuleDescriptor.create1(32 /* PlusToken */, 37 /* PlusPlusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                        this.SpaceAfterPostdecrementWhenFollowedBySubtract = new formatting.Rule(formatting.RuleDescriptor.create1(38 /* MinusMinusToken */, 33 /* MinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                        this.SpaceAfterSubtractWhenFollowedByUnaryMinus = new formatting.Rule(formatting.RuleDescriptor.create1(33 /* MinusToken */, 33 /* MinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                        this.SpaceAfterSubtractWhenFollowedByPredecrement = new formatting.Rule(formatting.RuleDescriptor.create1(33 /* MinusToken */, 38 /* MinusMinusToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                        this.NoSpaceBeforeComma = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 22 /* CommaToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.SpaceAfterCertainKeywords = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([96 /* VarKeyword */, 92 /* ThrowKeyword */, 86 /* NewKeyword */, 72 /* DeleteKeyword */, 88 /* ReturnKeyword */, 95 /* TypeOfKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.NoSpaceBeforeOpenParenInFuncCall = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 15 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsFunctionCallOrNewContext), 8 /* Delete */));
                        this.SpaceAfterFunctionInFuncDecl = new formatting.Rule(formatting.RuleDescriptor.create3(81 /* FunctionKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 2 /* Space */));
                        this.NoSpaceBeforeOpenParenInFuncDecl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 15 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsFunctionDeclContext), 8 /* Delete */));
                        this.SpaceAfterVoidOperator = new formatting.Rule(formatting.RuleDescriptor.create3(97 /* VoidKeyword */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsVoidOpContext), 2 /* Space */));
                        this.NoSpaceBetweenReturnAndSemicolon = new formatting.Rule(formatting.RuleDescriptor.create1(88 /* ReturnKeyword */, 21 /* SemicolonToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.SpaceBetweenStatements = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([16 /* CloseParenToken */, 73 /* DoKeyword */, 74 /* ElseKeyword */, 65 /* CaseKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotForContext), 2 /* Space */));
                        this.SpaceAfterTryFinally = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.FromTokens([94 /* TryKeyword */, 79 /* FinallyKeyword */]), 13 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.SpaceAfterGetSetInMember = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.FromTokens([113 /* GetKeyword */, 117 /* SetKeyword */]), 63 /* Identifier */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 2 /* Space */));
                        this.SpaceBeforeBinaryKeywordOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.BinaryKeywordOperators), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                        this.SpaceAfterBinaryKeywordOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.BinaryKeywordOperators, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                        this.NoSpaceAfterConstructor = new formatting.Rule(formatting.RuleDescriptor.create1(111 /* ConstructorKeyword */, 15 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceAfterModuleImport = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.FromTokens([114 /* ModuleKeyword */, 115 /* RequireKeyword */]), 15 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.SpaceAfterCertainTypeScriptKeywords = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.FromTokens([67 /* ClassKeyword */, 112 /* DeclareKeyword */, 75 /* EnumKeyword */, 76 /* ExportKeyword */, 77 /* ExtendsKeyword */, 113 /* GetKeyword */, 100 /* ImplementsKeyword */, 83 /* ImportKeyword */, 101 /* InterfaceKeyword */, 114 /* ModuleKeyword */, 104 /* PrivateKeyword */, 106 /* PublicKeyword */, 117 /* SetKeyword */, 107 /* StaticKeyword */]), formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.SpaceBeforeCertainTypeScriptKeywords = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.FromTokens([77 /* ExtendsKeyword */, 100 /* ImplementsKeyword */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.SpaceAfterModuleName = new formatting.Rule(formatting.RuleDescriptor.create1(7 /* StringLiteral */, 13 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsModuleDeclContext), 2 /* Space */));
                        this.SpaceAfterArrow = new formatting.Rule(formatting.RuleDescriptor.create3(31 /* EqualsGreaterThanToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.NoSpaceAfterEllipsis = new formatting.Rule(formatting.RuleDescriptor.create1(20 /* DotDotDotToken */, 63 /* Identifier */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceAfterOptionalParameters = new formatting.Rule(formatting.RuleDescriptor.create3(49 /* QuestionToken */, formatting.Shared.TokenRange.FromTokens([16 /* CloseParenToken */, 22 /* CommaToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsNotBinaryOpContext), 8 /* Delete */));
                        this.NoSpaceBeforeOpenAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.TypeNames, 23 /* LessThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterContext), 8 /* Delete */));
                        this.NoSpaceBetweenCloseParenAndAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create1(16 /* CloseParenToken */, 23 /* LessThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterContext), 8 /* Delete */));
                        this.NoSpaceAfterOpenAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create3(23 /* LessThanToken */, formatting.Shared.TokenRange.TypeNames), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterContext), 8 /* Delete */));
                        this.NoSpaceBeforeCloseAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 24 /* GreaterThanToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterContext), 8 /* Delete */));
                        this.NoSpaceAfterCloseAngularBracket = new formatting.Rule(formatting.RuleDescriptor.create3(24 /* GreaterThanToken */, formatting.Shared.TokenRange.FromTokens([15 /* OpenParenToken */, 17 /* OpenBracketToken */, 24 /* GreaterThanToken */, 22 /* CommaToken */])), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsTypeArgumentOrParameterContext), 8 /* Delete */));
                        this.NoSpaceBetweenEmptyInterfaceBraceBrackets = new formatting.Rule(formatting.RuleDescriptor.create1(13 /* OpenBraceToken */, 14 /* CloseBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsObjectTypeContext), 8 /* Delete */));
                        this.HighPriorityCommonRules = [
                            this.IgnoreBeforeComment,
                            this.IgnoreAfterLineComment,
                            this.NoSpaceBeforeColon,
                            this.SpaceAfterColon,
                            this.NoSpaceBeforeQMark,
                            this.SpaceAfterQMark,
                            this.NoSpaceBeforeDot,
                            this.NoSpaceAfterDot,
                            this.NoSpaceAfterUnaryPrefixOperator,
                            this.NoSpaceAfterUnaryPreincrementOperator,
                            this.NoSpaceAfterUnaryPredecrementOperator,
                            this.NoSpaceBeforeUnaryPostincrementOperator,
                            this.NoSpaceBeforeUnaryPostdecrementOperator,
                            this.SpaceAfterPostincrementWhenFollowedByAdd,
                            this.SpaceAfterAddWhenFollowedByUnaryPlus,
                            this.SpaceAfterAddWhenFollowedByPreincrement,
                            this.SpaceAfterPostdecrementWhenFollowedBySubtract,
                            this.SpaceAfterSubtractWhenFollowedByUnaryMinus,
                            this.SpaceAfterSubtractWhenFollowedByPredecrement,
                            this.NoSpaceAfterCloseBrace,
                            this.SpaceAfterOpenBrace,
                            this.SpaceBeforeCloseBrace,
                            this.NewLineBeforeCloseBraceInBlockContext,
                            this.SpaceAfterCloseBrace,
                            this.SpaceBetweenCloseBraceAndElse,
                            this.SpaceBetweenCloseBraceAndWhile,
                            this.NoSpaceBetweenEmptyBraceBrackets,
                            this.SpaceAfterFunctionInFuncDecl,
                            this.NewLineAfterOpenBraceInBlockContext,
                            this.SpaceAfterGetSetInMember,
                            this.NoSpaceBetweenReturnAndSemicolon,
                            this.SpaceAfterCertainKeywords,
                            this.NoSpaceBeforeOpenParenInFuncCall,
                            this.SpaceBeforeBinaryKeywordOperator,
                            this.SpaceAfterBinaryKeywordOperator,
                            this.SpaceAfterVoidOperator,
                            this.NoSpaceAfterConstructor,
                            this.NoSpaceAfterModuleImport,
                            this.SpaceAfterCertainTypeScriptKeywords,
                            this.SpaceBeforeCertainTypeScriptKeywords,
                            this.SpaceAfterModuleName,
                            this.SpaceAfterArrow,
                            this.NoSpaceAfterEllipsis,
                            this.NoSpaceAfterOptionalParameters,
                            this.NoSpaceBetweenEmptyInterfaceBraceBrackets,
                            this.NoSpaceBeforeOpenAngularBracket,
                            this.NoSpaceBetweenCloseParenAndAngularBracket,
                            this.NoSpaceAfterOpenAngularBracket,
                            this.NoSpaceBeforeCloseAngularBracket,
                            this.NoSpaceAfterCloseAngularBracket
                        ];
                        this.LowPriorityCommonRules = [
                            this.NoSpaceBeforeSemicolon,
                            this.SpaceBeforeOpenBraceInControl,
                            this.SpaceBeforeOpenBraceInFunction,
                            this.SpaceBeforeOpenBraceInTypeScriptDeclWithBlock,
                            this.NoSpaceBeforeComma,
                            this.NoSpaceBeforeOpenBracket,
                            this.NoSpaceAfterOpenBracket,
                            this.NoSpaceBeforeCloseBracket,
                            this.NoSpaceAfterCloseBracket,
                            this.SpaceAfterSemicolon,
                            this.NoSpaceBeforeOpenParenInFuncDecl,
                            this.SpaceBetweenStatements,
                            this.SpaceAfterTryFinally
                        ];
                        this.SpaceAfterComma = new formatting.Rule(formatting.RuleDescriptor.create3(22 /* CommaToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.NoSpaceAfterComma = new formatting.Rule(formatting.RuleDescriptor.create3(22 /* CommaToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.SpaceBeforeBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.BinaryOperators), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                        this.SpaceAfterBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.BinaryOperators, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 2 /* Space */));
                        this.NoSpaceBeforeBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.Any, formatting.Shared.TokenRange.BinaryOperators), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 8 /* Delete */));
                        this.NoSpaceAfterBinaryOperator = new formatting.Rule(formatting.RuleDescriptor.create4(formatting.Shared.TokenRange.BinaryOperators, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsBinaryOpContext), 8 /* Delete */));
                        this.SpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 15 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext), 2 /* Space */));
                        this.NoSpaceAfterKeywordInControl = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Keywords, 15 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext), 8 /* Delete */));
                        this.NewLineBeforeOpenBraceInFunction = new formatting.Rule(formatting.RuleDescriptor.create2(this.FunctionOpenBraceLeftTokenRange, 13 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
                        this.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock = new formatting.Rule(formatting.RuleDescriptor.create2(this.TypeScriptOpenBraceLeftTokenRange, 13 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsTypeScriptDeclWithBlockContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
                        this.NewLineBeforeOpenBraceInControl = new formatting.Rule(formatting.RuleDescriptor.create2(this.ControlOpenBraceLeftTokenRange, 13 /* OpenBraceToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsControlDeclContext, Rules.IsBeforeMultilineBlockContext), 4 /* NewLine */), 1 /* CanDeleteNewLines */);
                        this.SpaceAfterSemicolonInFor = new formatting.Rule(formatting.RuleDescriptor.create3(21 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsForContext), 2 /* Space */));
                        this.NoSpaceAfterSemicolonInFor = new formatting.Rule(formatting.RuleDescriptor.create3(21 /* SemicolonToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext, Rules.IsForContext), 8 /* Delete */));
                        this.SpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(15 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.SpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 16 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 2 /* Space */));
                        this.NoSpaceBetweenParens = new formatting.Rule(formatting.RuleDescriptor.create1(15 /* OpenParenToken */, 16 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceAfterOpenParen = new formatting.Rule(formatting.RuleDescriptor.create3(15 /* OpenParenToken */, formatting.Shared.TokenRange.Any), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.NoSpaceBeforeCloseParen = new formatting.Rule(formatting.RuleDescriptor.create2(formatting.Shared.TokenRange.Any, 16 /* CloseParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsSameLineTokenContext), 8 /* Delete */));
                        this.SpaceAfterAnonymousFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(81 /* FunctionKeyword */, 15 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 2 /* Space */));
                        this.NoSpaceAfterAnonymousFunctionKeyword = new formatting.Rule(formatting.RuleDescriptor.create1(81 /* FunctionKeyword */, 15 /* OpenParenToken */), formatting.RuleOperation.create2(new formatting.RuleOperationContext(Rules.IsFunctionDeclContext), 8 /* Delete */));
                    }
                    Rules.prototype.getRuleName = function (rule) {
                        var o = this;
                        for (var name in o) {
                            if (o[name] === rule) {
                                return name;
                            }
                        }
                        throw new Error("Unknown rule");
                    };
                    Rules.IsForContext = function (context) {
                        return context.contextNode.kind === 170 /* ForStatement */;
                    };
                    Rules.IsNotForContext = function (context) {
                        return !Rules.IsForContext(context);
                    };
                    Rules.IsBinaryOpContext = function (context) {
                        switch (context.contextNode.kind) {
                            case 157 /* BinaryExpression */:
                            case 158 /* ConditionalExpression */:
                                return true;
                            case 195 /* ImportDeclaration */:
                            case 186 /* VariableDeclaration */:
                            case 124 /* Parameter */:
                            case 197 /* EnumMember */:
                            case 125 /* Property */:
                                return context.currentTokenSpan.kind === 51 /* EqualsToken */ || context.nextTokenSpan.kind === 51 /* EqualsToken */;
                            case 171 /* ForInStatement */:
                                return context.currentTokenSpan.kind === 84 /* InKeyword */ || context.nextTokenSpan.kind === 84 /* InKeyword */;
                        }
                        return false;
                    };
                    Rules.IsNotBinaryOpContext = function (context) {
                        return !Rules.IsBinaryOpContext(context);
                    };
                    Rules.IsSameLineTokenOrBeforeMultilineBlockContext = function (context) {
                        return context.TokensAreOnSameLine() || Rules.IsBeforeMultilineBlockContext(context);
                    };
                    Rules.IsBeforeMultilineBlockContext = function (context) {
                        return Rules.IsBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine());
                    };
                    Rules.IsMultilineBlockContext = function (context) {
                        return Rules.IsBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
                    };
                    Rules.IsSingleLineBlockContext = function (context) {
                        return Rules.IsBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine());
                    };
                    Rules.IsBlockContext = function (context) {
                        return Rules.NodeIsBlockContext(context.contextNode);
                    };
                    Rules.IsBeforeBlockContext = function (context) {
                        return Rules.NodeIsBlockContext(context.nextTokenParent);
                    };
                    Rules.NodeIsBlockContext = function (node) {
                        if (Rules.NodeIsTypeScriptDeclWithBlockContext(node)) {
                            return true;
                        }
                        switch (node.kind) {
                            case 163 /* Block */:
                            case 176 /* SwitchStatement */:
                            case 143 /* ObjectLiteral */:
                            case 182 /* TryBlock */:
                            case 183 /* CatchBlock */:
                            case 184 /* FinallyBlock */:
                            case 188 /* FunctionBlock */:
                            case 194 /* ModuleBlock */:
                                return true;
                        }
                        return false;
                    };
                    Rules.IsFunctionDeclContext = function (context) {
                        switch (context.contextNode.kind) {
                            case 187 /* FunctionDeclaration */:
                            case 126 /* Method */:
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                            case 130 /* CallSignature */:
                            case 153 /* FunctionExpression */:
                            case 127 /* Constructor */:
                            case 154 /* ArrowFunction */:
                            case 190 /* InterfaceDeclaration */:
                                return true;
                        }
                        return false;
                    };
                    Rules.IsTypeScriptDeclWithBlockContext = function (context) {
                        return Rules.NodeIsTypeScriptDeclWithBlockContext(context.contextNode);
                    };
                    Rules.NodeIsTypeScriptDeclWithBlockContext = function (node) {
                        switch (node.kind) {
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                            case 192 /* EnumDeclaration */:
                            case 137 /* TypeLiteral */:
                            case 193 /* ModuleDeclaration */:
                                return true;
                        }
                        return false;
                    };
                    Rules.IsAfterCodeBlockContext = function (context) {
                        switch (context.currentTokenParent.kind) {
                            case 189 /* ClassDeclaration */:
                            case 193 /* ModuleDeclaration */:
                            case 192 /* EnumDeclaration */:
                            case 163 /* Block */:
                            case 182 /* TryBlock */:
                            case 183 /* CatchBlock */:
                            case 184 /* FinallyBlock */:
                            case 188 /* FunctionBlock */:
                            case 194 /* ModuleBlock */:
                            case 176 /* SwitchStatement */:
                                return true;
                        }
                        return false;
                    };
                    Rules.IsControlDeclContext = function (context) {
                        switch (context.contextNode.kind) {
                            case 167 /* IfStatement */:
                            case 176 /* SwitchStatement */:
                            case 170 /* ForStatement */:
                            case 171 /* ForInStatement */:
                            case 169 /* WhileStatement */:
                            case 181 /* TryStatement */:
                            case 168 /* DoStatement */:
                            case 175 /* WithStatement */:
                            case 183 /* CatchBlock */:
                            case 184 /* FinallyBlock */:
                                return true;
                            default:
                                return false;
                        }
                    };
                    Rules.IsObjectContext = function (context) {
                        return context.contextNode.kind === 143 /* ObjectLiteral */;
                    };
                    Rules.IsFunctionCallContext = function (context) {
                        return context.contextNode.kind === 148 /* CallExpression */;
                    };
                    Rules.IsNewContext = function (context) {
                        return context.contextNode.kind === 149 /* NewExpression */;
                    };
                    Rules.IsFunctionCallOrNewContext = function (context) {
                        return Rules.IsFunctionCallContext(context) || Rules.IsNewContext(context);
                    };
                    Rules.IsSameLineTokenContext = function (context) {
                        return context.TokensAreOnSameLine();
                    };
                    Rules.IsNotFormatOnEnter = function (context) {
                        return context.formattingRequestKind != 2 /* FormatOnEnter */;
                    };
                    Rules.IsModuleDeclContext = function (context) {
                        return context.contextNode.kind === 193 /* ModuleDeclaration */;
                    };
                    Rules.IsObjectTypeContext = function (context) {
                        return context.contextNode.kind === 137 /* TypeLiteral */;
                    };
                    Rules.IsTypeArgumentOrParameter = function (token, parent) {
                        if (token.kind !== 23 /* LessThanToken */ && token.kind !== 24 /* GreaterThanToken */) {
                            return false;
                        }
                        switch (parent.kind) {
                            case 133 /* TypeReference */:
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                            case 187 /* FunctionDeclaration */:
                            case 153 /* FunctionExpression */:
                            case 154 /* ArrowFunction */:
                            case 126 /* Method */:
                            case 130 /* CallSignature */:
                            case 131 /* ConstructSignature */:
                            case 148 /* CallExpression */:
                            case 149 /* NewExpression */:
                                return true;
                            default:
                                return false;
                        }
                    };
                    Rules.IsTypeArgumentOrParameterContext = function (context) {
                        return Rules.IsTypeArgumentOrParameter(context.currentTokenSpan, context.currentTokenParent) || Rules.IsTypeArgumentOrParameter(context.nextTokenSpan, context.nextTokenParent);
                    };
                    Rules.IsVoidOpContext = function (context) {
                        return context.currentTokenSpan.kind === 97 /* VoidKeyword */ && context.currentTokenParent.kind === 155 /* PrefixOperator */;
                    };
                    return Rules;
                })();
                formatting.Rules = Rules;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var RulesMap = (function () {
                    function RulesMap() {
                        this.map = [];
                        this.mapRowLength = 0;
                    }
                    RulesMap.create = function (rules) {
                        var result = new RulesMap();
                        result.Initialize(rules);
                        return result;
                    };
                    RulesMap.prototype.Initialize = function (rules) {
                        this.mapRowLength = 119 /* LastToken */ + 1;
                        this.map = new Array(this.mapRowLength * this.mapRowLength);
                        var rulesBucketConstructionStateList = new Array(this.map.length);
                        this.FillRules(rules, rulesBucketConstructionStateList);
                        return this.map;
                    };
                    RulesMap.prototype.FillRules = function (rules, rulesBucketConstructionStateList) {
                        var _this = this;
                        rules.forEach(function (rule) {
                            _this.FillRule(rule, rulesBucketConstructionStateList);
                        });
                    };
                    RulesMap.prototype.GetRuleBucketIndex = function (row, column) {
                        var rulesBucketIndex = (row * this.mapRowLength) + column;
                        return rulesBucketIndex;
                    };
                    RulesMap.prototype.FillRule = function (rule, rulesBucketConstructionStateList) {
                        var _this = this;
                        var specificRule = rule.Descriptor.LeftTokenRange != formatting.Shared.TokenRange.Any && rule.Descriptor.RightTokenRange != formatting.Shared.TokenRange.Any;
                        rule.Descriptor.LeftTokenRange.GetTokens().forEach(function (left) {
                            rule.Descriptor.RightTokenRange.GetTokens().forEach(function (right) {
                                var rulesBucketIndex = _this.GetRuleBucketIndex(left, right);
                                var rulesBucket = _this.map[rulesBucketIndex];
                                if (rulesBucket == undefined) {
                                    rulesBucket = _this.map[rulesBucketIndex] = new RulesBucket();
                                }
                                rulesBucket.AddRule(rule, specificRule, rulesBucketConstructionStateList, rulesBucketIndex);
                            });
                        });
                    };
                    RulesMap.prototype.GetRule = function (context) {
                        var bucketIndex = this.GetRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind);
                        var bucket = this.map[bucketIndex];
                        if (bucket != null) {
                            for (var i = 0, len = bucket.Rules().length; i < len; i++) {
                                var rule = bucket.Rules()[i];
                                if (rule.Operation.Context.InContext(context))
                                    return rule;
                            }
                        }
                        return null;
                    };
                    return RulesMap;
                })();
                formatting.RulesMap = RulesMap;
                var MaskBitSize = 5;
                var Mask = 0x1f;
                (function (RulesPosition) {
                    RulesPosition[RulesPosition["IgnoreRulesSpecific"] = 0] = "IgnoreRulesSpecific";
                    RulesPosition[RulesPosition["IgnoreRulesAny"] = MaskBitSize * 1] = "IgnoreRulesAny";
                    RulesPosition[RulesPosition["ContextRulesSpecific"] = MaskBitSize * 2] = "ContextRulesSpecific";
                    RulesPosition[RulesPosition["ContextRulesAny"] = MaskBitSize * 3] = "ContextRulesAny";
                    RulesPosition[RulesPosition["NoContextRulesSpecific"] = MaskBitSize * 4] = "NoContextRulesSpecific";
                    RulesPosition[RulesPosition["NoContextRulesAny"] = MaskBitSize * 5] = "NoContextRulesAny";
                })(formatting.RulesPosition || (formatting.RulesPosition = {}));
                var RulesPosition = formatting.RulesPosition;
                var RulesBucketConstructionState = (function () {
                    function RulesBucketConstructionState() {
                        this.rulesInsertionIndexBitmap = 0;
                    }
                    RulesBucketConstructionState.prototype.GetInsertionIndex = function (maskPosition) {
                        var index = 0;
                        var pos = 0;
                        var indexBitmap = this.rulesInsertionIndexBitmap;
                        while (pos <= maskPosition) {
                            index += (indexBitmap & Mask);
                            indexBitmap >>= MaskBitSize;
                            pos += MaskBitSize;
                        }
                        return index;
                    };
                    RulesBucketConstructionState.prototype.IncreaseInsertionIndex = function (maskPosition) {
                        var value = (this.rulesInsertionIndexBitmap >> maskPosition) & Mask;
                        value++;
                        ts.Debug.assert((value & Mask) == value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
                        var temp = this.rulesInsertionIndexBitmap & ~(Mask << maskPosition);
                        temp |= value << maskPosition;
                        this.rulesInsertionIndexBitmap = temp;
                    };
                    return RulesBucketConstructionState;
                })();
                formatting.RulesBucketConstructionState = RulesBucketConstructionState;
                var RulesBucket = (function () {
                    function RulesBucket() {
                        this.rules = [];
                    }
                    RulesBucket.prototype.Rules = function () {
                        return this.rules;
                    };
                    RulesBucket.prototype.AddRule = function (rule, specificTokens, constructionState, rulesBucketIndex) {
                        var position;
                        if (rule.Operation.Action == 1 /* Ignore */) {
                            position = specificTokens ? 0 /* IgnoreRulesSpecific */ : RulesPosition.IgnoreRulesAny;
                        }
                        else if (!rule.Operation.Context.IsAny()) {
                            position = specificTokens ? RulesPosition.ContextRulesSpecific : RulesPosition.ContextRulesAny;
                        }
                        else {
                            position = specificTokens ? RulesPosition.NoContextRulesSpecific : RulesPosition.NoContextRulesAny;
                        }
                        var state = constructionState[rulesBucketIndex];
                        if (state === undefined) {
                            state = constructionState[rulesBucketIndex] = new RulesBucketConstructionState();
                        }
                        var index = state.GetInsertionIndex(position);
                        this.rules.splice(index, 0, rule);
                        state.IncreaseInsertionIndex(position);
                    };
                    return RulesBucket;
                })();
                formatting.RulesBucket = RulesBucket;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var Shared;
                (function (Shared) {
                    var TokenRangeAccess = (function () {
                        function TokenRangeAccess(from, to, except) {
                            this.tokens = [];
                            for (var token = from; token <= to; token++) {
                                if (except.indexOf(token) < 0) {
                                    this.tokens.push(token);
                                }
                            }
                        }
                        TokenRangeAccess.prototype.GetTokens = function () {
                            return this.tokens;
                        };
                        TokenRangeAccess.prototype.Contains = function (token) {
                            return this.tokens.indexOf(token) >= 0;
                        };
                        return TokenRangeAccess;
                    })();
                    Shared.TokenRangeAccess = TokenRangeAccess;
                    var TokenValuesAccess = (function () {
                        function TokenValuesAccess(tks) {
                            this.tokens = tks && tks.length ? tks : [];
                        }
                        TokenValuesAccess.prototype.GetTokens = function () {
                            return this.tokens;
                        };
                        TokenValuesAccess.prototype.Contains = function (token) {
                            return this.tokens.indexOf(token) >= 0;
                        };
                        return TokenValuesAccess;
                    })();
                    Shared.TokenValuesAccess = TokenValuesAccess;
                    var TokenSingleValueAccess = (function () {
                        function TokenSingleValueAccess(token) {
                            this.token = token;
                        }
                        TokenSingleValueAccess.prototype.GetTokens = function () {
                            return [this.token];
                        };
                        TokenSingleValueAccess.prototype.Contains = function (tokenValue) {
                            return tokenValue == this.token;
                        };
                        return TokenSingleValueAccess;
                    })();
                    Shared.TokenSingleValueAccess = TokenSingleValueAccess;
                    var TokenAllAccess = (function () {
                        function TokenAllAccess() {
                        }
                        TokenAllAccess.prototype.GetTokens = function () {
                            var result = [];
                            for (var token = 1 /* FirstToken */; token <= 119 /* LastToken */; token++) {
                                result.push(token);
                            }
                            return result;
                        };
                        TokenAllAccess.prototype.Contains = function (tokenValue) {
                            return true;
                        };
                        TokenAllAccess.prototype.toString = function () {
                            return "[allTokens]";
                        };
                        return TokenAllAccess;
                    })();
                    Shared.TokenAllAccess = TokenAllAccess;
                    var TokenRange = (function () {
                        function TokenRange(tokenAccess) {
                            this.tokenAccess = tokenAccess;
                        }
                        TokenRange.FromToken = function (token) {
                            return new TokenRange(new TokenSingleValueAccess(token));
                        };
                        TokenRange.FromTokens = function (tokens) {
                            return new TokenRange(new TokenValuesAccess(tokens));
                        };
                        TokenRange.FromRange = function (f, to, except) {
                            if (except === void 0) { except = []; }
                            return new TokenRange(new TokenRangeAccess(f, to, except));
                        };
                        TokenRange.AllTokens = function () {
                            return new TokenRange(new TokenAllAccess());
                        };
                        TokenRange.prototype.GetTokens = function () {
                            return this.tokenAccess.GetTokens();
                        };
                        TokenRange.prototype.Contains = function (token) {
                            return this.tokenAccess.Contains(token);
                        };
                        TokenRange.prototype.toString = function () {
                            return this.tokenAccess.toString();
                        };
                        TokenRange.Any = TokenRange.AllTokens();
                        TokenRange.AnyIncludingMultilineComments = TokenRange.FromTokens(TokenRange.Any.GetTokens().concat([3 /* MultiLineCommentTrivia */]));
                        TokenRange.Keywords = TokenRange.FromRange(64 /* FirstKeyword */, 119 /* LastKeyword */);
                        TokenRange.Operators = TokenRange.FromRange(21 /* FirstOperator */, 62 /* LastOperator */);
                        TokenRange.BinaryOperators = TokenRange.FromRange(23 /* FirstBinaryOperator */, 62 /* LastBinaryOperator */);
                        TokenRange.BinaryKeywordOperators = TokenRange.FromTokens([84 /* InKeyword */, 85 /* InstanceOfKeyword */]);
                        TokenRange.ReservedKeywords = TokenRange.FromRange(100 /* FirstFutureReservedWord */, 108 /* LastFutureReservedWord */);
                        TokenRange.UnaryPrefixOperators = TokenRange.FromTokens([37 /* PlusPlusToken */, 38 /* MinusMinusToken */, 46 /* TildeToken */, 45 /* ExclamationToken */]);
                        TokenRange.UnaryPrefixExpressions = TokenRange.FromTokens([6 /* NumericLiteral */, 63 /* Identifier */, 15 /* OpenParenToken */, 17 /* OpenBracketToken */, 13 /* OpenBraceToken */, 91 /* ThisKeyword */, 86 /* NewKeyword */]);
                        TokenRange.UnaryPreincrementExpressions = TokenRange.FromTokens([63 /* Identifier */, 15 /* OpenParenToken */, 91 /* ThisKeyword */, 86 /* NewKeyword */]);
                        TokenRange.UnaryPostincrementExpressions = TokenRange.FromTokens([63 /* Identifier */, 16 /* CloseParenToken */, 18 /* CloseBracketToken */, 86 /* NewKeyword */]);
                        TokenRange.UnaryPredecrementExpressions = TokenRange.FromTokens([63 /* Identifier */, 15 /* OpenParenToken */, 91 /* ThisKeyword */, 86 /* NewKeyword */]);
                        TokenRange.UnaryPostdecrementExpressions = TokenRange.FromTokens([63 /* Identifier */, 16 /* CloseParenToken */, 18 /* CloseBracketToken */, 86 /* NewKeyword */]);
                        TokenRange.Comments = TokenRange.FromTokens([2 /* SingleLineCommentTrivia */, 3 /* MultiLineCommentTrivia */]);
                        TokenRange.TypeNames = TokenRange.FromTokens([63 /* Identifier */, 116 /* NumberKeyword */, 118 /* StringKeyword */, 110 /* BooleanKeyword */, 97 /* VoidKeyword */, 109 /* AnyKeyword */]);
                        return TokenRange;
                    })();
                    Shared.TokenRange = TokenRange;
                })(Shared = formatting.Shared || (formatting.Shared = {}));
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var __extends = this.__extends || function (d, b) {
            for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
            function __() { this.constructor = d; }
            __.prototype = b.prototype;
            d.prototype = new __();
        };
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var TokenSpan = (function (_super) {
                    __extends(TokenSpan, _super);
                    function TokenSpan(kind, start, length) {
                        _super.call(this, start, length);
                        this.kind = kind;
                    }
                    return TokenSpan;
                })(ts.TextSpan);
                formatting.TokenSpan = TokenSpan;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var RulesProvider = (function () {
                    function RulesProvider(logger) {
                        this.logger = logger;
                        this.globalRules = new formatting.Rules();
                    }
                    RulesProvider.prototype.getRuleName = function (rule) {
                        return this.globalRules.getRuleName(rule);
                    };
                    RulesProvider.prototype.getRuleByName = function (name) {
                        return this.globalRules[name];
                    };
                    RulesProvider.prototype.getRulesMap = function () {
                        return this.rulesMap;
                    };
                    RulesProvider.prototype.ensureUpToDate = function (options) {
                        if (this.options == null || !ts.compareDataObjects(this.options, options)) {
                            var activeRules = this.createActiveRules(options);
                            var rulesMap = formatting.RulesMap.create(activeRules);
                            this.activeRules = activeRules;
                            this.rulesMap = rulesMap;
                            this.options = ts.clone(options);
                        }
                    };
                    RulesProvider.prototype.createActiveRules = function (options) {
                        var rules = this.globalRules.HighPriorityCommonRules.slice(0);
                        if (options.InsertSpaceAfterCommaDelimiter) {
                            rules.push(this.globalRules.SpaceAfterComma);
                        }
                        else {
                            rules.push(this.globalRules.NoSpaceAfterComma);
                        }
                        if (options.InsertSpaceAfterFunctionKeywordForAnonymousFunctions) {
                            rules.push(this.globalRules.SpaceAfterAnonymousFunctionKeyword);
                        }
                        else {
                            rules.push(this.globalRules.NoSpaceAfterAnonymousFunctionKeyword);
                        }
                        if (options.InsertSpaceAfterKeywordsInControlFlowStatements) {
                            rules.push(this.globalRules.SpaceAfterKeywordInControl);
                        }
                        else {
                            rules.push(this.globalRules.NoSpaceAfterKeywordInControl);
                        }
                        if (options.InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis) {
                            rules.push(this.globalRules.SpaceAfterOpenParen);
                            rules.push(this.globalRules.SpaceBeforeCloseParen);
                            rules.push(this.globalRules.NoSpaceBetweenParens);
                        }
                        else {
                            rules.push(this.globalRules.NoSpaceAfterOpenParen);
                            rules.push(this.globalRules.NoSpaceBeforeCloseParen);
                            rules.push(this.globalRules.NoSpaceBetweenParens);
                        }
                        if (options.InsertSpaceAfterSemicolonInForStatements) {
                            rules.push(this.globalRules.SpaceAfterSemicolonInFor);
                        }
                        else {
                            rules.push(this.globalRules.NoSpaceAfterSemicolonInFor);
                        }
                        if (options.InsertSpaceBeforeAndAfterBinaryOperators) {
                            rules.push(this.globalRules.SpaceBeforeBinaryOperator);
                            rules.push(this.globalRules.SpaceAfterBinaryOperator);
                        }
                        else {
                            rules.push(this.globalRules.NoSpaceBeforeBinaryOperator);
                            rules.push(this.globalRules.NoSpaceAfterBinaryOperator);
                        }
                        if (options.PlaceOpenBraceOnNewLineForControlBlocks) {
                            rules.push(this.globalRules.NewLineBeforeOpenBraceInControl);
                        }
                        if (options.PlaceOpenBraceOnNewLineForFunctions) {
                            rules.push(this.globalRules.NewLineBeforeOpenBraceInFunction);
                            rules.push(this.globalRules.NewLineBeforeOpenBraceInTypeScriptDeclWithBlock);
                        }
                        rules = rules.concat(this.globalRules.LowPriorityCommonRules);
                        return rules;
                    };
                    return RulesProvider;
                })();
                formatting.RulesProvider = RulesProvider;
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var formatting;
            (function (formatting) {
                var Constants;
                (function (Constants) {
                    Constants[Constants["Unknown"] = -1] = "Unknown";
                })(Constants || (Constants = {}));
                function formatOnEnter(position, sourceFile, rulesProvider, options) {
                    var line = sourceFile.getLineAndCharacterFromPosition(position).line;
                    ts.Debug.assert(line >= 2);
                    var span = {
                        pos: ts.getStartPositionOfLine(line - 1, sourceFile),
                        end: ts.getEndLinePosition(line, sourceFile) + 1
                    };
                    return formatSpan(span, sourceFile, options, rulesProvider, 2 /* FormatOnEnter */);
                }
                formatting.formatOnEnter = formatOnEnter;
                function formatOnSemicolon(position, sourceFile, rulesProvider, options) {
                    return formatOutermostParent(position, 21 /* SemicolonToken */, sourceFile, options, rulesProvider, 3 /* FormatOnSemicolon */);
                }
                formatting.formatOnSemicolon = formatOnSemicolon;
                function formatOnClosingCurly(position, sourceFile, rulesProvider, options) {
                    return formatOutermostParent(position, 14 /* CloseBraceToken */, sourceFile, options, rulesProvider, 4 /* FormatOnClosingCurlyBrace */);
                }
                formatting.formatOnClosingCurly = formatOnClosingCurly;
                function formatDocument(sourceFile, rulesProvider, options) {
                    var span = {
                        pos: 0,
                        end: sourceFile.text.length
                    };
                    return formatSpan(span, sourceFile, options, rulesProvider, 0 /* FormatDocument */);
                }
                formatting.formatDocument = formatDocument;
                function formatSelection(start, end, sourceFile, rulesProvider, options) {
                    var span = {
                        pos: ts.getStartLinePositionForPosition(start, sourceFile),
                        end: end
                    };
                    return formatSpan(span, sourceFile, options, rulesProvider, 1 /* FormatSelection */);
                }
                formatting.formatSelection = formatSelection;
                function formatOutermostParent(position, expectedLastToken, sourceFile, options, rulesProvider, requestKind) {
                    var parent = findOutermostParent(position, expectedLastToken, sourceFile);
                    if (!parent) {
                        return [];
                    }
                    var span = {
                        pos: ts.getStartLinePositionForPosition(parent.getStart(sourceFile), sourceFile),
                        end: parent.end
                    };
                    return formatSpan(span, sourceFile, options, rulesProvider, requestKind);
                }
                function findOutermostParent(position, expectedTokenKind, sourceFile) {
                    var precedingToken = ts.findPrecedingToken(position, sourceFile);
                    if (!precedingToken || precedingToken.kind !== expectedTokenKind) {
                        return undefined;
                    }
                    var current = precedingToken;
                    while (current && current.parent && current.parent.end === precedingToken.end && !isListElement(current.parent, current)) {
                        current = current.parent;
                    }
                    return current;
                }
                function isListElement(parent, node) {
                    switch (parent.kind) {
                        case 189 /* ClassDeclaration */:
                        case 190 /* InterfaceDeclaration */:
                            return ts.rangeContainsRange(parent.members, node);
                        case 193 /* ModuleDeclaration */:
                            var body = parent.body;
                            return body && body.kind === 163 /* Block */ && ts.rangeContainsRange(body.statements, node);
                        case 198 /* SourceFile */:
                        case 163 /* Block */:
                        case 182 /* TryBlock */:
                        case 183 /* CatchBlock */:
                        case 184 /* FinallyBlock */:
                        case 194 /* ModuleBlock */:
                            return ts.rangeContainsRange(parent.statements, node);
                    }
                    return false;
                }
                function findEnclosingNode(range, sourceFile) {
                    return find(sourceFile);
                    function find(n) {
                        var candidate = ts.forEachChild(n, function (c) { return ts.startEndContainsRange(c.getStart(sourceFile), c.end, range) && c; });
                        if (candidate) {
                            var result = find(candidate);
                            if (result) {
                                return result;
                            }
                        }
                        return n;
                    }
                }
                function prepareRangeContainsErrorFunction(errors, originalRange) {
                    if (!errors.length) {
                        return rangeHasNoErrors;
                    }
                    var sorted = errors.filter(function (d) { return d.isParseError && ts.rangeOverlapsWithStartEnd(originalRange, d.start, d.start + d.length); }).sort(function (e1, e2) { return e1.start - e2.start; });
                    if (!sorted.length) {
                        return rangeHasNoErrors;
                    }
                    var index = 0;
                    return function (r) {
                        while (true) {
                            if (index >= sorted.length) {
                                return false;
                            }
                            var error = sorted[index];
                            if (r.end <= error.start) {
                                return false;
                            }
                            if (ts.startEndOverlapsWithStartEnd(r.pos, r.end, error.start, error.start + error.length)) {
                                return true;
                            }
                            index++;
                        }
                    };
                    function rangeHasNoErrors(r) {
                        return false;
                    }
                }
                function getScanStartPosition(enclosingNode, originalRange, sourceFile) {
                    var start = enclosingNode.getStart(sourceFile);
                    if (start === originalRange.pos && enclosingNode.end === originalRange.end) {
                        return start;
                    }
                    var precedingToken = ts.findPrecedingToken(originalRange.pos, sourceFile);
                    return precedingToken ? precedingToken.end : enclosingNode.pos;
                }
                function formatSpan(originalRange, sourceFile, options, rulesProvider, requestKind) {
                    var rangeContainsError = prepareRangeContainsErrorFunction(sourceFile.getSyntacticDiagnostics(), originalRange);
                    var formattingContext = new formatting.FormattingContext(sourceFile, requestKind);
                    var enclosingNode = findEnclosingNode(originalRange, sourceFile);
                    var formattingScanner = formatting.getFormattingScanner(sourceFile, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end);
                    var initialIndentation = formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, options);
                    var previousRangeHasError;
                    var previousRange;
                    var previousParent;
                    var previousRangeStartLine;
                    var edits = [];
                    formattingScanner.advance();
                    if (formattingScanner.isOnToken()) {
                        var startLine = sourceFile.getLineAndCharacterFromPosition(enclosingNode.getStart(sourceFile)).line;
                        var delta = formatting.SmartIndenter.shouldIndentChildNode(enclosingNode.kind, 0 /* Unknown */) ? options.IndentSize : 0;
                        processNode(enclosingNode, enclosingNode, startLine, initialIndentation, delta);
                    }
                    formattingScanner.close();
                    return edits;
                    function tryComputeIndentationForListItem(startPos, endPos, parentStartLine, range, inheritedIndentation) {
                        if (ts.rangeOverlapsWithStartEnd(range, startPos, endPos)) {
                            if (inheritedIndentation !== -1 /* Unknown */) {
                                return inheritedIndentation;
                            }
                        }
                        else {
                            var startLine = sourceFile.getLineAndCharacterFromPosition(startPos).line;
                            var startLinePosition = ts.getStartLinePositionForPosition(startPos, sourceFile);
                            var column = formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, startPos, sourceFile, options);
                            if (startLine !== parentStartLine || startPos === column) {
                                return column;
                            }
                        }
                        return -1 /* Unknown */;
                    }
                    function computeIndentation(node, startLine, inheritedIndentation, parent, parentDynamicIndentation, effectiveParentStartLine) {
                        var indentation = inheritedIndentation;
                        if (indentation === -1 /* Unknown */) {
                            if (isSomeBlock(node.kind)) {
                                if (isSomeBlock(parent.kind) || parent.kind === 198 /* SourceFile */ || parent.kind === 177 /* CaseClause */ || parent.kind === 178 /* DefaultClause */) {
                                    indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta();
                                }
                                else {
                                    indentation = parentDynamicIndentation.getIndentation();
                                }
                            }
                            else {
                                if (formatting.SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) {
                                    indentation = parentDynamicIndentation.getIndentation();
                                }
                                else {
                                    indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta();
                                }
                            }
                        }
                        var delta = formatting.SmartIndenter.shouldIndentChildNode(node.kind, 0 /* Unknown */) ? options.IndentSize : 0;
                        if (effectiveParentStartLine === startLine) {
                            indentation = parentDynamicIndentation.getIndentation();
                            delta = Math.min(options.IndentSize, parentDynamicIndentation.getDelta() + delta);
                        }
                        return {
                            indentation: indentation,
                            delta: delta
                        };
                    }
                    function getDynamicIndentation(node, nodeStartLine, indentation, delta) {
                        return {
                            getIndentationForComment: function (kind) {
                                switch (kind) {
                                    case 14 /* CloseBraceToken */:
                                    case 18 /* CloseBracketToken */:
                                        return indentation + delta;
                                }
                                return indentation;
                            },
                            getIndentationForToken: function (line, kind) {
                                switch (kind) {
                                    case 13 /* OpenBraceToken */:
                                    case 14 /* CloseBraceToken */:
                                    case 17 /* OpenBracketToken */:
                                    case 18 /* CloseBracketToken */:
                                    case 74 /* ElseKeyword */:
                                    case 98 /* WhileKeyword */:
                                        return indentation;
                                    default:
                                        return nodeStartLine !== line ? indentation + delta : indentation;
                                }
                            },
                            getIndentation: function () { return indentation; },
                            getDelta: function () { return delta; },
                            recomputeIndentation: function (lineAdded) {
                                if (node.parent && formatting.SmartIndenter.shouldIndentChildNode(node.parent.kind, node.kind)) {
                                    if (lineAdded) {
                                        indentation += options.IndentSize;
                                    }
                                    else {
                                        indentation -= options.IndentSize;
                                    }
                                    if (formatting.SmartIndenter.shouldIndentChildNode(node.kind, 0 /* Unknown */)) {
                                        delta = options.IndentSize;
                                    }
                                    else {
                                        delta = 0;
                                    }
                                }
                            }
                        };
                    }
                    function processNode(node, contextNode, nodeStartLine, indentation, delta) {
                        if (!ts.rangeOverlapsWithStartEnd(originalRange, node.getStart(sourceFile), node.getEnd())) {
                            return;
                        }
                        var nodeDynamicIndentation = getDynamicIndentation(node, nodeStartLine, indentation, delta);
                        var childContextNode = contextNode;
                        ts.forEachChild(node, function (child) {
                            processChildNode(child, -1 /* Unknown */, node, nodeDynamicIndentation, nodeStartLine, false);
                        }, function (nodes) {
                            processChildNodes(nodes, node, nodeStartLine, nodeDynamicIndentation);
                        });
                        while (formattingScanner.isOnToken()) {
                            var tokenInfo = formattingScanner.readTokenInfo(node);
                            if (tokenInfo.token.end > node.end) {
                                break;
                            }
                            consumeTokenAndAdvanceScanner(tokenInfo, node, nodeDynamicIndentation);
                        }
                        function processChildNode(child, inheritedIndentation, parent, parentDynamicIndentation, parentStartLine, isListItem) {
                            var childStartPos = child.getStart(sourceFile);
                            var childStart = sourceFile.getLineAndCharacterFromPosition(childStartPos);
                            var childIndentationAmount = -1 /* Unknown */;
                            if (isListItem) {
                                childIndentationAmount = tryComputeIndentationForListItem(childStartPos, child.end, parentStartLine, originalRange, inheritedIndentation);
                                if (childIndentationAmount !== -1 /* Unknown */) {
                                    inheritedIndentation = childIndentationAmount;
                                }
                            }
                            if (!ts.rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) {
                                return inheritedIndentation;
                            }
                            if (child.kind === 120 /* Missing */) {
                                return inheritedIndentation;
                            }
                            while (formattingScanner.isOnToken()) {
                                var tokenInfo = formattingScanner.readTokenInfo(node);
                                if (tokenInfo.token.end > childStartPos) {
                                    break;
                                }
                                consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation);
                            }
                            if (!formattingScanner.isOnToken()) {
                                return inheritedIndentation;
                            }
                            if (ts.isToken(child)) {
                                var tokenInfo = formattingScanner.readTokenInfo(child);
                                ts.Debug.assert(tokenInfo.token.end === child.end);
                                consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation);
                                return inheritedIndentation;
                            }
                            var childIndentation = computeIndentation(child, childStart.line, childIndentationAmount, node, parentDynamicIndentation, parentStartLine);
                            processNode(child, childContextNode, childStart.line, childIndentation.indentation, childIndentation.delta);
                            childContextNode = node;
                            return inheritedIndentation;
                        }
                        function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) {
                            var listStartToken = getOpenTokenForList(parent, nodes);
                            var listEndToken = getCloseTokenForOpenToken(listStartToken);
                            var listDynamicIndentation = parentDynamicIndentation;
                            var startLine = parentStartLine;
                            if (listStartToken !== 0 /* Unknown */) {
                                while (formattingScanner.isOnToken()) {
                                    var tokenInfo = formattingScanner.readTokenInfo(parent);
                                    if (tokenInfo.token.end > nodes.pos) {
                                        break;
                                    }
                                    else if (tokenInfo.token.kind === listStartToken) {
                                        startLine = sourceFile.getLineAndCharacterFromPosition(tokenInfo.token.pos).line;
                                        var indentation = computeIndentation(tokenInfo.token, startLine, -1 /* Unknown */, parent, parentDynamicIndentation, startLine);
                                        listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentation.indentation, indentation.delta);
                                        consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation);
                                    }
                                    else {
                                        consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation);
                                    }
                                }
                            }
                            var inheritedIndentation = -1 /* Unknown */;
                            for (var i = 0, len = nodes.length; i < len; ++i) {
                                inheritedIndentation = processChildNode(nodes[i], inheritedIndentation, node, listDynamicIndentation, startLine, true);
                            }
                            if (listEndToken !== 0 /* Unknown */) {
                                if (formattingScanner.isOnToken()) {
                                    var tokenInfo = formattingScanner.readTokenInfo(parent);
                                    if (tokenInfo.token.kind === listEndToken) {
                                        consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation);
                                    }
                                }
                            }
                        }
                        function consumeTokenAndAdvanceScanner(currentTokenInfo, parent, dynamicIndentation) {
                            ts.Debug.assert(ts.rangeContainsRange(parent, currentTokenInfo.token));
                            var lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine();
                            var indentToken = false;
                            if (currentTokenInfo.leadingTrivia) {
                                processTrivia(currentTokenInfo.leadingTrivia, parent, childContextNode, dynamicIndentation);
                            }
                            var lineAdded;
                            var isTokenInRange = ts.rangeContainsRange(originalRange, currentTokenInfo.token);
                            var tokenStart = sourceFile.getLineAndCharacterFromPosition(currentTokenInfo.token.pos);
                            if (isTokenInRange) {
                                var prevStartLine = previousRangeStartLine;
                                lineAdded = processRange(currentTokenInfo.token, tokenStart, parent, childContextNode, dynamicIndentation);
                                if (lineAdded !== undefined) {
                                    indentToken = lineAdded;
                                }
                                else {
                                    indentToken = lastTriviaWasNewLine && tokenStart.line !== prevStartLine;
                                }
                            }
                            if (currentTokenInfo.trailingTrivia) {
                                processTrivia(currentTokenInfo.trailingTrivia, parent, childContextNode, dynamicIndentation);
                            }
                            if (indentToken) {
                                var indentNextTokenOrTrivia = true;
                                if (currentTokenInfo.leadingTrivia) {
                                    for (var i = 0, len = currentTokenInfo.leadingTrivia.length; i < len; ++i) {
                                        var triviaItem = currentTokenInfo.leadingTrivia[i];
                                        if (!ts.rangeContainsRange(originalRange, triviaItem)) {
                                            continue;
                                        }
                                        var triviaStartLine = sourceFile.getLineAndCharacterFromPosition(triviaItem.pos).line;
                                        switch (triviaItem.kind) {
                                            case 3 /* MultiLineCommentTrivia */:
                                                var commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind);
                                                indentMultilineComment(triviaItem, commentIndentation, !indentNextTokenOrTrivia);
                                                indentNextTokenOrTrivia = false;
                                                break;
                                            case 2 /* SingleLineCommentTrivia */:
                                                if (indentNextTokenOrTrivia) {
                                                    var commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind);
                                                    insertIndentation(triviaItem.pos, commentIndentation, false);
                                                    indentNextTokenOrTrivia = false;
                                                }
                                                break;
                                            case 4 /* NewLineTrivia */:
                                                indentNextTokenOrTrivia = true;
                                                break;
                                        }
                                    }
                                }
                                if (isTokenInRange && !rangeContainsError(currentTokenInfo.token)) {
                                    var tokenIndentation = dynamicIndentation.getIndentationForToken(tokenStart.line, currentTokenInfo.token.kind);
                                    insertIndentation(currentTokenInfo.token.pos, tokenIndentation, lineAdded);
                                }
                            }
                            formattingScanner.advance();
                            childContextNode = parent;
                        }
                    }
                    function processTrivia(trivia, parent, contextNode, dynamicIndentation) {
                        for (var i = 0, len = trivia.length; i < len; ++i) {
                            var triviaItem = trivia[i];
                            if (ts.isComment(triviaItem.kind) && ts.rangeContainsRange(originalRange, triviaItem)) {
                                var triviaItemStart = sourceFile.getLineAndCharacterFromPosition(triviaItem.pos);
                                processRange(triviaItem, triviaItemStart, parent, contextNode, dynamicIndentation);
                            }
                        }
                    }
                    function processRange(range, rangeStart, parent, contextNode, dynamicIndentation) {
                        var rangeHasError = rangeContainsError(range);
                        var lineAdded;
                        if (!rangeHasError && !previousRangeHasError) {
                            if (!previousRange) {
                                var originalStart = sourceFile.getLineAndCharacterFromPosition(originalRange.pos);
                                trimTrailingWhitespacesForLines(originalStart.line, rangeStart.line);
                            }
                            else {
                                lineAdded = processPair(range, rangeStart.line, parent, previousRange, previousRangeStartLine, previousParent, contextNode, dynamicIndentation);
                            }
                        }
                        previousRange = range;
                        previousParent = parent;
                        previousRangeStartLine = rangeStart.line;
                        previousRangeHasError = rangeHasError;
                        return lineAdded;
                    }
                    function processPair(currentItem, currentStartLine, currentParent, previousItem, previousStartLine, previousParent, contextNode, dynamicIndentation) {
                        formattingContext.updateContext(previousItem, previousParent, currentItem, currentParent, contextNode);
                        var rule = rulesProvider.getRulesMap().GetRule(formattingContext);
                        var trimTrailingWhitespaces;
                        var lineAdded;
                        if (rule) {
                            applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine);
                            if (rule.Operation.Action & (2 /* Space */ | 8 /* Delete */) && currentStartLine !== previousStartLine) {
                                lineAdded = false;
                                if (currentParent.getStart(sourceFile) === currentItem.pos) {
                                    dynamicIndentation.recomputeIndentation(false);
                                }
                            }
                            else if (rule.Operation.Action & 4 /* NewLine */ && currentStartLine === previousStartLine) {
                                lineAdded = true;
                                if (currentParent.getStart(sourceFile) === currentItem.pos) {
                                    dynamicIndentation.recomputeIndentation(true);
                                }
                            }
                            trimTrailingWhitespaces = (rule.Operation.Action & (4 /* NewLine */ | 2 /* Space */)) && rule.Flag !== 1 /* CanDeleteNewLines */;
                        }
                        else {
                            trimTrailingWhitespaces = true;
                        }
                        if (currentStartLine !== previousStartLine && trimTrailingWhitespaces) {
                            trimTrailingWhitespacesForLines(previousStartLine, currentStartLine, previousItem);
                        }
                        return lineAdded;
                    }
                    function insertIndentation(pos, indentation, lineAdded) {
                        var indentationString = formatting.getIndentationString(indentation, options);
                        if (lineAdded) {
                            recordReplace(pos, 0, indentationString);
                        }
                        else {
                            var tokenStart = sourceFile.getLineAndCharacterFromPosition(pos);
                            if (indentation !== tokenStart.character - 1) {
                                var startLinePosition = ts.getStartPositionOfLine(tokenStart.line, sourceFile);
                                recordReplace(startLinePosition, tokenStart.character - 1, indentationString);
                            }
                        }
                    }
                    function indentMultilineComment(commentRange, indentation, firstLineIsIndented) {
                        var startLine = sourceFile.getLineAndCharacterFromPosition(commentRange.pos).line;
                        var endLine = sourceFile.getLineAndCharacterFromPosition(commentRange.end).line;
                        if (startLine === endLine) {
                            if (!firstLineIsIndented) {
                                insertIndentation(commentRange.pos, indentation, false);
                            }
                            return;
                        }
                        else {
                            var parts = [];
                            var startPos = commentRange.pos;
                            for (var line = startLine; line < endLine; ++line) {
                                var endOfLine = ts.getEndLinePosition(line, sourceFile);
                                parts.push({ pos: startPos, end: endOfLine });
                                startPos = ts.getStartPositionOfLine(line + 1, sourceFile);
                            }
                            parts.push({ pos: startPos, end: commentRange.end });
                        }
                        var startLinePos = ts.getStartPositionOfLine(startLine, sourceFile);
                        var nonWhitespaceColumnInFirstPart = formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePos, parts[0].pos, sourceFile, options);
                        if (indentation === nonWhitespaceColumnInFirstPart) {
                            return;
                        }
                        var startIndex = 0;
                        if (firstLineIsIndented) {
                            startIndex = 1;
                            startLine++;
                        }
                        var delta = indentation - nonWhitespaceColumnInFirstPart;
                        for (var i = startIndex, len = parts.length; i < len; ++i, ++startLine) {
                            var startLinePos = ts.getStartPositionOfLine(startLine, sourceFile);
                            var nonWhitespaceColumn = i === 0 ? nonWhitespaceColumnInFirstPart : formatting.SmartIndenter.findFirstNonWhitespaceColumn(parts[i].pos, parts[i].end, sourceFile, options);
                            var newIndentation = nonWhitespaceColumn + delta;
                            if (newIndentation > 0) {
                                var indentationString = formatting.getIndentationString(newIndentation, options);
                                recordReplace(startLinePos, nonWhitespaceColumn, indentationString);
                            }
                            else {
                                recordDelete(startLinePos, nonWhitespaceColumn);
                            }
                        }
                    }
                    function trimTrailingWhitespacesForLines(line1, line2, range) {
                        for (var line = line1; line < line2; ++line) {
                            var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile);
                            var lineEndPosition = ts.getEndLinePosition(line, sourceFile);
                            if (range && ts.isComment(range.kind) && range.pos <= lineEndPosition && range.end > lineEndPosition) {
                                continue;
                            }
                            var pos = lineEndPosition;
                            while (pos >= lineStartPosition && ts.isWhiteSpace(sourceFile.text.charCodeAt(pos))) {
                                pos--;
                            }
                            if (pos !== lineEndPosition) {
                                ts.Debug.assert(pos === lineStartPosition || !ts.isWhiteSpace(sourceFile.text.charCodeAt(pos)));
                                recordDelete(pos + 1, lineEndPosition - pos);
                            }
                        }
                    }
                    function newTextChange(start, len, newText) {
                        return { span: new ts.TextSpan(start, len), newText: newText };
                    }
                    function recordDelete(start, len) {
                        if (len) {
                            edits.push(newTextChange(start, len, ""));
                        }
                    }
                    function recordReplace(start, len, newText) {
                        if (len || newText) {
                            edits.push(newTextChange(start, len, newText));
                        }
                    }
                    function applyRuleEdits(rule, previousRange, previousStartLine, currentRange, currentStartLine) {
                        var between;
                        switch (rule.Operation.Action) {
                            case 1 /* Ignore */:
                                return;
                            case 8 /* Delete */:
                                if (previousRange.end !== currentRange.pos) {
                                    recordDelete(previousRange.end, currentRange.pos - previousRange.end);
                                }
                                break;
                            case 4 /* NewLine */:
                                if (rule.Flag !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) {
                                    return;
                                }
                                var lineDelta = currentStartLine - previousStartLine;
                                if (lineDelta !== 1) {
                                    recordReplace(previousRange.end, currentRange.pos - previousRange.end, options.NewLineCharacter);
                                }
                                break;
                            case 2 /* Space */:
                                if (rule.Flag !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) {
                                    return;
                                }
                                var posDelta = currentRange.pos - previousRange.end;
                                if (posDelta !== 1 || sourceFile.text.charCodeAt(previousRange.end) !== 32 /* space */) {
                                    recordReplace(previousRange.end, currentRange.pos - previousRange.end, " ");
                                }
                                break;
                        }
                    }
                }
                function isSomeBlock(kind) {
                    switch (kind) {
                        case 163 /* Block */:
                        case 188 /* FunctionBlock */:
                        case 182 /* TryBlock */:
                        case 183 /* CatchBlock */:
                        case 184 /* FinallyBlock */:
                        case 194 /* ModuleBlock */:
                            return true;
                    }
                    return false;
                }
                function getOpenTokenForList(node, list) {
                    switch (node.kind) {
                        case 127 /* Constructor */:
                        case 187 /* FunctionDeclaration */:
                        case 153 /* FunctionExpression */:
                        case 126 /* Method */:
                        case 154 /* ArrowFunction */:
                            if (node.typeParameters === list) {
                                return 23 /* LessThanToken */;
                            }
                            else if (node.parameters === list) {
                                return 15 /* OpenParenToken */;
                            }
                            break;
                        case 148 /* CallExpression */:
                        case 149 /* NewExpression */:
                            if (node.typeArguments === list) {
                                return 23 /* LessThanToken */;
                            }
                            else if (node.arguments === list) {
                                return 15 /* OpenParenToken */;
                            }
                            break;
                        case 133 /* TypeReference */:
                            if (node.typeArguments === list) {
                                return 23 /* LessThanToken */;
                            }
                    }
                    return 0 /* Unknown */;
                }
                function getCloseTokenForOpenToken(kind) {
                    switch (kind) {
                        case 15 /* OpenParenToken */:
                            return 16 /* CloseParenToken */;
                        case 23 /* LessThanToken */:
                            return 24 /* GreaterThanToken */;
                    }
                    return 0 /* Unknown */;
                }
            })(formatting = ts.formatting || (ts.formatting = {}));
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var ScriptSnapshot;
            (function (ScriptSnapshot) {
                var StringScriptSnapshot = (function () {
                    function StringScriptSnapshot(text) {
                        this.text = text;
                        this._lineStartPositions = undefined;
                    }
                    StringScriptSnapshot.prototype.getText = function (start, end) {
                        return this.text.substring(start, end);
                    };
                    StringScriptSnapshot.prototype.getLength = function () {
                        return this.text.length;
                    };
                    StringScriptSnapshot.prototype.getLineStartPositions = function () {
                        if (!this._lineStartPositions) {
                            this._lineStartPositions = ts.computeLineStarts(this.text);
                        }
                        return this._lineStartPositions;
                    };
                    StringScriptSnapshot.prototype.getChangeRange = function (oldSnapshot) {
                        throw new Error("not yet implemented");
                    };
                    return StringScriptSnapshot;
                })();
                function fromString(text) {
                    return new StringScriptSnapshot(text);
                }
                ScriptSnapshot.fromString = fromString;
            })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {}));
            var scanner = ts.createScanner(2 /* Latest */, true);
            var emptyArray = [];
            function createNode(kind, pos, end, flags, parent) {
                var node = new (ts.getNodeConstructor(kind))();
                node.pos = pos;
                node.end = end;
                node.flags = flags;
                node.parent = parent;
                return node;
            }
            var NodeObject = (function () {
                function NodeObject() {
                }
                NodeObject.prototype.getSourceFile = function () {
                    return ts.getSourceFileOfNode(this);
                };
                NodeObject.prototype.getStart = function (sourceFile) {
                    return ts.getTokenPosOfNode(this, sourceFile);
                };
                NodeObject.prototype.getFullStart = function () {
                    return this.pos;
                };
                NodeObject.prototype.getEnd = function () {
                    return this.end;
                };
                NodeObject.prototype.getWidth = function (sourceFile) {
                    return this.getEnd() - this.getStart(sourceFile);
                };
                NodeObject.prototype.getFullWidth = function () {
                    return this.end - this.getFullStart();
                };
                NodeObject.prototype.getLeadingTriviaWidth = function (sourceFile) {
                    return this.getStart(sourceFile) - this.pos;
                };
                NodeObject.prototype.getFullText = function (sourceFile) {
                    return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end);
                };
                NodeObject.prototype.getText = function (sourceFile) {
                    return (sourceFile || this.getSourceFile()).text.substring(this.getStart(), this.getEnd());
                };
                NodeObject.prototype.addSyntheticNodes = function (nodes, pos, end) {
                    scanner.setTextPos(pos);
                    while (pos < end) {
                        var token = scanner.scan();
                        var textPos = scanner.getTextPos();
                        nodes.push(createNode(token, pos, textPos, 512 /* Synthetic */, this));
                        pos = textPos;
                    }
                    return pos;
                };
                NodeObject.prototype.createSyntaxList = function (nodes) {
                    var list = createNode(200 /* SyntaxList */, nodes.pos, nodes.end, 512 /* Synthetic */, this);
                    list._children = [];
                    var pos = nodes.pos;
                    for (var i = 0, len = nodes.length; i < len; i++) {
                        var node = nodes[i];
                        if (pos < node.pos) {
                            pos = this.addSyntheticNodes(list._children, pos, node.pos);
                        }
                        list._children.push(node);
                        pos = node.end;
                    }
                    if (pos < nodes.end) {
                        this.addSyntheticNodes(list._children, pos, nodes.end);
                    }
                    return list;
                };
                NodeObject.prototype.createChildren = function (sourceFile) {
                    var _this = this;
                    if (this.kind > 120 /* Missing */) {
                        scanner.setText((sourceFile || this.getSourceFile()).text);
                        var children = [];
                        var pos = this.pos;
                        var processNode = function (node) {
                            if (pos < node.pos) {
                                pos = _this.addSyntheticNodes(children, pos, node.pos);
                            }
                            children.push(node);
                            pos = node.end;
                        };
                        var processNodes = function (nodes) {
                            if (pos < nodes.pos) {
                                pos = _this.addSyntheticNodes(children, pos, nodes.pos);
                            }
                            children.push(_this.createSyntaxList(nodes));
                            pos = nodes.end;
                        };
                        ts.forEachChild(this, processNode, processNodes);
                        if (pos < this.end) {
                            this.addSyntheticNodes(children, pos, this.end);
                        }
                        scanner.setText(undefined);
                    }
                    this._children = children || emptyArray;
                };
                NodeObject.prototype.getChildCount = function (sourceFile) {
                    if (!this._children)
                        this.createChildren(sourceFile);
                    return this._children.length;
                };
                NodeObject.prototype.getChildAt = function (index, sourceFile) {
                    if (!this._children)
                        this.createChildren(sourceFile);
                    return this._children[index];
                };
                NodeObject.prototype.getChildren = function (sourceFile) {
                    if (!this._children)
                        this.createChildren(sourceFile);
                    return this._children;
                };
                NodeObject.prototype.getFirstToken = function (sourceFile) {
                    var children = this.getChildren();
                    for (var i = 0; i < children.length; i++) {
                        var child = children[i];
                        if (child.kind < 120 /* Missing */)
                            return child;
                        if (child.kind > 120 /* Missing */)
                            return child.getFirstToken(sourceFile);
                    }
                };
                NodeObject.prototype.getLastToken = function (sourceFile) {
                    var children = this.getChildren(sourceFile);
                    for (var i = children.length - 1; i >= 0; i--) {
                        var child = children[i];
                        if (child.kind < 120 /* Missing */)
                            return child;
                        if (child.kind > 120 /* Missing */)
                            return child.getLastToken(sourceFile);
                    }
                };
                return NodeObject;
            })();
            var SymbolObject = (function () {
                function SymbolObject(flags, name) {
                    this.flags = flags;
                    this.name = name;
                }
                SymbolObject.prototype.getFlags = function () {
                    return this.flags;
                };
                SymbolObject.prototype.getName = function () {
                    return this.name;
                };
                SymbolObject.prototype.getDeclarations = function () {
                    return this.declarations;
                };
                SymbolObject.prototype.getDocumentationComment = function () {
                    if (this.documentationComment === undefined) {
                        this.documentationComment = getJsDocCommentsFromDeclarations(this.declarations, this.name, !(this.flags & 4 /* Property */));
                    }
                    return this.documentationComment;
                };
                return SymbolObject;
            })();
            function getJsDocCommentsFromDeclarations(declarations, name, canUseParsedParamTagComments) {
                var documentationComment = [];
                var docComments = getJsDocCommentsSeparatedByNewLines();
                ts.forEach(docComments, function (docComment) {
                    if (documentationComment.length) {
                        documentationComment.push(lineBreakPart());
                    }
                    documentationComment.push(docComment);
                });
                return documentationComment;
                function getJsDocCommentsSeparatedByNewLines() {
                    var paramTag = "@param";
                    var jsDocCommentParts = [];
                    ts.forEach(declarations, function (declaration) {
                        var sourceFileOfDeclaration = ts.getSourceFileOfNode(declaration);
                        if (canUseParsedParamTagComments && declaration.kind === 124 /* Parameter */) {
                            ts.forEach(getJsDocCommentTextRange(declaration.parent, sourceFileOfDeclaration), function (jsDocCommentTextRange) {
                                var cleanedParamJsDocComment = getCleanedParamJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration);
                                if (cleanedParamJsDocComment) {
                                    jsDocCommentParts.push.apply(jsDocCommentParts, cleanedParamJsDocComment);
                                }
                            });
                        }
                        if (declaration.kind === 193 /* ModuleDeclaration */ && declaration.body.kind === 193 /* ModuleDeclaration */) {
                            return;
                        }
                        while (declaration.kind === 193 /* ModuleDeclaration */ && declaration.parent.kind === 193 /* ModuleDeclaration */) {
                            declaration = declaration.parent;
                        }
                        ts.forEach(getJsDocCommentTextRange(declaration.kind === 186 /* VariableDeclaration */ ? declaration.parent : declaration, sourceFileOfDeclaration), function (jsDocCommentTextRange) {
                            var cleanedJsDocComment = getCleanedJsDocComment(jsDocCommentTextRange.pos, jsDocCommentTextRange.end, sourceFileOfDeclaration);
                            if (cleanedJsDocComment) {
                                jsDocCommentParts.push.apply(jsDocCommentParts, cleanedJsDocComment);
                            }
                        });
                    });
                    return jsDocCommentParts;
                    function getJsDocCommentTextRange(node, sourceFile) {
                        return ts.map(ts.getJsDocComments(node, sourceFile), function (jsDocComment) {
                            return {
                                pos: jsDocComment.pos + "/*".length,
                                end: jsDocComment.end - "*/".length
                            };
                        });
                    }
                    function consumeWhiteSpacesOnTheLine(pos, end, sourceFile, maxSpacesToRemove) {
                        if (maxSpacesToRemove !== undefined) {
                            end = Math.min(end, pos + maxSpacesToRemove);
                        }
                        for (; pos < end; pos++) {
                            var ch = sourceFile.text.charCodeAt(pos);
                            if (!ts.isWhiteSpace(ch) || ts.isLineBreak(ch)) {
                                return pos;
                            }
                        }
                        return end;
                    }
                    function consumeLineBreaks(pos, end, sourceFile) {
                        while (pos < end && ts.isLineBreak(sourceFile.text.charCodeAt(pos))) {
                            pos++;
                        }
                        return pos;
                    }
                    function isName(pos, end, sourceFile, name) {
                        return pos + name.length < end && sourceFile.text.substr(pos, name.length) === name && (ts.isWhiteSpace(sourceFile.text.charCodeAt(pos + name.length)) || ts.isLineBreak(sourceFile.text.charCodeAt(pos + name.length)));
                    }
                    function isParamTag(pos, end, sourceFile) {
                        return isName(pos, end, sourceFile, paramTag);
                    }
                    function pushDocCommentLineText(docComments, text, blankLineCount) {
                        while (blankLineCount--)
                            docComments.push(textPart(""));
                        docComments.push(textPart(text));
                    }
                    function getCleanedJsDocComment(pos, end, sourceFile) {
                        var spacesToRemoveAfterAsterisk;
                        var docComments = [];
                        var blankLineCount = 0;
                        var isInParamTag = false;
                        while (pos < end) {
                            var docCommentTextOfLine = "";
                            pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile);
                            if (pos < end && sourceFile.text.charCodeAt(pos) === 42 /* asterisk */) {
                                var lineStartPos = pos + 1;
                                pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, spacesToRemoveAfterAsterisk);
                                if (spacesToRemoveAfterAsterisk === undefined && pos < end && !ts.isLineBreak(sourceFile.text.charCodeAt(pos))) {
                                    spacesToRemoveAfterAsterisk = pos - lineStartPos;
                                }
                            }
                            else if (spacesToRemoveAfterAsterisk === undefined) {
                                spacesToRemoveAfterAsterisk = 0;
                            }
                            while (pos < end && !ts.isLineBreak(sourceFile.text.charCodeAt(pos))) {
                                var ch = sourceFile.text.charAt(pos);
                                if (ch === "@") {
                                    if (isParamTag(pos, end, sourceFile)) {
                                        isInParamTag = true;
                                        pos += paramTag.length;
                                        continue;
                                    }
                                    else {
                                        isInParamTag = false;
                                    }
                                }
                                if (!isInParamTag) {
                                    docCommentTextOfLine += ch;
                                }
                                pos++;
                            }
                            pos = consumeLineBreaks(pos, end, sourceFile);
                            if (docCommentTextOfLine) {
                                pushDocCommentLineText(docComments, docCommentTextOfLine, blankLineCount);
                                blankLineCount = 0;
                            }
                            else if (!isInParamTag && docComments.length) {
                                blankLineCount++;
                            }
                        }
                        return docComments;
                    }
                    function getCleanedParamJsDocComment(pos, end, sourceFile) {
                        var paramHelpStringMargin;
                        var paramDocComments = [];
                        while (pos < end) {
                            if (isParamTag(pos, end, sourceFile)) {
                                var blankLineCount = 0;
                                var recordedParamTag = false;
                                pos = consumeWhiteSpaces(pos + paramTag.length);
                                if (pos >= end) {
                                    break;
                                }
                                if (sourceFile.text.charCodeAt(pos) === 123 /* openBrace */) {
                                    pos++;
                                    for (var curlies = 1; pos < end; pos++) {
                                        var charCode = sourceFile.text.charCodeAt(pos);
                                        if (charCode === 123 /* openBrace */) {
                                            curlies++;
                                            continue;
                                        }
                                        if (charCode === 125 /* closeBrace */) {
                                            curlies--;
                                            if (curlies === 0) {
                                                pos++;
                                                break;
                                            }
                                            else {
                                                continue;
                                            }
                                        }
                                        if (charCode === 64 /* at */) {
                                            break;
                                        }
                                    }
                                    pos = consumeWhiteSpaces(pos);
                                    if (pos >= end) {
                                        break;
                                    }
                                }
                                if (isName(pos, end, sourceFile, name)) {
                                    pos = consumeWhiteSpaces(pos + name.length);
                                    if (pos >= end) {
                                        break;
                                    }
                                    var paramHelpString = "";
                                    var firstLineParamHelpStringPos = pos;
                                    while (pos < end) {
                                        var ch = sourceFile.text.charCodeAt(pos);
                                        if (ts.isLineBreak(ch)) {
                                            if (paramHelpString) {
                                                pushDocCommentLineText(paramDocComments, paramHelpString, blankLineCount);
                                                paramHelpString = "";
                                                blankLineCount = 0;
                                                recordedParamTag = true;
                                            }
                                            else if (recordedParamTag) {
                                                blankLineCount++;
                                            }
                                            setPosForParamHelpStringOnNextLine(firstLineParamHelpStringPos);
                                            continue;
                                        }
                                        if (ch === 64 /* at */) {
                                            break;
                                        }
                                        paramHelpString += sourceFile.text.charAt(pos);
                                        pos++;
                                    }
                                    if (paramHelpString) {
                                        pushDocCommentLineText(paramDocComments, paramHelpString, blankLineCount);
                                    }
                                    paramHelpStringMargin = undefined;
                                }
                                if (sourceFile.text.charCodeAt(pos) === 64 /* at */) {
                                    continue;
                                }
                            }
                            pos++;
                        }
                        return paramDocComments;
                        function consumeWhiteSpaces(pos) {
                            while (pos < end && ts.isWhiteSpace(sourceFile.text.charCodeAt(pos))) {
                                pos++;
                            }
                            return pos;
                        }
                        function setPosForParamHelpStringOnNextLine(firstLineParamHelpStringPos) {
                            pos = consumeLineBreaks(pos, end, sourceFile);
                            if (pos >= end) {
                                return;
                            }
                            if (paramHelpStringMargin === undefined) {
                                paramHelpStringMargin = sourceFile.getLineAndCharacterFromPosition(firstLineParamHelpStringPos).character - 1;
                            }
                            var startOfLinePos = pos;
                            pos = consumeWhiteSpacesOnTheLine(pos, end, sourceFile, paramHelpStringMargin);
                            if (pos >= end) {
                                return;
                            }
                            var consumedSpaces = pos - startOfLinePos;
                            if (consumedSpaces < paramHelpStringMargin) {
                                var ch = sourceFile.text.charCodeAt(pos);
                                if (ch === 42 /* asterisk */) {
                                    pos = consumeWhiteSpacesOnTheLine(pos + 1, end, sourceFile, paramHelpStringMargin - consumedSpaces - 1);
                                }
                            }
                        }
                    }
                }
            }
            var TypeObject = (function () {
                function TypeObject(checker, flags) {
                    this.checker = checker;
                    this.flags = flags;
                }
                TypeObject.prototype.getFlags = function () {
                    return this.flags;
                };
                TypeObject.prototype.getSymbol = function () {
                    return this.symbol;
                };
                TypeObject.prototype.getProperties = function () {
                    return this.checker.getPropertiesOfType(this);
                };
                TypeObject.prototype.getProperty = function (propertyName) {
                    return this.checker.getPropertyOfType(this, propertyName);
                };
                TypeObject.prototype.getApparentProperties = function () {
                    return this.checker.getAugmentedPropertiesOfType(this);
                };
                TypeObject.prototype.getCallSignatures = function () {
                    return this.checker.getSignaturesOfType(this, 0 /* Call */);
                };
                TypeObject.prototype.getConstructSignatures = function () {
                    return this.checker.getSignaturesOfType(this, 1 /* Construct */);
                };
                TypeObject.prototype.getStringIndexType = function () {
                    return this.checker.getIndexTypeOfType(this, 0 /* String */);
                };
                TypeObject.prototype.getNumberIndexType = function () {
                    return this.checker.getIndexTypeOfType(this, 1 /* Number */);
                };
                return TypeObject;
            })();
            var SignatureObject = (function () {
                function SignatureObject(checker) {
                    this.checker = checker;
                }
                SignatureObject.prototype.getDeclaration = function () {
                    return this.declaration;
                };
                SignatureObject.prototype.getTypeParameters = function () {
                    return this.typeParameters;
                };
                SignatureObject.prototype.getParameters = function () {
                    return this.parameters;
                };
                SignatureObject.prototype.getReturnType = function () {
                    return this.checker.getReturnTypeOfSignature(this);
                };
                SignatureObject.prototype.getDocumentationComment = function () {
                    if (this.documentationComment === undefined) {
                        this.documentationComment = this.declaration ? getJsDocCommentsFromDeclarations([this.declaration], undefined, false) : [];
                    }
                    return this.documentationComment;
                };
                return SignatureObject;
            })();
            var SourceFileObject = (function (_super) {
                __extends(SourceFileObject, _super);
                function SourceFileObject() {
                    _super.apply(this, arguments);
                }
                SourceFileObject.prototype.getScriptSnapshot = function () {
                    return this.scriptSnapshot;
                };
                SourceFileObject.prototype.getNamedDeclarations = function () {
                    if (!this.namedDeclarations) {
                        var sourceFile = this;
                        var namedDeclarations = [];
                        ts.forEachChild(sourceFile, function visit(node) {
                            switch (node.kind) {
                                case 187 /* FunctionDeclaration */:
                                case 126 /* Method */:
                                    var functionDeclaration = node;
                                    if (functionDeclaration.name && functionDeclaration.name.kind !== 120 /* Missing */) {
                                        var lastDeclaration = namedDeclarations.length > 0 ? namedDeclarations[namedDeclarations.length - 1] : undefined;
                                        if (lastDeclaration && functionDeclaration.symbol === lastDeclaration.symbol) {
                                            if (functionDeclaration.body && !lastDeclaration.body) {
                                                namedDeclarations[namedDeclarations.length - 1] = functionDeclaration;
                                            }
                                        }
                                        else {
                                            namedDeclarations.push(node);
                                        }
                                        ts.forEachChild(node, visit);
                                    }
                                    break;
                                case 189 /* ClassDeclaration */:
                                case 190 /* InterfaceDeclaration */:
                                case 191 /* TypeAliasDeclaration */:
                                case 192 /* EnumDeclaration */:
                                case 193 /* ModuleDeclaration */:
                                case 195 /* ImportDeclaration */:
                                case 128 /* GetAccessor */:
                                case 129 /* SetAccessor */:
                                case 137 /* TypeLiteral */:
                                    if (node.name) {
                                        namedDeclarations.push(node);
                                    }
                                case 127 /* Constructor */:
                                case 164 /* VariableStatement */:
                                case 194 /* ModuleBlock */:
                                case 188 /* FunctionBlock */:
                                    ts.forEachChild(node, visit);
                                    break;
                                case 124 /* Parameter */:
                                    if (!(node.flags & 112 /* AccessibilityModifier */)) {
                                        break;
                                    }
                                case 186 /* VariableDeclaration */:
                                case 197 /* EnumMember */:
                                case 125 /* Property */:
                                    namedDeclarations.push(node);
                                    break;
                            }
                        });
                        this.namedDeclarations = namedDeclarations;
                    }
                    return this.namedDeclarations;
                };
                SourceFileObject.prototype.update = function (scriptSnapshot, version, isOpen, textChangeRange) {
                    if (textChangeRange && ts.Debug.shouldAssert(1 /* Normal */)) {
                        var oldText = this.scriptSnapshot;
                        var newText = scriptSnapshot;
                        ts.Debug.assert((oldText.getLength() - textChangeRange.span().length() + textChangeRange.newLength()) === newText.getLength());
                        if (ts.Debug.shouldAssert(3 /* VeryAggressive */)) {
                            var oldTextPrefix = oldText.getText(0, textChangeRange.span().start());
                            var newTextPrefix = newText.getText(0, textChangeRange.span().start());
                            ts.Debug.assert(oldTextPrefix === newTextPrefix);
                            var oldTextSuffix = oldText.getText(textChangeRange.span().end(), oldText.getLength());
                            var newTextSuffix = newText.getText(textChangeRange.newSpan().end(), newText.getLength());
                            ts.Debug.assert(oldTextSuffix === newTextSuffix);
                        }
                    }
                    return SourceFileObject.createSourceFileObject(this.filename, scriptSnapshot, this.languageVersion, version, isOpen);
                };
                SourceFileObject.createSourceFileObject = function (filename, scriptSnapshot, languageVersion, version, isOpen) {
                    var newSourceFile = ts.createSourceFile(filename, scriptSnapshot.getText(0, scriptSnapshot.getLength()), languageVersion, version, isOpen);
                    newSourceFile.scriptSnapshot = scriptSnapshot;
                    return newSourceFile;
                };
                return SourceFileObject;
            })(NodeObject);
            var TextChange = (function () {
                function TextChange() {
                }
                return TextChange;
            })();
            ts.TextChange = TextChange;
            (function (SymbolDisplayPartKind) {
                SymbolDisplayPartKind[SymbolDisplayPartKind["aliasName"] = 0] = "aliasName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["className"] = 1] = "className";
                SymbolDisplayPartKind[SymbolDisplayPartKind["enumName"] = 2] = "enumName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["fieldName"] = 3] = "fieldName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["interfaceName"] = 4] = "interfaceName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["keyword"] = 5] = "keyword";
                SymbolDisplayPartKind[SymbolDisplayPartKind["lineBreak"] = 6] = "lineBreak";
                SymbolDisplayPartKind[SymbolDisplayPartKind["numericLiteral"] = 7] = "numericLiteral";
                SymbolDisplayPartKind[SymbolDisplayPartKind["stringLiteral"] = 8] = "stringLiteral";
                SymbolDisplayPartKind[SymbolDisplayPartKind["localName"] = 9] = "localName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["methodName"] = 10] = "methodName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["moduleName"] = 11] = "moduleName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["operator"] = 12] = "operator";
                SymbolDisplayPartKind[SymbolDisplayPartKind["parameterName"] = 13] = "parameterName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["propertyName"] = 14] = "propertyName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["punctuation"] = 15] = "punctuation";
                SymbolDisplayPartKind[SymbolDisplayPartKind["space"] = 16] = "space";
                SymbolDisplayPartKind[SymbolDisplayPartKind["text"] = 17] = "text";
                SymbolDisplayPartKind[SymbolDisplayPartKind["typeParameterName"] = 18] = "typeParameterName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["enumMemberName"] = 19] = "enumMemberName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["functionName"] = 20] = "functionName";
                SymbolDisplayPartKind[SymbolDisplayPartKind["regularExpressionLiteral"] = 21] = "regularExpressionLiteral";
            })(ts.SymbolDisplayPartKind || (ts.SymbolDisplayPartKind = {}));
            var SymbolDisplayPartKind = ts.SymbolDisplayPartKind;
            (function (OutputFileType) {
                OutputFileType[OutputFileType["JavaScript"] = 0] = "JavaScript";
                OutputFileType[OutputFileType["SourceMap"] = 1] = "SourceMap";
                OutputFileType[OutputFileType["Declaration"] = 2] = "Declaration";
            })(ts.OutputFileType || (ts.OutputFileType = {}));
            var OutputFileType = ts.OutputFileType;
            (function (EndOfLineState) {
                EndOfLineState[EndOfLineState["Start"] = 0] = "Start";
                EndOfLineState[EndOfLineState["InMultiLineCommentTrivia"] = 1] = "InMultiLineCommentTrivia";
                EndOfLineState[EndOfLineState["InSingleQuoteStringLiteral"] = 2] = "InSingleQuoteStringLiteral";
                EndOfLineState[EndOfLineState["InDoubleQuoteStringLiteral"] = 3] = "InDoubleQuoteStringLiteral";
            })(ts.EndOfLineState || (ts.EndOfLineState = {}));
            var EndOfLineState = ts.EndOfLineState;
            (function (TokenClass) {
                TokenClass[TokenClass["Punctuation"] = 0] = "Punctuation";
                TokenClass[TokenClass["Keyword"] = 1] = "Keyword";
                TokenClass[TokenClass["Operator"] = 2] = "Operator";
                TokenClass[TokenClass["Comment"] = 3] = "Comment";
                TokenClass[TokenClass["Whitespace"] = 4] = "Whitespace";
                TokenClass[TokenClass["Identifier"] = 5] = "Identifier";
                TokenClass[TokenClass["NumberLiteral"] = 6] = "NumberLiteral";
                TokenClass[TokenClass["StringLiteral"] = 7] = "StringLiteral";
                TokenClass[TokenClass["RegExpLiteral"] = 8] = "RegExpLiteral";
            })(ts.TokenClass || (ts.TokenClass = {}));
            var TokenClass = ts.TokenClass;
            var ScriptElementKind = (function () {
                function ScriptElementKind() {
                }
                ScriptElementKind.unknown = "";
                ScriptElementKind.keyword = "keyword";
                ScriptElementKind.scriptElement = "script";
                ScriptElementKind.moduleElement = "module";
                ScriptElementKind.classElement = "class";
                ScriptElementKind.interfaceElement = "interface";
                ScriptElementKind.typeElement = "type";
                ScriptElementKind.enumElement = "enum";
                ScriptElementKind.variableElement = "var";
                ScriptElementKind.localVariableElement = "local var";
                ScriptElementKind.functionElement = "function";
                ScriptElementKind.localFunctionElement = "local function";
                ScriptElementKind.memberFunctionElement = "method";
                ScriptElementKind.memberGetAccessorElement = "getter";
                ScriptElementKind.memberSetAccessorElement = "setter";
                ScriptElementKind.memberVariableElement = "property";
                ScriptElementKind.constructorImplementationElement = "constructor";
                ScriptElementKind.callSignatureElement = "call";
                ScriptElementKind.indexSignatureElement = "index";
                ScriptElementKind.constructSignatureElement = "construct";
                ScriptElementKind.parameterElement = "parameter";
                ScriptElementKind.typeParameterElement = "type parameter";
                ScriptElementKind.primitiveType = "primitive type";
                ScriptElementKind.label = "label";
                ScriptElementKind.alias = "alias";
                ScriptElementKind.constElement = "const";
                ScriptElementKind.letElement = "let";
                return ScriptElementKind;
            })();
            ts.ScriptElementKind = ScriptElementKind;
            var ScriptElementKindModifier = (function () {
                function ScriptElementKindModifier() {
                }
                ScriptElementKindModifier.none = "";
                ScriptElementKindModifier.publicMemberModifier = "public";
                ScriptElementKindModifier.privateMemberModifier = "private";
                ScriptElementKindModifier.protectedMemberModifier = "protected";
                ScriptElementKindModifier.exportedModifier = "export";
                ScriptElementKindModifier.ambientModifier = "declare";
                ScriptElementKindModifier.staticModifier = "static";
                return ScriptElementKindModifier;
            })();
            ts.ScriptElementKindModifier = ScriptElementKindModifier;
            var ClassificationTypeNames = (function () {
                function ClassificationTypeNames() {
                }
                ClassificationTypeNames.comment = "comment";
                ClassificationTypeNames.identifier = "identifier";
                ClassificationTypeNames.keyword = "keyword";
                ClassificationTypeNames.numericLiteral = "number";
                ClassificationTypeNames.operator = "operator";
                ClassificationTypeNames.stringLiteral = "string";
                ClassificationTypeNames.whiteSpace = "whitespace";
                ClassificationTypeNames.text = "text";
                ClassificationTypeNames.punctuation = "punctuation";
                ClassificationTypeNames.className = "class name";
                ClassificationTypeNames.enumName = "enum name";
                ClassificationTypeNames.interfaceName = "interface name";
                ClassificationTypeNames.moduleName = "module name";
                ClassificationTypeNames.typeParameterName = "type parameter name";
                return ClassificationTypeNames;
            })();
            ts.ClassificationTypeNames = ClassificationTypeNames;
            var MatchKind;
            (function (MatchKind) {
                MatchKind[MatchKind["none"] = 0] = "none";
                MatchKind[MatchKind["exact"] = 1] = "exact";
                MatchKind[MatchKind["substring"] = 2] = "substring";
                MatchKind[MatchKind["prefix"] = 3] = "prefix";
            })(MatchKind || (MatchKind = {}));
            function displayPartsToString(displayParts) {
                if (displayParts) {
                    return ts.map(displayParts, function (displayPart) { return displayPart.text; }).join("");
                }
                return "";
            }
            ts.displayPartsToString = displayPartsToString;
            var displayPartWriter = getDisplayPartWriter();
            function getDisplayPartWriter() {
                var displayParts;
                var lineStart;
                var indent;
                resetWriter();
                return {
                    displayParts: function () { return displayParts; },
                    writeKeyword: function (text) { return writeKind(text, 5 /* keyword */); },
                    writeOperator: function (text) { return writeKind(text, 12 /* operator */); },
                    writePunctuation: function (text) { return writeKind(text, 15 /* punctuation */); },
                    writeSpace: function (text) { return writeKind(text, 16 /* space */); },
                    writeStringLiteral: function (text) { return writeKind(text, 8 /* stringLiteral */); },
                    writeParameter: function (text) { return writeKind(text, 13 /* parameterName */); },
                    writeSymbol: writeSymbol,
                    writeLine: writeLine,
                    increaseIndent: function () {
                        indent++;
                    },
                    decreaseIndent: function () {
                        indent--;
                    },
                    clear: resetWriter,
                    trackSymbol: function () {
                    }
                };
                function writeIndent() {
                    if (lineStart) {
                        displayParts.push(displayPart(ts.getIndentString(indent), 16 /* space */));
                        lineStart = false;
                    }
                }
                function writeKind(text, kind) {
                    writeIndent();
                    displayParts.push(displayPart(text, kind));
                }
                function writeSymbol(text, symbol) {
                    writeIndent();
                    displayParts.push(symbolPart(text, symbol));
                }
                function writeLine() {
                    displayParts.push(lineBreakPart());
                    lineStart = true;
                }
                function resetWriter() {
                    displayParts = [];
                    lineStart = true;
                    indent = 0;
                }
            }
            function displayPart(text, kind, symbol) {
                return {
                    text: text,
                    kind: SymbolDisplayPartKind[kind]
                };
            }
            function spacePart() {
                return displayPart(" ", 16 /* space */);
            }
            ts.spacePart = spacePart;
            function keywordPart(kind) {
                return displayPart(ts.tokenToString(kind), 5 /* keyword */);
            }
            ts.keywordPart = keywordPart;
            function punctuationPart(kind) {
                return displayPart(ts.tokenToString(kind), 15 /* punctuation */);
            }
            ts.punctuationPart = punctuationPart;
            function operatorPart(kind) {
                return displayPart(ts.tokenToString(kind), 12 /* operator */);
            }
            ts.operatorPart = operatorPart;
            function textPart(text) {
                return displayPart(text, 17 /* text */);
            }
            ts.textPart = textPart;
            function lineBreakPart() {
                return displayPart("\n", 6 /* lineBreak */);
            }
            ts.lineBreakPart = lineBreakPart;
            function isFirstDeclarationOfSymbolParameter(symbol) {
                return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === 124 /* Parameter */;
            }
            function isLocalVariableOrFunction(symbol) {
                if (symbol.parent) {
                    return false;
                }
                return ts.forEach(symbol.declarations, function (declaration) {
                    if (declaration.kind === 153 /* FunctionExpression */) {
                        return true;
                    }
                    if (declaration.kind !== 186 /* VariableDeclaration */ && declaration.kind !== 187 /* FunctionDeclaration */) {
                        return false;
                    }
                    for (var parent = declaration.parent; parent.kind !== 188 /* FunctionBlock */; parent = parent.parent) {
                        if (parent.kind === 198 /* SourceFile */ || parent.kind === 194 /* ModuleBlock */) {
                            return false;
                        }
                    }
                    return true;
                });
            }
            function symbolPart(text, symbol) {
                return displayPart(text, displayPartKind(symbol), symbol);
                function displayPartKind(symbol) {
                    var flags = symbol.flags;
                    if (flags & 3 /* Variable */) {
                        return isFirstDeclarationOfSymbolParameter(symbol) ? 13 /* parameterName */ : 9 /* localName */;
                    }
                    else if (flags & 4 /* Property */) {
                        return 14 /* propertyName */;
                    }
                    else if (flags & 8 /* EnumMember */) {
                        return 19 /* enumMemberName */;
                    }
                    else if (flags & 16 /* Function */) {
                        return 20 /* functionName */;
                    }
                    else if (flags & 32 /* Class */) {
                        return 1 /* className */;
                    }
                    else if (flags & 64 /* Interface */) {
                        return 4 /* interfaceName */;
                    }
                    else if (flags & 384 /* Enum */) {
                        return 2 /* enumName */;
                    }
                    else if (flags & 1536 /* Module */) {
                        return 11 /* moduleName */;
                    }
                    else if (flags & 8192 /* Method */) {
                        return 10 /* methodName */;
                    }
                    else if (flags & 1048576 /* TypeParameter */) {
                        return 18 /* typeParameterName */;
                    }
                    return 17 /* text */;
                }
            }
            ts.symbolPart = symbolPart;
            function mapToDisplayParts(writeDisplayParts) {
                writeDisplayParts(displayPartWriter);
                var result = displayPartWriter.displayParts();
                displayPartWriter.clear();
                return result;
            }
            ts.mapToDisplayParts = mapToDisplayParts;
            function typeToDisplayParts(typechecker, type, enclosingDeclaration, flags) {
                return mapToDisplayParts(function (writer) {
                    typechecker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
                });
            }
            ts.typeToDisplayParts = typeToDisplayParts;
            function symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration, meaning, flags) {
                return mapToDisplayParts(function (writer) {
                    typeChecker.getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags);
                });
            }
            ts.symbolToDisplayParts = symbolToDisplayParts;
            function signatureToDisplayParts(typechecker, signature, enclosingDeclaration, flags) {
                return mapToDisplayParts(function (writer) {
                    typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags);
                });
            }
            function getDefaultCompilerOptions() {
                return {
                    target: 2 /* Latest */,
                    module: 0 /* None */
                };
            }
            ts.getDefaultCompilerOptions = getDefaultCompilerOptions;
            function compareDataObjects(dst, src) {
                for (var e in dst) {
                    if (typeof dst[e] === "object") {
                        if (!compareDataObjects(dst[e], src[e]))
                            return false;
                    }
                    else if (typeof dst[e] !== "function") {
                        if (dst[e] !== src[e])
                            return false;
                    }
                }
                return true;
            }
            ts.compareDataObjects = compareDataObjects;
            var OperationCanceledException = (function () {
                function OperationCanceledException() {
                }
                return OperationCanceledException;
            })();
            ts.OperationCanceledException = OperationCanceledException;
            var CancellationTokenObject = (function () {
                function CancellationTokenObject(cancellationToken) {
                    this.cancellationToken = cancellationToken;
                }
                CancellationTokenObject.prototype.isCancellationRequested = function () {
                    return this.cancellationToken && this.cancellationToken.isCancellationRequested();
                };
                CancellationTokenObject.prototype.throwIfCancellationRequested = function () {
                    if (this.isCancellationRequested()) {
                        throw new OperationCanceledException();
                    }
                };
                CancellationTokenObject.None = new CancellationTokenObject(null);
                return CancellationTokenObject;
            })();
            ts.CancellationTokenObject = CancellationTokenObject;
            var HostCache = (function () {
                function HostCache(host) {
                    this.host = host;
                    this.filenameToEntry = {};
                    var filenames = host.getScriptFileNames();
                    for (var i = 0, n = filenames.length; i < n; i++) {
                        var filename = filenames[i];
                        this.filenameToEntry[ts.normalizeSlashes(filename)] = {
                            filename: filename,
                            version: host.getScriptVersion(filename),
                            isOpen: host.getScriptIsOpen(filename)
                        };
                    }
                    this._compilationSettings = host.getCompilationSettings() || getDefaultCompilerOptions();
                }
                HostCache.prototype.compilationSettings = function () {
                    return this._compilationSettings;
                };
                HostCache.prototype.getEntry = function (filename) {
                    filename = ts.normalizeSlashes(filename);
                    return ts.lookUp(this.filenameToEntry, filename);
                };
                HostCache.prototype.contains = function (filename) {
                    return !!this.getEntry(filename);
                };
                HostCache.prototype.getHostfilename = function (filename) {
                    var hostCacheEntry = this.getEntry(filename);
                    if (hostCacheEntry) {
                        return hostCacheEntry.filename;
                    }
                    return filename;
                };
                HostCache.prototype.getFilenames = function () {
                    var _this = this;
                    var fileNames = [];
                    ts.forEachKey(this.filenameToEntry, function (key) {
                        if (ts.hasProperty(_this.filenameToEntry, key))
                            fileNames.push(key);
                    });
                    return fileNames;
                };
                HostCache.prototype.getVersion = function (filename) {
                    return this.getEntry(filename).version;
                };
                HostCache.prototype.isOpen = function (filename) {
                    return this.getEntry(filename).isOpen;
                };
                HostCache.prototype.getScriptSnapshot = function (filename) {
                    var file = this.getEntry(filename);
                    if (!file.sourceText) {
                        file.sourceText = this.host.getScriptSnapshot(file.filename);
                    }
                    return file.sourceText;
                };
                HostCache.prototype.getChangeRange = function (filename, lastKnownVersion, oldScriptSnapshot) {
                    var currentVersion = this.getVersion(filename);
                    if (lastKnownVersion === currentVersion) {
                        return ts.TextChangeRange.unchanged;
                    }
                    var scriptSnapshot = this.getScriptSnapshot(filename);
                    return scriptSnapshot.getChangeRange(oldScriptSnapshot);
                };
                return HostCache;
            })();
            var SyntaxTreeCache = (function () {
                function SyntaxTreeCache(host) {
                    this.host = host;
                    this.currentFilename = "";
                    this.currentFileVersion = null;
                    this.currentSourceFile = null;
                    this.hostCache = new HostCache(host);
                }
                SyntaxTreeCache.prototype.initialize = function (filename) {
                    var start = new Date().getTime();
                    this.hostCache = new HostCache(this.host);
                    this.host.log("SyntaxTreeCache.Initialize: new HostCache: " + (new Date().getTime() - start));
                    var version = this.hostCache.getVersion(filename);
                    var sourceFile;
                    if (this.currentFilename !== filename) {
                        var scriptSnapshot = this.hostCache.getScriptSnapshot(filename);
                        var start = new Date().getTime();
                        sourceFile = createSourceFileFromScriptSnapshot(filename, scriptSnapshot, getDefaultCompilerOptions(), version, true);
                        this.host.log("SyntaxTreeCache.Initialize: createSourceFile: " + (new Date().getTime() - start));
                        var start = new Date().getTime();
                        fixupParentReferences(sourceFile);
                        this.host.log("SyntaxTreeCache.Initialize: fixupParentRefs : " + (new Date().getTime() - start));
                    }
                    else if (this.currentFileVersion !== version) {
                        var scriptSnapshot = this.hostCache.getScriptSnapshot(filename);
                        var editRange = this.hostCache.getChangeRange(filename, this.currentFileVersion, this.currentSourceFile.getScriptSnapshot());
                        var start = new Date().getTime();
                        sourceFile = !editRange ? createSourceFileFromScriptSnapshot(filename, scriptSnapshot, getDefaultCompilerOptions(), version, true) : this.currentSourceFile.update(scriptSnapshot, version, true, editRange);
                        this.host.log("SyntaxTreeCache.Initialize: updateSourceFile: " + (new Date().getTime() - start));
                        var start = new Date().getTime();
                        fixupParentReferences(sourceFile);
                        this.host.log("SyntaxTreeCache.Initialize: fixupParentRefs : " + (new Date().getTime() - start));
                    }
                    if (sourceFile) {
                        this.currentFileVersion = version;
                        this.currentFilename = filename;
                        this.currentSourceFile = sourceFile;
                    }
                    function fixupParentReferences(sourceFile) {
                        var parent = sourceFile;
                        function walk(n) {
                            n.parent = parent;
                            var saveParent = parent;
                            parent = n;
                            ts.forEachChild(n, walk);
                            parent = saveParent;
                        }
                        ts.forEachChild(sourceFile, walk);
                    }
                };
                SyntaxTreeCache.prototype.getCurrentSourceFile = function (filename) {
                    this.initialize(filename);
                    return this.currentSourceFile;
                };
                SyntaxTreeCache.prototype.getCurrentScriptSnapshot = function (filename) {
                    return this.getCurrentSourceFile(filename).getScriptSnapshot();
                };
                return SyntaxTreeCache;
            })();
            function createSourceFileFromScriptSnapshot(filename, scriptSnapshot, settings, version, isOpen) {
                return SourceFileObject.createSourceFileObject(filename, scriptSnapshot, settings.target, version, isOpen);
            }
            function createDocumentRegistry() {
                var buckets = {};
                function getKeyFromCompilationSettings(settings) {
                    return "_" + settings.target;
                }
                function getBucketForCompilationSettings(settings, createIfMissing) {
                    var key = getKeyFromCompilationSettings(settings);
                    var bucket = ts.lookUp(buckets, key);
                    if (!bucket && createIfMissing) {
                        buckets[key] = bucket = {};
                    }
                    return bucket;
                }
                function reportStats() {
                    var bucketInfoArray = Object.keys(buckets).filter(function (name) { return name && name.charAt(0) === '_'; }).map(function (name) {
                        var entries = ts.lookUp(buckets, name);
                        var sourceFiles = [];
                        for (var i in entries) {
                            var entry = entries[i];
                            sourceFiles.push({
                                name: i,
                                refCount: entry.refCount,
                                references: entry.owners.slice(0)
                            });
                        }
                        sourceFiles.sort(function (x, y) { return y.refCount - x.refCount; });
                        return {
                            bucket: name,
                            sourceFiles: sourceFiles
                        };
                    });
                    return JSON.stringify(bucketInfoArray, null, 2);
                }
                function acquireDocument(filename, compilationSettings, scriptSnapshot, version, isOpen) {
                    var bucket = getBucketForCompilationSettings(compilationSettings, true);
                    var entry = ts.lookUp(bucket, filename);
                    if (!entry) {
                        var sourceFile = createSourceFileFromScriptSnapshot(filename, scriptSnapshot, compilationSettings, version, isOpen);
                        bucket[filename] = entry = {
                            sourceFile: sourceFile,
                            refCount: 0,
                            owners: []
                        };
                    }
                    entry.refCount++;
                    return entry.sourceFile;
                }
                function updateDocument(sourceFile, filename, compilationSettings, scriptSnapshot, version, isOpen, textChangeRange) {
                    var bucket = getBucketForCompilationSettings(compilationSettings, false);
                    ts.Debug.assert(bucket !== undefined);
                    var entry = ts.lookUp(bucket, filename);
                    ts.Debug.assert(entry !== undefined);
                    if (entry.sourceFile.isOpen === isOpen && entry.sourceFile.version === version) {
                        return entry.sourceFile;
                    }
                    entry.sourceFile = entry.sourceFile.update(scriptSnapshot, version, isOpen, textChangeRange);
                    return entry.sourceFile;
                }
                function releaseDocument(filename, compilationSettings) {
                    var bucket = getBucketForCompilationSettings(compilationSettings, false);
                    ts.Debug.assert(bucket !== undefined);
                    var entry = ts.lookUp(bucket, filename);
                    entry.refCount--;
                    ts.Debug.assert(entry.refCount >= 0);
                    if (entry.refCount === 0) {
                        delete bucket[filename];
                    }
                }
                return {
                    acquireDocument: acquireDocument,
                    updateDocument: updateDocument,
                    releaseDocument: releaseDocument,
                    reportStats: reportStats
                };
            }
            ts.createDocumentRegistry = createDocumentRegistry;
            function preProcessFile(sourceText, readImportFiles) {
                if (readImportFiles === void 0) { readImportFiles = true; }
                var referencedFiles = [];
                var importedFiles = [];
                var isNoDefaultLib = false;
                function processTripleSlashDirectives() {
                    var commentRanges = ts.getLeadingCommentRanges(sourceText, 0);
                    ts.forEach(commentRanges, function (commentRange) {
                        var comment = sourceText.substring(commentRange.pos, commentRange.end);
                        var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, commentRange);
                        if (referencePathMatchResult) {
                            isNoDefaultLib = referencePathMatchResult.isNoDefaultLib;
                            var fileReference = referencePathMatchResult.fileReference;
                            if (fileReference) {
                                referencedFiles.push(fileReference);
                            }
                        }
                    });
                }
                function processImport() {
                    scanner.setText(sourceText);
                    var token = scanner.scan();
                    while (token !== 1 /* EndOfFileToken */) {
                        if (token === 83 /* ImportKeyword */) {
                            token = scanner.scan();
                            if (token === 63 /* Identifier */) {
                                token = scanner.scan();
                                if (token === 51 /* EqualsToken */) {
                                    token = scanner.scan();
                                    if (token === 115 /* RequireKeyword */) {
                                        token = scanner.scan();
                                        if (token === 15 /* OpenParenToken */) {
                                            token = scanner.scan();
                                            if (token === 7 /* StringLiteral */) {
                                                var importPath = scanner.getTokenValue();
                                                var pos = scanner.getTokenPos();
                                                importedFiles.push({
                                                    filename: importPath,
                                                    pos: pos,
                                                    end: pos + importPath.length
                                                });
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        token = scanner.scan();
                    }
                    scanner.setText(undefined);
                }
                if (readImportFiles) {
                    processImport();
                }
                processTripleSlashDirectives();
                return { referencedFiles: referencedFiles, importedFiles: importedFiles, isLibFile: isNoDefaultLib };
            }
            ts.preProcessFile = preProcessFile;
            function getNodeModifiers(node) {
                var flags = node.flags;
                var result = [];
                if (flags & 32 /* Private */)
                    result.push(ScriptElementKindModifier.privateMemberModifier);
                if (flags & 64 /* Protected */)
                    result.push(ScriptElementKindModifier.protectedMemberModifier);
                if (flags & 16 /* Public */)
                    result.push(ScriptElementKindModifier.publicMemberModifier);
                if (flags & 128 /* Static */)
                    result.push(ScriptElementKindModifier.staticModifier);
                if (flags & 1 /* Export */)
                    result.push(ScriptElementKindModifier.exportedModifier);
                if (ts.isInAmbientContext(node))
                    result.push(ScriptElementKindModifier.ambientModifier);
                return result.length > 0 ? result.join(',') : ScriptElementKindModifier.none;
            }
            ts.getNodeModifiers = getNodeModifiers;
            function getTargetLabel(referenceNode, labelName) {
                while (referenceNode) {
                    if (referenceNode.kind === 179 /* LabeledStatement */ && referenceNode.label.text === labelName) {
                        return referenceNode.label;
                    }
                    referenceNode = referenceNode.parent;
                }
                return undefined;
            }
            function isJumpStatementTarget(node) {
                return node.kind === 63 /* Identifier */ && (node.parent.kind === 173 /* BreakStatement */ || node.parent.kind === 172 /* ContinueStatement */) && node.parent.label === node;
            }
            function isLabelOfLabeledStatement(node) {
                return node.kind === 63 /* Identifier */ && node.parent.kind === 179 /* LabeledStatement */ && node.parent.label === node;
            }
            function isLabeledBy(node, labelName) {
                for (var owner = node.parent; owner.kind === 179 /* LabeledStatement */; owner = owner.parent) {
                    if (owner.label.text === labelName) {
                        return true;
                    }
                }
                return false;
            }
            function isLabelName(node) {
                return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node);
            }
            function isRightSideOfQualifiedName(node) {
                return node.parent.kind === 121 /* QualifiedName */ && node.parent.right === node;
            }
            function isRightSideOfPropertyAccess(node) {
                return node && node.parent && node.parent.kind === 146 /* PropertyAccess */ && node.parent.right === node;
            }
            function isCallExpressionTarget(node) {
                if (isRightSideOfPropertyAccess(node)) {
                    node = node.parent;
                }
                return node && node.parent && node.parent.kind === 148 /* CallExpression */ && node.parent.func === node;
            }
            function isNewExpressionTarget(node) {
                if (isRightSideOfPropertyAccess(node)) {
                    node = node.parent;
                }
                return node && node.parent && node.parent.kind === 149 /* NewExpression */ && node.parent.func === node;
            }
            function isNameOfModuleDeclaration(node) {
                return node.parent.kind === 193 /* ModuleDeclaration */ && node.parent.name === node;
            }
            function isNameOfFunctionDeclaration(node) {
                return node.kind === 63 /* Identifier */ && ts.isAnyFunction(node.parent) && node.parent.name === node;
            }
            function isNameOfPropertyAssignment(node) {
                return (node.kind === 63 /* Identifier */ || node.kind === 7 /* StringLiteral */ || node.kind === 6 /* NumericLiteral */) && (node.parent.kind === 144 /* PropertyAssignment */ || node.parent.kind === 145 /* ShorthandPropertyAssignment */) && node.parent.name === node;
            }
            function isLiteralNameOfPropertyDeclarationOrIndexAccess(node) {
                if (node.kind === 7 /* StringLiteral */ || node.kind === 6 /* NumericLiteral */) {
                    switch (node.parent.kind) {
                        case 125 /* Property */:
                        case 144 /* PropertyAssignment */:
                        case 197 /* EnumMember */:
                        case 126 /* Method */:
                        case 128 /* GetAccessor */:
                        case 129 /* SetAccessor */:
                        case 193 /* ModuleDeclaration */:
                            return node.parent.name === node;
                        case 147 /* IndexedAccess */:
                            return node.parent.index === node;
                    }
                }
                return false;
            }
            function isNameOfExternalModuleImportOrDeclaration(node) {
                return node.kind === 7 /* StringLiteral */ && (isNameOfModuleDeclaration(node) || (node.parent.kind === 195 /* ImportDeclaration */ && node.parent.externalModuleName === node));
            }
            function isInsideComment(sourceFile, token, position) {
                return position <= token.getStart(sourceFile) && (isInsideCommentRange(ts.getTrailingCommentRanges(sourceFile.text, token.getFullStart())) || isInsideCommentRange(ts.getLeadingCommentRanges(sourceFile.text, token.getFullStart())));
                function isInsideCommentRange(comments) {
                    return ts.forEach(comments, function (comment) {
                        if (comment.pos < position && position < comment.end) {
                            return true;
                        }
                        else if (position === comment.end) {
                            var text = sourceFile.text;
                            var width = comment.end - comment.pos;
                            if (width <= 2 || text.charCodeAt(comment.pos + 1) === 47 /* slash */) {
                                return true;
                            }
                            else {
                                return !(text.charCodeAt(comment.end - 1) === 47 /* slash */ && text.charCodeAt(comment.end - 2) === 42 /* asterisk */);
                            }
                        }
                        return false;
                    });
                }
            }
            var SemanticMeaning;
            (function (SemanticMeaning) {
                SemanticMeaning[SemanticMeaning["None"] = 0] = "None";
                SemanticMeaning[SemanticMeaning["Value"] = 1] = "Value";
                SemanticMeaning[SemanticMeaning["Type"] = 2] = "Type";
                SemanticMeaning[SemanticMeaning["Namespace"] = 4] = "Namespace";
                SemanticMeaning[SemanticMeaning["All"] = 7] = "All";
            })(SemanticMeaning || (SemanticMeaning = {}));
            var BreakContinueSearchType;
            (function (BreakContinueSearchType) {
                BreakContinueSearchType[BreakContinueSearchType["None"] = 0] = "None";
                BreakContinueSearchType[BreakContinueSearchType["Unlabeled"] = 1] = "Unlabeled";
                BreakContinueSearchType[BreakContinueSearchType["Labeled"] = 2] = "Labeled";
                BreakContinueSearchType[BreakContinueSearchType["All"] = 3] = "All";
            })(BreakContinueSearchType || (BreakContinueSearchType = {}));
            var keywordCompletions = [];
            for (var i = 64 /* FirstKeyword */; i <= 119 /* LastKeyword */; i++) {
                keywordCompletions.push({
                    name: ts.tokenToString(i),
                    kind: ScriptElementKind.keyword,
                    kindModifiers: ScriptElementKindModifier.none
                });
            }
            function createLanguageService(host, documentRegistry) {
                var syntaxTreeCache = new SyntaxTreeCache(host);
                var ruleProvider;
                var hostCache;
                var program;
                var typeInfoResolver;
                var fullTypeCheckChecker_doNotAccessDirectly;
                var useCaseSensitivefilenames = false;
                var sourceFilesByName = {};
                var documentRegistry = documentRegistry;
                var cancellationToken = new CancellationTokenObject(host.getCancellationToken());
                var activeCompletionSession;
                var writer = undefined;
                if (!ts.localizedDiagnosticMessages) {
                    ts.localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages();
                }
                function getCanonicalFileName(filename) {
                    return useCaseSensitivefilenames ? filename : filename.toLowerCase();
                }
                function getSourceFile(filename) {
                    return ts.lookUp(sourceFilesByName, getCanonicalFileName(filename));
                }
                function getFullTypeCheckChecker() {
                    return fullTypeCheckChecker_doNotAccessDirectly || (fullTypeCheckChecker_doNotAccessDirectly = program.getTypeChecker(true));
                }
                function getRuleProvider(options) {
                    if (!ruleProvider) {
                        ruleProvider = new ts.formatting.RulesProvider(host);
                    }
                    ruleProvider.ensureUpToDate(options);
                    return ruleProvider;
                }
                function createCompilerHost() {
                    return {
                        getSourceFile: function (filename, languageVersion) {
                            var sourceFile = getSourceFile(filename);
                            return sourceFile && sourceFile.getSourceFile();
                        },
                        getCancellationToken: function () { return cancellationToken; },
                        getCanonicalFileName: function (filename) { return useCaseSensitivefilenames ? filename : filename.toLowerCase(); },
                        useCaseSensitiveFileNames: function () { return useCaseSensitivefilenames; },
                        getNewLine: function () { return "\r\n"; },
                        getDefaultLibFilename: function () {
                            return host.getDefaultLibFilename();
                        },
                        writeFile: function (filename, data, writeByteOrderMark) {
                            writer(filename, data, writeByteOrderMark);
                        },
                        getCurrentDirectory: function () {
                            return host.getCurrentDirectory();
                        }
                    };
                }
                function sourceFileUpToDate(sourceFile) {
                    return sourceFile && sourceFile.version === hostCache.getVersion(sourceFile.filename) && sourceFile.isOpen === hostCache.isOpen(sourceFile.filename);
                }
                function programUpToDate() {
                    if (!program) {
                        return false;
                    }
                    var hostFilenames = hostCache.getFilenames();
                    if (program.getSourceFiles().length !== hostFilenames.length) {
                        return false;
                    }
                    for (var i = 0, n = hostFilenames.length; i < n; i++) {
                        if (!sourceFileUpToDate(program.getSourceFile(hostFilenames[i]))) {
                            return false;
                        }
                    }
                    return compareDataObjects(program.getCompilerOptions(), hostCache.compilationSettings());
                }
                function synchronizeHostData() {
                    hostCache = new HostCache(host);
                    if (programUpToDate()) {
                        return;
                    }
                    var compilationSettings = hostCache.compilationSettings();
                    var oldProgram = program;
                    if (oldProgram) {
                        var oldSettings = program.getCompilerOptions();
                        var settingsChangeAffectsSyntax = oldSettings.target !== compilationSettings.target || oldSettings.module !== compilationSettings.module;
                        var changesInCompilationSettingsAffectSyntax = oldSettings && compilationSettings && !compareDataObjects(oldSettings, compilationSettings) && settingsChangeAffectsSyntax;
                        var oldSourceFiles = program.getSourceFiles();
                        for (var i = 0, n = oldSourceFiles.length; i < n; i++) {
                            cancellationToken.throwIfCancellationRequested();
                            var filename = oldSourceFiles[i].filename;
                            if (!hostCache.contains(filename) || changesInCompilationSettingsAffectSyntax) {
                                documentRegistry.releaseDocument(filename, oldSettings);
                                delete sourceFilesByName[getCanonicalFileName(filename)];
                            }
                        }
                    }
                    var hostfilenames = hostCache.getFilenames();
                    for (var i = 0, n = hostfilenames.length; i < n; i++) {
                        var filename = hostfilenames[i];
                        var version = hostCache.getVersion(filename);
                        var isOpen = hostCache.isOpen(filename);
                        var scriptSnapshot = hostCache.getScriptSnapshot(filename);
                        var sourceFile = getSourceFile(filename);
                        if (sourceFile) {
                            if (sourceFileUpToDate(sourceFile)) {
                                continue;
                            }
                            var textChangeRange = null;
                            if (sourceFile.isOpen && isOpen) {
                                textChangeRange = hostCache.getChangeRange(filename, sourceFile.version, sourceFile.getScriptSnapshot());
                            }
                            sourceFile = documentRegistry.updateDocument(sourceFile, filename, compilationSettings, scriptSnapshot, version, isOpen, textChangeRange);
                        }
                        else {
                            sourceFile = documentRegistry.acquireDocument(filename, compilationSettings, scriptSnapshot, version, isOpen);
                        }
                        sourceFilesByName[getCanonicalFileName(filename)] = sourceFile;
                    }
                    program = ts.createProgram(hostfilenames, compilationSettings, createCompilerHost());
                    typeInfoResolver = program.getTypeChecker(false);
                    fullTypeCheckChecker_doNotAccessDirectly = undefined;
                }
                function cleanupSemanticCache() {
                    if (program) {
                        typeInfoResolver = program.getTypeChecker(false);
                        fullTypeCheckChecker_doNotAccessDirectly = undefined;
                    }
                }
                function dispose() {
                    if (program) {
                        ts.forEach(program.getSourceFiles(), function (f) {
                            documentRegistry.releaseDocument(f.filename, program.getCompilerOptions());
                        });
                    }
                }
                function getSyntacticDiagnostics(filename) {
                    synchronizeHostData();
                    filename = ts.normalizeSlashes(filename);
                    return program.getDiagnostics(getSourceFile(filename).getSourceFile());
                }
                function getSemanticDiagnostics(filename) {
                    synchronizeHostData();
                    filename = ts.normalizeSlashes(filename);
                    var compilerOptions = program.getCompilerOptions();
                    var checker = getFullTypeCheckChecker();
                    var targetSourceFile = getSourceFile(filename);
                    var allDiagnostics = checker.getDiagnostics(targetSourceFile);
                    if (compilerOptions.declaration) {
                        allDiagnostics = allDiagnostics.concat(checker.getDeclarationDiagnostics(targetSourceFile));
                    }
                    return allDiagnostics;
                }
                function getCompilerOptionsDiagnostics() {
                    synchronizeHostData();
                    return program.getGlobalDiagnostics();
                }
                function getValidCompletionEntryDisplayName(symbol, target) {
                    var displayName = symbol.getName();
                    if (displayName && displayName.length > 0) {
                        var firstCharCode = displayName.charCodeAt(0);
                        if ((symbol.flags & 1536 /* Namespace */) && (firstCharCode === 39 /* singleQuote */ || firstCharCode === 34 /* doubleQuote */)) {
                            return undefined;
                        }
                        if (displayName && displayName.length >= 2 && firstCharCode === displayName.charCodeAt(displayName.length - 1) && (firstCharCode === 39 /* singleQuote */ || firstCharCode === 34 /* doubleQuote */)) {
                            displayName = displayName.substring(1, displayName.length - 1);
                        }
                        var isValid = ts.isIdentifierStart(displayName.charCodeAt(0), target);
                        for (var i = 1, n = displayName.length; isValid && i < n; i++) {
                            isValid = ts.isIdentifierPart(displayName.charCodeAt(i), target);
                        }
                        if (isValid) {
                            return ts.unescapeIdentifier(displayName);
                        }
                    }
                    return undefined;
                }
                function createCompletionEntry(symbol, typeChecker, location) {
                    var displayName = getValidCompletionEntryDisplayName(symbol, program.getCompilerOptions().target);
                    if (!displayName) {
                        return undefined;
                    }
                    return {
                        name: displayName,
                        kind: getSymbolKind(symbol, typeChecker, location),
                        kindModifiers: getSymbolModifiers(symbol)
                    };
                }
                function getCompletionsAtPosition(filename, position, isMemberCompletion) {
                    synchronizeHostData();
                    filename = ts.normalizeSlashes(filename);
                    var syntacticStart = new Date().getTime();
                    var sourceFile = getSourceFile(filename);
                    var start = new Date().getTime();
                    var currentToken = ts.getTokenAtPosition(sourceFile, position);
                    host.log("getCompletionsAtPosition: Get current token: " + (new Date().getTime() - start));
                    var start = new Date().getTime();
                    var insideComment = isInsideComment(sourceFile, currentToken, position);
                    host.log("getCompletionsAtPosition: Is inside comment: " + (new Date().getTime() - start));
                    if (insideComment) {
                        host.log("Returning an empty list because completion was inside a comment.");
                        return undefined;
                    }
                    var start = new Date().getTime();
                    var previousToken = ts.findPrecedingToken(position, sourceFile);
                    host.log("getCompletionsAtPosition: Get previous token 1: " + (new Date().getTime() - start));
                    if (previousToken && position <= previousToken.end && previousToken.kind === 63 /* Identifier */) {
                        var start = new Date().getTime();
                        previousToken = ts.findPrecedingToken(previousToken.pos, sourceFile);
                        host.log("getCompletionsAtPosition: Get previous token 2: " + (new Date().getTime() - start));
                    }
                    if (previousToken && isCompletionListBlocker(previousToken)) {
                        host.log("Returning an empty list because completion was requested in an invalid position.");
                        return undefined;
                    }
                    var node;
                    var isRightOfDot;
                    if (previousToken && previousToken.kind === 19 /* DotToken */ && (previousToken.parent.kind === 146 /* PropertyAccess */ || previousToken.parent.kind === 121 /* QualifiedName */)) {
                        node = previousToken.parent.left;
                        isRightOfDot = true;
                    }
                    else {
                        node = currentToken;
                        isRightOfDot = false;
                    }
                    activeCompletionSession = {
                        filename: filename,
                        position: position,
                        entries: [],
                        symbols: {},
                        typeChecker: typeInfoResolver
                    };
                    host.log("getCompletionsAtPosition: Syntactic work: " + (new Date().getTime() - syntacticStart));
                    var location = ts.getTouchingPropertyName(sourceFile, position);
                    var semanticStart = new Date().getTime();
                    if (isRightOfDot) {
                        var symbols = [];
                        isMemberCompletion = true;
                        if (node.kind === 63 /* Identifier */ || node.kind === 121 /* QualifiedName */ || node.kind === 146 /* PropertyAccess */) {
                            var symbol = typeInfoResolver.getSymbolInfo(node);
                            if (symbol && symbol.flags & 33554432 /* Import */) {
                                symbol = typeInfoResolver.getAliasedSymbol(symbol);
                            }
                            if (symbol && symbol.flags & 1952 /* HasExports */) {
                                ts.forEachValue(symbol.exports, function (symbol) {
                                    if (typeInfoResolver.isValidPropertyAccess((node.parent), symbol.name)) {
                                        symbols.push(symbol);
                                    }
                                });
                            }
                        }
                        var type = typeInfoResolver.getTypeOfNode(node);
                        if (type) {
                            ts.forEach(type.getApparentProperties(), function (symbol) {
                                if (typeInfoResolver.isValidPropertyAccess((node.parent), symbol.name)) {
                                    symbols.push(symbol);
                                }
                            });
                        }
                        getCompletionEntriesFromSymbols(symbols, activeCompletionSession);
                    }
                    else {
                        var containingObjectLiteral = getContainingObjectLiteralApplicableForCompletion(previousToken);
                        if (containingObjectLiteral) {
                            isMemberCompletion = true;
                            var contextualType = typeInfoResolver.getContextualType(containingObjectLiteral);
                            if (!contextualType) {
                                return undefined;
                            }
                            var contextualTypeMembers = typeInfoResolver.getPropertiesOfType(contextualType);
                            if (contextualTypeMembers && contextualTypeMembers.length > 0) {
                                var filteredMembers = filterContextualMembersList(contextualTypeMembers, containingObjectLiteral.properties);
                                getCompletionEntriesFromSymbols(filteredMembers, activeCompletionSession);
                            }
                        }
                        else {
                            isMemberCompletion = false;
                            var symbolMeanings = 3152352 /* Type */ | 107455 /* Value */ | 1536 /* Namespace */ | 33554432 /* Import */;
                            var symbols = typeInfoResolver.getSymbolsInScope(node, symbolMeanings);
                            getCompletionEntriesFromSymbols(symbols, activeCompletionSession);
                        }
                    }
                    if (!isMemberCompletion) {
                        Array.prototype.push.apply(activeCompletionSession.entries, keywordCompletions);
                    }
                    host.log("getCompletionsAtPosition: Semantic work: " + (new Date().getTime() - semanticStart));
                    return {
                        isMemberCompletion: isMemberCompletion,
                        entries: activeCompletionSession.entries
                    };
                    function getCompletionEntriesFromSymbols(symbols, session) {
                        var start = new Date().getTime();
                        ts.forEach(symbols, function (symbol) {
                            var entry = createCompletionEntry(symbol, session.typeChecker, location);
                            if (entry) {
                                var id = ts.escapeIdentifier(entry.name);
                                if (!ts.lookUp(session.symbols, id)) {
                                    session.entries.push(entry);
                                    session.symbols[id] = symbol;
                                }
                            }
                        });
                        host.log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (new Date().getTime() - start));
                    }
                    function isCompletionListBlocker(previousToken) {
                        var start = new Date().getTime();
                        var result = isInStringOrRegularExpressionOrTemplateLiteral(previousToken) || isIdentifierDefinitionLocation(previousToken) || isRightOfIllegalDot(previousToken);
                        host.log("getCompletionsAtPosition: isCompletionListBlocker: " + (new Date().getTime() - start));
                        return result;
                    }
                    function isInStringOrRegularExpressionOrTemplateLiteral(previousToken) {
                        if (previousToken.kind === 7 /* StringLiteral */ || ts.isTemplateLiteralKind(previousToken.kind)) {
                            var start = previousToken.getStart();
                            var end = previousToken.getEnd();
                            if (start < position && position < end) {
                                return true;
                            }
                            else if (position === end) {
                                var width = end - start;
                                var text = previousToken.getSourceFile().text;
                                if (width <= 1 || text.charCodeAt(end - 2) === 92 /* backslash */) {
                                    return true;
                                }
                                switch (previousToken.kind) {
                                    case 7 /* StringLiteral */:
                                    case 9 /* NoSubstitutionTemplateLiteral */:
                                        return text.charCodeAt(start) !== text.charCodeAt(end - 1);
                                    case 10 /* TemplateHead */:
                                    case 11 /* TemplateMiddle */:
                                        return text.charCodeAt(end - 1) !== 123 /* openBrace */ || text.charCodeAt(end - 2) !== 36 /* $ */;
                                    case 12 /* TemplateTail */:
                                        return text.charCodeAt(end - 1) !== 96 /* backtick */;
                                }
                                return false;
                            }
                        }
                        else if (previousToken.kind === 8 /* RegularExpressionLiteral */) {
                            return previousToken.getStart() < position && position < previousToken.getEnd();
                        }
                        return false;
                    }
                    function getContainingObjectLiteralApplicableForCompletion(previousToken) {
                        if (previousToken) {
                            var parent = previousToken.parent;
                            switch (previousToken.kind) {
                                case 13 /* OpenBraceToken */:
                                case 22 /* CommaToken */:
                                    if (parent && parent.kind === 143 /* ObjectLiteral */) {
                                        return parent;
                                    }
                                    break;
                            }
                        }
                        return undefined;
                    }
                    function isFunction(kind) {
                        switch (kind) {
                            case 153 /* FunctionExpression */:
                            case 154 /* ArrowFunction */:
                            case 187 /* FunctionDeclaration */:
                            case 126 /* Method */:
                            case 127 /* Constructor */:
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                            case 130 /* CallSignature */:
                            case 131 /* ConstructSignature */:
                            case 132 /* IndexSignature */:
                                return true;
                        }
                        return false;
                    }
                    function isIdentifierDefinitionLocation(previousToken) {
                        if (previousToken) {
                            var containingNodeKind = previousToken.parent.kind;
                            switch (previousToken.kind) {
                                case 22 /* CommaToken */:
                                    return containingNodeKind === 186 /* VariableDeclaration */ || containingNodeKind === 164 /* VariableStatement */ || containingNodeKind === 192 /* EnumDeclaration */ || isFunction(containingNodeKind);
                                case 15 /* OpenParenToken */:
                                    return containingNodeKind === 183 /* CatchBlock */ || isFunction(containingNodeKind);
                                case 13 /* OpenBraceToken */:
                                    return containingNodeKind === 192 /* EnumDeclaration */ || containingNodeKind === 190 /* InterfaceDeclaration */;
                                case 21 /* SemicolonToken */:
                                    return containingNodeKind === 125 /* Property */ && previousToken.parent.parent.kind === 190 /* InterfaceDeclaration */;
                                case 106 /* PublicKeyword */:
                                case 104 /* PrivateKeyword */:
                                case 107 /* StaticKeyword */:
                                case 20 /* DotDotDotToken */:
                                    return containingNodeKind === 124 /* Parameter */;
                                case 67 /* ClassKeyword */:
                                case 114 /* ModuleKeyword */:
                                case 75 /* EnumKeyword */:
                                case 101 /* InterfaceKeyword */:
                                case 81 /* FunctionKeyword */:
                                case 96 /* VarKeyword */:
                                case 113 /* GetKeyword */:
                                case 117 /* SetKeyword */:
                                case 83 /* ImportKeyword */:
                                    return true;
                            }
                            switch (previousToken.getText()) {
                                case "class":
                                case "interface":
                                case "enum":
                                case "module":
                                case "function":
                                case "var":
                                    return true;
                            }
                        }
                        return false;
                    }
                    function isRightOfIllegalDot(previousToken) {
                        if (previousToken && previousToken.kind === 6 /* NumericLiteral */) {
                            var text = previousToken.getFullText();
                            return text.charAt(text.length - 1) === ".";
                        }
                        return false;
                    }
                    function filterContextualMembersList(contextualMemberSymbols, existingMembers) {
                        if (!existingMembers || existingMembers.length === 0) {
                            return contextualMemberSymbols;
                        }
                        var existingMemberNames = {};
                        ts.forEach(existingMembers, function (m) {
                            if (m.kind !== 144 /* PropertyAssignment */ && m.kind !== 145 /* ShorthandPropertyAssignment */) {
                                return;
                            }
                            if (m.getStart() <= position && position <= m.getEnd()) {
                                return;
                            }
                            existingMemberNames[m.name.text] = true;
                        });
                        var filteredMembers = [];
                        ts.forEach(contextualMemberSymbols, function (s) {
                            if (!existingMemberNames[s.name]) {
                                filteredMembers.push(s);
                            }
                        });
                        return filteredMembers;
                    }
                }
                function getCompletionEntryDetails(filename, position, entryName) {
                    filename = ts.normalizeSlashes(filename);
                    var sourceFile = getSourceFile(filename);
                    var session = activeCompletionSession;
                    if (!session || session.filename !== filename || session.position !== position) {
                        return undefined;
                    }
                    var symbol = ts.lookUp(activeCompletionSession.symbols, ts.escapeIdentifier(entryName));
                    if (symbol) {
                        var location = ts.getTouchingPropertyName(sourceFile, position);
                        var completionEntry = createCompletionEntry(symbol, session.typeChecker, location);
                        ts.Debug.assert(session.typeChecker.getNarrowedTypeOfSymbol(symbol, location) !== undefined, "Could not find type for symbol");
                        var displayPartsDocumentationsAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getSourceFile(filename), location, session.typeChecker, location, 7 /* All */);
                        return {
                            name: entryName,
                            kind: displayPartsDocumentationsAndSymbolKind.symbolKind,
                            kindModifiers: completionEntry.kindModifiers,
                            displayParts: displayPartsDocumentationsAndSymbolKind.displayParts,
                            documentation: displayPartsDocumentationsAndSymbolKind.documentation
                        };
                    }
                    else {
                        return {
                            name: entryName,
                            kind: ScriptElementKind.keyword,
                            kindModifiers: ScriptElementKindModifier.none,
                            displayParts: [displayPart(entryName, 5 /* keyword */)],
                            documentation: undefined
                        };
                    }
                }
                function getContainerNode(node) {
                    while (true) {
                        node = node.parent;
                        if (!node) {
                            return undefined;
                        }
                        switch (node.kind) {
                            case 198 /* SourceFile */:
                            case 126 /* Method */:
                            case 187 /* FunctionDeclaration */:
                            case 153 /* FunctionExpression */:
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                            case 189 /* ClassDeclaration */:
                            case 190 /* InterfaceDeclaration */:
                            case 192 /* EnumDeclaration */:
                            case 193 /* ModuleDeclaration */:
                                return node;
                        }
                    }
                }
                function getSymbolKind(symbol, typeResolver, location) {
                    var flags = symbol.getFlags();
                    if (flags & 32 /* Class */)
                        return ScriptElementKind.classElement;
                    if (flags & 384 /* Enum */)
                        return ScriptElementKind.enumElement;
                    if (flags & 2097152 /* TypeAlias */)
                        return ScriptElementKind.typeElement;
                    if (flags & 64 /* Interface */)
                        return ScriptElementKind.interfaceElement;
                    if (flags & 1048576 /* TypeParameter */)
                        return ScriptElementKind.typeParameterElement;
                    var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, typeResolver, location);
                    if (result === ScriptElementKind.unknown) {
                        if (flags & 1048576 /* TypeParameter */)
                            return ScriptElementKind.typeParameterElement;
                        if (flags & 8 /* EnumMember */)
                            return ScriptElementKind.variableElement;
                        if (flags & 33554432 /* Import */)
                            return ScriptElementKind.alias;
                    }
                    return result;
                }
                function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, flags, typeResolver, location) {
                    if (typeResolver.isUndefinedSymbol(symbol)) {
                        return ScriptElementKind.variableElement;
                    }
                    if (typeResolver.isArgumentsSymbol(symbol)) {
                        return ScriptElementKind.localVariableElement;
                    }
                    if (flags & 3 /* Variable */) {
                        if (isFirstDeclarationOfSymbolParameter(symbol)) {
                            return ScriptElementKind.parameterElement;
                        }
                        else if (symbol.valueDeclaration && ts.isConst(symbol.valueDeclaration)) {
                            return ScriptElementKind.constElement;
                        }
                        else if (ts.forEach(symbol.declarations, function (declaration) { return ts.isLet(declaration); })) {
                            return ScriptElementKind.letElement;
                        }
                        return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localVariableElement : ScriptElementKind.variableElement;
                    }
                    if (flags & 16 /* Function */)
                        return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localFunctionElement : ScriptElementKind.functionElement;
                    if (flags & 32768 /* GetAccessor */)
                        return ScriptElementKind.memberGetAccessorElement;
                    if (flags & 65536 /* SetAccessor */)
                        return ScriptElementKind.memberSetAccessorElement;
                    if (flags & 8192 /* Method */)
                        return ScriptElementKind.memberFunctionElement;
                    if (flags & 16384 /* Constructor */)
                        return ScriptElementKind.constructorImplementationElement;
                    if (flags & 4 /* Property */) {
                        if (flags & 1073741824 /* UnionProperty */) {
                            var unionPropertyKind = ts.forEach(typeInfoResolver.getRootSymbols(symbol), function (rootSymbol) {
                                var rootSymbolFlags = rootSymbol.getFlags();
                                if (rootSymbolFlags & (98308 /* PropertyOrAccessor */ | 3 /* Variable */)) {
                                    return ScriptElementKind.memberVariableElement;
                                }
                                ts.Debug.assert(!!(rootSymbolFlags & 8192 /* Method */));
                            });
                            if (!unionPropertyKind) {
                                var typeOfUnionProperty = typeInfoResolver.getNarrowedTypeOfSymbol(symbol, location);
                                if (typeOfUnionProperty.getCallSignatures().length) {
                                    return ScriptElementKind.memberFunctionElement;
                                }
                                return ScriptElementKind.memberVariableElement;
                            }
                            return unionPropertyKind;
                        }
                        return ScriptElementKind.memberVariableElement;
                    }
                    return ScriptElementKind.unknown;
                }
                function getTypeKind(type) {
                    var flags = type.getFlags();
                    if (flags & 128 /* Enum */)
                        return ScriptElementKind.enumElement;
                    if (flags & 1024 /* Class */)
                        return ScriptElementKind.classElement;
                    if (flags & 2048 /* Interface */)
                        return ScriptElementKind.interfaceElement;
                    if (flags & 512 /* TypeParameter */)
                        return ScriptElementKind.typeParameterElement;
                    if (flags & 127 /* Intrinsic */)
                        return ScriptElementKind.primitiveType;
                    if (flags & 256 /* StringLiteral */)
                        return ScriptElementKind.primitiveType;
                    return ScriptElementKind.unknown;
                }
                function getNodeKind(node) {
                    switch (node.kind) {
                        case 193 /* ModuleDeclaration */: return ScriptElementKind.moduleElement;
                        case 189 /* ClassDeclaration */: return ScriptElementKind.classElement;
                        case 190 /* InterfaceDeclaration */: return ScriptElementKind.interfaceElement;
                        case 191 /* TypeAliasDeclaration */: return ScriptElementKind.typeElement;
                        case 192 /* EnumDeclaration */: return ScriptElementKind.enumElement;
                        case 186 /* VariableDeclaration */: return ts.isConst(node) ? ScriptElementKind.constElement : node.flags & 2048 /* Let */ ? ScriptElementKind.letElement : ScriptElementKind.variableElement;
                        case 187 /* FunctionDeclaration */: return ScriptElementKind.functionElement;
                        case 128 /* GetAccessor */: return ScriptElementKind.memberGetAccessorElement;
                        case 129 /* SetAccessor */: return ScriptElementKind.memberSetAccessorElement;
                        case 126 /* Method */: return ScriptElementKind.memberFunctionElement;
                        case 125 /* Property */: return ScriptElementKind.memberVariableElement;
                        case 132 /* IndexSignature */: return ScriptElementKind.indexSignatureElement;
                        case 131 /* ConstructSignature */: return ScriptElementKind.constructSignatureElement;
                        case 130 /* CallSignature */: return ScriptElementKind.callSignatureElement;
                        case 127 /* Constructor */: return ScriptElementKind.constructorImplementationElement;
                        case 123 /* TypeParameter */: return ScriptElementKind.typeParameterElement;
                        case 197 /* EnumMember */: return ScriptElementKind.variableElement;
                        case 124 /* Parameter */: return (node.flags & 112 /* AccessibilityModifier */) ? ScriptElementKind.memberVariableElement : ScriptElementKind.parameterElement;
                    }
                    return ScriptElementKind.unknown;
                }
                function getSymbolModifiers(symbol) {
                    return symbol && symbol.declarations && symbol.declarations.length > 0 ? getNodeModifiers(symbol.declarations[0]) : ScriptElementKindModifier.none;
                }
                function getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, enclosingDeclaration, typeResolver, location, semanticMeaning) {
                    if (semanticMeaning === void 0) { semanticMeaning = getMeaningFromLocation(location); }
                    var displayParts = [];
                    var documentation;
                    var symbolFlags = symbol.flags;
                    var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(symbol, symbolFlags, typeResolver, location);
                    var hasAddedSymbolInfo;
                    if (symbolKind !== ScriptElementKind.unknown || symbolFlags & 32 /* Class */ || symbolFlags & 33554432 /* Import */) {
                        if (symbolKind === ScriptElementKind.memberGetAccessorElement || symbolKind === ScriptElementKind.memberSetAccessorElement) {
                            symbolKind = ScriptElementKind.memberVariableElement;
                        }
                        var type = typeResolver.getNarrowedTypeOfSymbol(symbol, location);
                        if (type) {
                            if (location.parent && location.parent.kind === 146 /* PropertyAccess */) {
                                var right = location.parent.right;
                                if (right === location || (right && right.kind === 120 /* Missing */)) {
                                    location = location.parent;
                                }
                            }
                            var callExpression;
                            if (location.kind === 148 /* CallExpression */ || location.kind === 149 /* NewExpression */) {
                                callExpression = location;
                            }
                            else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) {
                                callExpression = location.parent;
                            }
                            if (callExpression) {
                                var candidateSignatures = [];
                                signature = typeResolver.getResolvedSignature(callExpression, candidateSignatures);
                                if (!signature && candidateSignatures.length) {
                                    signature = candidateSignatures[0];
                                }
                                var useConstructSignatures = callExpression.kind === 149 /* NewExpression */ || callExpression.func.kind === 89 /* SuperKeyword */;
                                var allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures();
                                if (!ts.contains(allSignatures, signature.target || signature)) {
                                    signature = allSignatures.length ? allSignatures[0] : undefined;
                                }
                                if (signature) {
                                    if (useConstructSignatures && (symbolFlags & 32 /* Class */)) {
                                        symbolKind = ScriptElementKind.constructorImplementationElement;
                                        addPrefixForAnyFunctionOrVar(type.symbol, symbolKind);
                                    }
                                    else if (symbolFlags & 33554432 /* Import */) {
                                        symbolKind = ScriptElementKind.alias;
                                        displayParts.push(punctuationPart(15 /* OpenParenToken */));
                                        displayParts.push(textPart(symbolKind));
                                        displayParts.push(punctuationPart(16 /* CloseParenToken */));
                                        displayParts.push(spacePart());
                                        if (useConstructSignatures) {
                                            displayParts.push(keywordPart(86 /* NewKeyword */));
                                            displayParts.push(spacePart());
                                        }
                                        addFullSymbolName(symbol);
                                    }
                                    else {
                                        addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                                    }
                                    switch (symbolKind) {
                                        case ScriptElementKind.memberVariableElement:
                                        case ScriptElementKind.variableElement:
                                        case ScriptElementKind.constElement:
                                        case ScriptElementKind.parameterElement:
                                        case ScriptElementKind.localVariableElement:
                                            displayParts.push(punctuationPart(50 /* ColonToken */));
                                            displayParts.push(spacePart());
                                            if (useConstructSignatures) {
                                                displayParts.push(keywordPart(86 /* NewKeyword */));
                                                displayParts.push(spacePart());
                                            }
                                            if (!(type.flags & 32768 /* Anonymous */)) {
                                                displayParts.push.apply(displayParts, symbolToDisplayParts(typeResolver, type.symbol, enclosingDeclaration, undefined, 1 /* WriteTypeParametersOrArguments */));
                                            }
                                            addSignatureDisplayParts(signature, allSignatures, 8 /* WriteArrowStyleSignature */);
                                            break;
                                        default:
                                            addSignatureDisplayParts(signature, allSignatures);
                                    }
                                    hasAddedSymbolInfo = true;
                                }
                            }
                            else if ((isNameOfFunctionDeclaration(location) && !(symbol.flags & 98304 /* Accessor */)) || (location.kind === 111 /* ConstructorKeyword */ && location.parent.kind === 127 /* Constructor */)) {
                                var signature;
                                var functionDeclaration = location.parent;
                                var allSignatures = functionDeclaration.kind === 127 /* Constructor */ ? type.getConstructSignatures() : type.getCallSignatures();
                                if (!typeResolver.isImplementationOfOverload(functionDeclaration)) {
                                    signature = typeResolver.getSignatureFromDeclaration(functionDeclaration);
                                }
                                else {
                                    signature = allSignatures[0];
                                }
                                if (functionDeclaration.kind === 127 /* Constructor */) {
                                    addPrefixForAnyFunctionOrVar(type.symbol, ScriptElementKind.constructorImplementationElement);
                                }
                                else {
                                    addPrefixForAnyFunctionOrVar(functionDeclaration.kind === 130 /* CallSignature */ && !(type.symbol.flags & 2048 /* TypeLiteral */ || type.symbol.flags & 4096 /* ObjectLiteral */) ? type.symbol : symbol, symbolKind);
                                }
                                addSignatureDisplayParts(signature, allSignatures);
                                hasAddedSymbolInfo = true;
                            }
                        }
                    }
                    if (symbolFlags & 32 /* Class */ && !hasAddedSymbolInfo) {
                        displayParts.push(keywordPart(67 /* ClassKeyword */));
                        displayParts.push(spacePart());
                        addFullSymbolName(symbol);
                        writeTypeParametersOfSymbol(symbol, sourceFile);
                    }
                    if ((symbolFlags & 64 /* Interface */) && (semanticMeaning & 2 /* Type */)) {
                        addNewLineIfDisplayPartsExist();
                        displayParts.push(keywordPart(101 /* InterfaceKeyword */));
                        displayParts.push(spacePart());
                        addFullSymbolName(symbol);
                        writeTypeParametersOfSymbol(symbol, sourceFile);
                    }
                    if (symbolFlags & 2097152 /* TypeAlias */) {
                        addNewLineIfDisplayPartsExist();
                        displayParts.push(keywordPart(119 /* TypeKeyword */));
                        displayParts.push(spacePart());
                        addFullSymbolName(symbol);
                        displayParts.push(spacePart());
                        displayParts.push(punctuationPart(51 /* EqualsToken */));
                        displayParts.push(spacePart());
                        displayParts.push.apply(displayParts, typeToDisplayParts(typeResolver, typeResolver.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration));
                    }
                    if (symbolFlags & 384 /* Enum */) {
                        addNewLineIfDisplayPartsExist();
                        if (ts.forEach(symbol.declarations, function (declaration) { return ts.isConstEnumDeclaration(declaration); })) {
                            displayParts.push(keywordPart(68 /* ConstKeyword */));
                            displayParts.push(spacePart());
                        }
                        displayParts.push(keywordPart(75 /* EnumKeyword */));
                        displayParts.push(spacePart());
                        addFullSymbolName(symbol);
                    }
                    if (symbolFlags & 1536 /* Module */) {
                        addNewLineIfDisplayPartsExist();
                        displayParts.push(keywordPart(114 /* ModuleKeyword */));
                        displayParts.push(spacePart());
                        addFullSymbolName(symbol);
                    }
                    if ((symbolFlags & 1048576 /* TypeParameter */) && (semanticMeaning & 2 /* Type */)) {
                        addNewLineIfDisplayPartsExist();
                        displayParts.push(punctuationPart(15 /* OpenParenToken */));
                        displayParts.push(textPart("type parameter"));
                        displayParts.push(punctuationPart(16 /* CloseParenToken */));
                        displayParts.push(spacePart());
                        addFullSymbolName(symbol);
                        displayParts.push(spacePart());
                        displayParts.push(keywordPart(84 /* InKeyword */));
                        displayParts.push(spacePart());
                        if (symbol.parent) {
                            addFullSymbolName(symbol.parent, enclosingDeclaration);
                            writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration);
                        }
                        else {
                            var signatureDeclaration = ts.getDeclarationOfKind(symbol, 123 /* TypeParameter */).parent;
                            var signature = typeResolver.getSignatureFromDeclaration(signatureDeclaration);
                            if (signatureDeclaration.kind === 131 /* ConstructSignature */) {
                                displayParts.push(keywordPart(86 /* NewKeyword */));
                                displayParts.push(spacePart());
                            }
                            else if (signatureDeclaration.kind !== 130 /* CallSignature */ && signatureDeclaration.name) {
                                addFullSymbolName(signatureDeclaration.symbol);
                            }
                            displayParts.push.apply(displayParts, signatureToDisplayParts(typeResolver, signature, sourceFile, 32 /* WriteTypeArgumentsOfSignature */));
                        }
                    }
                    if (symbolFlags & 8 /* EnumMember */) {
                        addPrefixForAnyFunctionOrVar(symbol, "enum member");
                        var declaration = symbol.declarations[0];
                        if (declaration.kind === 197 /* EnumMember */) {
                            var constantValue = typeResolver.getEnumMemberValue(declaration);
                            if (constantValue !== undefined) {
                                displayParts.push(spacePart());
                                displayParts.push(operatorPart(51 /* EqualsToken */));
                                displayParts.push(spacePart());
                                displayParts.push(displayPart(constantValue.toString(), 7 /* numericLiteral */));
                            }
                        }
                    }
                    if (symbolFlags & 33554432 /* Import */) {
                        addNewLineIfDisplayPartsExist();
                        displayParts.push(keywordPart(83 /* ImportKeyword */));
                        displayParts.push(spacePart());
                        addFullSymbolName(symbol);
                        ts.forEach(symbol.declarations, function (declaration) {
                            if (declaration.kind === 195 /* ImportDeclaration */) {
                                var importDeclaration = declaration;
                                if (importDeclaration.externalModuleName) {
                                    displayParts.push(spacePart());
                                    displayParts.push(punctuationPart(51 /* EqualsToken */));
                                    displayParts.push(spacePart());
                                    displayParts.push(keywordPart(115 /* RequireKeyword */));
                                    displayParts.push(punctuationPart(15 /* OpenParenToken */));
                                    displayParts.push(displayPart(ts.getTextOfNode(importDeclaration.externalModuleName), 8 /* stringLiteral */));
                                    displayParts.push(punctuationPart(16 /* CloseParenToken */));
                                }
                                else {
                                    var internalAliasSymbol = typeResolver.getSymbolInfo(importDeclaration.entityName);
                                    if (internalAliasSymbol) {
                                        displayParts.push(spacePart());
                                        displayParts.push(punctuationPart(51 /* EqualsToken */));
                                        displayParts.push(spacePart());
                                        addFullSymbolName(internalAliasSymbol, enclosingDeclaration);
                                    }
                                }
                                return true;
                            }
                        });
                    }
                    if (!hasAddedSymbolInfo) {
                        if (symbolKind !== ScriptElementKind.unknown) {
                            if (type) {
                                addPrefixForAnyFunctionOrVar(symbol, symbolKind);
                                if (symbolKind === ScriptElementKind.memberVariableElement || symbolFlags & 3 /* Variable */ || symbolKind === ScriptElementKind.localVariableElement) {
                                    displayParts.push(punctuationPart(50 /* ColonToken */));
                                    displayParts.push(spacePart());
                                    if (type.symbol && type.symbol.flags & 1048576 /* TypeParameter */) {
                                        var typeParameterParts = mapToDisplayParts(function (writer) {
                                            typeResolver.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration);
                                        });
                                        displayParts.push.apply(displayParts, typeParameterParts);
                                    }
                                    else {
                                        displayParts.push.apply(displayParts, typeToDisplayParts(typeResolver, type, enclosingDeclaration));
                                    }
                                }
                                else if (symbolFlags & 16 /* Function */ || symbolFlags & 8192 /* Method */ || symbolFlags & 16384 /* Constructor */ || symbolFlags & 917504 /* Signature */ || symbolFlags & 98304 /* Accessor */ || symbolKind === ScriptElementKind.memberFunctionElement) {
                                    var allSignatures = type.getCallSignatures();
                                    addSignatureDisplayParts(allSignatures[0], allSignatures);
                                }
                            }
                        }
                        else {
                            symbolKind = getSymbolKind(symbol, typeResolver, location);
                        }
                    }
                    if (!documentation) {
                        documentation = symbol.getDocumentationComment();
                    }
                    return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind };
                    function addNewLineIfDisplayPartsExist() {
                        if (displayParts.length) {
                            displayParts.push(lineBreakPart());
                        }
                    }
                    function addFullSymbolName(symbol, enclosingDeclaration) {
                        var fullSymbolDisplayParts = symbolToDisplayParts(typeResolver, symbol, enclosingDeclaration || sourceFile, undefined, 1 /* WriteTypeParametersOrArguments */ | 2 /* UseOnlyExternalAliasing */);
                        displayParts.push.apply(displayParts, fullSymbolDisplayParts);
                    }
                    function addPrefixForAnyFunctionOrVar(symbol, symbolKind) {
                        addNewLineIfDisplayPartsExist();
                        if (symbolKind) {
                            displayParts.push(punctuationPart(15 /* OpenParenToken */));
                            displayParts.push(textPart(symbolKind));
                            displayParts.push(punctuationPart(16 /* CloseParenToken */));
                            displayParts.push(spacePart());
                            addFullSymbolName(symbol);
                        }
                    }
                    function addSignatureDisplayParts(signature, allSignatures, flags) {
                        displayParts.push.apply(displayParts, signatureToDisplayParts(typeResolver, signature, enclosingDeclaration, flags | 32 /* WriteTypeArgumentsOfSignature */));
                        if (allSignatures.length > 1) {
                            displayParts.push(spacePart());
                            displayParts.push(punctuationPart(15 /* OpenParenToken */));
                            displayParts.push(operatorPart(32 /* PlusToken */));
                            displayParts.push(displayPart((allSignatures.length - 1).toString(), 7 /* numericLiteral */));
                            displayParts.push(spacePart());
                            displayParts.push(textPart(allSignatures.length === 2 ? "overload" : "overloads"));
                            displayParts.push(punctuationPart(16 /* CloseParenToken */));
                        }
                        documentation = signature.getDocumentationComment();
                    }
                    function writeTypeParametersOfSymbol(symbol, enclosingDeclaration) {
                        var typeParameterParts = mapToDisplayParts(function (writer) {
                            typeResolver.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration);
                        });
                        displayParts.push.apply(displayParts, typeParameterParts);
                    }
                }
                function getQuickInfoAtPosition(fileName, position) {
                    synchronizeHostData();
                    fileName = ts.normalizeSlashes(fileName);
                    var sourceFile = getSourceFile(fileName);
                    var node = ts.getTouchingPropertyName(sourceFile, position);
                    if (!node) {
                        return undefined;
                    }
                    var symbol = typeInfoResolver.getSymbolInfo(node);
                    if (!symbol) {
                        switch (node.kind) {
                            case 63 /* Identifier */:
                            case 146 /* PropertyAccess */:
                            case 121 /* QualifiedName */:
                            case 91 /* ThisKeyword */:
                            case 89 /* SuperKeyword */:
                                var type = typeInfoResolver.getTypeOfNode(node);
                                if (type) {
                                    return {
                                        kind: ScriptElementKind.unknown,
                                        kindModifiers: ScriptElementKindModifier.none,
                                        textSpan: new ts.TextSpan(node.getStart(), node.getWidth()),
                                        displayParts: typeToDisplayParts(typeInfoResolver, type, getContainerNode(node)),
                                        documentation: type.symbol ? type.symbol.getDocumentationComment() : undefined
                                    };
                                }
                        }
                        return undefined;
                    }
                    var displayPartsDocumentationsAndKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, sourceFile, getContainerNode(node), typeInfoResolver, node);
                    return {
                        kind: displayPartsDocumentationsAndKind.symbolKind,
                        kindModifiers: getSymbolModifiers(symbol),
                        textSpan: new ts.TextSpan(node.getStart(), node.getWidth()),
                        displayParts: displayPartsDocumentationsAndKind.displayParts,
                        documentation: displayPartsDocumentationsAndKind.documentation
                    };
                }
                function getDefinitionAtPosition(filename, position) {
                    function getDefinitionInfo(node, symbolKind, symbolName, containerName) {
                        return {
                            fileName: node.getSourceFile().filename,
                            textSpan: ts.TextSpan.fromBounds(node.getStart(), node.getEnd()),
                            kind: symbolKind,
                            name: symbolName,
                            containerKind: undefined,
                            containerName: containerName
                        };
                    }
                    function tryAddSignature(signatureDeclarations, selectConstructors, symbolKind, symbolName, containerName, result) {
                        var declarations = [];
                        var definition;
                        ts.forEach(signatureDeclarations, function (d) {
                            if ((selectConstructors && d.kind === 127 /* Constructor */) || (!selectConstructors && (d.kind === 187 /* FunctionDeclaration */ || d.kind === 126 /* Method */))) {
                                declarations.push(d);
                                if (d.body)
                                    definition = d;
                            }
                        });
                        if (definition) {
                            result.push(getDefinitionInfo(definition, symbolKind, symbolName, containerName));
                            return true;
                        }
                        else if (declarations.length) {
                            result.push(getDefinitionInfo(declarations[declarations.length - 1], symbolKind, symbolName, containerName));
                            return true;
                        }
                        return false;
                    }
                    function tryAddConstructSignature(symbol, location, symbolKind, symbolName, containerName, result) {
                        if (isNewExpressionTarget(location) || location.kind === 111 /* ConstructorKeyword */) {
                            if (symbol.flags & 32 /* Class */) {
                                var classDeclaration = symbol.getDeclarations()[0];
                                ts.Debug.assert(classDeclaration && classDeclaration.kind === 189 /* ClassDeclaration */);
                                return tryAddSignature(classDeclaration.members, true, symbolKind, symbolName, containerName, result);
                            }
                        }
                        return false;
                    }
                    function tryAddCallSignature(symbol, location, symbolKind, symbolName, containerName, result) {
                        if (isCallExpressionTarget(location) || isNewExpressionTarget(location) || isNameOfFunctionDeclaration(location)) {
                            return tryAddSignature(symbol.declarations, false, symbolKind, symbolName, containerName, result);
                        }
                        return false;
                    }
                    synchronizeHostData();
                    filename = ts.normalizeSlashes(filename);
                    var sourceFile = getSourceFile(filename);
                    var node = ts.getTouchingPropertyName(sourceFile, position);
                    if (!node) {
                        return undefined;
                    }
                    if (isJumpStatementTarget(node)) {
                        var labelName = node.text;
                        var label = getTargetLabel(node.parent, node.text);
                        return label ? [getDefinitionInfo(label, ScriptElementKind.label, labelName, undefined)] : undefined;
                    }
                    var comment = ts.forEach(sourceFile.referencedFiles, function (r) { return (r.pos <= position && position < r.end) ? r : undefined; });
                    if (comment) {
                        var referenceFile = ts.tryResolveScriptReference(program, sourceFile, comment);
                        if (referenceFile) {
                            return [{
                                fileName: referenceFile.filename,
                                textSpan: ts.TextSpan.fromBounds(0, 0),
                                kind: ScriptElementKind.scriptElement,
                                name: comment.filename,
                                containerName: undefined,
                                containerKind: undefined
                            }];
                        }
                        return undefined;
                    }
                    var symbol = typeInfoResolver.getSymbolInfo(node);
                    if (!symbol) {
                        return undefined;
                    }
                    var result = [];
                    if (node.parent.kind === 145 /* ShorthandPropertyAssignment */) {
                        var shorthandSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
                        var shorthandDeclarations = shorthandSymbol.getDeclarations();
                        var shorthandSymbolKind = getSymbolKind(shorthandSymbol, typeInfoResolver);
                        var shorthandSymbolName = typeInfoResolver.symbolToString(shorthandSymbol);
                        var shorthandContainerName = typeInfoResolver.symbolToString(symbol.parent, node);
                        ts.forEach(shorthandDeclarations, function (declaration) {
                            result.push(getDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName));
                        });
                        return result;
                    }
                    var declarations = symbol.getDeclarations();
                    var symbolName = typeInfoResolver.symbolToString(symbol);
                    var symbolKind = getSymbolKind(symbol, typeInfoResolver);
                    var containerSymbol = symbol.parent;
                    var containerName = containerSymbol ? typeInfoResolver.symbolToString(containerSymbol, node) : "";
                    if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) && !tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
                        ts.forEach(declarations, function (declaration) {
                            result.push(getDefinitionInfo(declaration, symbolKind, symbolName, containerName));
                        });
                    }
                    return result;
                }
                function getOccurrencesAtPosition(filename, position) {
                    synchronizeHostData();
                    filename = ts.normalizeSlashes(filename);
                    var sourceFile = getSourceFile(filename);
                    var node = ts.getTouchingWord(sourceFile, position);
                    if (!node) {
                        return undefined;
                    }
                    if (node.kind === 63 /* Identifier */ || node.kind === 91 /* ThisKeyword */ || node.kind === 89 /* SuperKeyword */ || isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) {
                        return getReferencesForNode(node, [sourceFile], false, false);
                    }
                    switch (node.kind) {
                        case 82 /* IfKeyword */:
                        case 74 /* ElseKeyword */:
                            if (hasKind(node.parent, 167 /* IfStatement */)) {
                                return getIfElseOccurrences(node.parent);
                            }
                            break;
                        case 88 /* ReturnKeyword */:
                            if (hasKind(node.parent, 174 /* ReturnStatement */)) {
                                return getReturnOccurrences(node.parent);
                            }
                            break;
                        case 92 /* ThrowKeyword */:
                            if (hasKind(node.parent, 180 /* ThrowStatement */)) {
                                return getThrowOccurrences(node.parent);
                            }
                            break;
                        case 94 /* TryKeyword */:
                        case 66 /* CatchKeyword */:
                        case 79 /* FinallyKeyword */:
                            if (hasKind(parent(parent(node)), 181 /* TryStatement */)) {
                                return getTryCatchFinallyOccurrences(node.parent.parent);
                            }
                            break;
                        case 90 /* SwitchKeyword */:
                            if (hasKind(node.parent, 176 /* SwitchStatement */)) {
                                return getSwitchCaseDefaultOccurrences(node.parent);
                            }
                            break;
                        case 65 /* CaseKeyword */:
                        case 71 /* DefaultKeyword */:
                            if (hasKind(parent(parent(node)), 176 /* SwitchStatement */)) {
                                return getSwitchCaseDefaultOccurrences(node.parent.parent);
                            }
                            break;
                        case 64 /* BreakKeyword */:
                        case 69 /* ContinueKeyword */:
                            if (hasKind(node.parent, 173 /* BreakStatement */) || hasKind(node.parent, 172 /* ContinueStatement */)) {
                                return getBreakOrContinueStatementOccurences(node.parent);
                            }
                            break;
                        case 80 /* ForKeyword */:
                            if (hasKind(node.parent, 170 /* ForStatement */) || hasKind(node.parent, 171 /* ForInStatement */)) {
                                return getLoopBreakContinueOccurrences(node.parent);
                            }
                            break;
                        case 98 /* WhileKeyword */:
                        case 73 /* DoKeyword */:
                            if (hasKind(node.parent, 169 /* WhileStatement */) || hasKind(node.parent, 168 /* DoStatement */)) {
                                return getLoopBreakContinueOccurrences(node.parent);
                            }
                            break;
                        case 111 /* ConstructorKeyword */:
                            if (hasKind(node.parent, 127 /* Constructor */)) {
                                return getConstructorOccurrences(node.parent);
                            }
                            break;
                        case 113 /* GetKeyword */:
                        case 117 /* SetKeyword */:
                            if (hasKind(node.parent, 128 /* GetAccessor */) || hasKind(node.parent, 129 /* SetAccessor */)) {
                                return getGetAndSetOccurrences(node.parent);
                            }
                        default:
                            if (ts.isModifier(node.kind) && node.parent && (ts.isDeclaration(node.parent) || node.parent.kind === 164 /* VariableStatement */)) {
                                return getModifierOccurrences(node.kind, node.parent);
                            }
                    }
                    return undefined;
                    function getIfElseOccurrences(ifStatement) {
                        var keywords = [];
                        while (hasKind(ifStatement.parent, 167 /* IfStatement */) && ifStatement.parent.elseStatement === ifStatement) {
                            ifStatement = ifStatement.parent;
                        }
                        while (ifStatement) {
                            var children = ifStatement.getChildren();
                            pushKeywordIf(keywords, children[0], 82 /* IfKeyword */);
                            for (var i = children.length - 1; i >= 0; i--) {
                                if (pushKeywordIf(keywords, children[i], 74 /* ElseKeyword */)) {
                                    break;
                                }
                            }
                            if (!hasKind(ifStatement.elseStatement, 167 /* IfStatement */)) {
                                break;
                            }
                            ifStatement = ifStatement.elseStatement;
                        }
                        var result = [];
                        for (var i = 0; i < keywords.length; i++) {
                            if (keywords[i].kind === 74 /* ElseKeyword */ && i < keywords.length - 1) {
                                var elseKeyword = keywords[i];
                                var ifKeyword = keywords[i + 1];
                                var shouldHighlightNextKeyword = true;
                                for (var j = ifKeyword.getStart() - 1; j >= elseKeyword.end; j--) {
                                    if (!ts.isWhiteSpace(sourceFile.text.charCodeAt(j))) {
                                        shouldHighlightNextKeyword = false;
                                        break;
                                    }
                                }
                                if (shouldHighlightNextKeyword) {
                                    result.push({
                                        fileName: filename,
                                        textSpan: ts.TextSpan.fromBounds(elseKeyword.getStart(), ifKeyword.end),
                                        isWriteAccess: false
                                    });
                                    i++;
                                    continue;
                                }
                            }
                            result.push(getReferenceEntryFromNode(keywords[i]));
                        }
                        return result;
                    }
                    function getReturnOccurrences(returnStatement) {
                        var func = ts.getContainingFunction(returnStatement);
                        if (!(func && hasKind(func.body, 188 /* FunctionBlock */))) {
                            return undefined;
                        }
                        var keywords = [];
                        ts.forEachReturnStatement(func.body, function (returnStatement) {
                            pushKeywordIf(keywords, returnStatement.getFirstToken(), 88 /* ReturnKeyword */);
                        });
                        ts.forEach(aggregateOwnedThrowStatements(func.body), function (throwStatement) {
                            pushKeywordIf(keywords, throwStatement.getFirstToken(), 92 /* ThrowKeyword */);
                        });
                        return ts.map(keywords, getReferenceEntryFromNode);
                    }
                    function getThrowOccurrences(throwStatement) {
                        var owner = getThrowStatementOwner(throwStatement);
                        if (!owner) {
                            return undefined;
                        }
                        var keywords = [];
                        ts.forEach(aggregateOwnedThrowStatements(owner), function (throwStatement) {
                            pushKeywordIf(keywords, throwStatement.getFirstToken(), 92 /* ThrowKeyword */);
                        });
                        if (owner.kind === 188 /* FunctionBlock */) {
                            ts.forEachReturnStatement(owner, function (returnStatement) {
                                pushKeywordIf(keywords, returnStatement.getFirstToken(), 88 /* ReturnKeyword */);
                            });
                        }
                        return ts.map(keywords, getReferenceEntryFromNode);
                    }
                    function aggregateOwnedThrowStatements(node) {
                        var statementAccumulator = [];
                        aggregate(node);
                        return statementAccumulator;
                        function aggregate(node) {
                            if (node.kind === 180 /* ThrowStatement */) {
                                statementAccumulator.push(node);
                            }
                            else if (node.kind === 181 /* TryStatement */) {
                                var tryStatement = node;
                                if (tryStatement.catchBlock) {
                                    aggregate(tryStatement.catchBlock);
                                }
                                else {
                                    aggregate(tryStatement.tryBlock);
                                }
                                if (tryStatement.finallyBlock) {
                                    aggregate(tryStatement.finallyBlock);
                                }
                            }
                            else if (!ts.isAnyFunction(node)) {
                                ts.forEachChild(node, aggregate);
                            }
                        }
                        ;
                    }
                    function getThrowStatementOwner(throwStatement) {
                        var child = throwStatement;
                        while (child.parent) {
                            var parent = child.parent;
                            if (parent.kind === 188 /* FunctionBlock */ || parent.kind === 198 /* SourceFile */) {
                                return parent;
                            }
                            if (parent.kind === 181 /* TryStatement */) {
                                var tryStatement = parent;
                                if (tryStatement.tryBlock === child && tryStatement.catchBlock) {
                                    return child;
                                }
                            }
                            child = parent;
                        }
                        return undefined;
                    }
                    function getTryCatchFinallyOccurrences(tryStatement) {
                        var keywords = [];
                        pushKeywordIf(keywords, tryStatement.getFirstToken(), 94 /* TryKeyword */);
                        if (tryStatement.catchBlock) {
                            pushKeywordIf(keywords, tryStatement.catchBlock.getFirstToken(), 66 /* CatchKeyword */);
                        }
                        if (tryStatement.finallyBlock) {
                            pushKeywordIf(keywords, tryStatement.finallyBlock.getFirstToken(), 79 /* FinallyKeyword */);
                        }
                        return ts.map(keywords, getReferenceEntryFromNode);
                    }
                    function getLoopBreakContinueOccurrences(loopNode) {
                        var keywords = [];
                        if (pushKeywordIf(keywords, loopNode.getFirstToken(), 80 /* ForKeyword */, 98 /* WhileKeyword */, 73 /* DoKeyword */)) {
                            if (loopNode.kind === 168 /* DoStatement */) {
                                var loopTokens = loopNode.getChildren();
                                for (var i = loopTokens.length - 1; i >= 0; i--) {
                                    if (pushKeywordIf(keywords, loopTokens[i], 98 /* WhileKeyword */)) {
                                        break;
                                    }
                                }
                            }
                        }
                        var breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement);
                        ts.forEach(breaksAndContinues, function (statement) {
                            if (ownsBreakOrContinueStatement(loopNode, statement)) {
                                pushKeywordIf(keywords, statement.getFirstToken(), 64 /* BreakKeyword */, 69 /* ContinueKeyword */);
                            }
                        });
                        return ts.map(keywords, getReferenceEntryFromNode);
                    }
                    function getSwitchCaseDefaultOccurrences(switchStatement) {
                        var keywords = [];
                        pushKeywordIf(keywords, switchStatement.getFirstToken(), 90 /* SwitchKeyword */);
                        ts.forEach(switchStatement.clauses, function (clause) {
                            pushKeywordIf(keywords, clause.getFirstToken(), 65 /* CaseKeyword */, 71 /* DefaultKeyword */);
                            var breaksAndContinues = aggregateAllBreakAndContinueStatements(clause);
                            ts.forEach(breaksAndContinues, function (statement) {
                                if (ownsBreakOrContinueStatement(switchStatement, statement)) {
                                    pushKeywordIf(keywords, statement.getFirstToken(), 64 /* BreakKeyword */);
                                }
                            });
                        });
                        return ts.map(keywords, getReferenceEntryFromNode);
                    }
                    function getBreakOrContinueStatementOccurences(breakOrContinueStatement) {
                        var owner = getBreakOrContinueOwner(breakOrContinueStatement);
                        if (owner) {
                            switch (owner.kind) {
                                case 170 /* ForStatement */:
                                case 171 /* ForInStatement */:
                                case 168 /* DoStatement */:
                                case 169 /* WhileStatement */:
                                    return getLoopBreakContinueOccurrences(owner);
                                case 176 /* SwitchStatement */:
                                    return getSwitchCaseDefaultOccurrences(owner);
                            }
                        }
                        return undefined;
                    }
                    function aggregateAllBreakAndContinueStatements(node) {
                        var statementAccumulator = [];
                        aggregate(node);
                        return statementAccumulator;
                        function aggregate(node) {
                            if (node.kind === 173 /* BreakStatement */ || node.kind === 172 /* ContinueStatement */) {
                                statementAccumulator.push(node);
                            }
                            else if (!ts.isAnyFunction(node)) {
                                ts.forEachChild(node, aggregate);
                            }
                        }
                        ;
                    }
                    function ownsBreakOrContinueStatement(owner, statement) {
                        var actualOwner = getBreakOrContinueOwner(statement);
                        return actualOwner && actualOwner === owner;
                    }
                    function getBreakOrContinueOwner(statement) {
                        for (var node = statement.parent; node; node = node.parent) {
                            switch (node.kind) {
                                case 176 /* SwitchStatement */:
                                    if (statement.kind === 172 /* ContinueStatement */) {
                                        continue;
                                    }
                                case 170 /* ForStatement */:
                                case 171 /* ForInStatement */:
                                case 169 /* WhileStatement */:
                                case 168 /* DoStatement */:
                                    if (!statement.label || isLabeledBy(node, statement.label.text)) {
                                        return node;
                                    }
                                    break;
                                default:
                                    if (ts.isAnyFunction(node)) {
                                        return undefined;
                                    }
                                    break;
                            }
                        }
                        return undefined;
                    }
                    function getConstructorOccurrences(constructorDeclaration) {
                        var declarations = constructorDeclaration.symbol.getDeclarations();
                        var keywords = [];
                        ts.forEach(declarations, function (declaration) {
                            ts.forEach(declaration.getChildren(), function (token) {
                                return pushKeywordIf(keywords, token, 111 /* ConstructorKeyword */);
                            });
                        });
                        return ts.map(keywords, getReferenceEntryFromNode);
                    }
                    function getGetAndSetOccurrences(accessorDeclaration) {
                        var keywords = [];
                        tryPushAccessorKeyword(accessorDeclaration.symbol, 128 /* GetAccessor */);
                        tryPushAccessorKeyword(accessorDeclaration.symbol, 129 /* SetAccessor */);
                        return ts.map(keywords, getReferenceEntryFromNode);
                        function tryPushAccessorKeyword(accessorSymbol, accessorKind) {
                            var accessor = ts.getDeclarationOfKind(accessorSymbol, accessorKind);
                            if (accessor) {
                                ts.forEach(accessor.getChildren(), function (child) { return pushKeywordIf(keywords, child, 113 /* GetKeyword */, 117 /* SetKeyword */); });
                            }
                        }
                    }
                    function getModifierOccurrences(modifier, declaration) {
                        var container = declaration.parent;
                        if (declaration.flags & 112 /* AccessibilityModifier */) {
                            if (!(container.kind === 189 /* ClassDeclaration */ || (declaration.kind === 124 /* Parameter */ && hasKind(container, 127 /* Constructor */)))) {
                                return undefined;
                            }
                        }
                        else if (declaration.flags & 128 /* Static */) {
                            if (container.kind !== 189 /* ClassDeclaration */) {
                                return undefined;
                            }
                        }
                        else if (declaration.flags & (1 /* Export */ | 2 /* Ambient */)) {
                            if (!(container.kind === 194 /* ModuleBlock */ || container.kind === 198 /* SourceFile */)) {
                                return undefined;
                            }
                        }
                        var keywords = [];
                        var modifierFlag = getFlagFromModifier(modifier);
                        var nodes;
                        switch (container.kind) {
                            case 194 /* ModuleBlock */:
                            case 198 /* SourceFile */:
                                nodes = container.statements;
                                break;
                            case 127 /* Constructor */:
                                nodes = container.parameters.concat(container.parent.members);
                                break;
                            case 189 /* ClassDeclaration */:
                                nodes = container.members;
                                if (modifierFlag & 112 /* AccessibilityModifier */) {
                                    var constructor = ts.forEach(container.members, function (member) {
                                        return member.kind === 127 /* Constructor */ && member;
                                    });
                                    if (constructor) {
                                        nodes = nodes.concat(constructor.parameters);
                                    }
                                }
                                break;
                            default:
                                ts.Debug.fail("Invalid container kind.");
                        }
                        ts.forEach(nodes, function (node) {
                            if (node.flags & modifierFlag) {
                                ts.forEach(node.getChildren(), function (child) { return pushKeywordIf(keywords, child, modifier); });
                            }
                        });
                        return ts.map(keywords, getReferenceEntryFromNode);
                        function getFlagFromModifier(modifier) {
                            switch (modifier) {
                                case 106 /* PublicKeyword */:
                                    return 16 /* Public */;
                                case 104 /* PrivateKeyword */:
                                    return 32 /* Private */;
                                case 105 /* ProtectedKeyword */:
                                    return 64 /* Protected */;
                                case 107 /* StaticKeyword */:
                                    return 128 /* Static */;
                                case 76 /* ExportKeyword */:
                                    return 1 /* Export */;
                                case 112 /* DeclareKeyword */:
                                    return 2 /* Ambient */;
                                default:
                                    ts.Debug.fail();
                            }
                        }
                    }
                    function hasKind(node, kind) {
                        return node !== undefined && node.kind === kind;
                    }
                    function parent(node) {
                        return node && node.parent;
                    }
                    function pushKeywordIf(keywordList, token) {
                        var expected = [];
                        for (var _i = 2; _i < arguments.length; _i++) {
                            expected[_i - 2] = arguments[_i];
                        }
                        if (token && ts.contains(expected, token.kind)) {
                            keywordList.push(token);
                            return true;
                        }
                        return false;
                    }
                }
                function findRenameLocations(fileName, position, findInStrings, findInComments) {
                    return findReferences(fileName, position, findInStrings, findInComments);
                }
                function getReferencesAtPosition(fileName, position) {
                    return findReferences(fileName, position, false, false);
                }
                function findReferences(fileName, position, findInStrings, findInComments) {
                    synchronizeHostData();
                    fileName = ts.normalizeSlashes(fileName);
                    var sourceFile = getSourceFile(fileName);
                    var node = ts.getTouchingPropertyName(sourceFile, position);
                    if (!node) {
                        return undefined;
                    }
                    if (node.kind !== 63 /* Identifier */ && !isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && !isNameOfExternalModuleImportOrDeclaration(node)) {
                        return undefined;
                    }
                    ts.Debug.assert(node.kind === 63 /* Identifier */ || node.kind === 6 /* NumericLiteral */ || node.kind === 7 /* StringLiteral */);
                    return getReferencesForNode(node, program.getSourceFiles(), findInStrings, findInComments);
                }
                function getReferencesForNode(node, sourceFiles, findInStrings, findInComments) {
                    if (isLabelName(node)) {
                        if (isJumpStatementTarget(node)) {
                            var labelDefinition = getTargetLabel(node.parent, node.text);
                            return labelDefinition ? getLabelReferencesInNode(labelDefinition.parent, labelDefinition) : [getReferenceEntryFromNode(node)];
                        }
                        else {
                            return getLabelReferencesInNode(node.parent, node);
                        }
                    }
                    if (node.kind === 91 /* ThisKeyword */) {
                        return getReferencesForThisKeyword(node, sourceFiles);
                    }
                    if (node.kind === 89 /* SuperKeyword */) {
                        return getReferencesForSuperKeyword(node);
                    }
                    var symbol = typeInfoResolver.getSymbolInfo(node);
                    if (!symbol) {
                        return [getReferenceEntryFromNode(node)];
                    }
                    var declarations = symbol.declarations;
                    if (!declarations || !declarations.length) {
                        return undefined;
                    }
                    var result;
                    var searchMeaning = getIntersectingMeaningFromDeclarations(getMeaningFromLocation(node), declarations);
                    var declaredName = getDeclaredName(symbol);
                    var scope = getSymbolScope(symbol);
                    if (scope) {
                        result = [];
                        getReferencesInNode(scope, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result);
                    }
                    else {
                        var internedName = getInternedName(symbol, declarations);
                        ts.forEach(sourceFiles, function (sourceFile) {
                            cancellationToken.throwIfCancellationRequested();
                            if (ts.lookUp(sourceFile.identifiers, internedName)) {
                                result = result || [];
                                getReferencesInNode(sourceFile, symbol, declaredName, node, searchMeaning, findInStrings, findInComments, result);
                            }
                        });
                    }
                    return result;
                    function getDeclaredName(symbol) {
                        var name = typeInfoResolver.symbolToString(symbol);
                        return stripQuotes(name);
                    }
                    function getInternedName(symbol, declarations) {
                        var functionExpression = ts.forEach(declarations, function (d) { return d.kind === 153 /* FunctionExpression */ ? d : undefined; });
                        if (functionExpression && functionExpression.name) {
                            var name = functionExpression.name.text;
                        }
                        else {
                            var name = symbol.name;
                        }
                        return stripQuotes(name);
                    }
                    function stripQuotes(name) {
                        var length = name.length;
                        if (length >= 2 && name.charCodeAt(0) === 34 /* doubleQuote */ && name.charCodeAt(length - 1) === 34 /* doubleQuote */) {
                            return name.substring(1, length - 1);
                        }
                        ;
                        return name;
                    }
                    function getSymbolScope(symbol) {
                        if (symbol.getFlags() && (4 /* Property */ | 8192 /* Method */)) {
                            var privateDeclaration = ts.forEach(symbol.getDeclarations(), function (d) { return (d.flags & 32 /* Private */) ? d : undefined; });
                            if (privateDeclaration) {
                                return ts.getAncestor(privateDeclaration, 189 /* ClassDeclaration */);
                            }
                        }
                        if (symbol.parent) {
                            return undefined;
                        }
                        var scope = undefined;
                        var declarations = symbol.getDeclarations();
                        if (declarations) {
                            for (var i = 0, n = declarations.length; i < n; i++) {
                                var container = getContainerNode(declarations[i]);
                                if (!container) {
                                    return undefined;
                                }
                                if (scope && scope !== container) {
                                    return undefined;
                                }
                                if (container.kind === 198 /* SourceFile */ && !ts.isExternalModule(container)) {
                                    return undefined;
                                }
                                scope = container;
                            }
                        }
                        return scope;
                    }
                    function getPossibleSymbolReferencePositions(sourceFile, symbolName, start, end) {
                        var positions = [];
                        if (!symbolName || !symbolName.length) {
                            return positions;
                        }
                        var text = sourceFile.text;
                        var sourceLength = text.length;
                        var symbolNameLength = symbolName.length;
                        var position = text.indexOf(symbolName, start);
                        while (position >= 0) {
                            cancellationToken.throwIfCancellationRequested();
                            if (position > end)
                                break;
                            var endPosition = position + symbolNameLength;
                            if ((position === 0 || !ts.isIdentifierPart(text.charCodeAt(position - 1), 2 /* Latest */)) && (endPosition === sourceLength || !ts.isIdentifierPart(text.charCodeAt(endPosition), 2 /* Latest */))) {
                                positions.push(position);
                            }
                            position = text.indexOf(symbolName, position + symbolNameLength + 1);
                        }
                        return positions;
                    }
                    function getLabelReferencesInNode(container, targetLabel) {
                        var result = [];
                        var sourceFile = container.getSourceFile();
                        var labelName = targetLabel.text;
                        var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container.getStart(), container.getEnd());
                        ts.forEach(possiblePositions, function (position) {
                            cancellationToken.throwIfCancellationRequested();
                            var node = ts.getTouchingWord(sourceFile, position);
                            if (!node || node.getWidth() !== labelName.length) {
                                return;
                            }
                            if (node === targetLabel || (isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel)) {
                                result.push(getReferenceEntryFromNode(node));
                            }
                        });
                        return result;
                    }
                    function isValidReferencePosition(node, searchSymbolName) {
                        if (node) {
                            switch (node.kind) {
                                case 63 /* Identifier */:
                                    return node.getWidth() === searchSymbolName.length;
                                case 7 /* StringLiteral */:
                                    if (isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) {
                                        return node.getWidth() === searchSymbolName.length + 2;
                                    }
                                    break;
                                case 6 /* NumericLiteral */:
                                    if (isLiteralNameOfPropertyDeclarationOrIndexAccess(node)) {
                                        return node.getWidth() === searchSymbolName.length;
                                    }
                                    break;
                            }
                        }
                        return false;
                    }
                    function getReferencesInNode(container, searchSymbol, searchText, searchLocation, searchMeaning, findInStrings, findInComments, result) {
                        var sourceFile = container.getSourceFile();
                        var tripleSlashDirectivePrefixRegex = /^\/\/\/\s*</;
                        var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, container.getStart(), container.getEnd());
                        if (possiblePositions.length) {
                            var searchSymbols = populateSearchSymbolSet(searchSymbol, searchLocation);
                            ts.forEach(possiblePositions, function (position) {
                                cancellationToken.throwIfCancellationRequested();
                                var referenceLocation = ts.getTouchingPropertyName(sourceFile, position);
                                if (!isValidReferencePosition(referenceLocation, searchText)) {
                                    if ((findInStrings && isInString(position)) || (findInComments && isInComment(position))) {
                                        result.push({
                                            fileName: sourceFile.filename,
                                            textSpan: new ts.TextSpan(position, searchText.length),
                                            isWriteAccess: false
                                        });
                                    }
                                    return;
                                }
                                if (!(getMeaningFromLocation(referenceLocation) & searchMeaning)) {
                                    return;
                                }
                                var referenceSymbol = typeInfoResolver.getSymbolInfo(referenceLocation);
                                if (referenceSymbol) {
                                    var referenceSymbolDeclaration = referenceSymbol.valueDeclaration;
                                    var shorthandValueSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(referenceSymbolDeclaration);
                                    if (isRelatableToSearchSet(searchSymbols, referenceSymbol, referenceLocation)) {
                                        result.push(getReferenceEntryFromNode(referenceLocation));
                                    }
                                    else if (!(referenceSymbol.flags & 268435456 /* Transient */) && searchSymbols.indexOf(shorthandValueSymbol) >= 0) {
                                        result.push(getReferenceEntryFromNode(referenceSymbolDeclaration.name));
                                    }
                                }
                            });
                        }
                        function isInString(position) {
                            var token = ts.getTokenAtPosition(sourceFile, position);
                            return token && token.kind === 7 /* StringLiteral */ && position > token.getStart();
                        }
                        function isInComment(position) {
                            var token = ts.getTokenAtPosition(sourceFile, position);
                            if (token && position < token.getStart()) {
                                var commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos);
                                return ts.forEach(commentRanges, function (c) {
                                    if (c.pos < position && position < c.end) {
                                        var commentText = sourceFile.text.substring(c.pos, c.end);
                                        if (!tripleSlashDirectivePrefixRegex.test(commentText)) {
                                            return true;
                                        }
                                    }
                                });
                            }
                            return false;
                        }
                    }
                    function getReferencesForSuperKeyword(superKeyword) {
                        var searchSpaceNode = ts.getSuperContainer(superKeyword);
                        if (!searchSpaceNode) {
                            return undefined;
                        }
                        var staticFlag = 128 /* Static */;
                        switch (searchSpaceNode.kind) {
                            case 125 /* Property */:
                            case 126 /* Method */:
                            case 127 /* Constructor */:
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                                staticFlag &= searchSpaceNode.flags;
                                searchSpaceNode = searchSpaceNode.parent;
                                break;
                            default:
                                return undefined;
                        }
                        var result = [];
                        var sourceFile = searchSpaceNode.getSourceFile();
                        var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode.getStart(), searchSpaceNode.getEnd());
                        ts.forEach(possiblePositions, function (position) {
                            cancellationToken.throwIfCancellationRequested();
                            var node = ts.getTouchingWord(sourceFile, position);
                            if (!node || node.kind !== 89 /* SuperKeyword */) {
                                return;
                            }
                            var container = ts.getSuperContainer(node);
                            if (container && (128 /* Static */ & container.flags) === staticFlag && container.parent.symbol === searchSpaceNode.symbol) {
                                result.push(getReferenceEntryFromNode(node));
                            }
                        });
                        return result;
                    }
                    function getReferencesForThisKeyword(thisOrSuperKeyword, sourceFiles) {
                        var searchSpaceNode = ts.getThisContainer(thisOrSuperKeyword, false);
                        var staticFlag = 128 /* Static */;
                        switch (searchSpaceNode.kind) {
                            case 125 /* Property */:
                            case 126 /* Method */:
                            case 127 /* Constructor */:
                            case 128 /* GetAccessor */:
                            case 129 /* SetAccessor */:
                                staticFlag &= searchSpaceNode.flags;
                                searchSpaceNode = searchSpaceNode.parent;
                                break;
                            case 198 /* SourceFile */:
                                if (ts.isExternalModule(searchSpaceNode)) {
                                    return undefined;
                                }
                            case 187 /* FunctionDeclaration */:
                            case 153 /* FunctionExpression */:
                                break;
                            default:
                                return undefined;
                        }
                        var result = [];
                        if (searchSpaceNode.kind === 198 /* SourceFile */) {
                            ts.forEach(sourceFiles, function (sourceFile) {
                                var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", sourceFile.getStart(), sourceFile.getEnd());
                                getThisReferencesInFile(sourceFile, sourceFile, possiblePositions, result);
                            });
                        }
                        else {
                            var sourceFile = searchSpaceNode.getSourceFile();
                            var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode.getStart(), searchSpaceNode.getEnd());
                            getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, result);
                        }
                        return result;
                        function getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, result) {
                            ts.forEach(possiblePositions, function (position) {
                                cancellationToken.throwIfCancellationRequested();
                                var node = ts.getTouchingWord(sourceFile, position);
                                if (!node || node.kind !== 91 /* ThisKeyword */) {
                                    return;
                                }
                                var container = ts.getThisContainer(node, false);
                                switch (searchSpaceNode.kind) {
                                    case 153 /* FunctionExpression */:
                                    case 187 /* FunctionDeclaration */:
                                        if (searchSpaceNode.symbol === container.symbol) {
                                            result.push(getReferenceEntryFromNode(node));
                                        }
                                        break;
                                    case 189 /* ClassDeclaration */:
                                        if (container.parent && searchSpaceNode.symbol === container.parent.symbol && (container.flags & 128 /* Static */) === staticFlag) {
                                            result.push(getReferenceEntryFromNode(node));
                                        }
                                        break;
                                    case 198 /* SourceFile */:
                                        if (container.kind === 198 /* SourceFile */ && !ts.isExternalModule(container)) {
                                            result.push(getReferenceEntryFromNode(node));
                                        }
                                        break;
                                }
                            });
                        }
                    }
                    function populateSearchSymbolSet(symbol, location) {
                        var result = [symbol];
                        if (isNameOfPropertyAssignment(location)) {
                            ts.forEach(getPropertySymbolsFromContextualType(location), function (contextualSymbol) {
                                result.push.apply(result, typeInfoResolver.getRootSymbols(contextualSymbol));
                            });
                            var shorthandValueSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(location.parent);
                            if (shorthandValueSymbol) {
                                result.push(shorthandValueSymbol);
                            }
                        }
                        ts.forEach(typeInfoResolver.getRootSymbols(symbol), function (rootSymbol) {
                            if (rootSymbol !== symbol) {
                                result.push(rootSymbol);
                            }
                            if (rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */)) {
                                getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result);
                            }
                        });
                        return result;
                    }
                    function getPropertySymbolsFromBaseTypes(symbol, propertyName, result) {
                        if (symbol && symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                            ts.forEach(symbol.getDeclarations(), function (declaration) {
                                if (declaration.kind === 189 /* ClassDeclaration */) {
                                    getPropertySymbolFromTypeReference(declaration.baseType);
                                    ts.forEach(declaration.implementedTypes, getPropertySymbolFromTypeReference);
                                }
                                else if (declaration.kind === 190 /* InterfaceDeclaration */) {
                                    ts.forEach(declaration.baseTypes, getPropertySymbolFromTypeReference);
                                }
                            });
                        }
                        return;
                        function getPropertySymbolFromTypeReference(typeReference) {
                            if (typeReference) {
                                var type = typeInfoResolver.getTypeOfNode(typeReference);
                                if (type) {
                                    var propertySymbol = typeInfoResolver.getPropertyOfType(type, propertyName);
                                    if (propertySymbol) {
                                        result.push(propertySymbol);
                                    }
                                    getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result);
                                }
                            }
                        }
                    }
                    function isRelatableToSearchSet(searchSymbols, referenceSymbol, referenceLocation) {
                        if (searchSymbols.indexOf(referenceSymbol) >= 0) {
                            return true;
                        }
                        if (isNameOfPropertyAssignment(referenceLocation)) {
                            return ts.forEach(getPropertySymbolsFromContextualType(referenceLocation), function (contextualSymbol) {
                                return ts.forEach(typeInfoResolver.getRootSymbols(contextualSymbol), function (s) { return searchSymbols.indexOf(s) >= 0; });
                            });
                        }
                        return ts.forEach(typeInfoResolver.getRootSymbols(referenceSymbol), function (rootSymbol) {
                            if (searchSymbols.indexOf(rootSymbol) >= 0) {
                                return true;
                            }
                            if (rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */)) {
                                var result = [];
                                getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.getName(), result);
                                return ts.forEach(result, function (s) { return searchSymbols.indexOf(s) >= 0; });
                            }
                            return false;
                        });
                    }
                    function getPropertySymbolsFromContextualType(node) {
                        if (isNameOfPropertyAssignment(node)) {
                            var objectLiteral = node.parent.parent;
                            var contextualType = typeInfoResolver.getContextualType(objectLiteral);
                            var name = node.text;
                            if (contextualType) {
                                if (contextualType.flags & 16384 /* Union */) {
                                    var unionProperty = contextualType.getProperty(name);
                                    if (unionProperty) {
                                        return [unionProperty];
                                    }
                                    else {
                                        var result = [];
                                        ts.forEach(contextualType.types, function (t) {
                                            var symbol = t.getProperty(name);
                                            if (symbol) {
                                                result.push(symbol);
                                            }
                                        });
                                        return result;
                                    }
                                }
                                else {
                                    var symbol = contextualType.getProperty(name);
                                    if (symbol) {
                                        return [symbol];
                                    }
                                }
                            }
                        }
                        return undefined;
                    }
                    function getIntersectingMeaningFromDeclarations(meaning, declarations) {
                        if (declarations) {
                            do {
                                var lastIterationMeaning = meaning;
                                for (var i = 0, n = declarations.length; i < n; i++) {
                                    var declarationMeaning = getMeaningFromDeclaration(declarations[i]);
                                    if (declarationMeaning & meaning) {
                                        meaning |= declarationMeaning;
                                    }
                                }
                            } while (meaning !== lastIterationMeaning);
                        }
                        return meaning;
                    }
                }
                function getReferenceEntryFromNode(node) {
                    var start = node.getStart();
                    var end = node.getEnd();
                    if (node.kind === 7 /* StringLiteral */) {
                        start += 1;
                        end -= 1;
                    }
                    return {
                        fileName: node.getSourceFile().filename,
                        textSpan: ts.TextSpan.fromBounds(start, end),
                        isWriteAccess: isWriteAccess(node)
                    };
                }
                function isWriteAccess(node) {
                    if (node.kind === 63 /* Identifier */ && ts.isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
                        return true;
                    }
                    var parent = node.parent;
                    if (parent) {
                        if (parent.kind === 156 /* PostfixOperator */ || parent.kind === 155 /* PrefixOperator */) {
                            return true;
                        }
                        else if (parent.kind === 157 /* BinaryExpression */ && parent.left === node) {
                            var operator = parent.operator;
                            return 51 /* FirstAssignment */ <= operator && operator <= 62 /* LastAssignment */;
                        }
                    }
                    return false;
                }
                function getNavigateToItems(searchValue) {
                    synchronizeHostData();
                    var terms = searchValue.split(" ");
                    var searchTerms = ts.map(terms, function (t) { return ({ caseSensitive: hasAnyUpperCaseCharacter(t), term: t }); });
                    var items = [];
                    ts.forEach(program.getSourceFiles(), function (sourceFile) {
                        cancellationToken.throwIfCancellationRequested();
                        var filename = sourceFile.filename;
                        var declarations = sourceFile.getNamedDeclarations();
                        for (var i = 0, n = declarations.length; i < n; i++) {
                            var declaration = declarations[i];
                            var name = declaration.name.text;
                            var matchKind = getMatchKind(searchTerms, name);
                            if (matchKind !== 0 /* none */) {
                                var container = getContainerNode(declaration);
                                items.push({
                                    name: name,
                                    kind: getNodeKind(declaration),
                                    kindModifiers: getNodeModifiers(declaration),
                                    matchKind: MatchKind[matchKind],
                                    fileName: filename,
                                    textSpan: ts.TextSpan.fromBounds(declaration.getStart(), declaration.getEnd()),
                                    containerName: container && container.name ? container.name.text : "",
                                    containerKind: container && container.name ? getNodeKind(container) : ""
                                });
                            }
                        }
                    });
                    return items;
                    function hasAnyUpperCaseCharacter(s) {
                        for (var i = 0, n = s.length; i < n; i++) {
                            var c = s.charCodeAt(i);
                            if ((65 /* A */ <= c && c <= 90 /* Z */) || (c >= 127 /* maxAsciiCharacter */ && s.charAt(i).toLocaleLowerCase() !== s.charAt(i))) {
                                return true;
                            }
                        }
                        return false;
                    }
                    function getMatchKind(searchTerms, name) {
                        var matchKind = 0 /* none */;
                        if (name) {
                            for (var j = 0, n = searchTerms.length; j < n; j++) {
                                var searchTerm = searchTerms[j];
                                var nameToSearch = searchTerm.caseSensitive ? name : name.toLocaleLowerCase();
                                var index = nameToSearch.indexOf(searchTerm.term);
                                if (index < 0) {
                                    return 0 /* none */;
                                }
                                var termKind = 2 /* substring */;
                                if (index === 0) {
                                    termKind = name.length === searchTerm.term.length ? 1 /* exact */ : 3 /* prefix */;
                                }
                                if (matchKind === 0 /* none */ || termKind < matchKind) {
                                    matchKind = termKind;
                                }
                            }
                        }
                        return matchKind;
                    }
                }
                function containErrors(diagnostics) {
                    return ts.forEach(diagnostics, function (diagnostic) { return diagnostic.category === 1 /* Error */; });
                }
                function getEmitOutput(filename) {
                    synchronizeHostData();
                    filename = ts.normalizeSlashes(filename);
                    var compilerOptions = program.getCompilerOptions();
                    var targetSourceFile = program.getSourceFile(filename);
                    var shouldEmitToOwnFile = ts.shouldEmitToOwnFile(targetSourceFile, compilerOptions);
                    var emitOutput = {
                        outputFiles: [],
                        emitOutputStatus: undefined
                    };
                    function getEmitOutputWriter(filename, data, writeByteOrderMark) {
                        emitOutput.outputFiles.push({
                            name: filename,
                            writeByteOrderMark: writeByteOrderMark,
                            text: data
                        });
                    }
                    writer = getEmitOutputWriter;
                    var containSyntacticErrors = false;
                    if (shouldEmitToOwnFile) {
                        containSyntacticErrors = containErrors(program.getDiagnostics(targetSourceFile));
                    }
                    else {
                        containSyntacticErrors = ts.forEach(program.getSourceFiles(), function (sourceFile) {
                            if (!ts.isExternalModuleOrDeclarationFile(sourceFile)) {
                                return containErrors(program.getDiagnostics(sourceFile));
                            }
                            return false;
                        });
                    }
                    if (containSyntacticErrors) {
                        emitOutput.emitOutputStatus = 1 /* AllOutputGenerationSkipped */;
                        writer = undefined;
                        return emitOutput;
                    }
                    var emitFilesResult = getFullTypeCheckChecker().emitFiles(targetSourceFile);
                    emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus;
                    writer = undefined;
                    return emitOutput;
                }
                function getMeaningFromDeclaration(node) {
                    switch (node.kind) {
                        case 124 /* Parameter */:
                        case 186 /* VariableDeclaration */:
                        case 125 /* Property */:
                        case 144 /* PropertyAssignment */:
                        case 145 /* ShorthandPropertyAssignment */:
                        case 197 /* EnumMember */:
                        case 126 /* Method */:
                        case 127 /* Constructor */:
                        case 128 /* GetAccessor */:
                        case 129 /* SetAccessor */:
                        case 187 /* FunctionDeclaration */:
                        case 153 /* FunctionExpression */:
                        case 154 /* ArrowFunction */:
                        case 183 /* CatchBlock */:
                            return 1 /* Value */;
                        case 123 /* TypeParameter */:
                        case 190 /* InterfaceDeclaration */:
                        case 191 /* TypeAliasDeclaration */:
                        case 137 /* TypeLiteral */:
                            return 2 /* Type */;
                        case 189 /* ClassDeclaration */:
                        case 192 /* EnumDeclaration */:
                            return 1 /* Value */ | 2 /* Type */;
                        case 193 /* ModuleDeclaration */:
                            if (node.name.kind === 7 /* StringLiteral */) {
                                return 4 /* Namespace */ | 1 /* Value */;
                            }
                            else if (ts.getModuleInstanceState(node) === 1 /* Instantiated */) {
                                return 4 /* Namespace */ | 1 /* Value */;
                            }
                            else {
                                return 4 /* Namespace */;
                            }
                        case 195 /* ImportDeclaration */:
                            return 1 /* Value */ | 2 /* Type */ | 4 /* Namespace */;
                        case 198 /* SourceFile */:
                            return 4 /* Namespace */ | 1 /* Value */;
                    }
                    ts.Debug.fail("Unknown declaration type");
                }
                function isTypeReference(node) {
                    if (isRightSideOfQualifiedName(node)) {
                        node = node.parent;
                    }
                    return node.parent.kind === 133 /* TypeReference */;
                }
                function isNamespaceReference(node) {
                    var root = node;
                    var isLastClause = true;
                    if (root.parent.kind === 121 /* QualifiedName */) {
                        while (root.parent && root.parent.kind === 121 /* QualifiedName */)
                            root = root.parent;
                        isLastClause = root.right === node;
                    }
                    return root.parent.kind === 133 /* TypeReference */ && !isLastClause;
                }
                function isInRightSideOfImport(node) {
                    while (node.parent.kind === 121 /* QualifiedName */) {
                        node = node.parent;
                    }
                    return node.parent.kind === 195 /* ImportDeclaration */ && node.parent.entityName === node;
                }
                function getMeaningFromRightHandSideOfImport(node) {
                    ts.Debug.assert(node.kind === 63 /* Identifier */);
                    if (node.parent.kind === 121 /* QualifiedName */ && node.parent.right === node && node.parent.parent.kind === 195 /* ImportDeclaration */) {
                        return 1 /* Value */ | 2 /* Type */ | 4 /* Namespace */;
                    }
                    return 4 /* Namespace */;
                }
                function getMeaningFromLocation(node) {
                    if (node.parent.kind === 196 /* ExportAssignment */) {
                        return 1 /* Value */ | 2 /* Type */ | 4 /* Namespace */;
                    }
                    else if (isInRightSideOfImport(node)) {
                        return getMeaningFromRightHandSideOfImport(node);
                    }
                    else if (ts.isDeclarationOrFunctionExpressionOrCatchVariableName(node)) {
                        return getMeaningFromDeclaration(node.parent);
                    }
                    else if (isTypeReference(node)) {
                        return 2 /* Type */;
                    }
                    else if (isNamespaceReference(node)) {
                        return 4 /* Namespace */;
                    }
                    else {
                        return 1 /* Value */;
                    }
                }
                function getSignatureHelpItems(fileName, position) {
                    synchronizeHostData();
                    fileName = ts.normalizeSlashes(fileName);
                    var sourceFile = getSourceFile(fileName);
                    return ts.SignatureHelp.getSignatureHelpItems(sourceFile, position, typeInfoResolver, cancellationToken);
                }
                function getCurrentSourceFile(filename) {
                    filename = ts.normalizeSlashes(filename);
                    var currentSourceFile = syntaxTreeCache.getCurrentSourceFile(filename);
                    return currentSourceFile;
                }
                function getNameOrDottedNameSpan(filename, startPos, endPos) {
                    filename = ts.normalizeSlashes(filename);
                    var node = ts.getTouchingPropertyName(getCurrentSourceFile(filename), startPos);
                    if (!node) {
                        return;
                    }
                    switch (node.kind) {
                        case 146 /* PropertyAccess */:
                        case 121 /* QualifiedName */:
                        case 7 /* StringLiteral */:
                        case 78 /* FalseKeyword */:
                        case 93 /* TrueKeyword */:
                        case 87 /* NullKeyword */:
                        case 89 /* SuperKeyword */:
                        case 91 /* ThisKeyword */:
                        case 63 /* Identifier */:
                            break;
                        default:
                            return;
                    }
                    var nodeForStartPos = node;
                    while (true) {
                        if (isRightSideOfPropertyAccess(nodeForStartPos) || isRightSideOfQualifiedName(nodeForStartPos)) {
                            nodeForStartPos = nodeForStartPos.parent;
                        }
                        else if (isNameOfModuleDeclaration(nodeForStartPos)) {
                            if (nodeForStartPos.parent.parent.kind === 193 /* ModuleDeclaration */ && nodeForStartPos.parent.parent.body === nodeForStartPos.parent) {
                                nodeForStartPos = nodeForStartPos.parent.parent.name;
                            }
                            else {
                                break;
                            }
                        }
                        else {
                            break;
                        }
                    }
                    return ts.TextSpan.fromBounds(nodeForStartPos.getStart(), node.getEnd());
                }
                function getBreakpointStatementAtPosition(filename, position) {
                    filename = ts.normalizeSlashes(filename);
                    return ts.BreakpointResolver.spanInSourceFileAtLocation(getCurrentSourceFile(filename), position);
                }
                function getNavigationBarItems(filename) {
                    filename = ts.normalizeSlashes(filename);
                    return ts.NavigationBar.getNavigationBarItems(getCurrentSourceFile(filename));
                }
                function getSemanticClassifications(fileName, span) {
                    synchronizeHostData();
                    fileName = ts.normalizeSlashes(fileName);
                    var sourceFile = getSourceFile(fileName);
                    var result = [];
                    processNode(sourceFile);
                    return result;
                    function classifySymbol(symbol, meaningAtPosition) {
                        var flags = symbol.getFlags();
                        if (flags & 32 /* Class */) {
                            return ClassificationTypeNames.className;
                        }
                        else if (flags & 384 /* Enum */) {
                            return ClassificationTypeNames.enumName;
                        }
                        else if (meaningAtPosition & 2 /* Type */) {
                            if (flags & 64 /* Interface */) {
                                return ClassificationTypeNames.interfaceName;
                            }
                            else if (flags & 1048576 /* TypeParameter */) {
                                return ClassificationTypeNames.typeParameterName;
                            }
                        }
                        else if (flags & 1536 /* Module */) {
                            if (meaningAtPosition & 4 /* Namespace */ || (meaningAtPosition & 1 /* Value */ && hasValueSideModule(symbol))) {
                                return ClassificationTypeNames.moduleName;
                            }
                        }
                        return undefined;
                        function hasValueSideModule(symbol) {
                            return ts.forEach(symbol.declarations, function (declaration) {
                                return declaration.kind === 193 /* ModuleDeclaration */ && ts.getModuleInstanceState(declaration) == 1 /* Instantiated */;
                            });
                        }
                    }
                    function processNode(node) {
                        if (node && span.intersectsWith(node.getStart(), node.getWidth())) {
                            if (node.kind === 63 /* Identifier */ && node.getWidth() > 0) {
                                var symbol = typeInfoResolver.getSymbolInfo(node);
                                if (symbol) {
                                    var type = classifySymbol(symbol, getMeaningFromLocation(node));
                                    if (type) {
                                        result.push({
                                            textSpan: new ts.TextSpan(node.getStart(), node.getWidth()),
                                            classificationType: type
                                        });
                                    }
                                }
                            }
                            ts.forEachChild(node, processNode);
                        }
                    }
                }
                function getSyntacticClassifications(fileName, span) {
                    fileName = ts.normalizeSlashes(fileName);
                    var sourceFile = getCurrentSourceFile(fileName);
                    var result = [];
                    processElement(sourceFile);
                    return result;
                    function classifyComment(comment) {
                        var width = comment.end - comment.pos;
                        if (span.intersectsWith(comment.pos, width)) {
                            result.push({
                                textSpan: new ts.TextSpan(comment.pos, width),
                                classificationType: ClassificationTypeNames.comment
                            });
                        }
                    }
                    function classifyToken(token) {
                        ts.forEach(ts.getLeadingCommentRanges(sourceFile.text, token.getFullStart()), classifyComment);
                        if (token.getWidth() > 0) {
                            var type = classifyTokenType(token);
                            if (type) {
                                result.push({
                                    textSpan: new ts.TextSpan(token.getStart(), token.getWidth()),
                                    classificationType: type
                                });
                            }
                        }
                        ts.forEach(ts.getTrailingCommentRanges(sourceFile.text, token.getEnd()), classifyComment);
                    }
                    function classifyTokenType(token) {
                        var tokenKind = token.kind;
                        if (ts.isKeyword(tokenKind)) {
                            return ClassificationTypeNames.keyword;
                        }
                        if (tokenKind === 23 /* LessThanToken */ || tokenKind === 24 /* GreaterThanToken */) {
                            if (ts.getTypeArgumentOrTypeParameterList(token.parent)) {
                                return ClassificationTypeNames.punctuation;
                            }
                        }
                        if (ts.isPunctuation(token.kind)) {
                            if (token.parent.kind === 157 /* BinaryExpression */ || token.parent.kind === 186 /* VariableDeclaration */ || token.parent.kind === 155 /* PrefixOperator */ || token.parent.kind === 156 /* PostfixOperator */ || token.parent.kind === 158 /* ConditionalExpression */) {
                                return ClassificationTypeNames.operator;
                            }
                            else {
                                return ClassificationTypeNames.punctuation;
                            }
                        }
                        else if (tokenKind === 6 /* NumericLiteral */) {
                            return ClassificationTypeNames.numericLiteral;
                        }
                        else if (tokenKind === 7 /* StringLiteral */) {
                            return ClassificationTypeNames.stringLiteral;
                        }
                        else if (tokenKind === 8 /* RegularExpressionLiteral */) {
                            return ClassificationTypeNames.stringLiteral;
                        }
                        else if (ts.isTemplateLiteralKind(tokenKind)) {
                            return ClassificationTypeNames.stringLiteral;
                        }
                        else if (tokenKind === 63 /* Identifier */) {
                            switch (token.parent.kind) {
                                case 189 /* ClassDeclaration */:
                                    if (token.parent.name === token) {
                                        return ClassificationTypeNames.className;
                                    }
                                    return;
                                case 123 /* TypeParameter */:
                                    if (token.parent.name === token) {
                                        return ClassificationTypeNames.typeParameterName;
                                    }
                                    return;
                                case 190 /* InterfaceDeclaration */:
                                    if (token.parent.name === token) {
                                        return ClassificationTypeNames.interfaceName;
                                    }
                                    return;
                                case 192 /* EnumDeclaration */:
                                    if (token.parent.name === token) {
                                        return ClassificationTypeNames.enumName;
                                    }
                                    return;
                                case 193 /* ModuleDeclaration */:
                                    if (token.parent.name === token) {
                                        return ClassificationTypeNames.moduleName;
                                    }
                                    return;
                                default:
                                    return ClassificationTypeNames.text;
                            }
                        }
                    }
                    function processElement(element) {
                        if (span.intersectsWith(element.getFullStart(), element.getFullWidth())) {
                            var children = element.getChildren();
                            for (var i = 0, n = children.length; i < n; i++) {
                                var child = children[i];
                                if (ts.isToken(child)) {
                                    classifyToken(child);
                                }
                                else {
                                    processElement(child);
                                }
                            }
                        }
                    }
                }
                function getOutliningSpans(filename) {
                    filename = ts.normalizeSlashes(filename);
                    var sourceFile = getCurrentSourceFile(filename);
                    return ts.OutliningElementsCollector.collectElements(sourceFile);
                }
                function getBraceMatchingAtPosition(filename, position) {
                    var sourceFile = getCurrentSourceFile(filename);
                    var result = [];
                    var token = ts.getTouchingToken(sourceFile, position);
                    if (token.getStart(sourceFile) === position) {
                        var matchKind = getMatchingTokenKind(token);
                        if (matchKind) {
                            var parentElement = token.parent;
                            var childNodes = parentElement.getChildren(sourceFile);
                            for (var i = 0, n = childNodes.length; i < n; i++) {
                                33;
                                var current = childNodes[i];
                                if (current.kind === matchKind) {
                                    var range1 = new ts.TextSpan(token.getStart(sourceFile), token.getWidth(sourceFile));
                                    var range2 = new ts.TextSpan(current.getStart(sourceFile), current.getWidth(sourceFile));
                                    if (range1.start() < range2.start()) {
                                        result.push(range1, range2);
                                    }
                                    else {
                                        result.push(range2, range1);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    return result;
                    function getMatchingTokenKind(token) {
                        switch (token.kind) {
                            case 13 /* OpenBraceToken */: return 14 /* CloseBraceToken */;
                            case 15 /* OpenParenToken */: return 16 /* CloseParenToken */;
                            case 17 /* OpenBracketToken */: return 18 /* CloseBracketToken */;
                            case 23 /* LessThanToken */: return 24 /* GreaterThanToken */;
                            case 14 /* CloseBraceToken */: return 13 /* OpenBraceToken */;
                            case 16 /* CloseParenToken */: return 15 /* OpenParenToken */;
                            case 18 /* CloseBracketToken */: return 17 /* OpenBracketToken */;
                            case 24 /* GreaterThanToken */: return 23 /* LessThanToken */;
                        }
                        return undefined;
                    }
                }
                function getIndentationAtPosition(filename, position, editorOptions) {
                    filename = ts.normalizeSlashes(filename);
                    var start = new Date().getTime();
                    var sourceFile = getCurrentSourceFile(filename);
                    host.log("getIndentationAtPosition: getCurrentSourceFile: " + (new Date().getTime() - start));
                    var start = new Date().getTime();
                    var result = ts.formatting.SmartIndenter.getIndentation(position, sourceFile, editorOptions);
                    host.log("getIndentationAtPosition: computeIndentation  : " + (new Date().getTime() - start));
                    return result;
                }
                function getFormattingEditsForRange(fileName, start, end, options) {
                    fileName = ts.normalizeSlashes(fileName);
                    var sourceFile = getCurrentSourceFile(fileName);
                    return ts.formatting.formatSelection(start, end, sourceFile, getRuleProvider(options), options);
                }
                function getFormattingEditsForDocument(fileName, options) {
                    fileName = ts.normalizeSlashes(fileName);
                    var sourceFile = getCurrentSourceFile(fileName);
                    return ts.formatting.formatDocument(sourceFile, getRuleProvider(options), options);
                }
                function getFormattingEditsAfterKeystroke(fileName, position, key, options) {
                    fileName = ts.normalizeSlashes(fileName);
                    var sourceFile = getCurrentSourceFile(fileName);
                    if (key === "}") {
                        return ts.formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(options), options);
                    }
                    else if (key === ";") {
                        return ts.formatting.formatOnSemicolon(position, sourceFile, getRuleProvider(options), options);
                    }
                    else if (key === "\n") {
                        return ts.formatting.formatOnEnter(position, sourceFile, getRuleProvider(options), options);
                    }
                    return [];
                }
                function getTodoComments(filename, descriptors) {
                    synchronizeHostData();
                    filename = ts.normalizeSlashes(filename);
                    var sourceFile = getSourceFile(filename);
                    cancellationToken.throwIfCancellationRequested();
                    var fileContents = sourceFile.text;
                    cancellationToken.throwIfCancellationRequested();
                    var result = [];
                    if (descriptors.length > 0) {
                        var regExp = getTodoCommentsRegExp();
                        var matchArray;
                        while (matchArray = regExp.exec(fileContents)) {
                            cancellationToken.throwIfCancellationRequested();
                            var firstDescriptorCaptureIndex = 3;
                            ts.Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex);
                            var preamble = matchArray[1];
                            var matchPosition = matchArray.index + preamble.length;
                            var token = ts.getTokenAtPosition(sourceFile, matchPosition);
                            if (!isInsideComment(sourceFile, token, matchPosition)) {
                                continue;
                            }
                            var descriptor = undefined;
                            for (var i = 0, n = descriptors.length; i < n; i++) {
                                if (matchArray[i + firstDescriptorCaptureIndex]) {
                                    descriptor = descriptors[i];
                                }
                            }
                            ts.Debug.assert(descriptor !== undefined);
                            if (isLetterOrDigit(fileContents.charCodeAt(matchPosition + descriptor.text.length))) {
                                continue;
                            }
                            var message = matchArray[2];
                            result.push({
                                descriptor: descriptor,
                                message: message,
                                position: matchPosition
                            });
                        }
                    }
                    return result;
                    function escapeRegExp(str) {
                        return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
                    }
                    function getTodoCommentsRegExp() {
                        var singleLineCommentStart = /(?:\/\/+\s*)/.source;
                        var multiLineCommentStart = /(?:\/\*+\s*)/.source;
                        var anyNumberOfSpacesAndAsterixesAtStartOfLine = /(?:^(?:\s|\*)*)/.source;
                        var preamble = "(" + anyNumberOfSpacesAndAsterixesAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")";
                        var literals = "(?:" + ts.map(descriptors, function (d) { return "(" + escapeRegExp(d.text) + ")"; }).join("|") + ")";
                        var endOfLineOrEndOfComment = /(?:$|\*\/)/.source;
                        var messageRemainder = /(?:.*?)/.source;
                        var messagePortion = "(" + literals + messageRemainder + ")";
                        var regExpString = preamble + messagePortion + endOfLineOrEndOfComment;
                        return new RegExp(regExpString, "gim");
                    }
                    function getContainingComment(comments, position) {
                        if (comments) {
                            for (var i = 0, n = comments.length; i < n; i++) {
                                var comment = comments[i];
                                if (comment.pos <= position && position < comment.end) {
                                    return comment;
                                }
                            }
                        }
                        return undefined;
                    }
                    function isLetterOrDigit(char) {
                        return (char >= 97 /* a */ && char <= 122 /* z */) || (char >= 65 /* A */ && char <= 90 /* Z */) || (char >= 48 /* _0 */ && char <= 57 /* _9 */);
                    }
                }
                function getRenameInfo(fileName, position) {
                    synchronizeHostData();
                    fileName = ts.normalizeSlashes(fileName);
                    var sourceFile = getSourceFile(fileName);
                    var node = ts.getTouchingWord(sourceFile, position);
                    if (node && node.kind === 63 /* Identifier */) {
                        var symbol = typeInfoResolver.getSymbolInfo(node);
                        if (symbol && symbol.getDeclarations() && symbol.getDeclarations().length > 0) {
                            var kind = getSymbolKind(symbol, typeInfoResolver);
                            if (kind) {
                                return getRenameInfo(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind, getSymbolModifiers(symbol), new ts.TextSpan(node.getStart(), node.getWidth()));
                            }
                        }
                    }
                    return getRenameInfoError(ts.getLocaleSpecificMessage(ts.Diagnostics.You_cannot_rename_this_element.key));
                    function getRenameInfoError(localizedErrorMessage) {
                        return {
                            canRename: false,
                            localizedErrorMessage: ts.getLocaleSpecificMessage(ts.Diagnostics.You_cannot_rename_this_element.key),
                            displayName: undefined,
                            fullDisplayName: undefined,
                            kind: undefined,
                            kindModifiers: undefined,
                            triggerSpan: undefined
                        };
                    }
                    function getRenameInfo(displayName, fullDisplayName, kind, kindModifiers, triggerSpan) {
                        return {
                            canRename: true,
                            localizedErrorMessage: undefined,
                            displayName: displayName,
                            fullDisplayName: fullDisplayName,
                            kind: kind,
                            kindModifiers: kindModifiers,
                            triggerSpan: triggerSpan
                        };
                    }
                }
                return {
                    dispose: dispose,
                    cleanupSemanticCache: cleanupSemanticCache,
                    getSyntacticDiagnostics: getSyntacticDiagnostics,
                    getSemanticDiagnostics: getSemanticDiagnostics,
                    getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics,
                    getSyntacticClassifications: getSyntacticClassifications,
                    getSemanticClassifications: getSemanticClassifications,
                    getCompletionsAtPosition: getCompletionsAtPosition,
                    getCompletionEntryDetails: getCompletionEntryDetails,
                    getSignatureHelpItems: getSignatureHelpItems,
                    getQuickInfoAtPosition: getQuickInfoAtPosition,
                    getDefinitionAtPosition: getDefinitionAtPosition,
                    getReferencesAtPosition: getReferencesAtPosition,
                    getOccurrencesAtPosition: getOccurrencesAtPosition,
                    getNameOrDottedNameSpan: getNameOrDottedNameSpan,
                    getBreakpointStatementAtPosition: getBreakpointStatementAtPosition,
                    getNavigateToItems: getNavigateToItems,
                    getRenameInfo: getRenameInfo,
                    findRenameLocations: findRenameLocations,
                    getNavigationBarItems: getNavigationBarItems,
                    getOutliningSpans: getOutliningSpans,
                    getTodoComments: getTodoComments,
                    getBraceMatchingAtPosition: getBraceMatchingAtPosition,
                    getIndentationAtPosition: getIndentationAtPosition,
                    getFormattingEditsForRange: getFormattingEditsForRange,
                    getFormattingEditsForDocument: getFormattingEditsForDocument,
                    getFormattingEditsAfterKeystroke: getFormattingEditsAfterKeystroke,
                    getEmitOutput: getEmitOutput,
                    getSourceFile: getCurrentSourceFile
                };
            }
            ts.createLanguageService = createLanguageService;
            function createClassifier(host) {
                var scanner = ts.createScanner(2 /* Latest */, false);
                var noRegexTable = [];
                noRegexTable[63 /* Identifier */] = true;
                noRegexTable[7 /* StringLiteral */] = true;
                noRegexTable[6 /* NumericLiteral */] = true;
                noRegexTable[8 /* RegularExpressionLiteral */] = true;
                noRegexTable[91 /* ThisKeyword */] = true;
                noRegexTable[37 /* PlusPlusToken */] = true;
                noRegexTable[38 /* MinusMinusToken */] = true;
                noRegexTable[16 /* CloseParenToken */] = true;
                noRegexTable[18 /* CloseBracketToken */] = true;
                noRegexTable[14 /* CloseBraceToken */] = true;
                noRegexTable[93 /* TrueKeyword */] = true;
                noRegexTable[78 /* FalseKeyword */] = true;
                function isAccessibilityModifier(kind) {
                    switch (kind) {
                        case 106 /* PublicKeyword */:
                        case 104 /* PrivateKeyword */:
                        case 105 /* ProtectedKeyword */:
                            return true;
                    }
                    return false;
                }
                function canFollow(keyword1, keyword2) {
                    if (isAccessibilityModifier(keyword1)) {
                        if (keyword2 === 113 /* GetKeyword */ || keyword2 === 117 /* SetKeyword */ || keyword2 === 111 /* ConstructorKeyword */ || keyword2 === 107 /* StaticKeyword */) {
                            return true;
                        }
                        return false;
                    }
                    return true;
                }
                function getClassificationsForLine(text, lexState, classifyKeywordsInGenerics) {
                    var offset = 0;
                    var token = 0 /* Unknown */;
                    var lastNonTriviaToken = 0 /* Unknown */;
                    switch (lexState) {
                        case 3 /* InDoubleQuoteStringLiteral */:
                            text = '"\\\n' + text;
                            offset = 3;
                            break;
                        case 2 /* InSingleQuoteStringLiteral */:
                            text = "'\\\n" + text;
                            offset = 3;
                            break;
                        case 1 /* InMultiLineCommentTrivia */:
                            text = "/*\n" + text;
                            offset = 3;
                            break;
                    }
                    scanner.setText(text);
                    var result = {
                        finalLexState: 0 /* Start */,
                        entries: []
                    };
                    var angleBracketStack = 0;
                    do {
                        token = scanner.scan();
                        if (!ts.isTrivia(token)) {
                            if ((token === 35 /* SlashToken */ || token === 55 /* SlashEqualsToken */) && !noRegexTable[lastNonTriviaToken]) {
                                if (scanner.reScanSlashToken() === 8 /* RegularExpressionLiteral */) {
                                    token = 8 /* RegularExpressionLiteral */;
                                }
                            }
                            else if (lastNonTriviaToken === 19 /* DotToken */ && isKeyword(token)) {
                                token = 63 /* Identifier */;
                            }
                            else if (isKeyword(lastNonTriviaToken) && isKeyword(token) && !canFollow(lastNonTriviaToken, token)) {
                                token = 63 /* Identifier */;
                            }
                            else if (lastNonTriviaToken === 63 /* Identifier */ && token === 23 /* LessThanToken */) {
                                angleBracketStack++;
                            }
                            else if (token === 24 /* GreaterThanToken */ && angleBracketStack > 0) {
                                angleBracketStack--;
                            }
                            else if (token === 109 /* AnyKeyword */ || token === 118 /* StringKeyword */ || token === 116 /* NumberKeyword */ || token === 110 /* BooleanKeyword */) {
                                if (angleBracketStack > 0 && !classifyKeywordsInGenerics) {
                                    token = 63 /* Identifier */;
                                }
                            }
                            lastNonTriviaToken = token;
                        }
                        processToken();
                    } while (token !== 1 /* EndOfFileToken */);
                    return result;
                    function processToken() {
                        var start = scanner.getTokenPos();
                        var end = scanner.getTextPos();
                        addResult(end - start, classFromKind(token));
                        if (end >= text.length) {
                            if (token === 7 /* StringLiteral */) {
                                var tokenText = scanner.getTokenText();
                                if (tokenText.length > 0 && tokenText.charCodeAt(tokenText.length - 1) === 92 /* backslash */) {
                                    var quoteChar = tokenText.charCodeAt(0);
                                    result.finalLexState = quoteChar === 34 /* doubleQuote */ ? 3 /* InDoubleQuoteStringLiteral */ : 2 /* InSingleQuoteStringLiteral */;
                                }
                            }
                            else if (token === 3 /* MultiLineCommentTrivia */) {
                                var tokenText = scanner.getTokenText();
                                if (!(tokenText.length > 3 && tokenText.charCodeAt(tokenText.length - 2) === 42 /* asterisk */ && tokenText.charCodeAt(tokenText.length - 1) === 47 /* slash */)) {
                                    result.finalLexState = 1 /* InMultiLineCommentTrivia */;
                                }
                            }
                        }
                    }
                    function addResult(length, classification) {
                        if (length > 0) {
                            if (result.entries.length === 0) {
                                length -= offset;
                            }
                            result.entries.push({ length: length, classification: classification });
                        }
                    }
                }
                function isBinaryExpressionOperatorToken(token) {
                    switch (token) {
                        case 34 /* AsteriskToken */:
                        case 35 /* SlashToken */:
                        case 36 /* PercentToken */:
                        case 32 /* PlusToken */:
                        case 33 /* MinusToken */:
                        case 39 /* LessThanLessThanToken */:
                        case 40 /* GreaterThanGreaterThanToken */:
                        case 41 /* GreaterThanGreaterThanGreaterThanToken */:
                        case 23 /* LessThanToken */:
                        case 24 /* GreaterThanToken */:
                        case 25 /* LessThanEqualsToken */:
                        case 26 /* GreaterThanEqualsToken */:
                        case 85 /* InstanceOfKeyword */:
                        case 84 /* InKeyword */:
                        case 27 /* EqualsEqualsToken */:
                        case 28 /* ExclamationEqualsToken */:
                        case 29 /* EqualsEqualsEqualsToken */:
                        case 30 /* ExclamationEqualsEqualsToken */:
                        case 42 /* AmpersandToken */:
                        case 44 /* CaretToken */:
                        case 43 /* BarToken */:
                        case 47 /* AmpersandAmpersandToken */:
                        case 48 /* BarBarToken */:
                        case 61 /* BarEqualsToken */:
                        case 60 /* AmpersandEqualsToken */:
                        case 62 /* CaretEqualsToken */:
                        case 57 /* LessThanLessThanEqualsToken */:
                        case 58 /* GreaterThanGreaterThanEqualsToken */:
                        case 59 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                        case 52 /* PlusEqualsToken */:
                        case 53 /* MinusEqualsToken */:
                        case 54 /* AsteriskEqualsToken */:
                        case 55 /* SlashEqualsToken */:
                        case 56 /* PercentEqualsToken */:
                        case 51 /* EqualsToken */:
                        case 22 /* CommaToken */:
                            return true;
                        default: return false;
                    }
                }
                function isPrefixUnaryExpressionOperatorToken(token) {
                    switch (token) {
                        case 32 /* PlusToken */:
                        case 33 /* MinusToken */:
                        case 46 /* TildeToken */:
                        case 45 /* ExclamationToken */:
                        case 37 /* PlusPlusToken */:
                        case 38 /* MinusMinusToken */:
                            return true;
                        default:
                            return false;
                    }
                }
                function isKeyword(token) {
                    return token >= 64 /* FirstKeyword */ && token <= 119 /* LastKeyword */;
                }
                function classFromKind(token) {
                    if (isKeyword(token)) {
                        return 1 /* Keyword */;
                    }
                    else if (isBinaryExpressionOperatorToken(token) || isPrefixUnaryExpressionOperatorToken(token)) {
                        return 2 /* Operator */;
                    }
                    else if (token >= 13 /* FirstPunctuation */ && token <= 62 /* LastPunctuation */) {
                        return 0 /* Punctuation */;
                    }
                    switch (token) {
                        case 6 /* NumericLiteral */:
                            return 6 /* NumberLiteral */;
                        case 7 /* StringLiteral */:
                            return 7 /* StringLiteral */;
                        case 8 /* RegularExpressionLiteral */:
                            return 8 /* RegExpLiteral */;
                        case 3 /* MultiLineCommentTrivia */:
                        case 2 /* SingleLineCommentTrivia */:
                            return 3 /* Comment */;
                        case 5 /* WhitespaceTrivia */:
                            return 4 /* Whitespace */;
                        case 63 /* Identifier */:
                        default:
                            return 5 /* Identifier */;
                    }
                }
                return { getClassificationsForLine: getClassificationsForLine };
            }
            ts.createClassifier = createClassifier;
            function initializeServices() {
                ts.objectAllocator = {
                    getNodeConstructor: function (kind) {
                        function Node() {
                        }
                        var proto = kind === 198 /* SourceFile */ ? new SourceFileObject() : new NodeObject();
                        proto.kind = kind;
                        proto.pos = 0;
                        proto.end = 0;
                        proto.flags = 0;
                        proto.parent = undefined;
                        Node.prototype = proto;
                        return Node;
                    },
                    getSymbolConstructor: function () { return SymbolObject; },
                    getTypeConstructor: function () { return TypeObject; },
                    getSignatureConstructor: function () { return SignatureObject; }
                };
            }
            initializeServices();
        })(ts || (ts = {}));
        var ts;
        (function (ts) {
            var BreakpointResolver;
            (function (BreakpointResolver) {
                function spanInSourceFileAtLocation(sourceFile, position) {
                    if (sourceFile.flags & 1024 /* DeclarationFile */) {
                        return undefined;
                    }
                    var tokenAtLocation = ts.getTokenAtPosition(sourceFile, position);
                    var lineOfPosition = sourceFile.getLineAndCharacterFromPosition(position).line;
                    if (sourceFile.getLineAndCharacterFromPosition(tokenAtLocation.getStart()).line > lineOfPosition) {
                        tokenAtLocation = ts.findPrecedingToken(tokenAtLocation.pos, sourceFile);
                        if (!tokenAtLocation || sourceFile.getLineAndCharacterFromPosition(tokenAtLocation.getEnd()).line !== lineOfPosition) {
                            return undefined;
                        }
                    }
                    if (ts.isInAmbientContext(tokenAtLocation)) {
                        return undefined;
                    }
                    return spanInNode(tokenAtLocation);
                    function textSpan(startNode, endNode) {
                        return ts.TextSpan.fromBounds(startNode.getStart(), (endNode || startNode).getEnd());
                    }
                    function spanInNodeIfStartsOnSameLine(node, otherwiseOnNode) {
                        if (node && lineOfPosition === sourceFile.getLineAndCharacterFromPosition(node.getStart()).line) {
                            return spanInNode(node);
                        }
                        return spanInNode(otherwiseOnNode);
                    }
                    function spanInPreviousNode(node) {
                        return spanInNode(ts.findPrecedingToken(node.pos, sourceFile));
                    }
                    function spanInNextNode(node) {
                        return spanInNode(ts.findNextToken(node, node.parent));
                    }
                    function spanInNode(node) {
                        if (node) {
                            if (ts.isExpression(node)) {
                                if (node.parent.kind === 168 /* DoStatement */) {
                                    return spanInPreviousNode(node);
                                }
                                if (node.parent.kind === 170 /* ForStatement */) {
                                    return textSpan(node);
                                }
                                if (node.parent.kind === 157 /* BinaryExpression */ && node.parent.operator === 22 /* CommaToken */) {
                                    return textSpan(node);
                                }
                                if (node.parent.kind == 154 /* ArrowFunction */ && node.parent.body == node) {
                                    return textSpan(node);
                                }
                            }
                            switch (node.kind) {
                                case 164 /* VariableStatement */:
                                    return spanInVariableDeclaration(node.declarations[0]);
                                case 186 /* VariableDeclaration */:
                                case 125 /* Property */:
                                    return spanInVariableDeclaration(node);
                                case 124 /* Parameter */:
                                    return spanInParameterDeclaration(node);
                                case 187 /* FunctionDeclaration */:
                                case 126 /* Method */:
                                case 128 /* GetAccessor */:
                                case 129 /* SetAccessor */:
                                case 127 /* Constructor */:
                                case 153 /* FunctionExpression */:
                                case 154 /* ArrowFunction */:
                                    return spanInFunctionDeclaration(node);
                                case 188 /* FunctionBlock */:
                                    return spanInFunctionBlock(node);
                                case 163 /* Block */:
                                case 182 /* TryBlock */:
                                case 183 /* CatchBlock */:
                                case 184 /* FinallyBlock */:
                                case 194 /* ModuleBlock */:
                                    return spanInBlock(node);
                                case 166 /* ExpressionStatement */:
                                    return textSpan(node.expression);
                                case 174 /* ReturnStatement */:
                                    return textSpan(node.getChildAt(0), node.expression);
                                case 169 /* WhileStatement */:
                                    return textSpan(node, ts.findNextToken(node.expression, node));
                                case 168 /* DoStatement */:
                                    return spanInNode(node.statement);
                                case 185 /* DebuggerStatement */:
                                    return textSpan(node.getChildAt(0));
                                case 167 /* IfStatement */:
                                    return textSpan(node, ts.findNextToken(node.expression, node));
                                case 179 /* LabeledStatement */:
                                    return spanInNode(node.statement);
                                case 173 /* BreakStatement */:
                                case 172 /* ContinueStatement */:
                                    return textSpan(node.getChildAt(0), node.label);
                                case 170 /* ForStatement */:
                                    return spanInForStatement(node);
                                case 171 /* ForInStatement */:
                                    return textSpan(node, ts.findNextToken(node.expression, node));
                                case 176 /* SwitchStatement */:
                                    return textSpan(node, ts.findNextToken(node.expression, node));
                                case 177 /* CaseClause */:
                                case 178 /* DefaultClause */:
                                    return spanInNode(node.statements[0]);
                                case 181 /* TryStatement */:
                                    return spanInBlock(node.tryBlock);
                                case 180 /* ThrowStatement */:
                                    return textSpan(node, node.expression);
                                case 196 /* ExportAssignment */:
                                    return textSpan(node, node.exportName);
                                case 195 /* ImportDeclaration */:
                                    return textSpan(node, node.entityName || node.externalModuleName);
                                case 193 /* ModuleDeclaration */:
                                    if (ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                                        return undefined;
                                    }
                                case 189 /* ClassDeclaration */:
                                case 192 /* EnumDeclaration */:
                                case 197 /* EnumMember */:
                                case 148 /* CallExpression */:
                                case 149 /* NewExpression */:
                                    return textSpan(node);
                                case 175 /* WithStatement */:
                                    return spanInNode(node.statement);
                                case 190 /* InterfaceDeclaration */:
                                case 191 /* TypeAliasDeclaration */:
                                    return undefined;
                                case 21 /* SemicolonToken */:
                                case 1 /* EndOfFileToken */:
                                    return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile));
                                case 22 /* CommaToken */:
                                    return spanInPreviousNode(node);
                                case 13 /* OpenBraceToken */:
                                    return spanInOpenBraceToken(node);
                                case 14 /* CloseBraceToken */:
                                    return spanInCloseBraceToken(node);
                                case 15 /* OpenParenToken */:
                                    return spanInOpenParenToken(node);
                                case 16 /* CloseParenToken */:
                                    return spanInCloseParenToken(node);
                                case 50 /* ColonToken */:
                                    return spanInColonToken(node);
                                case 24 /* GreaterThanToken */:
                                case 23 /* LessThanToken */:
                                    return spanInGreaterThanOrLessThanToken(node);
                                case 98 /* WhileKeyword */:
                                    return spanInWhileKeyword(node);
                                case 74 /* ElseKeyword */:
                                case 66 /* CatchKeyword */:
                                case 79 /* FinallyKeyword */:
                                    return spanInNextNode(node);
                                default:
                                    if (node.parent.kind === 144 /* PropertyAssignment */ && node.parent.name === node) {
                                        return spanInNode(node.parent.initializer);
                                    }
                                    if (node.parent.kind === 151 /* TypeAssertion */ && node.parent.type === node) {
                                        return spanInNode(node.parent.operand);
                                    }
                                    if (ts.isAnyFunction(node.parent) && node.parent.type === node) {
                                        return spanInPreviousNode(node);
                                    }
                                    return spanInNode(node.parent);
                            }
                        }
                        function spanInVariableDeclaration(variableDeclaration) {
                            if (variableDeclaration.parent.kind === 171 /* ForInStatement */) {
                                return spanInNode(variableDeclaration.parent);
                            }
                            var isParentVariableStatement = variableDeclaration.parent.kind === 164 /* VariableStatement */;
                            var isDeclarationOfForStatement = variableDeclaration.parent.kind === 170 /* ForStatement */ && ts.contains(variableDeclaration.parent.declarations, variableDeclaration);
                            var declarations = isParentVariableStatement ? variableDeclaration.parent.declarations : isDeclarationOfForStatement ? variableDeclaration.parent.declarations : undefined;
                            if (variableDeclaration.initializer || (variableDeclaration.flags & 1 /* Export */)) {
                                if (declarations && declarations[0] === variableDeclaration) {
                                    if (isParentVariableStatement) {
                                        return textSpan(variableDeclaration.parent, variableDeclaration);
                                    }
                                    else {
                                        ts.Debug.assert(isDeclarationOfForStatement);
                                        return textSpan(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration);
                                    }
                                }
                                else {
                                    return textSpan(variableDeclaration);
                                }
                            }
                            else if (declarations && declarations[0] !== variableDeclaration) {
                                var indexOfCurrentDeclaration = ts.indexOf(declarations, variableDeclaration);
                                return spanInVariableDeclaration(declarations[indexOfCurrentDeclaration - 1]);
                            }
                        }
                        function canHaveSpanInParameterDeclaration(parameter) {
                            return !!parameter.initializer || !!(parameter.flags & 8 /* Rest */) || !!(parameter.flags & 16 /* Public */) || !!(parameter.flags & 32 /* Private */);
                        }
                        function spanInParameterDeclaration(parameter) {
                            if (canHaveSpanInParameterDeclaration(parameter)) {
                                return textSpan(parameter);
                            }
                            else {
                                var functionDeclaration = parameter.parent;
                                var indexOfParameter = ts.indexOf(functionDeclaration.parameters, parameter);
                                if (indexOfParameter) {
                                    return spanInParameterDeclaration(functionDeclaration.parameters[indexOfParameter - 1]);
                                }
                                else {
                                    return spanInNode(functionDeclaration.body);
                                }
                            }
                        }
                        function canFunctionHaveSpanInWholeDeclaration(functionDeclaration) {
                            return !!(functionDeclaration.flags & 1 /* Export */) || (functionDeclaration.parent.kind === 189 /* ClassDeclaration */ && functionDeclaration.kind !== 127 /* Constructor */);
                        }
                        function spanInFunctionDeclaration(functionDeclaration) {
                            if (!functionDeclaration.body) {
                                return undefined;
                            }
                            if (canFunctionHaveSpanInWholeDeclaration(functionDeclaration)) {
                                return textSpan(functionDeclaration);
                            }
                            return spanInNode(functionDeclaration.body);
                        }
                        function spanInFunctionBlock(block) {
                            var nodeForSpanInBlock = block.statements.length ? block.statements[0] : block.getLastToken();
                            if (canFunctionHaveSpanInWholeDeclaration(block.parent)) {
                                return spanInNodeIfStartsOnSameLine(block.parent, nodeForSpanInBlock);
                            }
                            return spanInNode(nodeForSpanInBlock);
                        }
                        function spanInBlock(block) {
                            switch (block.parent.kind) {
                                case 193 /* ModuleDeclaration */:
                                    if (ts.getModuleInstanceState(block.parent) !== 1 /* Instantiated */) {
                                        return undefined;
                                    }
                                case 169 /* WhileStatement */:
                                case 167 /* IfStatement */:
                                case 171 /* ForInStatement */:
                                    return spanInNodeIfStartsOnSameLine(block.parent, block.statements[0]);
                                case 170 /* ForStatement */:
                                    return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(block.pos, sourceFile, block.parent), block.statements[0]);
                            }
                            return spanInNode(block.statements[0]);
                        }
                        function spanInForStatement(forStatement) {
                            if (forStatement.declarations) {
                                return spanInNode(forStatement.declarations[0]);
                            }
                            if (forStatement.initializer) {
                                return spanInNode(forStatement.initializer);
                            }
                            if (forStatement.condition) {
                                return textSpan(forStatement.condition);
                            }
                            if (forStatement.iterator) {
                                return textSpan(forStatement.iterator);
                            }
                        }
                        function spanInOpenBraceToken(node) {
                            switch (node.parent.kind) {
                                case 192 /* EnumDeclaration */:
                                    var enumDeclaration = node.parent;
                                    return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), enumDeclaration.members.length ? enumDeclaration.members[0] : enumDeclaration.getLastToken(sourceFile));
                                case 189 /* ClassDeclaration */:
                                    var classDeclaration = node.parent;
                                    return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), classDeclaration.members.length ? classDeclaration.members[0] : classDeclaration.getLastToken(sourceFile));
                                case 176 /* SwitchStatement */:
                                    return spanInNodeIfStartsOnSameLine(node.parent, node.parent.clauses[0]);
                            }
                            return spanInNode(node.parent);
                        }
                        function spanInCloseBraceToken(node) {
                            switch (node.parent.kind) {
                                case 194 /* ModuleBlock */:
                                    if (ts.getModuleInstanceState(node.parent.parent) !== 1 /* Instantiated */) {
                                        return undefined;
                                    }
                                case 188 /* FunctionBlock */:
                                case 192 /* EnumDeclaration */:
                                case 189 /* ClassDeclaration */:
                                    return textSpan(node);
                                case 163 /* Block */:
                                case 182 /* TryBlock */:
                                case 183 /* CatchBlock */:
                                case 184 /* FinallyBlock */:
                                    return spanInNode(node.parent.statements[node.parent.statements.length - 1]);
                                    ;
                                case 176 /* SwitchStatement */:
                                    var switchStatement = node.parent;
                                    var lastClause = switchStatement.clauses[switchStatement.clauses.length - 1];
                                    if (lastClause) {
                                        return spanInNode(lastClause.statements[lastClause.statements.length - 1]);
                                    }
                                    return undefined;
                                default:
                                    return spanInNode(node.parent);
                            }
                        }
                        function spanInOpenParenToken(node) {
                            if (node.parent.kind === 168 /* DoStatement */) {
                                return spanInPreviousNode(node);
                            }
                            return spanInNode(node.parent);
                        }
                        function spanInCloseParenToken(node) {
                            switch (node.parent.kind) {
                                case 153 /* FunctionExpression */:
                                case 187 /* FunctionDeclaration */:
                                case 154 /* ArrowFunction */:
                                case 126 /* Method */:
                                case 128 /* GetAccessor */:
                                case 129 /* SetAccessor */:
                                case 127 /* Constructor */:
                                case 169 /* WhileStatement */:
                                case 168 /* DoStatement */:
                                case 170 /* ForStatement */:
                                    return spanInPreviousNode(node);
                                default:
                                    return spanInNode(node.parent);
                            }
                            return spanInNode(node.parent);
                        }
                        function spanInColonToken(node) {
                            if (ts.isAnyFunction(node.parent) || node.parent.kind === 144 /* PropertyAssignment */) {
                                return spanInPreviousNode(node);
                            }
                            return spanInNode(node.parent);
                        }
                        function spanInGreaterThanOrLessThanToken(node) {
                            if (node.parent.kind === 151 /* TypeAssertion */) {
                                return spanInNode(node.parent.operand);
                            }
                            return spanInNode(node.parent);
                        }
                        function spanInWhileKeyword(node) {
                            if (node.parent.kind === 168 /* DoStatement */) {
                                return textSpan(node, ts.findNextToken(node.parent.expression, node.parent));
                            }
                            return spanInNode(node.parent);
                        }
                    }
                }
                BreakpointResolver.spanInSourceFileAtLocation = spanInSourceFileAtLocation;
            })(BreakpointResolver = ts.BreakpointResolver || (ts.BreakpointResolver = {}));
        })(ts || (ts = {}));
        var debugObjectHost = this;
        var ts;
        (function (ts) {
            (function (LanguageVersion) {
                LanguageVersion[LanguageVersion["EcmaScript3"] = 0] = "EcmaScript3";
                LanguageVersion[LanguageVersion["EcmaScript5"] = 1] = "EcmaScript5";
                LanguageVersion[LanguageVersion["EcmaScript6"] = 2] = "EcmaScript6";
            })(ts.LanguageVersion || (ts.LanguageVersion = {}));
            var LanguageVersion = ts.LanguageVersion;
            (function (ModuleGenTarget) {
                ModuleGenTarget[ModuleGenTarget["Unspecified"] = 0] = "Unspecified";
                ModuleGenTarget[ModuleGenTarget["Synchronous"] = 1] = "Synchronous";
                ModuleGenTarget[ModuleGenTarget["Asynchronous"] = 2] = "Asynchronous";
            })(ts.ModuleGenTarget || (ts.ModuleGenTarget = {}));
            var ModuleGenTarget = ts.ModuleGenTarget;
            function languageVersionToScriptTarget(languageVersion) {
                if (typeof languageVersion === "undefined")
                    return undefined;
                switch (languageVersion) {
                    case 0 /* EcmaScript3 */: return 0 /* ES3 */;
                    case 1 /* EcmaScript5 */: return 1 /* ES5 */;
                    case 2 /* EcmaScript6 */: return 2 /* ES6 */;
                    default: throw Error("unsupported LanguageVersion value: " + languageVersion);
                }
            }
            function moduleGenTargetToModuleKind(moduleGenTarget) {
                if (typeof moduleGenTarget === "undefined")
                    return undefined;
                switch (moduleGenTarget) {
                    case 2 /* Asynchronous */: return 2 /* AMD */;
                    case 1 /* Synchronous */: return 1 /* CommonJS */;
                    case 0 /* Unspecified */: return 0 /* None */;
                    default: throw Error("unsupported ModuleGenTarget value: " + moduleGenTarget);
                }
            }
            function scriptTargetTolanguageVersion(scriptTarget) {
                if (typeof scriptTarget === "undefined")
                    return undefined;
                switch (scriptTarget) {
                    case 0 /* ES3 */: return 0 /* EcmaScript3 */;
                    case 1 /* ES5 */: return 1 /* EcmaScript5 */;
                    case 2 /* ES6 */: return 2 /* EcmaScript6 */;
                    default: throw Error("unsupported ScriptTarget value: " + scriptTarget);
                }
            }
            function moduleKindToModuleGenTarget(moduleKind) {
                if (typeof moduleKind === "undefined")
                    return undefined;
                switch (moduleKind) {
                    case 2 /* AMD */: return 2 /* Asynchronous */;
                    case 1 /* CommonJS */: return 1 /* Synchronous */;
                    case 0 /* None */: return 0 /* Unspecified */;
                    default: throw Error("unsupported ModuleKind value: " + moduleKind);
                }
            }
            function compilationSettingsToCompilerOptions(settings) {
                var options = {};
                options.removeComments = settings.removeComments;
                options.noResolve = settings.noResolve;
                options.noImplicitAny = settings.noImplicitAny;
                options.noLib = settings.noLib;
                options.target = languageVersionToScriptTarget(settings.codeGenTarget);
                options.module = moduleGenTargetToModuleKind(settings.moduleGenTarget);
                options.out = settings.outFileOption;
                options.outDir = settings.outDirOption;
                options.sourceMap = settings.mapSourceFiles;
                options.mapRoot = settings.mapRoot;
                options.sourceRoot = settings.sourceRoot;
                options.declaration = settings.generateDeclarationFiles;
                options.codepage = settings.codepage;
                options.emitBOM = settings.emitBOM;
                return options;
            }
            function compilerOptionsToCompilationSettings(options) {
                var settings = {};
                settings.removeComments = options.removeComments;
                settings.noResolve = options.noResolve;
                settings.noImplicitAny = options.noImplicitAny;
                settings.noLib = options.noLib;
                settings.codeGenTarget = scriptTargetTolanguageVersion(options.target);
                settings.moduleGenTarget = moduleKindToModuleGenTarget(options.module);
                settings.outFileOption = options.out;
                settings.outDirOption = options.outDir;
                settings.mapSourceFiles = options.sourceMap;
                settings.mapRoot = options.mapRoot;
                settings.sourceRoot = options.sourceRoot;
                settings.generateDeclarationFiles = options.declaration;
                settings.codepage = options.codepage;
                settings.emitBOM = options.emitBOM;
                return settings;
            }
            function logInternalError(logger, err) {
                logger.log("*INTERNAL ERROR* - Exception in typescript services: " + err.message);
            }
            var ScriptSnapshotShimAdapter = (function () {
                function ScriptSnapshotShimAdapter(scriptSnapshotShim) {
                    this.scriptSnapshotShim = scriptSnapshotShim;
                    this.lineStartPositions = null;
                }
                ScriptSnapshotShimAdapter.prototype.getText = function (start, end) {
                    return this.scriptSnapshotShim.getText(start, end);
                };
                ScriptSnapshotShimAdapter.prototype.getLength = function () {
                    return this.scriptSnapshotShim.getLength();
                };
                ScriptSnapshotShimAdapter.prototype.getLineStartPositions = function () {
                    if (this.lineStartPositions == null) {
                        this.lineStartPositions = JSON.parse(this.scriptSnapshotShim.getLineStartPositions());
                    }
                    return this.lineStartPositions;
                };
                ScriptSnapshotShimAdapter.prototype.getChangeRange = function (oldSnapshot) {
                    var oldSnapshotShim = oldSnapshot;
                    var encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim);
                    if (encoded == null) {
                        return null;
                    }
                    var decoded = JSON.parse(encoded);
                    return new ts.TextChangeRange(new ts.TextSpan(decoded.span.start, decoded.span.length), decoded.newLength);
                };
                return ScriptSnapshotShimAdapter;
            })();
            var LanguageServiceShimHostAdapter = (function () {
                function LanguageServiceShimHostAdapter(shimHost) {
                    this.shimHost = shimHost;
                }
                LanguageServiceShimHostAdapter.prototype.log = function (s) {
                    this.shimHost.log(s);
                };
                LanguageServiceShimHostAdapter.prototype.getCompilationSettings = function () {
                    var settingsJson = this.shimHost.getCompilationSettings();
                    if (settingsJson == null || settingsJson == "") {
                        throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings");
                        return null;
                    }
                    var options = compilationSettingsToCompilerOptions(JSON.parse(settingsJson));
                    return options;
                };
                LanguageServiceShimHostAdapter.prototype.getScriptFileNames = function () {
                    var encoded = this.shimHost.getScriptFileNames();
                    return JSON.parse(encoded);
                };
                LanguageServiceShimHostAdapter.prototype.getScriptSnapshot = function (fileName) {
                    return new ScriptSnapshotShimAdapter(this.shimHost.getScriptSnapshot(fileName));
                };
                LanguageServiceShimHostAdapter.prototype.getScriptVersion = function (fileName) {
                    return this.shimHost.getScriptVersion(fileName);
                };
                LanguageServiceShimHostAdapter.prototype.getScriptIsOpen = function (fileName) {
                    return this.shimHost.getScriptIsOpen(fileName);
                };
                LanguageServiceShimHostAdapter.prototype.getLocalizedDiagnosticMessages = function () {
                    var diagnosticMessagesJson = this.shimHost.getLocalizedDiagnosticMessages();
                    if (diagnosticMessagesJson == null || diagnosticMessagesJson == "") {
                        return null;
                    }
                    try {
                        return JSON.parse(diagnosticMessagesJson);
                    }
                    catch (e) {
                        this.log(e.description || "diagnosticMessages.generated.json has invalid JSON format");
                        return null;
                    }
                };
                LanguageServiceShimHostAdapter.prototype.getCancellationToken = function () {
                    return this.shimHost.getCancellationToken();
                };
                LanguageServiceShimHostAdapter.prototype.getDefaultLibFilename = function () {
                    return this.shimHost.getDefaultLibFilename();
                };
                LanguageServiceShimHostAdapter.prototype.getCurrentDirectory = function () {
                    return this.shimHost.getCurrentDirectory();
                };
                return LanguageServiceShimHostAdapter;
            })();
            ts.LanguageServiceShimHostAdapter = LanguageServiceShimHostAdapter;
            function simpleForwardCall(logger, actionDescription, action) {
                logger.log(actionDescription);
                var start = Date.now();
                var result = action();
                var end = Date.now();
                logger.log(actionDescription + " completed in " + (end - start) + " msec");
                if (typeof (result) === "string") {
                    var str = result;
                    if (str.length > 128) {
                        str = str.substring(0, 128) + "...";
                    }
                    logger.log("  result.length=" + str.length + ", result='" + JSON.stringify(str) + "'");
                }
                return result;
            }
            function forwardJSONCall(logger, actionDescription, action) {
                try {
                    var result = simpleForwardCall(logger, actionDescription, action);
                    return JSON.stringify({ result: result });
                }
                catch (err) {
                    if (err instanceof ts.OperationCanceledException) {
                        return JSON.stringify({ canceled: true });
                    }
                    logInternalError(logger, err);
                    err.description = actionDescription;
                    return JSON.stringify({ error: err });
                }
            }
            var ShimBase = (function () {
                function ShimBase(factory) {
                    this.factory = factory;
                    factory.registerShim(this);
                }
                ShimBase.prototype.dispose = function (dummy) {
                    this.factory.unregisterShim(this);
                };
                return ShimBase;
            })();
            var LanguageServiceShimObject = (function (_super) {
                __extends(LanguageServiceShimObject, _super);
                function LanguageServiceShimObject(factory, host, languageService) {
                    _super.call(this, factory);
                    this.host = host;
                    this.languageService = languageService;
                    this.logger = this.host;
                }
                LanguageServiceShimObject.prototype.forwardJSONCall = function (actionDescription, action) {
                    return forwardJSONCall(this.logger, actionDescription, action);
                };
                LanguageServiceShimObject.prototype.dispose = function (dummy) {
                    this.logger.log("dispose()");
                    this.languageService.dispose();
                    this.languageService = null;
                    if (debugObjectHost && debugObjectHost.CollectGarbage) {
                        debugObjectHost.CollectGarbage();
                        this.logger.log("CollectGarbage()");
                    }
                    this.logger = null;
                    _super.prototype.dispose.call(this, dummy);
                };
                LanguageServiceShimObject.prototype.refresh = function (throwOnError) {
                    this.forwardJSONCall("refresh(" + throwOnError + ")", function () {
                        return null;
                    });
                };
                LanguageServiceShimObject.prototype.cleanupSemanticCache = function () {
                    var _this = this;
                    this.forwardJSONCall("cleanupSemanticCache()", function () {
                        _this.languageService.cleanupSemanticCache();
                        return null;
                    });
                };
                LanguageServiceShimObject.realizeDiagnostic = function (diagnostic) {
                    return {
                        message: diagnostic.messageText,
                        start: diagnostic.start,
                        length: diagnostic.length,
                        category: ts.DiagnosticCategory[diagnostic.category].toLowerCase(),
                        code: diagnostic.code
                    };
                };
                LanguageServiceShimObject.prototype.getSyntacticClassifications = function (fileName, start, length) {
                    var _this = this;
                    return this.forwardJSONCall("getSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", function () {
                        var classifications = _this.languageService.getSyntacticClassifications(fileName, new ts.TextSpan(start, length));
                        return classifications;
                    });
                };
                LanguageServiceShimObject.prototype.getSemanticClassifications = function (fileName, start, length) {
                    var _this = this;
                    return this.forwardJSONCall("getSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", function () {
                        var classifications = _this.languageService.getSemanticClassifications(fileName, new ts.TextSpan(start, length));
                        return classifications;
                    });
                };
                LanguageServiceShimObject.prototype.getSyntacticDiagnostics = function (fileName) {
                    var _this = this;
                    return this.forwardJSONCall("getSyntacticDiagnostics('" + fileName + "')", function () {
                        var errors = _this.languageService.getSyntacticDiagnostics(fileName);
                        return errors.map(LanguageServiceShimObject.realizeDiagnostic);
                    });
                };
                LanguageServiceShimObject.prototype.getSemanticDiagnostics = function (fileName) {
                    var _this = this;
                    return this.forwardJSONCall("getSemanticDiagnostics('" + fileName + "')", function () {
                        var errors = _this.languageService.getSemanticDiagnostics(fileName);
                        return errors.map(LanguageServiceShimObject.realizeDiagnostic);
                    });
                };
                LanguageServiceShimObject.prototype.getCompilerOptionsDiagnostics = function () {
                    var _this = this;
                    return this.forwardJSONCall("getCompilerOptionsDiagnostics()", function () {
                        var errors = _this.languageService.getCompilerOptionsDiagnostics();
                        return errors.map(LanguageServiceShimObject.realizeDiagnostic);
                    });
                };
                LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (fileName, position) {
                    var _this = this;
                    return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () {
                        var quickInfo = _this.languageService.getQuickInfoAtPosition(fileName, position);
                        return quickInfo;
                    });
                };
                LanguageServiceShimObject.prototype.getNameOrDottedNameSpan = function (fileName, startPos, endPos) {
                    var _this = this;
                    return this.forwardJSONCall("getNameOrDottedNameSpan('" + fileName + "', " + startPos + ", " + endPos + ")", function () {
                        var spanInfo = _this.languageService.getNameOrDottedNameSpan(fileName, startPos, endPos);
                        return spanInfo;
                    });
                };
                LanguageServiceShimObject.prototype.getBreakpointStatementAtPosition = function (fileName, position) {
                    var _this = this;
                    return this.forwardJSONCall("getBreakpointStatementAtPosition('" + fileName + "', " + position + ")", function () {
                        var spanInfo = _this.languageService.getBreakpointStatementAtPosition(fileName, position);
                        return spanInfo;
                    });
                };
                LanguageServiceShimObject.prototype.getSignatureHelpItems = function (fileName, position) {
                    var _this = this;
                    return this.forwardJSONCall("getSignatureHelpItems('" + fileName + "', " + position + ")", function () {
                        var signatureInfo = _this.languageService.getSignatureHelpItems(fileName, position);
                        return signatureInfo;
                    });
                };
                LanguageServiceShimObject.prototype.getDefinitionAtPosition = function (fileName, position) {
                    var _this = this;
                    return this.forwardJSONCall("getDefinitionAtPosition('" + fileName + "', " + position + ")", function () {
                        return _this.languageService.getDefinitionAtPosition(fileName, position);
                    });
                };
                LanguageServiceShimObject.prototype.getRenameInfo = function (fileName, position) {
                    var _this = this;
                    return this.forwardJSONCall("getRenameInfo('" + fileName + "', " + position + ")", function () {
                        return _this.languageService.getRenameInfo(fileName, position);
                    });
                };
                LanguageServiceShimObject.prototype.findRenameLocations = function (fileName, position, findInStrings, findInComments) {
                    var _this = this;
                    return this.forwardJSONCall("findRenameLocations('" + fileName + "', " + position + ", " + findInStrings + ", " + findInComments + ")", function () {
                        return _this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments);
                    });
                };
                LanguageServiceShimObject.prototype.getBraceMatchingAtPosition = function (fileName, position) {
                    var _this = this;
                    return this.forwardJSONCall("getBraceMatchingAtPosition('" + fileName + "', " + position + ")", function () {
                        var textRanges = _this.languageService.getBraceMatchingAtPosition(fileName, position);
                        return textRanges;
                    });
                };
                LanguageServiceShimObject.prototype.getIndentationAtPosition = function (fileName, position, options) {
                    var _this = this;
                    return this.forwardJSONCall("getIndentationAtPosition('" + fileName + "', " + position + ")", function () {
                        var localOptions = JSON.parse(options);
                        return _this.languageService.getIndentationAtPosition(fileName, position, localOptions);
                    });
                };
                LanguageServiceShimObject.prototype.getReferencesAtPosition = function (fileName, position) {
                    var _this = this;
                    return this.forwardJSONCall("getReferencesAtPosition('" + fileName + "', " + position + ")", function () {
                        return _this.languageService.getReferencesAtPosition(fileName, position);
                    });
                };
                LanguageServiceShimObject.prototype.getOccurrencesAtPosition = function (fileName, position) {
                    var _this = this;
                    return this.forwardJSONCall("getOccurrencesAtPosition('" + fileName + "', " + position + ")", function () {
                        return _this.languageService.getOccurrencesAtPosition(fileName, position);
                    });
                };
                LanguageServiceShimObject.prototype.getCompletionsAtPosition = function (fileName, position, isMemberCompletion) {
                    var _this = this;
                    return this.forwardJSONCall("getCompletionsAtPosition('" + fileName + "', " + position + ", " + isMemberCompletion + ")", function () {
                        var completion = _this.languageService.getCompletionsAtPosition(fileName, position, isMemberCompletion);
                        return completion;
                    });
                };
                LanguageServiceShimObject.prototype.getCompletionEntryDetails = function (fileName, position, entryName) {
                    var _this = this;
                    return this.forwardJSONCall("getCompletionEntryDetails('" + fileName + "', " + position + ", " + entryName + ")", function () {
                        var details = _this.languageService.getCompletionEntryDetails(fileName, position, entryName);
                        return details;
                    });
                };
                LanguageServiceShimObject.prototype.getFormattingEditsForRange = function (fileName, start, end, options) {
                    var _this = this;
                    return this.forwardJSONCall("getFormattingEditsForRange('" + fileName + "', " + start + ", " + end + ")", function () {
                        var localOptions = JSON.parse(options);
                        var edits = _this.languageService.getFormattingEditsForRange(fileName, start, end, localOptions);
                        return edits;
                    });
                };
                LanguageServiceShimObject.prototype.getFormattingEditsForDocument = function (fileName, options) {
                    var _this = this;
                    return this.forwardJSONCall("getFormattingEditsForDocument('" + fileName + "')", function () {
                        var localOptions = JSON.parse(options);
                        var edits = _this.languageService.getFormattingEditsForDocument(fileName, localOptions);
                        return edits;
                    });
                };
                LanguageServiceShimObject.prototype.getFormattingEditsAfterKeystroke = function (fileName, position, key, options) {
                    var _this = this;
                    return this.forwardJSONCall("getFormattingEditsAfterKeystroke('" + fileName + "', " + position + ", '" + key + "')", function () {
                        var localOptions = JSON.parse(options);
                        var edits = _this.languageService.getFormattingEditsAfterKeystroke(fileName, position, key, localOptions);
                        return edits;
                    });
                };
                LanguageServiceShimObject.prototype.getNavigateToItems = function (searchValue) {
                    var _this = this;
                    return this.forwardJSONCall("getNavigateToItems('" + searchValue + "')", function () {
                        var items = _this.languageService.getNavigateToItems(searchValue);
                        return items;
                    });
                };
                LanguageServiceShimObject.prototype.getNavigationBarItems = function (fileName) {
                    var _this = this;
                    return this.forwardJSONCall("getNavigationBarItems('" + fileName + "')", function () {
                        var items = _this.languageService.getNavigationBarItems(fileName);
                        return items;
                    });
                };
                LanguageServiceShimObject.prototype.getOutliningSpans = function (fileName) {
                    var _this = this;
                    return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () {
                        var items = _this.languageService.getOutliningSpans(fileName);
                        return items;
                    });
                };
                LanguageServiceShimObject.prototype.getTodoComments = function (fileName, descriptors) {
                    var _this = this;
                    return this.forwardJSONCall("getTodoComments('" + fileName + "')", function () {
                        var items = _this.languageService.getTodoComments(fileName, JSON.parse(descriptors));
                        return items;
                    });
                };
                LanguageServiceShimObject.prototype.getEmitOutput = function (fileName) {
                    var _this = this;
                    return this.forwardJSONCall("getEmitOutput('" + fileName + "')", function () {
                        var output = _this.languageService.getEmitOutput(fileName);
                        return output;
                    });
                };
                return LanguageServiceShimObject;
            })(ShimBase);
            var ClassifierShimObject = (function (_super) {
                __extends(ClassifierShimObject, _super);
                function ClassifierShimObject(factory, logger) {
                    _super.call(this, factory);
                    this.logger = logger;
                    this.classifier = ts.createClassifier(this.logger);
                }
                ClassifierShimObject.prototype.getClassificationsForLine = function (text, lexState, classifyKeywordsInGenerics) {
                    var classification = this.classifier.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics);
                    var items = classification.entries;
                    var result = "";
                    for (var i = 0; i < items.length; i++) {
                        result += items[i].length + "\n";
                        result += items[i].classification + "\n";
                    }
                    result += classification.finalLexState;
                    return result;
                };
                return ClassifierShimObject;
            })(ShimBase);
            var CoreServicesShimObject = (function (_super) {
                __extends(CoreServicesShimObject, _super);
                function CoreServicesShimObject(factory, logger) {
                    _super.call(this, factory);
                    this.logger = logger;
                }
                CoreServicesShimObject.prototype.forwardJSONCall = function (actionDescription, action) {
                    return forwardJSONCall(this.logger, actionDescription, action);
                };
                CoreServicesShimObject.prototype.getPreProcessedFileInfo = function (fileName, sourceTextSnapshot) {
                    return this.forwardJSONCall("getPreProcessedFileInfo('" + fileName + "')", function () {
                        var result = ts.preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()));
                        var convertResult = {
                            referencedFiles: [],
                            importedFiles: [],
                            isLibFile: result.isLibFile
                        };
                        ts.forEach(result.referencedFiles, function (refFile) {
                            convertResult.referencedFiles.push({
                                path: ts.normalizePath(refFile.filename),
                                position: refFile.pos,
                                length: refFile.end - refFile.pos
                            });
                        });
                        ts.forEach(result.importedFiles, function (importedFile) {
                            convertResult.importedFiles.push({
                                path: ts.normalizeSlashes(importedFile.filename),
                                position: importedFile.pos,
                                length: importedFile.end - importedFile.pos
                            });
                        });
                        return convertResult;
                    });
                };
                CoreServicesShimObject.prototype.getDefaultCompilationSettings = function () {
                    return this.forwardJSONCall("getDefaultCompilationSettings()", function () {
                        return compilerOptionsToCompilationSettings(ts.getDefaultCompilerOptions());
                    });
                };
                return CoreServicesShimObject;
            })(ShimBase);
            var TypeScriptServicesFactory = (function () {
                function TypeScriptServicesFactory() {
                    this._shims = [];
                    this.documentRegistry = ts.createDocumentRegistry();
                }
                TypeScriptServicesFactory.prototype.createLanguageServiceShim = function (host) {
                    try {
                        var hostAdapter = new LanguageServiceShimHostAdapter(host);
                        var languageService = ts.createLanguageService(hostAdapter, this.documentRegistry);
                        return new LanguageServiceShimObject(this, host, languageService);
                    }
                    catch (err) {
                        logInternalError(host, err);
                        throw err;
                    }
                };
                TypeScriptServicesFactory.prototype.createClassifierShim = function (logger) {
                    try {
                        return new ClassifierShimObject(this, logger);
                    }
                    catch (err) {
                        logInternalError(logger, err);
                        throw err;
                    }
                };
                TypeScriptServicesFactory.prototype.createCoreServicesShim = function (logger) {
                    try {
                        return new CoreServicesShimObject(this, logger);
                    }
                    catch (err) {
                        logInternalError(logger, err);
                        throw err;
                    }
                };
                TypeScriptServicesFactory.prototype.close = function () {
                    this._shims = [];
                    this.documentRegistry = ts.createDocumentRegistry();
                };
                TypeScriptServicesFactory.prototype.registerShim = function (shim) {
                    this._shims.push(shim);
                };
                TypeScriptServicesFactory.prototype.unregisterShim = function (shim) {
                    for (var i = 0, n = this._shims.length; i < n; i++) {
                        if (this._shims[i] === shim) {
                            delete this._shims[i];
                            return;
                        }
                    }
                    throw new Error("Invalid operation");
                };
                return TypeScriptServicesFactory;
            })();
            ts.TypeScriptServicesFactory = TypeScriptServicesFactory;
        })(ts || (ts = {}));
        var TypeScript;
        (function (TypeScript) {
            var Services;
            (function (Services) {
                Services.TypeScriptServicesFactory = ts.TypeScriptServicesFactory;
            })(Services = TypeScript.Services || (TypeScript.Services = {}));
        })(TypeScript || (TypeScript = {}));
        //# sourceMappingURL=file:////home/mihailik/typescript/built/local/typescriptServices.js.map
    • zip.js
      • deflate.js
        /*
         Copyright (c) 2013 Gildas Lormeau. All rights reserved.
        
         Redistribution and use in source and binary forms, with or without
         modification, are permitted provided that the following conditions are met:
        
         1. Redistributions of source code must retain the above copyright notice,
         this list of conditions and the following disclaimer.
        
         2. Redistributions in binary form must reproduce the above copyright 
         notice, this list of conditions and the following disclaimer in 
         the documentation and/or other materials provided with the distribution.
        
         3. The names of the authors may not be used to endorse or promote products
         derived from this software without specific prior written permission.
        
         THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
         INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
         FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
         INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
         INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
         OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
         LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
         NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
         EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         */
        
        /*
         * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
         * JZlib is based on zlib-1.1.3, so all credit should go authors
         * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
         * and contributors of zlib.
         */
        
        (function(obj) {
        
        	// Global
        
        	var MAX_BITS = 15;
        	var D_CODES = 30;
        	var BL_CODES = 19;
        
        	var LENGTH_CODES = 29;
        	var LITERALS = 256;
        	var L_CODES = (LITERALS + 1 + LENGTH_CODES);
        	var HEAP_SIZE = (2 * L_CODES + 1);
        
        	var END_BLOCK = 256;
        
        	// Bit length codes must not exceed MAX_BL_BITS bits
        	var MAX_BL_BITS = 7;
        
        	// repeat previous bit length 3-6 times (2 bits of repeat count)
        	var REP_3_6 = 16;
        
        	// repeat a zero length 3-10 times (3 bits of repeat count)
        	var REPZ_3_10 = 17;
        
        	// repeat a zero length 11-138 times (7 bits of repeat count)
        	var REPZ_11_138 = 18;
        
        	// The lengths of the bit length codes are sent in order of decreasing
        	// probability, to avoid transmitting the lengths for unused bit
        	// length codes.
        
        	var Buf_size = 8 * 2;
        
        	// JZlib version : "1.0.2"
        	var Z_DEFAULT_COMPRESSION = -1;
        
        	// compression strategy
        	var Z_FILTERED = 1;
        	var Z_HUFFMAN_ONLY = 2;
        	var Z_DEFAULT_STRATEGY = 0;
        
        	var Z_NO_FLUSH = 0;
        	var Z_PARTIAL_FLUSH = 1;
        	var Z_FULL_FLUSH = 3;
        	var Z_FINISH = 4;
        
        	var Z_OK = 0;
        	var Z_STREAM_END = 1;
        	var Z_NEED_DICT = 2;
        	var Z_STREAM_ERROR = -2;
        	var Z_DATA_ERROR = -3;
        	var Z_BUF_ERROR = -5;
        
        	// Tree
        
        	// see definition of array dist_code below
        	var _dist_code = [ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
        			10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
        			12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
        			13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
        			14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
        			14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
        			15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19,
        			20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
        			24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
        			26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
        			27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
        			28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29,
        			29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
        			29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 ];
        
        	function Tree() {
        		var that = this;
        
        		// dyn_tree; // the dynamic tree
        		// max_code; // largest code with non zero frequency
        		// stat_desc; // the corresponding static tree
        
        		// Compute the optimal bit lengths for a tree and update the total bit
        		// length
        		// for the current block.
        		// IN assertion: the fields freq and dad are set, heap[heap_max] and
        		// above are the tree nodes sorted by increasing frequency.
        		// OUT assertions: the field len is set to the optimal bit length, the
        		// array bl_count contains the frequencies for each bit length.
        		// The length opt_len is updated; static_len is also updated if stree is
        		// not null.
        		function gen_bitlen(s) {
        			var tree = that.dyn_tree;
        			var stree = that.stat_desc.static_tree;
        			var extra = that.stat_desc.extra_bits;
        			var base = that.stat_desc.extra_base;
        			var max_length = that.stat_desc.max_length;
        			var h; // heap index
        			var n, m; // iterate over the tree elements
        			var bits; // bit length
        			var xbits; // extra bits
        			var f; // frequency
        			var overflow = 0; // number of elements with bit length too large
        
        			for (bits = 0; bits <= MAX_BITS; bits++)
        				s.bl_count[bits] = 0;
        
        			// In a first pass, compute the optimal bit lengths (which may
        			// overflow in the case of the bit length tree).
        			tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
        
        			for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
        				n = s.heap[h];
        				bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
        				if (bits > max_length) {
        					bits = max_length;
        					overflow++;
        				}
        				tree[n * 2 + 1] = bits;
        				// We overwrite tree[n*2+1] which is no longer needed
        
        				if (n > that.max_code)
        					continue; // not a leaf node
        
        				s.bl_count[bits]++;
        				xbits = 0;
        				if (n >= base)
        					xbits = extra[n - base];
        				f = tree[n * 2];
        				s.opt_len += f * (bits + xbits);
        				if (stree)
        					s.static_len += f * (stree[n * 2 + 1] + xbits);
        			}
        			if (overflow === 0)
        				return;
        
        			// This happens for example on obj2 and pic of the Calgary corpus
        			// Find the first bit length which could increase:
        			do {
        				bits = max_length - 1;
        				while (s.bl_count[bits] === 0)
        					bits--;
        				s.bl_count[bits]--; // move one leaf down the tree
        				s.bl_count[bits + 1] += 2; // move one overflow item as its brother
        				s.bl_count[max_length]--;
        				// The brother of the overflow item also moves one step up,
        				// but this does not affect bl_count[max_length]
        				overflow -= 2;
        			} while (overflow > 0);
        
        			for (bits = max_length; bits !== 0; bits--) {
        				n = s.bl_count[bits];
        				while (n !== 0) {
        					m = s.heap[--h];
        					if (m > that.max_code)
        						continue;
        					if (tree[m * 2 + 1] != bits) {
        						s.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2];
        						tree[m * 2 + 1] = bits;
        					}
        					n--;
        				}
        			}
        		}
        
        		// Reverse the first len bits of a code, using straightforward code (a
        		// faster
        		// method would use a table)
        		// IN assertion: 1 <= len <= 15
        		function bi_reverse(code, // the value to invert
        		len // its bit length
        		) {
        			var res = 0;
        			do {
        				res |= code & 1;
        				code >>>= 1;
        				res <<= 1;
        			} while (--len > 0);
        			return res >>> 1;
        		}
        
        		// Generate the codes for a given tree and bit counts (which need not be
        		// optimal).
        		// IN assertion: the array bl_count contains the bit length statistics for
        		// the given tree and the field len is set for all tree elements.
        		// OUT assertion: the field code is set for all tree elements of non
        		// zero code length.
        		function gen_codes(tree, // the tree to decorate
        		max_code, // largest code with non zero frequency
        		bl_count // number of codes at each bit length
        		) {
        			var next_code = []; // next code value for each
        			// bit length
        			var code = 0; // running code value
        			var bits; // bit index
        			var n; // code index
        			var len;
        
        			// The distribution counts are first used to generate the code values
        			// without bit reversal.
        			for (bits = 1; bits <= MAX_BITS; bits++) {
        				next_code[bits] = code = ((code + bl_count[bits - 1]) << 1);
        			}
        
        			// Check that the bit counts in bl_count are consistent. The last code
        			// must be all ones.
        			// Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
        			// "inconsistent bit counts");
        			// Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
        
        			for (n = 0; n <= max_code; n++) {
        				len = tree[n * 2 + 1];
        				if (len === 0)
        					continue;
        				// Now reverse the bits
        				tree[n * 2] = bi_reverse(next_code[len]++, len);
        			}
        		}
        
        		// Construct one Huffman tree and assigns the code bit strings and lengths.
        		// Update the total bit length for the current block.
        		// IN assertion: the field freq is set for all tree elements.
        		// OUT assertions: the fields len and code are set to the optimal bit length
        		// and corresponding code. The length opt_len is updated; static_len is
        		// also updated if stree is not null. The field max_code is set.
        		that.build_tree = function(s) {
        			var tree = that.dyn_tree;
        			var stree = that.stat_desc.static_tree;
        			var elems = that.stat_desc.elems;
        			var n, m; // iterate over heap elements
        			var max_code = -1; // largest code with non zero frequency
        			var node; // new node being created
        
        			// Construct the initial heap, with least frequent element in
        			// heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
        			// heap[0] is not used.
        			s.heap_len = 0;
        			s.heap_max = HEAP_SIZE;
        
        			for (n = 0; n < elems; n++) {
        				if (tree[n * 2] !== 0) {
        					s.heap[++s.heap_len] = max_code = n;
        					s.depth[n] = 0;
        				} else {
        					tree[n * 2 + 1] = 0;
        				}
        			}
        
        			// The pkzip format requires that at least one distance code exists,
        			// and that at least one bit should be sent even if there is only one
        			// possible code. So to avoid special checks later on we force at least
        			// two codes of non zero frequency.
        			while (s.heap_len < 2) {
        				node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;
        				tree[node * 2] = 1;
        				s.depth[node] = 0;
        				s.opt_len--;
        				if (stree)
        					s.static_len -= stree[node * 2 + 1];
        				// node is 0 or 1 so it does not have extra bits
        			}
        			that.max_code = max_code;
        
        			// The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
        			// establish sub-heaps of increasing lengths:
        
        			for (n = Math.floor(s.heap_len / 2); n >= 1; n--)
        				s.pqdownheap(tree, n);
        
        			// Construct the Huffman tree by repeatedly combining the least two
        			// frequent nodes.
        
        			node = elems; // next internal node of the tree
        			do {
        				// n = node of least frequency
        				n = s.heap[1];
        				s.heap[1] = s.heap[s.heap_len--];
        				s.pqdownheap(tree, 1);
        				m = s.heap[1]; // m = node of next least frequency
        
        				s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
        				s.heap[--s.heap_max] = m;
        
        				// Create a new node father of n and m
        				tree[node * 2] = (tree[n * 2] + tree[m * 2]);
        				s.depth[node] = Math.max(s.depth[n], s.depth[m]) + 1;
        				tree[n * 2 + 1] = tree[m * 2 + 1] = node;
        
        				// and insert the new node in the heap
        				s.heap[1] = node++;
        				s.pqdownheap(tree, 1);
        			} while (s.heap_len >= 2);
        
        			s.heap[--s.heap_max] = s.heap[1];
        
        			// At this point, the fields freq and dad are set. We can now
        			// generate the bit lengths.
        
        			gen_bitlen(s);
        
        			// The field len is now set, we can generate the bit codes
        			gen_codes(tree, that.max_code, s.bl_count);
        		};
        
        	}
        
        	Tree._length_code = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
        			16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,
        			20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
        			22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
        			24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
        			25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
        			26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 ];
        
        	Tree.base_length = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 ];
        
        	Tree.base_dist = [ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384,
        			24576 ];
        
        	// Mapping from a distance to a distance code. dist is the distance - 1 and
        	// must not have side effects. _dist_code[256] and _dist_code[257] are never
        	// used.
        	Tree.d_code = function(dist) {
        		return ((dist) < 256 ? _dist_code[dist] : _dist_code[256 + ((dist) >>> 7)]);
        	};
        
        	// extra bits for each length code
        	Tree.extra_lbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 ];
        
        	// extra bits for each distance code
        	Tree.extra_dbits = [ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ];
        
        	// extra bits for each bit length code
        	Tree.extra_blbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 ];
        
        	Tree.bl_order = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
        
        	// StaticTree
        
        	function StaticTree(static_tree, extra_bits, extra_base, elems, max_length) {
        		var that = this;
        		that.static_tree = static_tree;
        		that.extra_bits = extra_bits;
        		that.extra_base = extra_base;
        		that.elems = elems;
        		that.max_length = max_length;
        	}
        
        	StaticTree.static_ltree = [ 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8,
        			130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42,
        			8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8,
        			22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8,
        			222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113,
        			8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8,
        			69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8,
        			173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9,
        			51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9,
        			427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379,
        			9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23,
        			9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9,
        			399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9,
        			223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7,
        			40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8,
        			99, 8, 227, 8 ];
        
        	StaticTree.static_dtree = [ 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5,
        			25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 ];
        
        	StaticTree.static_l_desc = new StaticTree(StaticTree.static_ltree, Tree.extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
        
        	StaticTree.static_d_desc = new StaticTree(StaticTree.static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS);
        
        	StaticTree.static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS);
        
        	// Deflate
        
        	var MAX_MEM_LEVEL = 9;
        	var DEF_MEM_LEVEL = 8;
        
        	function Config(good_length, max_lazy, nice_length, max_chain, func) {
        		var that = this;
        		that.good_length = good_length;
        		that.max_lazy = max_lazy;
        		that.nice_length = nice_length;
        		that.max_chain = max_chain;
        		that.func = func;
        	}
        
        	var STORED = 0;
        	var FAST = 1;
        	var SLOW = 2;
        	var config_table = [ new Config(0, 0, 0, 0, STORED), new Config(4, 4, 8, 4, FAST), new Config(4, 5, 16, 8, FAST), new Config(4, 6, 32, 32, FAST),
        			new Config(4, 4, 16, 16, SLOW), new Config(8, 16, 32, 32, SLOW), new Config(8, 16, 128, 128, SLOW), new Config(8, 32, 128, 256, SLOW),
        			new Config(32, 128, 258, 1024, SLOW), new Config(32, 258, 258, 4096, SLOW) ];
        
        	var z_errmsg = [ "need dictionary", // Z_NEED_DICT
        	// 2
        	"stream end", // Z_STREAM_END 1
        	"", // Z_OK 0
        	"", // Z_ERRNO (-1)
        	"stream error", // Z_STREAM_ERROR (-2)
        	"data error", // Z_DATA_ERROR (-3)
        	"", // Z_MEM_ERROR (-4)
        	"buffer error", // Z_BUF_ERROR (-5)
        	"",// Z_VERSION_ERROR (-6)
        	"" ];
        
        	// block not completed, need more input or more output
        	var NeedMore = 0;
        
        	// block flush performed
        	var BlockDone = 1;
        
        	// finish started, need only more output at next deflate
        	var FinishStarted = 2;
        
        	// finish done, accept no more input or output
        	var FinishDone = 3;
        
        	// preset dictionary flag in zlib header
        	var PRESET_DICT = 0x20;
        
        	var INIT_STATE = 42;
        	var BUSY_STATE = 113;
        	var FINISH_STATE = 666;
        
        	// The deflate compression method
        	var Z_DEFLATED = 8;
        
        	var STORED_BLOCK = 0;
        	var STATIC_TREES = 1;
        	var DYN_TREES = 2;
        
        	var MIN_MATCH = 3;
        	var MAX_MATCH = 258;
        	var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
        
        	function smaller(tree, n, m, depth) {
        		var tn2 = tree[n * 2];
        		var tm2 = tree[m * 2];
        		return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m]));
        	}
        
        	function Deflate() {
        
        		var that = this;
        		var strm; // pointer back to this zlib stream
        		var status; // as the name implies
        		// pending_buf; // output still pending
        		var pending_buf_size; // size of pending_buf
        		// pending_out; // next pending byte to output to the stream
        		// pending; // nb of bytes in the pending buffer
        		var method; // STORED (for zip only) or DEFLATED
        		var last_flush; // value of flush param for previous deflate call
        
        		var w_size; // LZ77 window size (32K by default)
        		var w_bits; // log2(w_size) (8..16)
        		var w_mask; // w_size - 1
        
        		var window;
        		// Sliding window. Input bytes are read into the second half of the window,
        		// and move to the first half later to keep a dictionary of at least wSize
        		// bytes. With this organization, matches are limited to a distance of
        		// wSize-MAX_MATCH bytes, but this ensures that IO is always
        		// performed with a length multiple of the block size. Also, it limits
        		// the window size to 64K, which is quite useful on MSDOS.
        		// To do: use the user input buffer as sliding window.
        
        		var window_size;
        		// Actual size of window: 2*wSize, except when the user input buffer
        		// is directly used as sliding window.
        
        		var prev;
        		// Link to older string with same hash index. To limit the size of this
        		// array to 64K, this link is maintained only for the last 32K strings.
        		// An index in this array is thus a window index modulo 32K.
        
        		var head; // Heads of the hash chains or NIL.
        
        		var ins_h; // hash index of string to be inserted
        		var hash_size; // number of elements in hash table
        		var hash_bits; // log2(hash_size)
        		var hash_mask; // hash_size-1
        
        		// Number of bits by which ins_h must be shifted at each input
        		// step. It must be such that after MIN_MATCH steps, the oldest
        		// byte no longer takes part in the hash key, that is:
        		// hash_shift * MIN_MATCH >= hash_bits
        		var hash_shift;
        
        		// Window position at the beginning of the current output block. Gets
        		// negative when the window is moved backwards.
        
        		var block_start;
        
        		var match_length; // length of best match
        		var prev_match; // previous match
        		var match_available; // set if previous match exists
        		var strstart; // start of string to insert
        		var match_start; // start of matching string
        		var lookahead; // number of valid bytes ahead in window
        
        		// Length of the best match at previous step. Matches not greater than this
        		// are discarded. This is used in the lazy match evaluation.
        		var prev_length;
        
        		// To speed up deflation, hash chains are never searched beyond this
        		// length. A higher limit improves compression ratio but degrades the speed.
        		var max_chain_length;
        
        		// Attempt to find a better match only when the current match is strictly
        		// smaller than this value. This mechanism is used only for compression
        		// levels >= 4.
        		var max_lazy_match;
        
        		// Insert new strings in the hash table only if the match length is not
        		// greater than this length. This saves time but degrades compression.
        		// max_insert_length is used only for compression levels <= 3.
        
        		var level; // compression level (1..9)
        		var strategy; // favor or force Huffman coding
        
        		// Use a faster search when the previous match is longer than this
        		var good_match;
        
        		// Stop searching when current match exceeds this
        		var nice_match;
        
        		var dyn_ltree; // literal and length tree
        		var dyn_dtree; // distance tree
        		var bl_tree; // Huffman tree for bit lengths
        
        		var l_desc = new Tree(); // desc for literal tree
        		var d_desc = new Tree(); // desc for distance tree
        		var bl_desc = new Tree(); // desc for bit length tree
        
        		// that.heap_len; // number of elements in the heap
        		// that.heap_max; // element of largest frequency
        		// The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
        		// The same heap array is used to build all trees.
        
        		// Depth of each subtree used as tie breaker for trees of equal frequency
        		that.depth = [];
        
        		var l_buf; // index for literals or lengths */
        
        		// Size of match buffer for literals/lengths. There are 4 reasons for
        		// limiting lit_bufsize to 64K:
        		// - frequencies can be kept in 16 bit counters
        		// - if compression is not successful for the first block, all input
        		// data is still in the window so we can still emit a stored block even
        		// when input comes from standard input. (This can also be done for
        		// all blocks if lit_bufsize is not greater than 32K.)
        		// - if compression is not successful for a file smaller than 64K, we can
        		// even emit a stored file instead of a stored block (saving 5 bytes).
        		// This is applicable only for zip (not gzip or zlib).
        		// - creating new Huffman trees less frequently may not provide fast
        		// adaptation to changes in the input data statistics. (Take for
        		// example a binary file with poorly compressible code followed by
        		// a highly compressible string table.) Smaller buffer sizes give
        		// fast adaptation but have of course the overhead of transmitting
        		// trees more frequently.
        		// - I can't count above 4
        		var lit_bufsize;
        
        		var last_lit; // running index in l_buf
        
        		// Buffer for distances. To simplify the code, d_buf and l_buf have
        		// the same number of elements. To use different lengths, an extra flag
        		// array would be necessary.
        
        		var d_buf; // index of pendig_buf
        
        		// that.opt_len; // bit length of current block with optimal trees
        		// that.static_len; // bit length of current block with static trees
        		var matches; // number of string matches in current block
        		var last_eob_len; // bit length of EOB code for last block
        
        		// Output buffer. bits are inserted starting at the bottom (least
        		// significant bits).
        		var bi_buf;
        
        		// Number of valid bits in bi_buf. All bits above the last valid bit
        		// are always zero.
        		var bi_valid;
        
        		// number of codes at each bit length for an optimal tree
        		that.bl_count = [];
        
        		// heap used to build the Huffman trees
        		that.heap = [];
        
        		dyn_ltree = [];
        		dyn_dtree = [];
        		bl_tree = [];
        
        		function lm_init() {
        			var i;
        			window_size = 2 * w_size;
        
        			head[hash_size - 1] = 0;
        			for (i = 0; i < hash_size - 1; i++) {
        				head[i] = 0;
        			}
        
        			// Set the default configuration parameters:
        			max_lazy_match = config_table[level].max_lazy;
        			good_match = config_table[level].good_length;
        			nice_match = config_table[level].nice_length;
        			max_chain_length = config_table[level].max_chain;
        
        			strstart = 0;
        			block_start = 0;
        			lookahead = 0;
        			match_length = prev_length = MIN_MATCH - 1;
        			match_available = 0;
        			ins_h = 0;
        		}
        
        		function init_block() {
        			var i;
        			// Initialize the trees.
        			for (i = 0; i < L_CODES; i++)
        				dyn_ltree[i * 2] = 0;
        			for (i = 0; i < D_CODES; i++)
        				dyn_dtree[i * 2] = 0;
        			for (i = 0; i < BL_CODES; i++)
        				bl_tree[i * 2] = 0;
        
        			dyn_ltree[END_BLOCK * 2] = 1;
        			that.opt_len = that.static_len = 0;
        			last_lit = matches = 0;
        		}
        
        		// Initialize the tree data structures for a new zlib stream.
        		function tr_init() {
        
        			l_desc.dyn_tree = dyn_ltree;
        			l_desc.stat_desc = StaticTree.static_l_desc;
        
        			d_desc.dyn_tree = dyn_dtree;
        			d_desc.stat_desc = StaticTree.static_d_desc;
        
        			bl_desc.dyn_tree = bl_tree;
        			bl_desc.stat_desc = StaticTree.static_bl_desc;
        
        			bi_buf = 0;
        			bi_valid = 0;
        			last_eob_len = 8; // enough lookahead for inflate
        
        			// Initialize the first block of the first file:
        			init_block();
        		}
        
        		// Restore the heap property by moving down the tree starting at node k,
        		// exchanging a node with the smallest of its two sons if necessary,
        		// stopping
        		// when the heap property is re-established (each father smaller than its
        		// two sons).
        		that.pqdownheap = function(tree, // the tree to restore
        		k // node to move down
        		) {
        			var heap = that.heap;
        			var v = heap[k];
        			var j = k << 1; // left son of k
        			while (j <= that.heap_len) {
        				// Set j to the smallest of the two sons:
        				if (j < that.heap_len && smaller(tree, heap[j + 1], heap[j], that.depth)) {
        					j++;
        				}
        				// Exit if v is smaller than both sons
        				if (smaller(tree, v, heap[j], that.depth))
        					break;
        
        				// Exchange v with the smallest son
        				heap[k] = heap[j];
        				k = j;
        				// And continue down the tree, setting j to the left son of k
        				j <<= 1;
        			}
        			heap[k] = v;
        		};
        
        		// Scan a literal or distance tree to determine the frequencies of the codes
        		// in the bit length tree.
        		function scan_tree(tree,// the tree to be scanned
        		max_code // and its largest code of non zero frequency
        		) {
        			var n; // iterates over all tree elements
        			var prevlen = -1; // last emitted length
        			var curlen; // length of current code
        			var nextlen = tree[0 * 2 + 1]; // length of next code
        			var count = 0; // repeat count of the current code
        			var max_count = 7; // max repeat count
        			var min_count = 4; // min repeat count
        
        			if (nextlen === 0) {
        				max_count = 138;
        				min_count = 3;
        			}
        			tree[(max_code + 1) * 2 + 1] = 0xffff; // guard
        
        			for (n = 0; n <= max_code; n++) {
        				curlen = nextlen;
        				nextlen = tree[(n + 1) * 2 + 1];
        				if (++count < max_count && curlen == nextlen) {
        					continue;
        				} else if (count < min_count) {
        					bl_tree[curlen * 2] += count;
        				} else if (curlen !== 0) {
        					if (curlen != prevlen)
        						bl_tree[curlen * 2]++;
        					bl_tree[REP_3_6 * 2]++;
        				} else if (count <= 10) {
        					bl_tree[REPZ_3_10 * 2]++;
        				} else {
        					bl_tree[REPZ_11_138 * 2]++;
        				}
        				count = 0;
        				prevlen = curlen;
        				if (nextlen === 0) {
        					max_count = 138;
        					min_count = 3;
        				} else if (curlen == nextlen) {
        					max_count = 6;
        					min_count = 3;
        				} else {
        					max_count = 7;
        					min_count = 4;
        				}
        			}
        		}
        
        		// Construct the Huffman tree for the bit lengths and return the index in
        		// bl_order of the last bit length code to send.
        		function build_bl_tree() {
        			var max_blindex; // index of last bit length code of non zero freq
        
        			// Determine the bit length frequencies for literal and distance trees
        			scan_tree(dyn_ltree, l_desc.max_code);
        			scan_tree(dyn_dtree, d_desc.max_code);
        
        			// Build the bit length tree:
        			bl_desc.build_tree(that);
        			// opt_len now includes the length of the tree representations, except
        			// the lengths of the bit lengths codes and the 5+5+4 bits for the
        			// counts.
        
        			// Determine the number of bit length codes to send. The pkzip format
        			// requires that at least 4 bit length codes be sent. (appnote.txt says
        			// 3 but the actual value used is 4.)
        			for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
        				if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] !== 0)
        					break;
        			}
        			// Update opt_len to include the bit length tree and counts
        			that.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
        
        			return max_blindex;
        		}
        
        		// Output a byte on the stream.
        		// IN assertion: there is enough room in pending_buf.
        		function put_byte(p) {
        			that.pending_buf[that.pending++] = p;
        		}
        
        		function put_short(w) {
        			put_byte(w & 0xff);
        			put_byte((w >>> 8) & 0xff);
        		}
        
        		function putShortMSB(b) {
        			put_byte((b >> 8) & 0xff);
        			put_byte((b & 0xff) & 0xff);
        		}
        
        		function send_bits(value, length) {
        			var val, len = length;
        			if (bi_valid > Buf_size - len) {
        				val = value;
        				// bi_buf |= (val << bi_valid);
        				bi_buf |= ((val << bi_valid) & 0xffff);
        				put_short(bi_buf);
        				bi_buf = val >>> (Buf_size - bi_valid);
        				bi_valid += len - Buf_size;
        			} else {
        				// bi_buf |= (value) << bi_valid;
        				bi_buf |= (((value) << bi_valid) & 0xffff);
        				bi_valid += len;
        			}
        		}
        
        		function send_code(c, tree) {
        			var c2 = c * 2;
        			send_bits(tree[c2] & 0xffff, tree[c2 + 1] & 0xffff);
        		}
        
        		// Send a literal or distance tree in compressed form, using the codes in
        		// bl_tree.
        		function send_tree(tree,// the tree to be sent
        		max_code // and its largest code of non zero frequency
        		) {
        			var n; // iterates over all tree elements
        			var prevlen = -1; // last emitted length
        			var curlen; // length of current code
        			var nextlen = tree[0 * 2 + 1]; // length of next code
        			var count = 0; // repeat count of the current code
        			var max_count = 7; // max repeat count
        			var min_count = 4; // min repeat count
        
        			if (nextlen === 0) {
        				max_count = 138;
        				min_count = 3;
        			}
        
        			for (n = 0; n <= max_code; n++) {
        				curlen = nextlen;
        				nextlen = tree[(n + 1) * 2 + 1];
        				if (++count < max_count && curlen == nextlen) {
        					continue;
        				} else if (count < min_count) {
        					do {
        						send_code(curlen, bl_tree);
        					} while (--count !== 0);
        				} else if (curlen !== 0) {
        					if (curlen != prevlen) {
        						send_code(curlen, bl_tree);
        						count--;
        					}
        					send_code(REP_3_6, bl_tree);
        					send_bits(count - 3, 2);
        				} else if (count <= 10) {
        					send_code(REPZ_3_10, bl_tree);
        					send_bits(count - 3, 3);
        				} else {
        					send_code(REPZ_11_138, bl_tree);
        					send_bits(count - 11, 7);
        				}
        				count = 0;
        				prevlen = curlen;
        				if (nextlen === 0) {
        					max_count = 138;
        					min_count = 3;
        				} else if (curlen == nextlen) {
        					max_count = 6;
        					min_count = 3;
        				} else {
        					max_count = 7;
        					min_count = 4;
        				}
        			}
        		}
        
        		// Send the header for a block using dynamic Huffman trees: the counts, the
        		// lengths of the bit length codes, the literal tree and the distance tree.
        		// IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
        		function send_all_trees(lcodes, dcodes, blcodes) {
        			var rank; // index in bl_order
        
        			send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
        			send_bits(dcodes - 1, 5);
        			send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
        			for (rank = 0; rank < blcodes; rank++) {
        				send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
        			}
        			send_tree(dyn_ltree, lcodes - 1); // literal tree
        			send_tree(dyn_dtree, dcodes - 1); // distance tree
        		}
        
        		// Flush the bit buffer, keeping at most 7 bits in it.
        		function bi_flush() {
        			if (bi_valid == 16) {
        				put_short(bi_buf);
        				bi_buf = 0;
        				bi_valid = 0;
        			} else if (bi_valid >= 8) {
        				put_byte(bi_buf & 0xff);
        				bi_buf >>>= 8;
        				bi_valid -= 8;
        			}
        		}
        
        		// Send one empty static block to give enough lookahead for inflate.
        		// This takes 10 bits, of which 7 may remain in the bit buffer.
        		// The current inflate code requires 9 bits of lookahead. If the
        		// last two codes for the previous block (real code plus EOB) were coded
        		// on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
        		// the last real code. In this case we send two empty static blocks instead
        		// of one. (There are no problems if the previous block is stored or fixed.)
        		// To simplify the code, we assume the worst case of last real code encoded
        		// on one bit only.
        		function _tr_align() {
        			send_bits(STATIC_TREES << 1, 3);
        			send_code(END_BLOCK, StaticTree.static_ltree);
        
        			bi_flush();
        
        			// Of the 10 bits for the empty block, we have already sent
        			// (10 - bi_valid) bits. The lookahead for the last real code (before
        			// the EOB of the previous block) was thus at least one plus the length
        			// of the EOB plus what we have just sent of the empty static block.
        			if (1 + last_eob_len + 10 - bi_valid < 9) {
        				send_bits(STATIC_TREES << 1, 3);
        				send_code(END_BLOCK, StaticTree.static_ltree);
        				bi_flush();
        			}
        			last_eob_len = 7;
        		}
        
        		// Save the match info and tally the frequency counts. Return true if
        		// the current block must be flushed.
        		function _tr_tally(dist, // distance of matched string
        		lc // match length-MIN_MATCH or unmatched char (if dist==0)
        		) {
        			var out_length, in_length, dcode;
        			that.pending_buf[d_buf + last_lit * 2] = (dist >>> 8) & 0xff;
        			that.pending_buf[d_buf + last_lit * 2 + 1] = dist & 0xff;
        
        			that.pending_buf[l_buf + last_lit] = lc & 0xff;
        			last_lit++;
        
        			if (dist === 0) {
        				// lc is the unmatched char
        				dyn_ltree[lc * 2]++;
        			} else {
        				matches++;
        				// Here, lc is the match length - MIN_MATCH
        				dist--; // dist = match distance - 1
        				dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++;
        				dyn_dtree[Tree.d_code(dist) * 2]++;
        			}
        
        			if ((last_lit & 0x1fff) === 0 && level > 2) {
        				// Compute an upper bound for the compressed length
        				out_length = last_lit * 8;
        				in_length = strstart - block_start;
        				for (dcode = 0; dcode < D_CODES; dcode++) {
        					out_length += dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]);
        				}
        				out_length >>>= 3;
        				if ((matches < Math.floor(last_lit / 2)) && out_length < Math.floor(in_length / 2))
        					return true;
        			}
        
        			return (last_lit == lit_bufsize - 1);
        			// We avoid equality with lit_bufsize because of wraparound at 64K
        			// on 16 bit machines and because stored blocks are restricted to
        			// 64K-1 bytes.
        		}
        
        		// Send the block data compressed using the given Huffman trees
        		function compress_block(ltree, dtree) {
        			var dist; // distance of matched string
        			var lc; // match length or unmatched char (if dist === 0)
        			var lx = 0; // running index in l_buf
        			var code; // the code to send
        			var extra; // number of extra bits to send
        
        			if (last_lit !== 0) {
        				do {
        					dist = ((that.pending_buf[d_buf + lx * 2] << 8) & 0xff00) | (that.pending_buf[d_buf + lx * 2 + 1] & 0xff);
        					lc = (that.pending_buf[l_buf + lx]) & 0xff;
        					lx++;
        
        					if (dist === 0) {
        						send_code(lc, ltree); // send a literal byte
        					} else {
        						// Here, lc is the match length - MIN_MATCH
        						code = Tree._length_code[lc];
        
        						send_code(code + LITERALS + 1, ltree); // send the length
        						// code
        						extra = Tree.extra_lbits[code];
        						if (extra !== 0) {
        							lc -= Tree.base_length[code];
        							send_bits(lc, extra); // send the extra length bits
        						}
        						dist--; // dist is now the match distance - 1
        						code = Tree.d_code(dist);
        
        						send_code(code, dtree); // send the distance code
        						extra = Tree.extra_dbits[code];
        						if (extra !== 0) {
        							dist -= Tree.base_dist[code];
        							send_bits(dist, extra); // send the extra distance bits
        						}
        					} // literal or match pair ?
        
        					// Check that the overlay between pending_buf and d_buf+l_buf is
        					// ok:
        				} while (lx < last_lit);
        			}
        
        			send_code(END_BLOCK, ltree);
        			last_eob_len = ltree[END_BLOCK * 2 + 1];
        		}
        
        		// Flush the bit buffer and align the output on a byte boundary
        		function bi_windup() {
        			if (bi_valid > 8) {
        				put_short(bi_buf);
        			} else if (bi_valid > 0) {
        				put_byte(bi_buf & 0xff);
        			}
        			bi_buf = 0;
        			bi_valid = 0;
        		}
        
        		// Copy a stored block, storing first the length and its
        		// one's complement if requested.
        		function copy_block(buf, // the input data
        		len, // its length
        		header // true if block header must be written
        		) {
        			bi_windup(); // align on byte boundary
        			last_eob_len = 8; // enough lookahead for inflate
        
        			if (header) {
        				put_short(len);
        				put_short(~len);
        			}
        
        			that.pending_buf.set(window.subarray(buf, buf + len), that.pending);
        			that.pending += len;
        		}
        
        		// Send a stored block
        		function _tr_stored_block(buf, // input block
        		stored_len, // length of input block
        		eof // true if this is the last block for a file
        		) {
        			send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type
        			copy_block(buf, stored_len, true); // with header
        		}
        
        		// Determine the best encoding for the current block: dynamic trees, static
        		// trees or store, and output the encoded block to the zip file.
        		function _tr_flush_block(buf, // input block, or NULL if too old
        		stored_len, // length of input block
        		eof // true if this is the last block for a file
        		) {
        			var opt_lenb, static_lenb;// opt_len and static_len in bytes
        			var max_blindex = 0; // index of last bit length code of non zero freq
        
        			// Build the Huffman trees unless a stored block is forced
        			if (level > 0) {
        				// Construct the literal and distance trees
        				l_desc.build_tree(that);
        
        				d_desc.build_tree(that);
        
        				// At this point, opt_len and static_len are the total bit lengths
        				// of
        				// the compressed block data, excluding the tree representations.
        
        				// Build the bit length tree for the above two trees, and get the
        				// index
        				// in bl_order of the last bit length code to send.
        				max_blindex = build_bl_tree();
        
        				// Determine the best encoding. Compute first the block length in
        				// bytes
        				opt_lenb = (that.opt_len + 3 + 7) >>> 3;
        				static_lenb = (that.static_len + 3 + 7) >>> 3;
        
        				if (static_lenb <= opt_lenb)
        					opt_lenb = static_lenb;
        			} else {
        				opt_lenb = static_lenb = stored_len + 5; // force a stored block
        			}
        
        			if ((stored_len + 4 <= opt_lenb) && buf != -1) {
        				// 4: two words for the lengths
        				// The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
        				// Otherwise we can't have processed more than WSIZE input bytes
        				// since
        				// the last block flush, because compression would have been
        				// successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
        				// transform a block into a stored block.
        				_tr_stored_block(buf, stored_len, eof);
        			} else if (static_lenb == opt_lenb) {
        				send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);
        				compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
        			} else {
        				send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
        				send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1);
        				compress_block(dyn_ltree, dyn_dtree);
        			}
        
        			// The above check is made mod 2^32, for files larger than 512 MB
        			// and uLong implemented on 32 bits.
        
        			init_block();
        
        			if (eof) {
        				bi_windup();
        			}
        		}
        
        		function flush_block_only(eof) {
        			_tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof);
        			block_start = strstart;
        			strm.flush_pending();
        		}
        
        		// Fill the window when the lookahead becomes insufficient.
        		// Updates strstart and lookahead.
        		//
        		// IN assertion: lookahead < MIN_LOOKAHEAD
        		// OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
        		// At least one byte has been read, or avail_in === 0; reads are
        		// performed for at least two bytes (required for the zip translate_eol
        		// option -- not supported here).
        		function fill_window() {
        			var n, m;
        			var p;
        			var more; // Amount of free space at the end of the window.
        
        			do {
        				more = (window_size - lookahead - strstart);
        
        				// Deal with !@#$% 64K limit:
        				if (more === 0 && strstart === 0 && lookahead === 0) {
        					more = w_size;
        				} else if (more == -1) {
        					// Very unlikely, but possible on 16 bit machine if strstart ==
        					// 0
        					// and lookahead == 1 (input done one byte at time)
        					more--;
        
        					// If the window is almost full and there is insufficient
        					// lookahead,
        					// move the upper half to the lower one to make room in the
        					// upper half.
        				} else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) {
        					window.set(window.subarray(w_size, w_size + w_size), 0);
        
        					match_start -= w_size;
        					strstart -= w_size; // we now have strstart >= MAX_DIST
        					block_start -= w_size;
        
        					// Slide the hash table (could be avoided with 32 bit values
        					// at the expense of memory usage). We slide even when level ==
        					// 0
        					// to keep the hash table consistent if we switch back to level
        					// > 0
        					// later. (Using level 0 permanently is not an optimal usage of
        					// zlib, so we don't care about this pathological case.)
        
        					n = hash_size;
        					p = n;
        					do {
        						m = (head[--p] & 0xffff);
        						head[p] = (m >= w_size ? m - w_size : 0);
        					} while (--n !== 0);
        
        					n = w_size;
        					p = n;
        					do {
        						m = (prev[--p] & 0xffff);
        						prev[p] = (m >= w_size ? m - w_size : 0);
        						// If n is not on any hash chain, prev[n] is garbage but
        						// its value will never be used.
        					} while (--n !== 0);
        					more += w_size;
        				}
        
        				if (strm.avail_in === 0)
        					return;
        
        				// If there was no sliding:
        				// strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
        				// more == window_size - lookahead - strstart
        				// => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
        				// => more >= window_size - 2*WSIZE + 2
        				// In the BIG_MEM or MMAP case (not yet supported),
        				// window_size == input_size + MIN_LOOKAHEAD &&
        				// strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
        				// Otherwise, window_size == 2*WSIZE so more >= 2.
        				// If there was sliding, more >= WSIZE. So in all cases, more >= 2.
        
        				n = strm.read_buf(window, strstart + lookahead, more);
        				lookahead += n;
        
        				// Initialize the hash value now that we have some input:
        				if (lookahead >= MIN_MATCH) {
        					ins_h = window[strstart] & 0xff;
        					ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
        				}
        				// If the whole input has less than MIN_MATCH bytes, ins_h is
        				// garbage,
        				// but this is not important since only literal bytes will be
        				// emitted.
        			} while (lookahead < MIN_LOOKAHEAD && strm.avail_in !== 0);
        		}
        
        		// Copy without compression as much as possible from the input stream,
        		// return
        		// the current block state.
        		// This function does not insert new strings in the dictionary since
        		// uncompressible data is probably not useful. This function is used
        		// only for the level=0 compression option.
        		// NOTE: this function should be optimized to avoid extra copying from
        		// window to pending_buf.
        		function deflate_stored(flush) {
        			// Stored blocks are limited to 0xffff bytes, pending_buf is limited
        			// to pending_buf_size, and each stored block has a 5 byte header:
        
        			var max_block_size = 0xffff;
        			var max_start;
        
        			if (max_block_size > pending_buf_size - 5) {
        				max_block_size = pending_buf_size - 5;
        			}
        
        			// Copy as much as possible from input to output:
        			while (true) {
        				// Fill the window as much as possible:
        				if (lookahead <= 1) {
        					fill_window();
        					if (lookahead === 0 && flush == Z_NO_FLUSH)
        						return NeedMore;
        					if (lookahead === 0)
        						break; // flush the current block
        				}
        
        				strstart += lookahead;
        				lookahead = 0;
        
        				// Emit a stored block if pending_buf will be full:
        				max_start = block_start + max_block_size;
        				if (strstart === 0 || strstart >= max_start) {
        					// strstart === 0 is possible when wraparound on 16-bit machine
        					lookahead = (strstart - max_start);
        					strstart = max_start;
        
        					flush_block_only(false);
        					if (strm.avail_out === 0)
        						return NeedMore;
        
        				}
        
        				// Flush if we may have to slide, otherwise block_start may become
        				// negative and the data will be gone:
        				if (strstart - block_start >= w_size - MIN_LOOKAHEAD) {
        					flush_block_only(false);
        					if (strm.avail_out === 0)
        						return NeedMore;
        				}
        			}
        
        			flush_block_only(flush == Z_FINISH);
        			if (strm.avail_out === 0)
        				return (flush == Z_FINISH) ? FinishStarted : NeedMore;
        
        			return flush == Z_FINISH ? FinishDone : BlockDone;
        		}
        
        		function longest_match(cur_match) {
        			var chain_length = max_chain_length; // max hash chain length
        			var scan = strstart; // current string
        			var match; // matched string
        			var len; // length of current match
        			var best_len = prev_length; // best match length so far
        			var limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0;
        			var _nice_match = nice_match;
        
        			// Stop when cur_match becomes <= limit. To simplify the code,
        			// we prevent matches with the string of window index 0.
        
        			var wmask = w_mask;
        
        			var strend = strstart + MAX_MATCH;
        			var scan_end1 = window[scan + best_len - 1];
        			var scan_end = window[scan + best_len];
        
        			// The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of
        			// 16.
        			// It is easy to get rid of this optimization if necessary.
        
        			// Do not waste too much time if we already have a good match:
        			if (prev_length >= good_match) {
        				chain_length >>= 2;
        			}
        
        			// Do not look for matches beyond the end of the input. This is
        			// necessary
        			// to make deflate deterministic.
        			if (_nice_match > lookahead)
        				_nice_match = lookahead;
        
        			do {
        				match = cur_match;
        
        				// Skip to next match if the match length cannot increase
        				// or if the match length is less than 2:
        				if (window[match + best_len] != scan_end || window[match + best_len - 1] != scan_end1 || window[match] != window[scan]
        						|| window[++match] != window[scan + 1])
        					continue;
        
        				// The check at best_len-1 can be removed because it will be made
        				// again later. (This heuristic is not always a win.)
        				// It is not necessary to compare scan[2] and match[2] since they
        				// are always equal when the other bytes match, given that
        				// the hash keys are equal and that HASH_BITS >= 8.
        				scan += 2;
        				match++;
        
        				// We check for insufficient lookahead only every 8th comparison;
        				// the 256th check will be made at strstart+258.
        				do {
        				} while (window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]
        						&& window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]
        						&& window[++scan] == window[++match] && window[++scan] == window[++match] && scan < strend);
        
        				len = MAX_MATCH - (strend - scan);
        				scan = strend - MAX_MATCH;
        
        				if (len > best_len) {
        					match_start = cur_match;
        					best_len = len;
        					if (len >= _nice_match)
        						break;
        					scan_end1 = window[scan + best_len - 1];
        					scan_end = window[scan + best_len];
        				}
        
        			} while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length !== 0);
        
        			if (best_len <= lookahead)
        				return best_len;
        			return lookahead;
        		}
        
        		// Compress as much as possible from the input stream, return the current
        		// block state.
        		// This function does not perform lazy evaluation of matches and inserts
        		// new strings in the dictionary only for unmatched strings or for short
        		// matches. It is used only for the fast compression options.
        		function deflate_fast(flush) {
        			// short hash_head = 0; // head of the hash chain
        			var hash_head = 0; // head of the hash chain
        			var bflush; // set if current block must be flushed
        
        			while (true) {
        				// Make sure that we always have enough lookahead, except
        				// at the end of the input file. We need MAX_MATCH bytes
        				// for the next match, plus MIN_MATCH bytes to insert the
        				// string following the next match.
        				if (lookahead < MIN_LOOKAHEAD) {
        					fill_window();
        					if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
        						return NeedMore;
        					}
        					if (lookahead === 0)
        						break; // flush the current block
        				}
        
        				// Insert the string window[strstart .. strstart+2] in the
        				// dictionary, and set hash_head to the head of the hash chain:
        				if (lookahead >= MIN_MATCH) {
        					ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
        
        					// prev[strstart&w_mask]=hash_head=head[ins_h];
        					hash_head = (head[ins_h] & 0xffff);
        					prev[strstart & w_mask] = head[ins_h];
        					head[ins_h] = strstart;
        				}
        
        				// Find the longest match, discarding those <= prev_length.
        				// At this point we have always match_length < MIN_MATCH
        
        				if (hash_head !== 0 && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) {
        					// To simplify the code, we prevent matches with the string
        					// of window index 0 (in particular we have to avoid a match
        					// of the string with itself at the start of the input file).
        					if (strategy != Z_HUFFMAN_ONLY) {
        						match_length = longest_match(hash_head);
        					}
        					// longest_match() sets match_start
        				}
        				if (match_length >= MIN_MATCH) {
        					// check_match(strstart, match_start, match_length);
        
        					bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
        
        					lookahead -= match_length;
        
        					// Insert new strings in the hash table only if the match length
        					// is not too large. This saves time but degrades compression.
        					if (match_length <= max_lazy_match && lookahead >= MIN_MATCH) {
        						match_length--; // string at strstart already in hash table
        						do {
        							strstart++;
        
        							ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
        							// prev[strstart&w_mask]=hash_head=head[ins_h];
        							hash_head = (head[ins_h] & 0xffff);
        							prev[strstart & w_mask] = head[ins_h];
        							head[ins_h] = strstart;
        
        							// strstart never exceeds WSIZE-MAX_MATCH, so there are
        							// always MIN_MATCH bytes ahead.
        						} while (--match_length !== 0);
        						strstart++;
        					} else {
        						strstart += match_length;
        						match_length = 0;
        						ins_h = window[strstart] & 0xff;
        
        						ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
        						// If lookahead < MIN_MATCH, ins_h is garbage, but it does
        						// not
        						// matter since it will be recomputed at next deflate call.
        					}
        				} else {
        					// No match, output a literal byte
        
        					bflush = _tr_tally(0, window[strstart] & 0xff);
        					lookahead--;
        					strstart++;
        				}
        				if (bflush) {
        
        					flush_block_only(false);
        					if (strm.avail_out === 0)
        						return NeedMore;
        				}
        			}
        
        			flush_block_only(flush == Z_FINISH);
        			if (strm.avail_out === 0) {
        				if (flush == Z_FINISH)
        					return FinishStarted;
        				else
        					return NeedMore;
        			}
        			return flush == Z_FINISH ? FinishDone : BlockDone;
        		}
        
        		// Same as above, but achieves better compression. We use a lazy
        		// evaluation for matches: a match is finally adopted only if there is
        		// no better match at the next window position.
        		function deflate_slow(flush) {
        			// short hash_head = 0; // head of hash chain
        			var hash_head = 0; // head of hash chain
        			var bflush; // set if current block must be flushed
        			var max_insert;
        
        			// Process the input block.
        			while (true) {
        				// Make sure that we always have enough lookahead, except
        				// at the end of the input file. We need MAX_MATCH bytes
        				// for the next match, plus MIN_MATCH bytes to insert the
        				// string following the next match.
        
        				if (lookahead < MIN_LOOKAHEAD) {
        					fill_window();
        					if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
        						return NeedMore;
        					}
        					if (lookahead === 0)
        						break; // flush the current block
        				}
        
        				// Insert the string window[strstart .. strstart+2] in the
        				// dictionary, and set hash_head to the head of the hash chain:
        
        				if (lookahead >= MIN_MATCH) {
        					ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
        					// prev[strstart&w_mask]=hash_head=head[ins_h];
        					hash_head = (head[ins_h] & 0xffff);
        					prev[strstart & w_mask] = head[ins_h];
        					head[ins_h] = strstart;
        				}
        
        				// Find the longest match, discarding those <= prev_length.
        				prev_length = match_length;
        				prev_match = match_start;
        				match_length = MIN_MATCH - 1;
        
        				if (hash_head !== 0 && prev_length < max_lazy_match && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) {
        					// To simplify the code, we prevent matches with the string
        					// of window index 0 (in particular we have to avoid a match
        					// of the string with itself at the start of the input file).
        
        					if (strategy != Z_HUFFMAN_ONLY) {
        						match_length = longest_match(hash_head);
        					}
        					// longest_match() sets match_start
        
        					if (match_length <= 5 && (strategy == Z_FILTERED || (match_length == MIN_MATCH && strstart - match_start > 4096))) {
        
        						// If prev_match is also MIN_MATCH, match_start is garbage
        						// but we will ignore the current match anyway.
        						match_length = MIN_MATCH - 1;
        					}
        				}
        
        				// If there was a match at the previous step and the current
        				// match is not better, output the previous match:
        				if (prev_length >= MIN_MATCH && match_length <= prev_length) {
        					max_insert = strstart + lookahead - MIN_MATCH;
        					// Do not insert strings in hash table beyond this.
        
        					// check_match(strstart-1, prev_match, prev_length);
        
        					bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
        
        					// Insert in hash table all strings up to the end of the match.
        					// strstart-1 and strstart are already inserted. If there is not
        					// enough lookahead, the last two strings are not inserted in
        					// the hash table.
        					lookahead -= prev_length - 1;
        					prev_length -= 2;
        					do {
        						if (++strstart <= max_insert) {
        							ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
        							// prev[strstart&w_mask]=hash_head=head[ins_h];
        							hash_head = (head[ins_h] & 0xffff);
        							prev[strstart & w_mask] = head[ins_h];
        							head[ins_h] = strstart;
        						}
        					} while (--prev_length !== 0);
        					match_available = 0;
        					match_length = MIN_MATCH - 1;
        					strstart++;
        
        					if (bflush) {
        						flush_block_only(false);
        						if (strm.avail_out === 0)
        							return NeedMore;
        					}
        				} else if (match_available !== 0) {
        
        					// If there was no match at the previous position, output a
        					// single literal. If there was a match but the current match
        					// is longer, truncate the previous match to a single literal.
        
        					bflush = _tr_tally(0, window[strstart - 1] & 0xff);
        
        					if (bflush) {
        						flush_block_only(false);
        					}
        					strstart++;
        					lookahead--;
        					if (strm.avail_out === 0)
        						return NeedMore;
        				} else {
        					// There is no previous match to compare with, wait for
        					// the next step to decide.
        
        					match_available = 1;
        					strstart++;
        					lookahead--;
        				}
        			}
        
        			if (match_available !== 0) {
        				bflush = _tr_tally(0, window[strstart - 1] & 0xff);
        				match_available = 0;
        			}
        			flush_block_only(flush == Z_FINISH);
        
        			if (strm.avail_out === 0) {
        				if (flush == Z_FINISH)
        					return FinishStarted;
        				else
        					return NeedMore;
        			}
        
        			return flush == Z_FINISH ? FinishDone : BlockDone;
        		}
        
        		function deflateReset(strm) {
        			strm.total_in = strm.total_out = 0;
        			strm.msg = null; //
        			
        			that.pending = 0;
        			that.pending_out = 0;
        
        			status = BUSY_STATE;
        
        			last_flush = Z_NO_FLUSH;
        
        			tr_init();
        			lm_init();
        			return Z_OK;
        		}
        
        		that.deflateInit = function(strm, _level, bits, _method, memLevel, _strategy) {
        			if (!_method)
        				_method = Z_DEFLATED;
        			if (!memLevel)
        				memLevel = DEF_MEM_LEVEL;
        			if (!_strategy)
        				_strategy = Z_DEFAULT_STRATEGY;
        
        			// byte[] my_version=ZLIB_VERSION;
        
        			//
        			// if (!version || version[0] != my_version[0]
        			// || stream_size != sizeof(z_stream)) {
        			// return Z_VERSION_ERROR;
        			// }
        
        			strm.msg = null;
        
        			if (_level == Z_DEFAULT_COMPRESSION)
        				_level = 6;
        
        			if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || _method != Z_DEFLATED || bits < 9 || bits > 15 || _level < 0 || _level > 9 || _strategy < 0
        					|| _strategy > Z_HUFFMAN_ONLY) {
        				return Z_STREAM_ERROR;
        			}
        
        			strm.dstate = that;
        
        			w_bits = bits;
        			w_size = 1 << w_bits;
        			w_mask = w_size - 1;
        
        			hash_bits = memLevel + 7;
        			hash_size = 1 << hash_bits;
        			hash_mask = hash_size - 1;
        			hash_shift = Math.floor((hash_bits + MIN_MATCH - 1) / MIN_MATCH);
        
        			window = new Uint8Array(w_size * 2);
        			prev = [];
        			head = [];
        
        			lit_bufsize = 1 << (memLevel + 6); // 16K elements by default
        
        			// We overlay pending_buf and d_buf+l_buf. This works since the average
        			// output size for (length,distance) codes is <= 24 bits.
        			that.pending_buf = new Uint8Array(lit_bufsize * 4);
        			pending_buf_size = lit_bufsize * 4;
        
        			d_buf = Math.floor(lit_bufsize / 2);
        			l_buf = (1 + 2) * lit_bufsize;
        
        			level = _level;
        
        			strategy = _strategy;
        			method = _method & 0xff;
        
        			return deflateReset(strm);
        		};
        
        		that.deflateEnd = function() {
        			if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) {
        				return Z_STREAM_ERROR;
        			}
        			// Deallocate in reverse order of allocations:
        			that.pending_buf = null;
        			head = null;
        			prev = null;
        			window = null;
        			// free
        			that.dstate = null;
        			return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
        		};
        
        		that.deflateParams = function(strm, _level, _strategy) {
        			var err = Z_OK;
        
        			if (_level == Z_DEFAULT_COMPRESSION) {
        				_level = 6;
        			}
        			if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) {
        				return Z_STREAM_ERROR;
        			}
        
        			if (config_table[level].func != config_table[_level].func && strm.total_in !== 0) {
        				// Flush the last buffer:
        				err = strm.deflate(Z_PARTIAL_FLUSH);
        			}
        
        			if (level != _level) {
        				level = _level;
        				max_lazy_match = config_table[level].max_lazy;
        				good_match = config_table[level].good_length;
        				nice_match = config_table[level].nice_length;
        				max_chain_length = config_table[level].max_chain;
        			}
        			strategy = _strategy;
        			return err;
        		};
        
        		that.deflateSetDictionary = function(strm, dictionary, dictLength) {
        			var length = dictLength;
        			var n, index = 0;
        
        			if (!dictionary || status != INIT_STATE)
        				return Z_STREAM_ERROR;
        
        			if (length < MIN_MATCH)
        				return Z_OK;
        			if (length > w_size - MIN_LOOKAHEAD) {
        				length = w_size - MIN_LOOKAHEAD;
        				index = dictLength - length; // use the tail of the dictionary
        			}
        			window.set(dictionary.subarray(index, index + length), 0);
        
        			strstart = length;
        			block_start = length;
        
        			// Insert all strings in the hash table (except for the last two bytes).
        			// s->lookahead stays null, so s->ins_h will be recomputed at the next
        			// call of fill_window.
        
        			ins_h = window[0] & 0xff;
        			ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask;
        
        			for (n = 0; n <= length - MIN_MATCH; n++) {
        				ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
        				prev[n & w_mask] = head[ins_h];
        				head[ins_h] = n;
        			}
        			return Z_OK;
        		};
        
        		that.deflate = function(_strm, flush) {
        			var i, header, level_flags, old_flush, bstate;
        
        			if (flush > Z_FINISH || flush < 0) {
        				return Z_STREAM_ERROR;
        			}
        
        			if (!_strm.next_out || (!_strm.next_in && _strm.avail_in !== 0) || (status == FINISH_STATE && flush != Z_FINISH)) {
        				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_STREAM_ERROR)];
        				return Z_STREAM_ERROR;
        			}
        			if (_strm.avail_out === 0) {
        				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
        				return Z_BUF_ERROR;
        			}
        
        			strm = _strm; // just in case
        			old_flush = last_flush;
        			last_flush = flush;
        
        			// Write the zlib header
        			if (status == INIT_STATE) {
        				header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
        				level_flags = ((level - 1) & 0xff) >> 1;
        
        				if (level_flags > 3)
        					level_flags = 3;
        				header |= (level_flags << 6);
        				if (strstart !== 0)
        					header |= PRESET_DICT;
        				header += 31 - (header % 31);
        
        				status = BUSY_STATE;
        				putShortMSB(header);
        			}
        
        			// Flush as much pending output as possible
        			if (that.pending !== 0) {
        				strm.flush_pending();
        				if (strm.avail_out === 0) {
        					// console.log(" avail_out==0");
        					// Since avail_out is 0, deflate will be called again with
        					// more output space, but possibly with both pending and
        					// avail_in equal to zero. There won't be anything to do,
        					// but this is not an error situation so make sure we
        					// return OK instead of BUF_ERROR at next call of deflate:
        					last_flush = -1;
        					return Z_OK;
        				}
        
        				// Make sure there is something to do and avoid duplicate
        				// consecutive
        				// flushes. For repeated and useless calls with Z_FINISH, we keep
        				// returning Z_STREAM_END instead of Z_BUFF_ERROR.
        			} else if (strm.avail_in === 0 && flush <= old_flush && flush != Z_FINISH) {
        				strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
        				return Z_BUF_ERROR;
        			}
        
        			// User must not provide more input after the first FINISH:
        			if (status == FINISH_STATE && strm.avail_in !== 0) {
        				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
        				return Z_BUF_ERROR;
        			}
        
        			// Start a new block or continue the current one.
        			if (strm.avail_in !== 0 || lookahead !== 0 || (flush != Z_NO_FLUSH && status != FINISH_STATE)) {
        				bstate = -1;
        				switch (config_table[level].func) {
        				case STORED:
        					bstate = deflate_stored(flush);
        					break;
        				case FAST:
        					bstate = deflate_fast(flush);
        					break;
        				case SLOW:
        					bstate = deflate_slow(flush);
        					break;
        				default:
        				}
        
        				if (bstate == FinishStarted || bstate == FinishDone) {
        					status = FINISH_STATE;
        				}
        				if (bstate == NeedMore || bstate == FinishStarted) {
        					if (strm.avail_out === 0) {
        						last_flush = -1; // avoid BUF_ERROR next call, see above
        					}
        					return Z_OK;
        					// If flush != Z_NO_FLUSH && avail_out === 0, the next call
        					// of deflate should use the same flush parameter to make sure
        					// that the flush is complete. So we don't have to output an
        					// empty block here, this will be done at next call. This also
        					// ensures that for a very small output buffer, we emit at most
        					// one empty block.
        				}
        
        				if (bstate == BlockDone) {
        					if (flush == Z_PARTIAL_FLUSH) {
        						_tr_align();
        					} else { // FULL_FLUSH or SYNC_FLUSH
        						_tr_stored_block(0, 0, false);
        						// For a full flush, this empty block will be recognized
        						// as a special marker by inflate_sync().
        						if (flush == Z_FULL_FLUSH) {
        							// state.head[s.hash_size-1]=0;
        							for (i = 0; i < hash_size/*-1*/; i++)
        								// forget history
        								head[i] = 0;
        						}
        					}
        					strm.flush_pending();
        					if (strm.avail_out === 0) {
        						last_flush = -1; // avoid BUF_ERROR at next call, see above
        						return Z_OK;
        					}
        				}
        			}
        
        			if (flush != Z_FINISH)
        				return Z_OK;
        			return Z_STREAM_END;
        		};
        	}
        
        	// ZStream
        
        	function ZStream() {
        		var that = this;
        		that.next_in_index = 0;
        		that.next_out_index = 0;
        		// that.next_in; // next input byte
        		that.avail_in = 0; // number of bytes available at next_in
        		that.total_in = 0; // total nb of input bytes read so far
        		// that.next_out; // next output byte should be put there
        		that.avail_out = 0; // remaining free space at next_out
        		that.total_out = 0; // total nb of bytes output so far
        		// that.msg;
        		// that.dstate;
        	}
        
        	ZStream.prototype = {
        		deflateInit : function(level, bits) {
        			var that = this;
        			that.dstate = new Deflate();
        			if (!bits)
        				bits = MAX_BITS;
        			return that.dstate.deflateInit(that, level, bits);
        		},
        
        		deflate : function(flush) {
        			var that = this;
        			if (!that.dstate) {
        				return Z_STREAM_ERROR;
        			}
        			return that.dstate.deflate(that, flush);
        		},
        
        		deflateEnd : function() {
        			var that = this;
        			if (!that.dstate)
        				return Z_STREAM_ERROR;
        			var ret = that.dstate.deflateEnd();
        			that.dstate = null;
        			return ret;
        		},
        
        		deflateParams : function(level, strategy) {
        			var that = this;
        			if (!that.dstate)
        				return Z_STREAM_ERROR;
        			return that.dstate.deflateParams(that, level, strategy);
        		},
        
        		deflateSetDictionary : function(dictionary, dictLength) {
        			var that = this;
        			if (!that.dstate)
        				return Z_STREAM_ERROR;
        			return that.dstate.deflateSetDictionary(that, dictionary, dictLength);
        		},
        
        		// Read a new buffer from the current input stream, update the
        		// total number of bytes read. All deflate() input goes through
        		// this function so some applications may wish to modify it to avoid
        		// allocating a large strm->next_in buffer and copying from it.
        		// (See also flush_pending()).
        		read_buf : function(buf, start, size) {
        			var that = this;
        			var len = that.avail_in;
        			if (len > size)
        				len = size;
        			if (len === 0)
        				return 0;
        			that.avail_in -= len;
        			buf.set(that.next_in.subarray(that.next_in_index, that.next_in_index + len), start);
        			that.next_in_index += len;
        			that.total_in += len;
        			return len;
        		},
        
        		// Flush as much pending output as possible. All deflate() output goes
        		// through this function so some applications may wish to modify it
        		// to avoid allocating a large strm->next_out buffer and copying into it.
        		// (See also read_buf()).
        		flush_pending : function() {
        			var that = this;
        			var len = that.dstate.pending;
        
        			if (len > that.avail_out)
        				len = that.avail_out;
        			if (len === 0)
        				return;
        
        			// if (that.dstate.pending_buf.length <= that.dstate.pending_out || that.next_out.length <= that.next_out_index
        			// || that.dstate.pending_buf.length < (that.dstate.pending_out + len) || that.next_out.length < (that.next_out_index +
        			// len)) {
        			// console.log(that.dstate.pending_buf.length + ", " + that.dstate.pending_out + ", " + that.next_out.length + ", " +
        			// that.next_out_index + ", " + len);
        			// console.log("avail_out=" + that.avail_out);
        			// }
        
        			that.next_out.set(that.dstate.pending_buf.subarray(that.dstate.pending_out, that.dstate.pending_out + len), that.next_out_index);
        
        			that.next_out_index += len;
        			that.dstate.pending_out += len;
        			that.total_out += len;
        			that.avail_out -= len;
        			that.dstate.pending -= len;
        			if (that.dstate.pending === 0) {
        				that.dstate.pending_out = 0;
        			}
        		}
        	};
        
        	// Deflater
        
        	function Deflater(level) {
        		var that = this;
        		var z = new ZStream();
        		var bufsize = 512;
        		var flush = Z_NO_FLUSH;
        		var buf = new Uint8Array(bufsize);
        
        		if (typeof level == "undefined")
        			level = Z_DEFAULT_COMPRESSION;
        		z.deflateInit(level);
        		z.next_out = buf;
        
        		that.append = function(data, onprogress) {
        			var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;
        			if (!data.length)
        				return;
        			z.next_in_index = 0;
        			z.next_in = data;
        			z.avail_in = data.length;
        			do {
        				z.next_out_index = 0;
        				z.avail_out = bufsize;
        				err = z.deflate(flush);
        				if (err != Z_OK)
        					throw "deflating: " + z.msg;
        				if (z.next_out_index)
        					if (z.next_out_index == bufsize)
        						buffers.push(new Uint8Array(buf));
        					else
        						buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
        				bufferSize += z.next_out_index;
        				if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {
        					onprogress(z.next_in_index);
        					lastIndex = z.next_in_index;
        				}
        			} while (z.avail_in > 0 || z.avail_out === 0);
        			array = new Uint8Array(bufferSize);
        			buffers.forEach(function(chunk) {
        				array.set(chunk, bufferIndex);
        				bufferIndex += chunk.length;
        			});
        			return array;
        		};
        		that.flush = function() {
        			var err, buffers = [], bufferIndex = 0, bufferSize = 0, array;
        			do {
        				z.next_out_index = 0;
        				z.avail_out = bufsize;
        				err = z.deflate(Z_FINISH);
        				if (err != Z_STREAM_END && err != Z_OK)
        					throw "deflating: " + z.msg;
        				if (bufsize - z.avail_out > 0)
        					buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
        				bufferSize += z.next_out_index;
        			} while (z.avail_in > 0 || z.avail_out === 0);
        			z.deflateEnd();
        			array = new Uint8Array(bufferSize);
        			buffers.forEach(function(chunk) {
        				array.set(chunk, bufferIndex);
        				bufferIndex += chunk.length;
        			});
        			return array;
        		};
        	}
        
        	var deflater;
        
        	if (obj.zip)
        		obj.zip.Deflater = Deflater;
        	else {
        		deflater = new Deflater();
        		obj.addEventListener("message", function(event) {
        			var message = event.data;
        			if (message.init) {
        				deflater = new Deflater(message.level);
        				obj.postMessage({
        					oninit : true
        				});
        			}
        			if (message.append)
        				obj.postMessage({
        					onappend : true,
        					data : deflater.append(message.data, function(current) {
        						obj.postMessage({
        							progress : true,
        							current : current
        						});
        					})
        				});
        			if (message.flush)
        				obj.postMessage({
        					onflush : true,
        					data : deflater.flush()
        				});
        		}, false);
        	}
        
        })(this);
        
      • inflate.js
        /*
         Copyright (c) 2013 Gildas Lormeau. All rights reserved.
        
         Redistribution and use in source and binary forms, with or without
         modification, are permitted provided that the following conditions are met:
        
         1. Redistributions of source code must retain the above copyright notice,
         this list of conditions and the following disclaimer.
        
         2. Redistributions in binary form must reproduce the above copyright 
         notice, this list of conditions and the following disclaimer in 
         the documentation and/or other materials provided with the distribution.
        
         3. The names of the authors may not be used to endorse or promote products
         derived from this software without specific prior written permission.
        
         THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
         INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
         FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
         INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
         INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
         OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
         LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
         NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
         EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         */
        
        /*
         * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
         * JZlib is based on zlib-1.1.3, so all credit should go authors
         * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
         * and contributors of zlib.
         */
        
        (function(obj) {
        
        	// Global
        	var MAX_BITS = 15;
        
        	var Z_OK = 0;
        	var Z_STREAM_END = 1;
        	var Z_NEED_DICT = 2;
        	var Z_STREAM_ERROR = -2;
        	var Z_DATA_ERROR = -3;
        	var Z_MEM_ERROR = -4;
        	var Z_BUF_ERROR = -5;
        
        	var inflate_mask = [ 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff,
        			0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff ];
        
        	var MANY = 1440;
        
        	// JZlib version : "1.0.2"
        	var Z_NO_FLUSH = 0;
        	var Z_FINISH = 4;
        
        	// InfTree
        	var fixed_bl = 9;
        	var fixed_bd = 5;
        
        	var fixed_tl = [ 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0,
        			0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40,
        			0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13,
        			0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60,
        			0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7,
        			35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8,
        			26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80,
        			7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0,
        			8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0,
        			8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97,
        			0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210,
        			81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117,
        			0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154,
        			84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83,
        			0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230,
        			80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139,
        			0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174,
        			0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111,
        			0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9,
        			193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8,
        			120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8,
        			227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8,
        			92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9,
        			249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8,
        			130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9,
        			181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8,
        			102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9,
        			221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0,
        			8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9,
        			147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8,
        			85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9,
        			235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8,
        			141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9,
        			167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8,
        			107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9,
        			207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8,
        			127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255 ];
        	var fixed_td = [ 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5,
        			8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5,
        			24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577 ];
        
        	// Tables for deflate from PKZIP's appnote.txt.
        	var cplens = [ // Copy lengths for literal codes 257..285
        	3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 ];
        
        	// see note #13 above about 258
        	var cplext = [ // Extra bits for literal codes 257..285
        	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid
        	];
        
        	var cpdist = [ // Copy offsets for distance codes 0..29
        	1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ];
        
        	var cpdext = [ // Extra bits for distance codes
        	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ];
        
        	// If BMAX needs to be larger than 16, then h and x[] should be uLong.
        	var BMAX = 15; // maximum bit length of any code
        
        	function InfTree() {
        		var that = this;
        
        		var hn; // hufts used in space
        		var v; // work area for huft_build
        		var c; // bit length count table
        		var r; // table entry for structure assignment
        		var u; // table stack
        		var x; // bit offsets, then code stack
        
        		function huft_build(b, // code lengths in bits (all assumed <=
        		// BMAX)
        		bindex, n, // number of codes (assumed <= 288)
        		s, // number of simple-valued codes (0..s-1)
        		d, // list of base values for non-simple codes
        		e, // list of extra bits for non-simple codes
        		t, // result: starting table
        		m, // maximum lookup bits, returns actual
        		hp,// space for trees
        		hn,// hufts used in space
        		v // working area: values in order of bit length
        		) {
        			// Given a list of code lengths and a maximum table size, make a set of
        			// tables to decode that set of codes. Return Z_OK on success,
        			// Z_BUF_ERROR
        			// if the given code set is incomplete (the tables are still built in
        			// this
        			// case), Z_DATA_ERROR if the input is invalid (an over-subscribed set
        			// of
        			// lengths), or Z_MEM_ERROR if not enough memory.
        
        			var a; // counter for codes of length k
        			var f; // i repeats in table every f entries
        			var g; // maximum code length
        			var h; // table level
        			var i; // counter, current code
        			var j; // counter
        			var k; // number of bits in current code
        			var l; // bits per table (returned in m)
        			var mask; // (1 << w) - 1, to avoid cc -O bug on HP
        			var p; // pointer into c[], b[], or v[]
        			var q; // points to current table
        			var w; // bits before this table == (l * h)
        			var xp; // pointer into x
        			var y; // number of dummy codes added
        			var z; // number of entries in current table
        
        			// Generate counts for each bit length
        
        			p = 0;
        			i = n;
        			do {
        				c[b[bindex + p]]++;
        				p++;
        				i--; // assume all entries <= BMAX
        			} while (i !== 0);
        
        			if (c[0] == n) { // null input--all zero length codes
        				t[0] = -1;
        				m[0] = 0;
        				return Z_OK;
        			}
        
        			// Find minimum and maximum length, bound *m by those
        			l = m[0];
        			for (j = 1; j <= BMAX; j++)
        				if (c[j] !== 0)
        					break;
        			k = j; // minimum code length
        			if (l < j) {
        				l = j;
        			}
        			for (i = BMAX; i !== 0; i--) {
        				if (c[i] !== 0)
        					break;
        			}
        			g = i; // maximum code length
        			if (l > i) {
        				l = i;
        			}
        			m[0] = l;
        
        			// Adjust last length count to fill out codes, if needed
        			for (y = 1 << j; j < i; j++, y <<= 1) {
        				if ((y -= c[j]) < 0) {
        					return Z_DATA_ERROR;
        				}
        			}
        			if ((y -= c[i]) < 0) {
        				return Z_DATA_ERROR;
        			}
        			c[i] += y;
        
        			// Generate starting offsets into the value table for each length
        			x[1] = j = 0;
        			p = 1;
        			xp = 2;
        			while (--i !== 0) { // note that i == g from above
        				x[xp] = (j += c[p]);
        				xp++;
        				p++;
        			}
        
        			// Make a table of values in order of bit lengths
        			i = 0;
        			p = 0;
        			do {
        				if ((j = b[bindex + p]) !== 0) {
        					v[x[j]++] = i;
        				}
        				p++;
        			} while (++i < n);
        			n = x[g]; // set n to length of v
        
        			// Generate the Huffman codes and for each, make the table entries
        			x[0] = i = 0; // first Huffman code is zero
        			p = 0; // grab values in bit order
        			h = -1; // no tables yet--level -1
        			w = -l; // bits decoded == (l * h)
        			u[0] = 0; // just to keep compilers happy
        			q = 0; // ditto
        			z = 0; // ditto
        
        			// go through the bit lengths (k already is bits in shortest code)
        			for (; k <= g; k++) {
        				a = c[k];
        				while (a-- !== 0) {
        					// here i is the Huffman code of length k bits for value *p
        					// make tables up to required level
        					while (k > w + l) {
        						h++;
        						w += l; // previous table always l bits
        						// compute minimum size table less than or equal to l bits
        						z = g - w;
        						z = (z > l) ? l : z; // table size upper limit
        						if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
        							// too few codes for
        							// k-w bit table
        							f -= a + 1; // deduct codes from patterns left
        							xp = k;
        							if (j < z) {
        								while (++j < z) { // try smaller tables up to z bits
        									if ((f <<= 1) <= c[++xp])
        										break; // enough codes to use up j bits
        									f -= c[xp]; // else deduct codes from patterns
        								}
        							}
        						}
        						z = 1 << j; // table entries for j-bit table
        
        						// allocate new table
        						if (hn[0] + z > MANY) { // (note: doesn't matter for fixed)
        							return Z_DATA_ERROR; // overflow of MANY
        						}
        						u[h] = q = /* hp+ */hn[0]; // DEBUG
        						hn[0] += z;
        
        						// connect to last table, if there is one
        						if (h !== 0) {
        							x[h] = i; // save pattern for backing up
        							r[0] = /* (byte) */j; // bits in this table
        							r[1] = /* (byte) */l; // bits to dump before this table
        							j = i >>> (w - l);
        							r[2] = /* (int) */(q - u[h - 1] - j); // offset to this table
        							hp.set(r, (u[h - 1] + j) * 3);
        							// to
        							// last
        							// table
        						} else {
        							t[0] = q; // first table is returned result
        						}
        					}
        
        					// set up table entry in r
        					r[1] = /* (byte) */(k - w);
        					if (p >= n) {
        						r[0] = 128 + 64; // out of values--invalid code
        					} else if (v[p] < s) {
        						r[0] = /* (byte) */(v[p] < 256 ? 0 : 32 + 64); // 256 is
        						// end-of-block
        						r[2] = v[p++]; // simple code is just the value
        					} else {
        						r[0] = /* (byte) */(e[v[p] - s] + 16 + 64); // non-simple--look
        						// up in lists
        						r[2] = d[v[p++] - s];
        					}
        
        					// fill code-like entries with r
        					f = 1 << (k - w);
        					for (j = i >>> w; j < z; j += f) {
        						hp.set(r, (q + j) * 3);
        					}
        
        					// backwards increment the k-bit code i
        					for (j = 1 << (k - 1); (i & j) !== 0; j >>>= 1) {
        						i ^= j;
        					}
        					i ^= j;
        
        					// backup over finished tables
        					mask = (1 << w) - 1; // needed on HP, cc -O bug
        					while ((i & mask) != x[h]) {
        						h--; // don't need to update q
        						w -= l;
        						mask = (1 << w) - 1;
        					}
        				}
        			}
        			// Return Z_BUF_ERROR if we were given an incomplete table
        			return y !== 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
        		}
        
        		function initWorkArea(vsize) {
        			var i;
        			if (!hn) {
        				hn = []; // []; //new Array(1);
        				v = []; // new Array(vsize);
        				c = new Int32Array(BMAX + 1); // new Array(BMAX + 1);
        				r = []; // new Array(3);
        				u = new Int32Array(BMAX); // new Array(BMAX);
        				x = new Int32Array(BMAX + 1); // new Array(BMAX + 1);
        			}
        			if (v.length < vsize) {
        				v = []; // new Array(vsize);
        			}
        			for (i = 0; i < vsize; i++) {
        				v[i] = 0;
        			}
        			for (i = 0; i < BMAX + 1; i++) {
        				c[i] = 0;
        			}
        			for (i = 0; i < 3; i++) {
        				r[i] = 0;
        			}
        			// for(int i=0; i<BMAX; i++){u[i]=0;}
        			u.set(c.subarray(0, BMAX), 0);
        			// for(int i=0; i<BMAX+1; i++){x[i]=0;}
        			x.set(c.subarray(0, BMAX + 1), 0);
        		}
        
        		that.inflate_trees_bits = function(c, // 19 code lengths
        		bb, // bits tree desired/actual depth
        		tb, // bits tree result
        		hp, // space for trees
        		z // for messages
        		) {
        			var result;
        			initWorkArea(19);
        			hn[0] = 0;
        			result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
        
        			if (result == Z_DATA_ERROR) {
        				z.msg = "oversubscribed dynamic bit lengths tree";
        			} else if (result == Z_BUF_ERROR || bb[0] === 0) {
        				z.msg = "incomplete dynamic bit lengths tree";
        				result = Z_DATA_ERROR;
        			}
        			return result;
        		};
        
        		that.inflate_trees_dynamic = function(nl, // number of literal/length codes
        		nd, // number of distance codes
        		c, // that many (total) code lengths
        		bl, // literal desired/actual bit depth
        		bd, // distance desired/actual bit depth
        		tl, // literal/length tree result
        		td, // distance tree result
        		hp, // space for trees
        		z // for messages
        		) {
        			var result;
        
        			// build literal/length tree
        			initWorkArea(288);
        			hn[0] = 0;
        			result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
        			if (result != Z_OK || bl[0] === 0) {
        				if (result == Z_DATA_ERROR) {
        					z.msg = "oversubscribed literal/length tree";
        				} else if (result != Z_MEM_ERROR) {
        					z.msg = "incomplete literal/length tree";
        					result = Z_DATA_ERROR;
        				}
        				return result;
        			}
        
        			// build distance tree
        			initWorkArea(288);
        			result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
        
        			if (result != Z_OK || (bd[0] === 0 && nl > 257)) {
        				if (result == Z_DATA_ERROR) {
        					z.msg = "oversubscribed distance tree";
        				} else if (result == Z_BUF_ERROR) {
        					z.msg = "incomplete distance tree";
        					result = Z_DATA_ERROR;
        				} else if (result != Z_MEM_ERROR) {
        					z.msg = "empty distance tree with lengths";
        					result = Z_DATA_ERROR;
        				}
        				return result;
        			}
        
        			return Z_OK;
        		};
        
        	}
        
        	InfTree.inflate_trees_fixed = function(bl, // literal desired/actual bit depth
        	bd, // distance desired/actual bit depth
        	tl,// literal/length tree result
        	td// distance tree result
        	) {
        		bl[0] = fixed_bl;
        		bd[0] = fixed_bd;
        		tl[0] = fixed_tl;
        		td[0] = fixed_td;
        		return Z_OK;
        	};
        
        	// InfCodes
        
        	// waiting for "i:"=input,
        	// "o:"=output,
        	// "x:"=nothing
        	var START = 0; // x: set up for LEN
        	var LEN = 1; // i: get length/literal/eob next
        	var LENEXT = 2; // i: getting length extra (have base)
        	var DIST = 3; // i: get distance next
        	var DISTEXT = 4;// i: getting distance extra
        	var COPY = 5; // o: copying bytes in window, waiting
        	// for space
        	var LIT = 6; // o: got literal, waiting for output
        	// space
        	var WASH = 7; // o: got eob, possibly still output
        	// waiting
        	var END = 8; // x: got eob and all data flushed
        	var BADCODE = 9;// x: got error
        
        	function InfCodes() {
        		var that = this;
        
        		var mode; // current inflate_codes mode
        
        		// mode dependent information
        		var len = 0;
        
        		var tree; // pointer into tree
        		var tree_index = 0;
        		var need = 0; // bits needed
        
        		var lit = 0;
        
        		// if EXT or COPY, where and how much
        		var get = 0; // bits to get for extra
        		var dist = 0; // distance back to copy from
        
        		var lbits = 0; // ltree bits decoded per branch
        		var dbits = 0; // dtree bits decoder per branch
        		var ltree; // literal/length/eob tree
        		var ltree_index = 0; // literal/length/eob tree
        		var dtree; // distance tree
        		var dtree_index = 0; // distance tree
        
        		// Called with number of bytes left to write in window at least 258
        		// (the maximum string length) and number of input bytes available
        		// at least ten. The ten bytes are six bytes for the longest length/
        		// distance pair plus four bytes for overloading the bit buffer.
        
        		function inflate_fast(bl, bd, tl, tl_index, td, td_index, s, z) {
        			var t; // temporary pointer
        			var tp; // temporary pointer
        			var tp_index; // temporary pointer
        			var e; // extra bits or operation
        			var b; // bit buffer
        			var k; // bits in bit buffer
        			var p; // input data pointer
        			var n; // bytes available there
        			var q; // output window write pointer
        			var m; // bytes to end of window or read pointer
        			var ml; // mask for literal/length tree
        			var md; // mask for distance tree
        			var c; // bytes to copy
        			var d; // distance back to copy from
        			var r; // copy source pointer
        
        			var tp_index_t_3; // (tp_index+t)*3
        
        			// load input, output, bit values
        			p = z.next_in_index;
        			n = z.avail_in;
        			b = s.bitb;
        			k = s.bitk;
        			q = s.write;
        			m = q < s.read ? s.read - q - 1 : s.end - q;
        
        			// initialize masks
        			ml = inflate_mask[bl];
        			md = inflate_mask[bd];
        
        			// do until not enough input or output space for fast loop
        			do { // assume called with m >= 258 && n >= 10
        				// get literal/length code
        				while (k < (20)) { // max bits for literal/length code
        					n--;
        					b |= (z.read_byte(p++) & 0xff) << k;
        					k += 8;
        				}
        
        				t = b & ml;
        				tp = tl;
        				tp_index = tl_index;
        				tp_index_t_3 = (tp_index + t) * 3;
        				if ((e = tp[tp_index_t_3]) === 0) {
        					b >>= (tp[tp_index_t_3 + 1]);
        					k -= (tp[tp_index_t_3 + 1]);
        
        					s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2];
        					m--;
        					continue;
        				}
        				do {
        
        					b >>= (tp[tp_index_t_3 + 1]);
        					k -= (tp[tp_index_t_3 + 1]);
        
        					if ((e & 16) !== 0) {
        						e &= 15;
        						c = tp[tp_index_t_3 + 2] + (/* (int) */b & inflate_mask[e]);
        
        						b >>= e;
        						k -= e;
        
        						// decode distance base of block to copy
        						while (k < (15)) { // max bits for distance code
        							n--;
        							b |= (z.read_byte(p++) & 0xff) << k;
        							k += 8;
        						}
        
        						t = b & md;
        						tp = td;
        						tp_index = td_index;
        						tp_index_t_3 = (tp_index + t) * 3;
        						e = tp[tp_index_t_3];
        
        						do {
        
        							b >>= (tp[tp_index_t_3 + 1]);
        							k -= (tp[tp_index_t_3 + 1]);
        
        							if ((e & 16) !== 0) {
        								// get extra bits to add to distance base
        								e &= 15;
        								while (k < (e)) { // get extra bits (up to 13)
        									n--;
        									b |= (z.read_byte(p++) & 0xff) << k;
        									k += 8;
        								}
        
        								d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]);
        
        								b >>= (e);
        								k -= (e);
        
        								// do the copy
        								m -= c;
        								if (q >= d) { // offset before dest
        									// just copy
        									r = q - d;
        									if (q - r > 0 && 2 > (q - r)) {
        										s.window[q++] = s.window[r++]; // minimum
        										// count is
        										// three,
        										s.window[q++] = s.window[r++]; // so unroll
        										// loop a
        										// little
        										c -= 2;
        									} else {
        										s.window.set(s.window.subarray(r, r + 2), q);
        										q += 2;
        										r += 2;
        										c -= 2;
        									}
        								} else { // else offset after destination
        									r = q - d;
        									do {
        										r += s.end; // force pointer in window
        									} while (r < 0); // covers invalid distances
        									e = s.end - r;
        									if (c > e) { // if source crosses,
        										c -= e; // wrapped copy
        										if (q - r > 0 && e > (q - r)) {
        											do {
        												s.window[q++] = s.window[r++];
        											} while (--e !== 0);
        										} else {
        											s.window.set(s.window.subarray(r, r + e), q);
        											q += e;
        											r += e;
        											e = 0;
        										}
        										r = 0; // copy rest from start of window
        									}
        
        								}
        
        								// copy all or what's left
        								if (q - r > 0 && c > (q - r)) {
        									do {
        										s.window[q++] = s.window[r++];
        									} while (--c !== 0);
        								} else {
        									s.window.set(s.window.subarray(r, r + c), q);
        									q += c;
        									r += c;
        									c = 0;
        								}
        								break;
        							} else if ((e & 64) === 0) {
        								t += tp[tp_index_t_3 + 2];
        								t += (b & inflate_mask[e]);
        								tp_index_t_3 = (tp_index + t) * 3;
        								e = tp[tp_index_t_3];
        							} else {
        								z.msg = "invalid distance code";
        
        								c = z.avail_in - n;
        								c = (k >> 3) < c ? k >> 3 : c;
        								n += c;
        								p -= c;
        								k -= c << 3;
        
        								s.bitb = b;
        								s.bitk = k;
        								z.avail_in = n;
        								z.total_in += p - z.next_in_index;
        								z.next_in_index = p;
        								s.write = q;
        
        								return Z_DATA_ERROR;
        							}
        						} while (true);
        						break;
        					}
        
        					if ((e & 64) === 0) {
        						t += tp[tp_index_t_3 + 2];
        						t += (b & inflate_mask[e]);
        						tp_index_t_3 = (tp_index + t) * 3;
        						if ((e = tp[tp_index_t_3]) === 0) {
        
        							b >>= (tp[tp_index_t_3 + 1]);
        							k -= (tp[tp_index_t_3 + 1]);
        
        							s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2];
        							m--;
        							break;
        						}
        					} else if ((e & 32) !== 0) {
        
        						c = z.avail_in - n;
        						c = (k >> 3) < c ? k >> 3 : c;
        						n += c;
        						p -= c;
        						k -= c << 3;
        
        						s.bitb = b;
        						s.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						s.write = q;
        
        						return Z_STREAM_END;
        					} else {
        						z.msg = "invalid literal/length code";
        
        						c = z.avail_in - n;
        						c = (k >> 3) < c ? k >> 3 : c;
        						n += c;
        						p -= c;
        						k -= c << 3;
        
        						s.bitb = b;
        						s.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						s.write = q;
        
        						return Z_DATA_ERROR;
        					}
        				} while (true);
        			} while (m >= 258 && n >= 10);
        
        			// not enough input or output--restore pointers and return
        			c = z.avail_in - n;
        			c = (k >> 3) < c ? k >> 3 : c;
        			n += c;
        			p -= c;
        			k -= c << 3;
        
        			s.bitb = b;
        			s.bitk = k;
        			z.avail_in = n;
        			z.total_in += p - z.next_in_index;
        			z.next_in_index = p;
        			s.write = q;
        
        			return Z_OK;
        		}
        
        		that.init = function(bl, bd, tl, tl_index, td, td_index) {
        			mode = START;
        			lbits = /* (byte) */bl;
        			dbits = /* (byte) */bd;
        			ltree = tl;
        			ltree_index = tl_index;
        			dtree = td;
        			dtree_index = td_index;
        			tree = null;
        		};
        
        		that.proc = function(s, z, r) {
        			var j; // temporary storage
        			var tindex; // temporary pointer
        			var e; // extra bits or operation
        			var b = 0; // bit buffer
        			var k = 0; // bits in bit buffer
        			var p = 0; // input data pointer
        			var n; // bytes available there
        			var q; // output window write pointer
        			var m; // bytes to end of window or read pointer
        			var f; // pointer to copy strings from
        
        			// copy input/output information to locals (UPDATE macro restores)
        			p = z.next_in_index;
        			n = z.avail_in;
        			b = s.bitb;
        			k = s.bitk;
        			q = s.write;
        			m = q < s.read ? s.read - q - 1 : s.end - q;
        
        			// process input and output based on current state
        			while (true) {
        				switch (mode) {
        				// waiting for "i:"=input, "o:"=output, "x:"=nothing
        				case START: // x: set up for LEN
        					if (m >= 258 && n >= 10) {
        
        						s.bitb = b;
        						s.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						s.write = q;
        						r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z);
        
        						p = z.next_in_index;
        						n = z.avail_in;
        						b = s.bitb;
        						k = s.bitk;
        						q = s.write;
        						m = q < s.read ? s.read - q - 1 : s.end - q;
        
        						if (r != Z_OK) {
        							mode = r == Z_STREAM_END ? WASH : BADCODE;
        							break;
        						}
        					}
        					need = lbits;
        					tree = ltree;
        					tree_index = ltree_index;
        
        					mode = LEN;
        				case LEN: // i: get length/literal/eob next
        					j = need;
        
        					while (k < (j)) {
        						if (n !== 0)
        							r = Z_OK;
        						else {
        
        							s.bitb = b;
        							s.bitk = k;
        							z.avail_in = n;
        							z.total_in += p - z.next_in_index;
        							z.next_in_index = p;
        							s.write = q;
        							return s.inflate_flush(z, r);
        						}
        						n--;
        						b |= (z.read_byte(p++) & 0xff) << k;
        						k += 8;
        					}
        
        					tindex = (tree_index + (b & inflate_mask[j])) * 3;
        
        					b >>>= (tree[tindex + 1]);
        					k -= (tree[tindex + 1]);
        
        					e = tree[tindex];
        
        					if (e === 0) { // literal
        						lit = tree[tindex + 2];
        						mode = LIT;
        						break;
        					}
        					if ((e & 16) !== 0) { // length
        						get = e & 15;
        						len = tree[tindex + 2];
        						mode = LENEXT;
        						break;
        					}
        					if ((e & 64) === 0) { // next table
        						need = e;
        						tree_index = tindex / 3 + tree[tindex + 2];
        						break;
        					}
        					if ((e & 32) !== 0) { // end of block
        						mode = WASH;
        						break;
        					}
        					mode = BADCODE; // invalid code
        					z.msg = "invalid literal/length code";
        					r = Z_DATA_ERROR;
        
        					s.bitb = b;
        					s.bitk = k;
        					z.avail_in = n;
        					z.total_in += p - z.next_in_index;
        					z.next_in_index = p;
        					s.write = q;
        					return s.inflate_flush(z, r);
        
        				case LENEXT: // i: getting length extra (have base)
        					j = get;
        
        					while (k < (j)) {
        						if (n !== 0)
        							r = Z_OK;
        						else {
        
        							s.bitb = b;
        							s.bitk = k;
        							z.avail_in = n;
        							z.total_in += p - z.next_in_index;
        							z.next_in_index = p;
        							s.write = q;
        							return s.inflate_flush(z, r);
        						}
        						n--;
        						b |= (z.read_byte(p++) & 0xff) << k;
        						k += 8;
        					}
        
        					len += (b & inflate_mask[j]);
        
        					b >>= j;
        					k -= j;
        
        					need = dbits;
        					tree = dtree;
        					tree_index = dtree_index;
        					mode = DIST;
        				case DIST: // i: get distance next
        					j = need;
        
        					while (k < (j)) {
        						if (n !== 0)
        							r = Z_OK;
        						else {
        
        							s.bitb = b;
        							s.bitk = k;
        							z.avail_in = n;
        							z.total_in += p - z.next_in_index;
        							z.next_in_index = p;
        							s.write = q;
        							return s.inflate_flush(z, r);
        						}
        						n--;
        						b |= (z.read_byte(p++) & 0xff) << k;
        						k += 8;
        					}
        
        					tindex = (tree_index + (b & inflate_mask[j])) * 3;
        
        					b >>= tree[tindex + 1];
        					k -= tree[tindex + 1];
        
        					e = (tree[tindex]);
        					if ((e & 16) !== 0) { // distance
        						get = e & 15;
        						dist = tree[tindex + 2];
        						mode = DISTEXT;
        						break;
        					}
        					if ((e & 64) === 0) { // next table
        						need = e;
        						tree_index = tindex / 3 + tree[tindex + 2];
        						break;
        					}
        					mode = BADCODE; // invalid code
        					z.msg = "invalid distance code";
        					r = Z_DATA_ERROR;
        
        					s.bitb = b;
        					s.bitk = k;
        					z.avail_in = n;
        					z.total_in += p - z.next_in_index;
        					z.next_in_index = p;
        					s.write = q;
        					return s.inflate_flush(z, r);
        
        				case DISTEXT: // i: getting distance extra
        					j = get;
        
        					while (k < (j)) {
        						if (n !== 0)
        							r = Z_OK;
        						else {
        
        							s.bitb = b;
        							s.bitk = k;
        							z.avail_in = n;
        							z.total_in += p - z.next_in_index;
        							z.next_in_index = p;
        							s.write = q;
        							return s.inflate_flush(z, r);
        						}
        						n--;
        						b |= (z.read_byte(p++) & 0xff) << k;
        						k += 8;
        					}
        
        					dist += (b & inflate_mask[j]);
        
        					b >>= j;
        					k -= j;
        
        					mode = COPY;
        				case COPY: // o: copying bytes in window, waiting for space
        					f = q - dist;
        					while (f < 0) { // modulo window size-"while" instead
        						f += s.end; // of "if" handles invalid distances
        					}
        					while (len !== 0) {
        
        						if (m === 0) {
        							if (q == s.end && s.read !== 0) {
        								q = 0;
        								m = q < s.read ? s.read - q - 1 : s.end - q;
        							}
        							if (m === 0) {
        								s.write = q;
        								r = s.inflate_flush(z, r);
        								q = s.write;
        								m = q < s.read ? s.read - q - 1 : s.end - q;
        
        								if (q == s.end && s.read !== 0) {
        									q = 0;
        									m = q < s.read ? s.read - q - 1 : s.end - q;
        								}
        
        								if (m === 0) {
        									s.bitb = b;
        									s.bitk = k;
        									z.avail_in = n;
        									z.total_in += p - z.next_in_index;
        									z.next_in_index = p;
        									s.write = q;
        									return s.inflate_flush(z, r);
        								}
        							}
        						}
        
        						s.window[q++] = s.window[f++];
        						m--;
        
        						if (f == s.end)
        							f = 0;
        						len--;
        					}
        					mode = START;
        					break;
        				case LIT: // o: got literal, waiting for output space
        					if (m === 0) {
        						if (q == s.end && s.read !== 0) {
        							q = 0;
        							m = q < s.read ? s.read - q - 1 : s.end - q;
        						}
        						if (m === 0) {
        							s.write = q;
        							r = s.inflate_flush(z, r);
        							q = s.write;
        							m = q < s.read ? s.read - q - 1 : s.end - q;
        
        							if (q == s.end && s.read !== 0) {
        								q = 0;
        								m = q < s.read ? s.read - q - 1 : s.end - q;
        							}
        							if (m === 0) {
        								s.bitb = b;
        								s.bitk = k;
        								z.avail_in = n;
        								z.total_in += p - z.next_in_index;
        								z.next_in_index = p;
        								s.write = q;
        								return s.inflate_flush(z, r);
        							}
        						}
        					}
        					r = Z_OK;
        
        					s.window[q++] = /* (byte) */lit;
        					m--;
        
        					mode = START;
        					break;
        				case WASH: // o: got eob, possibly more output
        					if (k > 7) { // return unused byte, if any
        						k -= 8;
        						n++;
        						p--; // can always return one
        					}
        
        					s.write = q;
        					r = s.inflate_flush(z, r);
        					q = s.write;
        					m = q < s.read ? s.read - q - 1 : s.end - q;
        
        					if (s.read != s.write) {
        						s.bitb = b;
        						s.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						s.write = q;
        						return s.inflate_flush(z, r);
        					}
        					mode = END;
        				case END:
        					r = Z_STREAM_END;
        					s.bitb = b;
        					s.bitk = k;
        					z.avail_in = n;
        					z.total_in += p - z.next_in_index;
        					z.next_in_index = p;
        					s.write = q;
        					return s.inflate_flush(z, r);
        
        				case BADCODE: // x: got error
        
        					r = Z_DATA_ERROR;
        
        					s.bitb = b;
        					s.bitk = k;
        					z.avail_in = n;
        					z.total_in += p - z.next_in_index;
        					z.next_in_index = p;
        					s.write = q;
        					return s.inflate_flush(z, r);
        
        				default:
        					r = Z_STREAM_ERROR;
        
        					s.bitb = b;
        					s.bitk = k;
        					z.avail_in = n;
        					z.total_in += p - z.next_in_index;
        					z.next_in_index = p;
        					s.write = q;
        					return s.inflate_flush(z, r);
        				}
        			}
        		};
        
        		that.free = function() {
        			// ZFREE(z, c);
        		};
        
        	}
        
        	// InfBlocks
        
        	// Table for deflate from PKZIP's appnote.txt.
        	var border = [ // Order of the bit length code lengths
        	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
        
        	var TYPE = 0; // get type bits (3, including end bit)
        	var LENS = 1; // get lengths for stored
        	var STORED = 2;// processing stored block
        	var TABLE = 3; // get table lengths
        	var BTREE = 4; // get bit lengths tree for a dynamic
        	// block
        	var DTREE = 5; // get length, distance trees for a
        	// dynamic block
        	var CODES = 6; // processing fixed or dynamic block
        	var DRY = 7; // output remaining window bytes
        	var DONELOCKS = 8; // finished last block, done
        	var BADBLOCKS = 9; // ot a data error--stuck here
        
        	function InfBlocks(z, w) {
        		var that = this;
        
        		var mode = TYPE; // current inflate_block mode
        
        		var left = 0; // if STORED, bytes left to copy
        
        		var table = 0; // table lengths (14 bits)
        		var index = 0; // index into blens (or border)
        		var blens; // bit lengths of codes
        		var bb = [ 0 ]; // bit length tree depth
        		var tb = [ 0 ]; // bit length decoding tree
        
        		var codes = new InfCodes(); // if CODES, current state
        
        		var last = 0; // true if this block is the last block
        
        		var hufts = new Int32Array(MANY * 3); // single malloc for tree space
        		var check = 0; // check on output
        		var inftree = new InfTree();
        
        		that.bitk = 0; // bits in bit buffer
        		that.bitb = 0; // bit buffer
        		that.window = new Uint8Array(w); // sliding window
        		that.end = w; // one byte after sliding window
        		that.read = 0; // window read pointer
        		that.write = 0; // window write pointer
        
        		that.reset = function(z, c) {
        			if (c)
        				c[0] = check;
        			// if (mode == BTREE || mode == DTREE) {
        			// }
        			if (mode == CODES) {
        				codes.free(z);
        			}
        			mode = TYPE;
        			that.bitk = 0;
        			that.bitb = 0;
        			that.read = that.write = 0;
        		};
        
        		that.reset(z, null);
        
        		// copy as much as possible from the sliding window to the output area
        		that.inflate_flush = function(z, r) {
        			var n;
        			var p;
        			var q;
        
        			// local copies of source and destination pointers
        			p = z.next_out_index;
        			q = that.read;
        
        			// compute number of bytes to copy as far as end of window
        			n = /* (int) */((q <= that.write ? that.write : that.end) - q);
        			if (n > z.avail_out)
        				n = z.avail_out;
        			if (n !== 0 && r == Z_BUF_ERROR)
        				r = Z_OK;
        
        			// update counters
        			z.avail_out -= n;
        			z.total_out += n;
        
        			// copy as far as end of window
        			z.next_out.set(that.window.subarray(q, q + n), p);
        			p += n;
        			q += n;
        
        			// see if more to copy at beginning of window
        			if (q == that.end) {
        				// wrap pointers
        				q = 0;
        				if (that.write == that.end)
        					that.write = 0;
        
        				// compute bytes to copy
        				n = that.write - q;
        				if (n > z.avail_out)
        					n = z.avail_out;
        				if (n !== 0 && r == Z_BUF_ERROR)
        					r = Z_OK;
        
        				// update counters
        				z.avail_out -= n;
        				z.total_out += n;
        
        				// copy
        				z.next_out.set(that.window.subarray(q, q + n), p);
        				p += n;
        				q += n;
        			}
        
        			// update pointers
        			z.next_out_index = p;
        			that.read = q;
        
        			// done
        			return r;
        		};
        
        		that.proc = function(z, r) {
        			var t; // temporary storage
        			var b; // bit buffer
        			var k; // bits in bit buffer
        			var p; // input data pointer
        			var n; // bytes available there
        			var q; // output window write pointer
        			var m; // bytes to end of window or read pointer
        
        			var i;
        
        			// copy input/output information to locals (UPDATE macro restores)
        			// {
        			p = z.next_in_index;
        			n = z.avail_in;
        			b = that.bitb;
        			k = that.bitk;
        			// }
        			// {
        			q = that.write;
        			m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
        			// }
        
        			// process input based on current state
        			// DEBUG dtree
        			while (true) {
        				switch (mode) {
        				case TYPE:
        
        					while (k < (3)) {
        						if (n !== 0) {
        							r = Z_OK;
        						} else {
        							that.bitb = b;
        							that.bitk = k;
        							z.avail_in = n;
        							z.total_in += p - z.next_in_index;
        							z.next_in_index = p;
        							that.write = q;
        							return that.inflate_flush(z, r);
        						}
        						n--;
        						b |= (z.read_byte(p++) & 0xff) << k;
        						k += 8;
        					}
        					t = /* (int) */(b & 7);
        					last = t & 1;
        
        					switch (t >>> 1) {
        					case 0: // stored
        						// {
        						b >>>= (3);
        						k -= (3);
        						// }
        						t = k & 7; // go to byte boundary
        
        						// {
        						b >>>= (t);
        						k -= (t);
        						// }
        						mode = LENS; // get length of stored block
        						break;
        					case 1: // fixed
        						// {
        						var bl = []; // new Array(1);
        						var bd = []; // new Array(1);
        						var tl = [ [] ]; // new Array(1);
        						var td = [ [] ]; // new Array(1);
        
        						InfTree.inflate_trees_fixed(bl, bd, tl, td);
        						codes.init(bl[0], bd[0], tl[0], 0, td[0], 0);
        						// }
        
        						// {
        						b >>>= (3);
        						k -= (3);
        						// }
        
        						mode = CODES;
        						break;
        					case 2: // dynamic
        
        						// {
        						b >>>= (3);
        						k -= (3);
        						// }
        
        						mode = TABLE;
        						break;
        					case 3: // illegal
        
        						// {
        						b >>>= (3);
        						k -= (3);
        						// }
        						mode = BADBLOCKS;
        						z.msg = "invalid block type";
        						r = Z_DATA_ERROR;
        
        						that.bitb = b;
        						that.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						that.write = q;
        						return that.inflate_flush(z, r);
        					}
        					break;
        				case LENS:
        
        					while (k < (32)) {
        						if (n !== 0) {
        							r = Z_OK;
        						} else {
        							that.bitb = b;
        							that.bitk = k;
        							z.avail_in = n;
        							z.total_in += p - z.next_in_index;
        							z.next_in_index = p;
        							that.write = q;
        							return that.inflate_flush(z, r);
        						}
        						n--;
        						b |= (z.read_byte(p++) & 0xff) << k;
        						k += 8;
        					}
        
        					if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) {
        						mode = BADBLOCKS;
        						z.msg = "invalid stored block lengths";
        						r = Z_DATA_ERROR;
        
        						that.bitb = b;
        						that.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						that.write = q;
        						return that.inflate_flush(z, r);
        					}
        					left = (b & 0xffff);
        					b = k = 0; // dump bits
        					mode = left !== 0 ? STORED : (last !== 0 ? DRY : TYPE);
        					break;
        				case STORED:
        					if (n === 0) {
        						that.bitb = b;
        						that.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						that.write = q;
        						return that.inflate_flush(z, r);
        					}
        
        					if (m === 0) {
        						if (q == that.end && that.read !== 0) {
        							q = 0;
        							m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
        						}
        						if (m === 0) {
        							that.write = q;
        							r = that.inflate_flush(z, r);
        							q = that.write;
        							m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
        							if (q == that.end && that.read !== 0) {
        								q = 0;
        								m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
        							}
        							if (m === 0) {
        								that.bitb = b;
        								that.bitk = k;
        								z.avail_in = n;
        								z.total_in += p - z.next_in_index;
        								z.next_in_index = p;
        								that.write = q;
        								return that.inflate_flush(z, r);
        							}
        						}
        					}
        					r = Z_OK;
        
        					t = left;
        					if (t > n)
        						t = n;
        					if (t > m)
        						t = m;
        					that.window.set(z.read_buf(p, t), q);
        					p += t;
        					n -= t;
        					q += t;
        					m -= t;
        					if ((left -= t) !== 0)
        						break;
        					mode = last !== 0 ? DRY : TYPE;
        					break;
        				case TABLE:
        
        					while (k < (14)) {
        						if (n !== 0) {
        							r = Z_OK;
        						} else {
        							that.bitb = b;
        							that.bitk = k;
        							z.avail_in = n;
        							z.total_in += p - z.next_in_index;
        							z.next_in_index = p;
        							that.write = q;
        							return that.inflate_flush(z, r);
        						}
        
        						n--;
        						b |= (z.read_byte(p++) & 0xff) << k;
        						k += 8;
        					}
        
        					table = t = (b & 0x3fff);
        					if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) {
        						mode = BADBLOCKS;
        						z.msg = "too many length or distance symbols";
        						r = Z_DATA_ERROR;
        
        						that.bitb = b;
        						that.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						that.write = q;
        						return that.inflate_flush(z, r);
        					}
        					t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
        					if (!blens || blens.length < t) {
        						blens = []; // new Array(t);
        					} else {
        						for (i = 0; i < t; i++) {
        							blens[i] = 0;
        						}
        					}
        
        					// {
        					b >>>= (14);
        					k -= (14);
        					// }
        
        					index = 0;
        					mode = BTREE;
        				case BTREE:
        					while (index < 4 + (table >>> 10)) {
        						while (k < (3)) {
        							if (n !== 0) {
        								r = Z_OK;
        							} else {
        								that.bitb = b;
        								that.bitk = k;
        								z.avail_in = n;
        								z.total_in += p - z.next_in_index;
        								z.next_in_index = p;
        								that.write = q;
        								return that.inflate_flush(z, r);
        							}
        							n--;
        							b |= (z.read_byte(p++) & 0xff) << k;
        							k += 8;
        						}
        
        						blens[border[index++]] = b & 7;
        
        						// {
        						b >>>= (3);
        						k -= (3);
        						// }
        					}
        
        					while (index < 19) {
        						blens[border[index++]] = 0;
        					}
        
        					bb[0] = 7;
        					t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z);
        					if (t != Z_OK) {
        						r = t;
        						if (r == Z_DATA_ERROR) {
        							blens = null;
        							mode = BADBLOCKS;
        						}
        
        						that.bitb = b;
        						that.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						that.write = q;
        						return that.inflate_flush(z, r);
        					}
        
        					index = 0;
        					mode = DTREE;
        				case DTREE:
        					while (true) {
        						t = table;
        						if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) {
        							break;
        						}
        
        						var j, c;
        
        						t = bb[0];
        
        						while (k < (t)) {
        							if (n !== 0) {
        								r = Z_OK;
        							} else {
        								that.bitb = b;
        								that.bitk = k;
        								z.avail_in = n;
        								z.total_in += p - z.next_in_index;
        								z.next_in_index = p;
        								that.write = q;
        								return that.inflate_flush(z, r);
        							}
        							n--;
        							b |= (z.read_byte(p++) & 0xff) << k;
        							k += 8;
        						}
        
        						// if (tb[0] == -1) {
        						// System.err.println("null...");
        						// }
        
        						t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1];
        						c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2];
        
        						if (c < 16) {
        							b >>>= (t);
        							k -= (t);
        							blens[index++] = c;
        						} else { // c == 16..18
        							i = c == 18 ? 7 : c - 14;
        							j = c == 18 ? 11 : 3;
        
        							while (k < (t + i)) {
        								if (n !== 0) {
        									r = Z_OK;
        								} else {
        									that.bitb = b;
        									that.bitk = k;
        									z.avail_in = n;
        									z.total_in += p - z.next_in_index;
        									z.next_in_index = p;
        									that.write = q;
        									return that.inflate_flush(z, r);
        								}
        								n--;
        								b |= (z.read_byte(p++) & 0xff) << k;
        								k += 8;
        							}
        
        							b >>>= (t);
        							k -= (t);
        
        							j += (b & inflate_mask[i]);
        
        							b >>>= (i);
        							k -= (i);
        
        							i = index;
        							t = table;
        							if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) {
        								blens = null;
        								mode = BADBLOCKS;
        								z.msg = "invalid bit length repeat";
        								r = Z_DATA_ERROR;
        
        								that.bitb = b;
        								that.bitk = k;
        								z.avail_in = n;
        								z.total_in += p - z.next_in_index;
        								z.next_in_index = p;
        								that.write = q;
        								return that.inflate_flush(z, r);
        							}
        
        							c = c == 16 ? blens[i - 1] : 0;
        							do {
        								blens[i++] = c;
        							} while (--j !== 0);
        							index = i;
        						}
        					}
        
        					tb[0] = -1;
        					// {
        					var bl_ = []; // new Array(1);
        					var bd_ = []; // new Array(1);
        					var tl_ = []; // new Array(1);
        					var td_ = []; // new Array(1);
        					bl_[0] = 9; // must be <= 9 for lookahead assumptions
        					bd_[0] = 6; // must be <= 9 for lookahead assumptions
        
        					t = table;
        					t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl_, bd_, tl_, td_, hufts, z);
        
        					if (t != Z_OK) {
        						if (t == Z_DATA_ERROR) {
        							blens = null;
        							mode = BADBLOCKS;
        						}
        						r = t;
        
        						that.bitb = b;
        						that.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						that.write = q;
        						return that.inflate_flush(z, r);
        					}
        					codes.init(bl_[0], bd_[0], hufts, tl_[0], hufts, td_[0]);
        					// }
        					mode = CODES;
        				case CODES:
        					that.bitb = b;
        					that.bitk = k;
        					z.avail_in = n;
        					z.total_in += p - z.next_in_index;
        					z.next_in_index = p;
        					that.write = q;
        
        					if ((r = codes.proc(that, z, r)) != Z_STREAM_END) {
        						return that.inflate_flush(z, r);
        					}
        					r = Z_OK;
        					codes.free(z);
        
        					p = z.next_in_index;
        					n = z.avail_in;
        					b = that.bitb;
        					k = that.bitk;
        					q = that.write;
        					m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
        
        					if (last === 0) {
        						mode = TYPE;
        						break;
        					}
        					mode = DRY;
        				case DRY:
        					that.write = q;
        					r = that.inflate_flush(z, r);
        					q = that.write;
        					m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
        					if (that.read != that.write) {
        						that.bitb = b;
        						that.bitk = k;
        						z.avail_in = n;
        						z.total_in += p - z.next_in_index;
        						z.next_in_index = p;
        						that.write = q;
        						return that.inflate_flush(z, r);
        					}
        					mode = DONELOCKS;
        				case DONELOCKS:
        					r = Z_STREAM_END;
        
        					that.bitb = b;
        					that.bitk = k;
        					z.avail_in = n;
        					z.total_in += p - z.next_in_index;
        					z.next_in_index = p;
        					that.write = q;
        					return that.inflate_flush(z, r);
        				case BADBLOCKS:
        					r = Z_DATA_ERROR;
        
        					that.bitb = b;
        					that.bitk = k;
        					z.avail_in = n;
        					z.total_in += p - z.next_in_index;
        					z.next_in_index = p;
        					that.write = q;
        					return that.inflate_flush(z, r);
        
        				default:
        					r = Z_STREAM_ERROR;
        
        					that.bitb = b;
        					that.bitk = k;
        					z.avail_in = n;
        					z.total_in += p - z.next_in_index;
        					z.next_in_index = p;
        					that.write = q;
        					return that.inflate_flush(z, r);
        				}
        			}
        		};
        
        		that.free = function(z) {
        			that.reset(z, null);
        			that.window = null;
        			hufts = null;
        			// ZFREE(z, s);
        		};
        
        		that.set_dictionary = function(d, start, n) {
        			that.window.set(d.subarray(start, start + n), 0);
        			that.read = that.write = n;
        		};
        
        		// Returns true if inflate is currently at the end of a block generated
        		// by Z_SYNC_FLUSH or Z_FULL_FLUSH.
        		that.sync_point = function() {
        			return mode == LENS ? 1 : 0;
        		};
        
        	}
        
        	// Inflate
        
        	// preset dictionary flag in zlib header
        	var PRESET_DICT = 0x20;
        
        	var Z_DEFLATED = 8;
        
        	var METHOD = 0; // waiting for method byte
        	var FLAG = 1; // waiting for flag byte
        	var DICT4 = 2; // four dictionary check bytes to go
        	var DICT3 = 3; // three dictionary check bytes to go
        	var DICT2 = 4; // two dictionary check bytes to go
        	var DICT1 = 5; // one dictionary check byte to go
        	var DICT0 = 6; // waiting for inflateSetDictionary
        	var BLOCKS = 7; // decompressing blocks
        	var DONE = 12; // finished check, done
        	var BAD = 13; // got an error--stay here
        
        	var mark = [ 0, 0, 0xff, 0xff ];
        
        	function Inflate() {
        		var that = this;
        
        		that.mode = 0; // current inflate mode
        
        		// mode dependent information
        		that.method = 0; // if FLAGS, method byte
        
        		// if CHECK, check values to compare
        		that.was = [ 0 ]; // new Array(1); // computed check value
        		that.need = 0; // stream check value
        
        		// if BAD, inflateSync's marker bytes count
        		that.marker = 0;
        
        		// mode independent information
        		that.wbits = 0; // log2(window size) (8..15, defaults to 15)
        
        		// this.blocks; // current inflate_blocks state
        
        		function inflateReset(z) {
        			if (!z || !z.istate)
        				return Z_STREAM_ERROR;
        
        			z.total_in = z.total_out = 0;
        			z.msg = null;
        			z.istate.mode = BLOCKS;
        			z.istate.blocks.reset(z, null);
        			return Z_OK;
        		}
        
        		that.inflateEnd = function(z) {
        			if (that.blocks)
        				that.blocks.free(z);
        			that.blocks = null;
        			// ZFREE(z, z->state);
        			return Z_OK;
        		};
        
        		that.inflateInit = function(z, w) {
        			z.msg = null;
        			that.blocks = null;
        
        			// set window size
        			if (w < 8 || w > 15) {
        				that.inflateEnd(z);
        				return Z_STREAM_ERROR;
        			}
        			that.wbits = w;
        
        			z.istate.blocks = new InfBlocks(z, 1 << w);
        
        			// reset state
        			inflateReset(z);
        			return Z_OK;
        		};
        
        		that.inflate = function(z, f) {
        			var r;
        			var b;
        
        			if (!z || !z.istate || !z.next_in)
        				return Z_STREAM_ERROR;
        			f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
        			r = Z_BUF_ERROR;
        			while (true) {
        				// System.out.println("mode: "+z.istate.mode);
        				switch (z.istate.mode) {
        				case METHOD:
        
        					if (z.avail_in === 0)
        						return r;
        					r = f;
        
        					z.avail_in--;
        					z.total_in++;
        					if (((z.istate.method = z.read_byte(z.next_in_index++)) & 0xf) != Z_DEFLATED) {
        						z.istate.mode = BAD;
        						z.msg = "unknown compression method";
        						z.istate.marker = 5; // can't try inflateSync
        						break;
        					}
        					if ((z.istate.method >> 4) + 8 > z.istate.wbits) {
        						z.istate.mode = BAD;
        						z.msg = "invalid window size";
        						z.istate.marker = 5; // can't try inflateSync
        						break;
        					}
        					z.istate.mode = FLAG;
        				case FLAG:
        
        					if (z.avail_in === 0)
        						return r;
        					r = f;
        
        					z.avail_in--;
        					z.total_in++;
        					b = (z.read_byte(z.next_in_index++)) & 0xff;
        
        					if ((((z.istate.method << 8) + b) % 31) !== 0) {
        						z.istate.mode = BAD;
        						z.msg = "incorrect header check";
        						z.istate.marker = 5; // can't try inflateSync
        						break;
        					}
        
        					if ((b & PRESET_DICT) === 0) {
        						z.istate.mode = BLOCKS;
        						break;
        					}
        					z.istate.mode = DICT4;
        				case DICT4:
        
        					if (z.avail_in === 0)
        						return r;
        					r = f;
        
        					z.avail_in--;
        					z.total_in++;
        					z.istate.need = ((z.read_byte(z.next_in_index++) & 0xff) << 24) & 0xff000000;
        					z.istate.mode = DICT3;
        				case DICT3:
        
        					if (z.avail_in === 0)
        						return r;
        					r = f;
        
        					z.avail_in--;
        					z.total_in++;
        					z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 16) & 0xff0000;
        					z.istate.mode = DICT2;
        				case DICT2:
        
        					if (z.avail_in === 0)
        						return r;
        					r = f;
        
        					z.avail_in--;
        					z.total_in++;
        					z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 8) & 0xff00;
        					z.istate.mode = DICT1;
        				case DICT1:
        
        					if (z.avail_in === 0)
        						return r;
        					r = f;
        
        					z.avail_in--;
        					z.total_in++;
        					z.istate.need += (z.read_byte(z.next_in_index++) & 0xff);
        					z.istate.mode = DICT0;
        					return Z_NEED_DICT;
        				case DICT0:
        					z.istate.mode = BAD;
        					z.msg = "need dictionary";
        					z.istate.marker = 0; // can try inflateSync
        					return Z_STREAM_ERROR;
        				case BLOCKS:
        
        					r = z.istate.blocks.proc(z, r);
        					if (r == Z_DATA_ERROR) {
        						z.istate.mode = BAD;
        						z.istate.marker = 0; // can try inflateSync
        						break;
        					}
        					if (r == Z_OK) {
        						r = f;
        					}
        					if (r != Z_STREAM_END) {
        						return r;
        					}
        					r = f;
        					z.istate.blocks.reset(z, z.istate.was);
        					z.istate.mode = DONE;
        				case DONE:
        					return Z_STREAM_END;
        				case BAD:
        					return Z_DATA_ERROR;
        				default:
        					return Z_STREAM_ERROR;
        				}
        			}
        		};
        
        		that.inflateSetDictionary = function(z, dictionary, dictLength) {
        			var index = 0;
        			var length = dictLength;
        			if (!z || !z.istate || z.istate.mode != DICT0)
        				return Z_STREAM_ERROR;
        
        			if (length >= (1 << z.istate.wbits)) {
        				length = (1 << z.istate.wbits) - 1;
        				index = dictLength - length;
        			}
        			z.istate.blocks.set_dictionary(dictionary, index, length);
        			z.istate.mode = BLOCKS;
        			return Z_OK;
        		};
        
        		that.inflateSync = function(z) {
        			var n; // number of bytes to look at
        			var p; // pointer to bytes
        			var m; // number of marker bytes found in a row
        			var r, w; // temporaries to save total_in and total_out
        
        			// set up
        			if (!z || !z.istate)
        				return Z_STREAM_ERROR;
        			if (z.istate.mode != BAD) {
        				z.istate.mode = BAD;
        				z.istate.marker = 0;
        			}
        			if ((n = z.avail_in) === 0)
        				return Z_BUF_ERROR;
        			p = z.next_in_index;
        			m = z.istate.marker;
        
        			// search
        			while (n !== 0 && m < 4) {
        				if (z.read_byte(p) == mark[m]) {
        					m++;
        				} else if (z.read_byte(p) !== 0) {
        					m = 0;
        				} else {
        					m = 4 - m;
        				}
        				p++;
        				n--;
        			}
        
        			// restore
        			z.total_in += p - z.next_in_index;
        			z.next_in_index = p;
        			z.avail_in = n;
        			z.istate.marker = m;
        
        			// return no joy or set up to restart on a new block
        			if (m != 4) {
        				return Z_DATA_ERROR;
        			}
        			r = z.total_in;
        			w = z.total_out;
        			inflateReset(z);
        			z.total_in = r;
        			z.total_out = w;
        			z.istate.mode = BLOCKS;
        			return Z_OK;
        		};
        
        		// Returns true if inflate is currently at the end of a block generated
        		// by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
        		// implementation to provide an additional safety check. PPP uses
        		// Z_SYNC_FLUSH
        		// but removes the length bytes of the resulting empty stored block. When
        		// decompressing, PPP checks that at the end of input packet, inflate is
        		// waiting for these length bytes.
        		that.inflateSyncPoint = function(z) {
        			if (!z || !z.istate || !z.istate.blocks)
        				return Z_STREAM_ERROR;
        			return z.istate.blocks.sync_point();
        		};
        	}
        
        	// ZStream
        
        	function ZStream() {
        	}
        
        	ZStream.prototype = {
        		inflateInit : function(bits) {
        			var that = this;
        			that.istate = new Inflate();
        			if (!bits)
        				bits = MAX_BITS;
        			return that.istate.inflateInit(that, bits);
        		},
        
        		inflate : function(f) {
        			var that = this;
        			if (!that.istate)
        				return Z_STREAM_ERROR;
        			return that.istate.inflate(that, f);
        		},
        
        		inflateEnd : function() {
        			var that = this;
        			if (!that.istate)
        				return Z_STREAM_ERROR;
        			var ret = that.istate.inflateEnd(that);
        			that.istate = null;
        			return ret;
        		},
        
        		inflateSync : function() {
        			var that = this;
        			if (!that.istate)
        				return Z_STREAM_ERROR;
        			return that.istate.inflateSync(that);
        		},
        		inflateSetDictionary : function(dictionary, dictLength) {
        			var that = this;
        			if (!that.istate)
        				return Z_STREAM_ERROR;
        			return that.istate.inflateSetDictionary(that, dictionary, dictLength);
        		},
        		read_byte : function(start) {
        			var that = this;
        			return that.next_in.subarray(start, start + 1)[0];
        		},
        		read_buf : function(start, size) {
        			var that = this;
        			return that.next_in.subarray(start, start + size);
        		}
        	};
        
        	// Inflater
        
        	function Inflater() {
        		var that = this;
        		var z = new ZStream();
        		var bufsize = 512;
        		var flush = Z_NO_FLUSH;
        		var buf = new Uint8Array(bufsize);
        		var nomoreinput = false;
        
        		z.inflateInit();
        		z.next_out = buf;
        
        		that.append = function(data, onprogress) {
        			var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;
        			if (data.length === 0)
        				return;
        			z.next_in_index = 0;
        			z.next_in = data;
        			z.avail_in = data.length;
        			do {
        				z.next_out_index = 0;
        				z.avail_out = bufsize;
        				if ((z.avail_in === 0) && (!nomoreinput)) { // if buffer is empty and more input is available, refill it
        					z.next_in_index = 0;
        					nomoreinput = true;
        				}
        				err = z.inflate(flush);
        				if (nomoreinput && (err == Z_BUF_ERROR))
        					return -1;
        				if (err != Z_OK && err != Z_STREAM_END)
        					throw "inflating: " + z.msg;
        				if ((nomoreinput || err == Z_STREAM_END) && (z.avail_in == data.length))
        					return -1;
        				if (z.next_out_index)
        					if (z.next_out_index == bufsize)
        						buffers.push(new Uint8Array(buf));
        					else
        						buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
        				bufferSize += z.next_out_index;
        				if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {
        					onprogress(z.next_in_index);
        					lastIndex = z.next_in_index;
        				}
        			} while (z.avail_in > 0 || z.avail_out === 0);
        			array = new Uint8Array(bufferSize);
        			buffers.forEach(function(chunk) {
        				array.set(chunk, bufferIndex);
        				bufferIndex += chunk.length;
        			});
        			return array;
        		};
        		that.flush = function() {
        			z.inflateEnd();
        		};
        	}
        
        	var inflater;
        
        	if (obj.zip)
        		obj.zip.Inflater = Inflater;
        	else {
        		inflater = new Inflater();
        		obj.addEventListener("message", function(event) {
        			var message = event.data;
        
        			if (message.append)
        				obj.postMessage({
        					onappend : true,
        					data : inflater.append(message.data, function(current) {
        						obj.postMessage({
        							progress : true,
        							current : current
        						});
        					})
        				});
        			if (message.flush) {
        				inflater.flush();
        				obj.postMessage({
        					onflush : true
        				});
        			}
        		}, false);
        	}
        
        })(this);
        
      • zip.js
        /*
         Copyright (c) 2013 Gildas Lormeau. All rights reserved.
        
         Redistribution and use in source and binary forms, with or without
         modification, are permitted provided that the following conditions are met:
        
         1. Redistributions of source code must retain the above copyright notice,
         this list of conditions and the following disclaimer.
        
         2. Redistributions in binary form must reproduce the above copyright
         notice, this list of conditions and the following disclaimer in
         the documentation and/or other materials provided with the distribution.
        
         3. The names of the authors may not be used to endorse or promote products
         derived from this software without specific prior written permission.
        
         THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
         INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
         FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
         INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
         INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
         OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
         LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
         NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
         EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         */
        
        (function(obj) {
        
        	var ERR_BAD_FORMAT = "File format is not recognized.";
        	var ERR_ENCRYPTED = "File contains encrypted entry.";
        	var ERR_ZIP64 = "File is using Zip64 (4gb+ file size).";
        	var ERR_READ = "Error while reading zip file.";
        	var ERR_WRITE = "Error while writing zip file.";
        	var ERR_WRITE_DATA = "Error while writing file data.";
        	var ERR_READ_DATA = "Error while reading file data.";
        	var ERR_DUPLICATED_NAME = "File already exists.";
        	var CHUNK_SIZE = 512 * 1024;
        
        	var INFLATE_JS = "inflate.js";
        	var DEFLATE_JS = "deflate.js";
        	
        	var TEXT_PLAIN = "text/plain";
        	
        	var MESSAGE_EVENT = "message";
        
        	var appendABViewSupported;
        	try {
        		appendABViewSupported = new Blob([ new DataView(new ArrayBuffer(0)) ]).size === 0;
        	} catch (e) {
        	}
        
        	function Crc32() {
        		var crc = -1, that = this;
        		that.append = function(data) {
        			var offset, table = that.table;
        			for (offset = 0; offset < data.length; offset++)
        				crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF];
        		};
        		that.get = function() {
        			return ~crc;
        		};
        	}
        	Crc32.prototype.table = (function() {
        		var i, j, t, table = [];
        		for (i = 0; i < 256; i++) {
        			t = i;
        			for (j = 0; j < 8; j++)
        				if (t & 1)
        					t = (t >>> 1) ^ 0xEDB88320;
        				else
        					t = t >>> 1;
        			table[i] = t;
        		}
        		return table;
        	})();
        
        	function blobSlice(blob, index, length) {
        		if (blob.slice)
        			return blob.slice(index, index + length);
        		else if (blob.webkitSlice)
        			return blob.webkitSlice(index, index + length);
        		else if (blob.mozSlice)
        			return blob.mozSlice(index, index + length);
        		else if (blob.msSlice)
        			return blob.msSlice(index, index + length);
        	}
        
        	function getDataHelper(byteLength, bytes) {
        		var dataBuffer, dataArray;
        		dataBuffer = new ArrayBuffer(byteLength);
        		dataArray = new Uint8Array(dataBuffer);
        		if (bytes)
        			dataArray.set(bytes, 0);
        		return {
        			buffer : dataBuffer,
        			array : dataArray,
        			view : new DataView(dataBuffer)
        		};
        	}
        
        	// Readers
        	function Reader() {
        	}
        
        	function TextReader(text) {
        		var that = this, blobReader;
        
        		function init(callback, onerror) {
        			var blob = new Blob([ text ], {
        				type : TEXT_PLAIN
        			});
        			blobReader = new BlobReader(blob);
        			blobReader.init(function() {
        				that.size = blobReader.size;
        				callback();
        			}, onerror);
        		}
        
        		function readUint8Array(index, length, callback, onerror) {
        			blobReader.readUint8Array(index, length, callback, onerror);
        		}
        
        		that.size = 0;
        		that.init = init;
        		that.readUint8Array = readUint8Array;
        	}
        	TextReader.prototype = new Reader();
        	TextReader.prototype.constructor = TextReader;
        
        	function Data64URIReader(dataURI) {
        		var that = this, dataStart;
        
        		function init(callback) {
        			var dataEnd = dataURI.length;
        			while (dataURI.charAt(dataEnd - 1) == "=")
        				dataEnd--;
        			dataStart = dataURI.indexOf(",") + 1;
        			that.size = Math.floor((dataEnd - dataStart) * 0.75);
        			callback();
        		}
        
        		function readUint8Array(index, length, callback) {
        			var i, data = getDataHelper(length);
        			var start = Math.floor(index / 3) * 4;
        			var end = Math.ceil((index + length) / 3) * 4;
        			var bytes = obj.atob(dataURI.substring(start + dataStart, end + dataStart));
        			var delta = index - Math.floor(start / 4) * 3;
        			for (i = delta; i < delta + length; i++)
        				data.array[i - delta] = bytes.charCodeAt(i);
        			callback(data.array);
        		}
        
        		that.size = 0;
        		that.init = init;
        		that.readUint8Array = readUint8Array;
        	}
        	Data64URIReader.prototype = new Reader();
        	Data64URIReader.prototype.constructor = Data64URIReader;
        
        	function BlobReader(blob) {
        		var that = this;
        
        		function init(callback) {
        			this.size = blob.size;
        			callback();
        		}
        
        		function readUint8Array(index, length, callback, onerror) {
        			var reader = new FileReader();
        			reader.onload = function(e) {
        				callback(new Uint8Array(e.target.result));
        			};
        			reader.onerror = onerror;
        			reader.readAsArrayBuffer(blobSlice(blob, index, length));
        		}
        
        		that.size = 0;
        		that.init = init;
        		that.readUint8Array = readUint8Array;
        	}
        	BlobReader.prototype = new Reader();
        	BlobReader.prototype.constructor = BlobReader;
        
        	// Writers
        
        	function Writer() {
        	}
        	Writer.prototype.getData = function(callback) {
        		callback(this.data);
        	};
        
        	function TextWriter(encoding) {
        		var that = this, blob;
        
        		function init(callback) {
        			blob = new Blob([], {
        				type : TEXT_PLAIN
        			});
        			callback();
        		}
        
        		function writeUint8Array(array, callback) {
        			blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], {
        				type : TEXT_PLAIN
        			});
        			callback();
        		}
        
        		function getData(callback, onerror) {
        			var reader = new FileReader();
        			reader.onload = function(e) {
        				callback(e.target.result);
        			};
        			reader.onerror = onerror;
        			reader.readAsText(blob, encoding);
        		}
        
        		that.init = init;
        		that.writeUint8Array = writeUint8Array;
        		that.getData = getData;
        	}
        	TextWriter.prototype = new Writer();
        	TextWriter.prototype.constructor = TextWriter;
        
        	function Data64URIWriter(contentType) {
        		var that = this, data = "", pending = "";
        
        		function init(callback) {
        			data += "data:" + (contentType || "") + ";base64,";
        			callback();
        		}
        
        		function writeUint8Array(array, callback) {
        			var i, delta = pending.length, dataString = pending;
        			pending = "";
        			for (i = 0; i < (Math.floor((delta + array.length) / 3) * 3) - delta; i++)
        				dataString += String.fromCharCode(array[i]);
        			for (; i < array.length; i++)
        				pending += String.fromCharCode(array[i]);
        			if (dataString.length > 2)
        				data += obj.btoa(dataString);
        			else
        				pending = dataString;
        			callback();
        		}
        
        		function getData(callback) {
        			callback(data + obj.btoa(pending));
        		}
        
        		that.init = init;
        		that.writeUint8Array = writeUint8Array;
        		that.getData = getData;
        	}
        	Data64URIWriter.prototype = new Writer();
        	Data64URIWriter.prototype.constructor = Data64URIWriter;
        
        	function BlobWriter(contentType) {
        		var blob, that = this;
        
        		function init(callback) {
        			blob = new Blob([], {
        				type : contentType
        			});
        			callback();
        		}
        
        		function writeUint8Array(array, callback) {
        			blob = new Blob([ blob, appendABViewSupported ? array : array.buffer ], {
        				type : contentType
        			});
        			callback();
        		}
        
        		function getData(callback) {
        			callback(blob);
        		}
        
        		that.init = init;
        		that.writeUint8Array = writeUint8Array;
        		that.getData = getData;
        	}
        	BlobWriter.prototype = new Writer();
        	BlobWriter.prototype.constructor = BlobWriter;
        
        	// inflate/deflate core functions
        
        	function launchWorkerProcess(worker, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) {
        		var chunkIndex = 0, index, outputSize;
        
        		function onflush() {
        			worker.removeEventListener(MESSAGE_EVENT, onmessage, false);
        			onend(outputSize);
        		}
        
        		function onmessage(event) {
        			var message = event.data, data = message.data;
        
        			if (message.onappend) {
        				outputSize += data.length;
        				writer.writeUint8Array(data, function() {
        					onappend(false, data);
        					step();
        				}, onwriteerror);
        			}
        			if (message.onflush)
        				if (data) {
        					outputSize += data.length;
        					writer.writeUint8Array(data, function() {
        						onappend(false, data);
        						onflush();
        					}, onwriteerror);
        				} else
        					onflush();
        			if (message.progress && onprogress)
        				onprogress(index + message.current, size);
        		}
        
        		function step() {
        			index = chunkIndex * CHUNK_SIZE;
        			if (index < size)
        				reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) {
        					worker.postMessage({
        						append : true,
        						data : array
        					});
        					chunkIndex++;
        					if (onprogress)
        						onprogress(index, size);
        					onappend(true, array);
        				}, onreaderror);
        			else
        				worker.postMessage({
        					flush : true
        				});
        		}
        
        		outputSize = 0;
        		worker.addEventListener(MESSAGE_EVENT, onmessage, false);
        		step();
        	}
        
        	function launchProcess(process, reader, writer, offset, size, onappend, onprogress, onend, onreaderror, onwriteerror) {
        		var chunkIndex = 0, index, outputSize = 0;
        
        		function step() {
        			var outputData;
        			index = chunkIndex * CHUNK_SIZE;
        			if (index < size)
        				reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(inputData) {
        					var outputData = process.append(inputData, function() {
        						if (onprogress)
        							onprogress(offset + index, size);
        					});
        					outputSize += outputData.length;
        					onappend(true, inputData);
        					writer.writeUint8Array(outputData, function() {
        						onappend(false, outputData);
        						chunkIndex++;
        						setTimeout(step, 1);
        					}, onwriteerror);
        					if (onprogress)
        						onprogress(index, size);
        				}, onreaderror);
        			else {
        				outputData = process.flush();
        				if (outputData) {
        					outputSize += outputData.length;
        					writer.writeUint8Array(outputData, function() {
        						onappend(false, outputData);
        						onend(outputSize);
        					}, onwriteerror);
        				} else
        					onend(outputSize);
        			}
        		}
        
        		step();
        	}
        
        	function inflate(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) {
        		var worker, crc32 = new Crc32();
        
        		function oninflateappend(sending, array) {
        			if (computeCrc32 && !sending)
        				crc32.append(array);
        		}
        
        		function oninflateend(outputSize) {
        			onend(outputSize, crc32.get());
        		}
        
        		if (obj.zip.useWebWorkers) {
        			worker = new Worker(obj.zip.workerScriptsPath + INFLATE_JS);
        			launchWorkerProcess(worker, reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror);
        		} else
        			launchProcess(new obj.zip.Inflater(), reader, writer, offset, size, oninflateappend, onprogress, oninflateend, onreaderror, onwriteerror);
        		return worker;
        	}
        
        	function deflate(reader, writer, level, onend, onprogress, onreaderror, onwriteerror) {
        		var worker, crc32 = new Crc32();
        
        		function ondeflateappend(sending, array) {
        			if (sending)
        				crc32.append(array);
        		}
        
        		function ondeflateend(outputSize) {
        			onend(outputSize, crc32.get());
        		}
        
        		function onmessage() {
        			worker.removeEventListener(MESSAGE_EVENT, onmessage, false);
        			launchWorkerProcess(worker, reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror);
        		}
        
        		if (obj.zip.useWebWorkers) {
        			worker = new Worker(obj.zip.workerScriptsPath + DEFLATE_JS);
        			worker.addEventListener(MESSAGE_EVENT, onmessage, false);
        			worker.postMessage({
        				init : true,
        				level : level
        			});
        		} else
        			launchProcess(new obj.zip.Deflater(), reader, writer, 0, reader.size, ondeflateappend, onprogress, ondeflateend, onreaderror, onwriteerror);
        		return worker;
        	}
        
        	function copy(reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) {
        		var chunkIndex = 0, crc32 = new Crc32();
        
        		function step() {
        			var index = chunkIndex * CHUNK_SIZE;
        			if (index < size)
        				reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function(array) {
        					if (computeCrc32)
        						crc32.append(array);
        					if (onprogress)
        						onprogress(index, size, array);
        					writer.writeUint8Array(array, function() {
        						chunkIndex++;
        						step();
        					}, onwriteerror);
        				}, onreaderror);
        			else
        				onend(size, crc32.get());
        		}
        
        		step();
        	}
        
        	// ZipReader
        
        	function decodeASCII(str) {
        		var i, out = "", charCode, extendedASCII = [ '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB',
        				'\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9',
        				'\u00FF', '\u00D6', '\u00DC', '\u00F8', '\u00A3', '\u00D8', '\u00D7', '\u0192', '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1',
        				'\u00AA', '\u00BA', '\u00BF', '\u00AE', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', '_', '_', '_', '\u00A6', '\u00A6',
        				'\u00C1', '\u00C2', '\u00C0', '\u00A9', '\u00A6', '\u00A6', '+', '+', '\u00A2', '\u00A5', '+', '+', '-', '-', '+', '-', '+', '\u00E3',
        				'\u00C3', '+', '+', '-', '-', '\u00A6', '-', '+', '\u00A4', '\u00F0', '\u00D0', '\u00CA', '\u00CB', '\u00C8', 'i', '\u00CD', '\u00CE',
        				'\u00CF', '+', '+', '_', '_', '\u00A6', '\u00CC', '_', '\u00D3', '\u00DF', '\u00D4', '\u00D2', '\u00F5', '\u00D5', '\u00B5', '\u00FE',
        				'\u00DE', '\u00DA', '\u00DB', '\u00D9', '\u00FD', '\u00DD', '\u00AF', '\u00B4', '\u00AD', '\u00B1', '_', '\u00BE', '\u00B6', '\u00A7',
        				'\u00F7', '\u00B8', '\u00B0', '\u00A8', '\u00B7', '\u00B9', '\u00B3', '\u00B2', '_', ' ' ];
        		for (i = 0; i < str.length; i++) {
        			charCode = str.charCodeAt(i) & 0xFF;
        			if (charCode > 127)
        				out += extendedASCII[charCode - 128];
        			else
        				out += String.fromCharCode(charCode);
        		}
        		return out;
        	}
        
        	function decodeUTF8(string) {
        		return decodeURIComponent(escape(string));
        	}
        
        	function getString(bytes) {
        		var i, str = "";
        		for (i = 0; i < bytes.length; i++)
        			str += String.fromCharCode(bytes[i]);
        		return str;
        	}
        
        	function getDate(timeRaw) {
        		var date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff;
        		try {
        			return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5,
        					(time & 0x001F) * 2, 0);
        		} catch (e) {
        		}
        	}
        
        	function readCommonHeader(entry, data, index, centralDirectory, onerror) {
        		entry.version = data.view.getUint16(index, true);
        		entry.bitFlag = data.view.getUint16(index + 2, true);
        		entry.compressionMethod = data.view.getUint16(index + 4, true);
        		entry.lastModDateRaw = data.view.getUint32(index + 6, true);
        		entry.lastModDate = getDate(entry.lastModDateRaw);
        		if ((entry.bitFlag & 0x01) === 0x01) {
        			onerror(ERR_ENCRYPTED);
        			return;
        		}
        		if (centralDirectory || (entry.bitFlag & 0x0008) != 0x0008) {
        			entry.crc32 = data.view.getUint32(index + 10, true);
        			entry.compressedSize = data.view.getUint32(index + 14, true);
        			entry.uncompressedSize = data.view.getUint32(index + 18, true);
        		}
        		if (entry.compressedSize === 0xFFFFFFFF || entry.uncompressedSize === 0xFFFFFFFF) {
        			onerror(ERR_ZIP64);
        			return;
        		}
        		entry.filenameLength = data.view.getUint16(index + 22, true);
        		entry.extraFieldLength = data.view.getUint16(index + 24, true);
        	}
        
        	function createZipReader(reader, onerror) {
        		function Entry() {
        		}
        
        		Entry.prototype.getData = function(writer, onend, onprogress, checkCrc32) {
        			var that = this, worker;
        
        			function terminate(callback, param) {
        				if (worker)
        					worker.terminate();
        				worker = null;
        				if (callback)
        					callback(param);
        			}
        
        			function testCrc32(crc32) {
        				var dataCrc32 = getDataHelper(4);
        				dataCrc32.view.setUint32(0, crc32);
        				return that.crc32 == dataCrc32.view.getUint32(0);
        			}
        
        			function getWriterData(uncompressedSize, crc32) {
        				if (checkCrc32 && !testCrc32(crc32))
        					onreaderror();
        				else
        					writer.getData(function(data) {
        						terminate(onend, data);
        					});
        			}
        
        			function onreaderror() {
        				terminate(onerror, ERR_READ_DATA);
        			}
        
        			function onwriteerror() {
        				terminate(onerror, ERR_WRITE_DATA);
        			}
        
        			reader.readUint8Array(that.offset, 30, function(bytes) {
        				var data = getDataHelper(bytes.length, bytes), dataOffset;
        				if (data.view.getUint32(0) != 0x504b0304) {
        					onerror(ERR_BAD_FORMAT);
        					return;
        				}
        				readCommonHeader(that, data, 4, false, onerror);
        				dataOffset = that.offset + 30 + that.filenameLength + that.extraFieldLength;
        				writer.init(function() {
        					if (that.compressionMethod === 0)
        						copy(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror);
        					else
        						worker = inflate(reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror);
        				}, onwriteerror);
        			}, onreaderror);
        		};
        
        		function seekEOCDR(offset, entriesCallback) {
        			reader.readUint8Array(reader.size - offset, offset, function(bytes) {
        				var dataView = getDataHelper(bytes.length, bytes).view;
        				if (dataView.getUint32(0) != 0x504b0506) {
        					seekEOCDR(offset + 1, entriesCallback);
        				} else {
        					entriesCallback(dataView);
        				}
        			}, function() {
        				onerror(ERR_READ);
        			});
        		}
        
        		return {
        			getEntries : function(callback) {
        				if (reader.size < 22) {
        					onerror(ERR_BAD_FORMAT);
        					return;
        				}
        				// look for End of central directory record
        				seekEOCDR(22, function(dataView) {
        					var datalength, fileslength;
        					datalength = dataView.getUint32(16, true);
        					fileslength = dataView.getUint16(8, true);
        					reader.readUint8Array(datalength, reader.size - datalength, function(bytes) {
        						var i, index = 0, entries = [], entry, filename, comment, data = getDataHelper(bytes.length, bytes);
        						for (i = 0; i < fileslength; i++) {
        							entry = new Entry();
        							if (data.view.getUint32(index) != 0x504b0102) {
        								onerror(ERR_BAD_FORMAT);
        								return;
        							}
        							readCommonHeader(entry, data, index + 6, true, onerror);
        							entry.commentLength = data.view.getUint16(index + 32, true);
        							entry.directory = ((data.view.getUint8(index + 38) & 0x10) == 0x10);
        							entry.offset = data.view.getUint32(index + 42, true);
        							filename = getString(data.array.subarray(index + 46, index + 46 + entry.filenameLength));
        							entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename);
        							if (!entry.directory && entry.filename.charAt(entry.filename.length - 1) == "/")
        								entry.directory = true;
        							comment = getString(data.array.subarray(index + 46 + entry.filenameLength + entry.extraFieldLength, index + 46
        									+ entry.filenameLength + entry.extraFieldLength + entry.commentLength));
        							entry.comment = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(comment) : decodeASCII(comment);
        							entries.push(entry);
        							index += 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength;
        						}
        						callback(entries);
        					}, function() {
        						onerror(ERR_READ);
        					});
        				});
        			},
        			close : function(callback) {
        				if (callback)
        					callback();
        			}
        		};
        	}
        
        	// ZipWriter
        
        	function encodeUTF8(string) {
        		return unescape(encodeURIComponent(string));
        	}
        
        	function getBytes(str) {
        		var i, array = [];
        		for (i = 0; i < str.length; i++)
        			array.push(str.charCodeAt(i));
        		return array;
        	}
        
        	function createZipWriter(writer, onerror, dontDeflate) {
        		var worker, files = {}, filenames = [], datalength = 0;
        
        		function terminate(callback, message) {
        			if (worker)
        				worker.terminate();
        			worker = null;
        			if (callback)
        				callback(message);
        		}
        
        		function onwriteerror() {
        			terminate(onerror, ERR_WRITE);
        		}
        
        		function onreaderror() {
        			terminate(onerror, ERR_READ_DATA);
        		}
        
        		return {
        			add : function(name, reader, onend, onprogress, options) {
        				var header, filename, date;
        
        				function writeHeader(callback) {
        					var data;
        					date = options.lastModDate || new Date();
        					header = getDataHelper(26);
        					files[name] = {
        						headerArray : header.array,
        						directory : options.directory,
        						filename : filename,
        						offset : datalength,
        						comment : getBytes(encodeUTF8(options.comment || ""))
        					};
        					header.view.setUint32(0, 0x14000808);
        					if (options.version)
        						header.view.setUint8(0, options.version);
        					if (!dontDeflate && options.level !== 0 && !options.directory)
        						header.view.setUint16(4, 0x0800);
        					header.view.setUint16(6, (((date.getHours() << 6) | date.getMinutes()) << 5) | date.getSeconds() / 2, true);
        					header.view.setUint16(8, ((((date.getFullYear() - 1980) << 4) | (date.getMonth() + 1)) << 5) | date.getDate(), true);
        					header.view.setUint16(22, filename.length, true);
        					data = getDataHelper(30 + filename.length);
        					data.view.setUint32(0, 0x504b0304);
        					data.array.set(header.array, 4);
        					data.array.set(filename, 30);
        					datalength += data.array.length;
        					writer.writeUint8Array(data.array, callback, onwriteerror);
        				}
        
        				function writeFooter(compressedLength, crc32) {
        					var footer = getDataHelper(16);
        					datalength += compressedLength || 0;
        					footer.view.setUint32(0, 0x504b0708);
        					if (typeof crc32 != "undefined") {
        						header.view.setUint32(10, crc32, true);
        						footer.view.setUint32(4, crc32, true);
        					}
        					if (reader) {
        						footer.view.setUint32(8, compressedLength, true);
        						header.view.setUint32(14, compressedLength, true);
        						footer.view.setUint32(12, reader.size, true);
        						header.view.setUint32(18, reader.size, true);
        					}
        					writer.writeUint8Array(footer.array, function() {
        						datalength += 16;
        						terminate(onend);
        					}, onwriteerror);
        				}
        
        				function writeFile() {
        					options = options || {};
        					name = name.trim();
        					if (options.directory && name.charAt(name.length - 1) != "/")
        						name += "/";
        					if (files.hasOwnProperty(name)) {
        						onerror(ERR_DUPLICATED_NAME);
        						return;
        					}
        					filename = getBytes(encodeUTF8(name));
        					filenames.push(name);
        					writeHeader(function() {
        						if (reader)
        							if (dontDeflate || options.level === 0)
        								copy(reader, writer, 0, reader.size, true, writeFooter, onprogress, onreaderror, onwriteerror);
        							else
        								worker = deflate(reader, writer, options.level, writeFooter, onprogress, onreaderror, onwriteerror);
        						else
        							writeFooter();
        					}, onwriteerror);
        				}
        
        				if (reader)
        					reader.init(writeFile, onreaderror);
        				else
        					writeFile();
        			},
        			close : function(callback) {
        				var data, length = 0, index = 0, indexFilename, file;
        				for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) {
        					file = files[filenames[indexFilename]];
        					length += 46 + file.filename.length + file.comment.length;
        				}
        				data = getDataHelper(length + 22);
        				for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) {
        					file = files[filenames[indexFilename]];
        					data.view.setUint32(index, 0x504b0102);
        					data.view.setUint16(index + 4, 0x1400);
        					data.array.set(file.headerArray, index + 6);
        					data.view.setUint16(index + 32, file.comment.length, true);
        					if (file.directory)
        						data.view.setUint8(index + 38, 0x10);
        					data.view.setUint32(index + 42, file.offset, true);
        					data.array.set(file.filename, index + 46);
        					data.array.set(file.comment, index + 46 + file.filename.length);
        					index += 46 + file.filename.length + file.comment.length;
        				}
        				data.view.setUint32(index, 0x504b0506);
        				data.view.setUint16(index + 8, filenames.length, true);
        				data.view.setUint16(index + 10, filenames.length, true);
        				data.view.setUint32(index + 12, length, true);
        				data.view.setUint32(index + 16, datalength, true);
        				writer.writeUint8Array(data.array, function() {
        					terminate(function() {
        						writer.getData(callback);
        					});
        				}, onwriteerror);
        			}
        		};
        	}
        
        	obj.zip = {
        		Reader : Reader,
        		Writer : Writer,
        		BlobReader : BlobReader,
        		Data64URIReader : Data64URIReader,
        		TextReader : TextReader,
        		BlobWriter : BlobWriter,
        		Data64URIWriter : Data64URIWriter,
        		TextWriter : TextWriter,
        		createReader : function(reader, callback, onerror) {
        			reader.init(function() {
        				callback(createZipReader(reader, onerror));
        			}, onerror);
        		},
        		createWriter : function(writer, callback, onerror, dontDeflate) {
        			writer.init(function() {
        				callback(createZipWriter(writer, onerror, dontDeflate));
        			}, onerror);
        		},
        		workerScriptsPath : "",
        		useWebWorkers : true
        	};
        
        })(this);
        
  • persistence
    • Drive.ts
      module teapo.persistence {
        
        export interface Drive {
      
          timestamp: number;
      
          files(): string[];
      
          read(file: string): string;
      
          write(file: string, content: string);
          
        }
        
        export module Drive {
          
          export interface Shadow {
      
            timestamp: number;
      
            write(file: string, content: string);
            
          }
          
          export interface Optional {
            
            detect(uniqueKey: string, callback: (detached: Detached) => void ): void;
            
          }
          
          export interface Detached {
            
            timestamp: number;
            
            applyTo(mainDrive: Drive, callback: Detached.CallbackWithShadow): void;
            
            purge(callback: Detached.CallbackWithShadow): void;
            
          }
      
          export module Detached {
            export interface CallbackWithShadow {
              
              (loaded: Shadow): void;
              progress?: (current: number, total: number) => void;
              
            }
          }
          
        }
        
      }
    • indexedDB.ts
      module teapo {
        
        function getIndexedDB() {
          return typeof indexedDB === 'undefined' ? null : indexedDB;
        }
        
        export module persistence.indexedDB {
      
          export function detect(uniqueKey: string, callback: (detached: Drive.Detached) => void ): void {
            var indexedDBInstance = getIndexedDB();
            if (!indexedDBInstance) {
              callback(null);
              return;
            }
      
            var dbName = uniqueKey || 'teapo';
      
            var openRequest = indexedDBInstance.open(dbName, 1);
            openRequest.onerror = (errorEvent) => callback(null);
      
            openRequest.onupgradeneeded = (versionChangeEvent) => {
              var db: IDBDatabase = openRequest.result;
              var filesStore = db.createObjectStore('files', { keyPath: 'path' });
              var metadataStore = db.createObjectStore('metadata', { keyPath: 'property' });
            };
      
            openRequest.onsuccess = (event) => {
              var db: IDBDatabase = openRequest.result;
      
              var transaction = db.transaction('metadata');
              transaction.onerror = (errorEvent) => callback(null);
      
              var metadataStore = transaction.objectStore('metadata');
      
              var editedUTCRequest = metadataStore.get('editedUTC');
      
              editedUTCRequest.onerror = (errorEvent) => {
                var detached = new IndexedDBDetached(db, null);
                callback(detached);
              };
      
              editedUTCRequest.onsuccess = (event) => {
                var result: MetadataData = editedUTCRequest.result;
                var detached = new IndexedDBDetached(db, result && typeof result.value === 'number' ? result.value : null);
                callback(detached);
              };
      
            };
          }
      
          class IndexedDBDetached implements Drive.Detached {
      
            constructor(
              private _db: IDBDatabase,
              public timestamp: number) {
            }
      
            applyTo(mainDrive: Drive, callback: Drive.Detached.CallbackWithShadow): void {
              var transaction = this._db.transaction(['files', 'metadata'], 'readwrite');
              var metadataStore = transaction.objectStore('metadata');
              var filesStore = transaction.objectStore('files');
      
              var countRequest = filesStore.count();
              countRequest.onerror = (errorEvent) => {
                console.error('Could not count files store.');
                callback(null);
              };
      
              countRequest.onsuccess = (event) => {
      
                var storeCount: number = countRequest.result;
      
                var cursorRequest = filesStore.openCursor();
                cursorRequest.onerror = (errorEvent) => callback(null);
      
                // to cleanup any files which content is the same on the main drive
                var deleteList: string[] = [];
                var anyLeft = false;
      
                var processedCount = 0;
      
                cursorRequest.onsuccess = (event) => {
                  var cursor: IDBCursor = cursorRequest.result;
      
                  if (!cursor) {
      
                    // cleaning up files whose content is duplicating the main drive
                    if (anyLeft) {
                      for (var i = 0; i < deleteList.length; i++) {
                        filesStore['delete'](deleteList[i]);
                      }
                    }
                    else {
                      filesStore.clear();
                      metadataStore.clear();
                    }
      
                    callback(new IndexedDBShadow(this._db, this.timestamp));
                    return;
                  }
      
                  if (callback.progress)
                    callback.progress(processedCount, storeCount);
                  processedCount++;
      
                  var result: FileData = (<any>cursor).value;
                  if (result && result.path) {
      
                    var existingContent = mainDrive.read(result.path);
                    if (existingContent === result.content) {
                      deleteList.push(result.path);
                    }
                    else {
                      mainDrive.timestamp = this.timestamp;
                      mainDrive.write(result.path, result.content);
                      anyLeft = true;
                    }
                  }
      
                  cursor['continue']();
                }; // cursorRequest.onsuccess
      
              }; // countRequest.onsuccess
      
            }
      
            purge(callback: Drive.Detached.CallbackWithShadow): void {
              var transaction = this._db.transaction(['files', 'metadata'], 'readwrite');
      
              var filesStore = transaction.objectStore('files');
              filesStore.clear();
      
              var metadataStore = transaction.objectStore('metadata');
              metadataStore.clear();
      
              callback(new IndexedDBShadow(this._db, -1));
            }
      
          }
      
          class IndexedDBShadow implements Drive.Shadow { 
      
            constructor(private _db: IDBDatabase, public timestamp: number) { 
            }
      
            write(file: string, content: string) { 
              var transaction = this._db.transaction(['files', 'metadata'], 'readwrite');
              var filesStore = transaction.objectStore('files');
              var metadataStore = transaction.objectStore('metadata');
      
              // no file deletion here: we need to keep account of deletions too!
              var fileData: FileData = {
                path: file,
                content: content,
                state: null
              };
      
              var putFile = filesStore.put(fileData);
      
              var md: MetadataData = {
                property: 'editedUTC',
                value: Date.now()
              };
      
              metadataStore.put(md);
      
            }
          }
      
      
          interface FileData {
            path: string;
            content: string;
            state: string;
          }
      
          interface MetadataData {
            property: string;
            value: any;
          }
      
      
        }
      }
    • mountDrive.ts
      module teapo.persistence {
        
        export function mountDrive(
          dom: Drive,
          uniqueKey: string,
          domTimestamp: number,
          optionalModules: { [moduleName: string]: Drive.Optional; },
          callback: mountDrive.Callback): void {
      
          var driveIndex = 0;
      
          var optional: Drive.Optional[] = [];
          if (optionalModules) {
            for (var moduleName in optionalModules) if (optionalModules.hasOwnProperty(moduleName)) {
              var moduleObj = optionalModules[moduleName];
              if (moduleObj && moduleObj.detect && typeof moduleObj.detect === 'function')
                optional.push(moduleObj);
            }
          }
      
          loadNextOptional();
      
          function loadNextOptional() {
            if (driveIndex >= optional.length) {
              callback(new MountedDrive(dom, null));
              return;
            }
      
            var op = optional[driveIndex];
            op.detect(
              uniqueKey,
              detached => {
                if (!detached) {
                  driveIndex++;
                  loadNextOptional();
                  return;
                }
      
                if (detached.timestamp > domTimestamp) {
                  var callbackWithShadow: Drive.Detached.CallbackWithShadow = loadedDrive => {
                    dom.timestamp = detached.timestamp;
                    callback(new MountedDrive(dom, loadedDrive));
                  };
                  if (callback.progress)
                    callbackWithShadow.progress = callback.progress;
                  detached.applyTo(dom, callbackWithShadow);
                }
                else {
                  var callbackWithShadow: Drive.Detached.CallbackWithShadow = loadedDrive => {
                    callback(new MountedDrive(dom, loadedDrive));
                  };
                  if (callback.progress)
                    callbackWithShadow.progress = callback.progress;
                  detached.purge(callbackWithShadow);
                }
              });
          }
      
        }
        
        export module mountDrive {
          
          export interface Callback {
      
            (drive: Drive): void;
      
            progress?: (current: number, total: number) => void;
      
          }
          
        }
        
        class MountedDrive implements Drive {
      
          timestamp: number = 0;
      
          constructor (private _dom: Drive, private _shadow: Drive.Shadow) {
            this.timestamp = this._dom.timestamp;
          }
          
          files(): string[] {
            return this._dom.files();
          }
      
          read(file: string): string {
            return this._dom.read(file);
          }
      
          write(file: string, content: string) {
            this._dom.timestamp = this.timestamp;
            this._dom.write(file, content);
            if (this._shadow) {
              this._shadow.timestamp = this.timestamp;
              this._shadow.write(file, content);
            }
          }
        }
        
      }
  • typescript
    • ExternalDocument.ts
      module teapo.typescript {
        
        export interface ExternalDocument {
          
          text(): string;
          changes(): ts.TextChangeRange[];
          
        }
        
      }
    • ScriptDocumentSnapshot.ts
      module teapo.typescript {
        
        export class ScriptDocumentSnapshot implements ts.IScriptSnapshot {
      
          changes: ts.TextChangeRange[];
      
          private _text: string;
          private _lineStartPositions: number[] = null;
      
          constructor(doc: ExternalDocument) {
            this._text = doc.text();
            this.changes = doc.changes();
          }
      
          getText(start: number, end: number): string {
            return this._text.slice(start, end);
          }
      
          getLength(): number {
            return this._text.length;
          }
      
          getLineStartPositions(): number[] {
            if (!this._lineStartPositions)
              this._lineStartPositions = ts.computeLineStarts(this._text);
            return this._lineStartPositions;
          }
      
          getChangeRange(oldSnapshot: ts.IScriptSnapshot): ts.TextChangeRange {
      
            if (!this.changes.length)
              return ts.TextChangeRange.unchanged;
      
            var typedOldSnapshot = <ScriptDocumentSnapshot>oldSnapshot;
            var chunk = typedOldSnapshot.changes ?
              this.changes.slice(typedOldSnapshot.changes.length) :
              this.changes;
      
            var result = ts.TextChangeRange.collapseChangesAcrossMultipleVersions(chunk);
      
            return result;
      
          }
      
      
        }
        
      }
    • ScriptDocumentState.ts
      module teapo.typescript {
        
        export class ScriptDocumentState {
      
          private _snapshot: ScriptDocumentSnapshot = null;
      
          constructor(public doc: ExternalDocument) {
          }
      
          getScriptSnapshot() {
            //if (!this._snapshot || this._snapshot.changes.length != this.doc.changes().length)
              this._snapshot = new ScriptDocumentSnapshot(this.doc);
            return this._snapshot;
          }
      
          getScriptVersion() {
            var changes = this.doc.changes();
            return changes.length;
          }
      
        }
        
      }
    • TypeScriptService.ts
      module teapo.typescript {
      
        export class TypeScriptService {
      
          private _service: ts.LanguageService;
      
          compilerOptions: ts.CompilerOptions;
          cancellation: ts.CancellationToken = null;
          currentDirectory = '/';
          defaultLibFilename = '#lib.d.ts';
      
          log: (text: string) => void = null;
        
          host: ts.LanguageServiceHost;
      
          private _scriptFileNames: string[] = null;
          private _scripts: { [fullPath: string]: ScriptDocumentState; } = {};
          private _defaultLibSnapshot: ts.IScriptSnapshot = null;
      
          private _preloadScriptFileNames: string[] = [this.defaultLibFilename];
          private _preloadPendingScriptFileNames: string[] = [];
          private _preloadTimeout = 0;
      
          constructor() {
            this.compilerOptions = ts.getDefaultCompilerOptions();
            this.host = this._createHost();
            this._service = ts.createLanguageService(
              this.host,
              this._createRegistry());
          }
      
          service() {
            if (this._preloadScriptFileNames) {
              this._preloadScriptFileNames = null;
              this._preloadPendingScriptFileNames = null;
            }
            return this._service;
          }
      
          addFile(file: string, doc: ExternalDocument){
            var script = new ScriptDocumentState(doc);
            this._scripts[file] = script;
            this._scriptFileNames = null;
            if (this._preloadPendingScriptFileNames) {
              this._preloadPendingScriptFileNames.push(file);
              if (this._preloadTimeout)
                clearTimeout(this._preloadTimeout);
              this._preloadTimeout = setTimeout(() => {
                if (this._preloadPendingScriptFileNames)
                  this._preloadPendingScriptFileNames.sort();
                this._continuePreload();
              }, 100);
            }
          }
      
          removeFile(file: string) {
            delete this._scripts[file];
            this._scriptFileNames = null;
      
            if (this._preloadScriptFileNames) {
              for (var i = 0; i < this._preloadPendingScriptFileNames.length; i++) {
                if (this._preloadPendingScriptFileNames[i] === file) {
                  delete this._preloadPendingScriptFileNames[i];
                  break;
                }
              }
            }
            if (this._preloadScriptFileNames) {
              for (var i = 0; i < this._preloadScriptFileNames.length; i++) {
                if (this._preloadScriptFileNames[i] === file) {
                  delete this._preloadScriptFileNames[i];
                  break;
                }
              }
            }
          }
      
          private _continuePreload() {
      
            this._preloadTimeout = 0;
      
            if (!this._preloadScriptFileNames || !this._preloadPendingScriptFileNames)
              return;
      
            if (!this._preloadPendingScriptFileNames.length) {
              this._preloadScriptFileNames = null;
              this._preloadPendingScriptFileNames = null;
              return; // TODO: call some event to notify it's all clear now
            }
      
            var nextFile = this._preloadPendingScriptFileNames.shift();
            this._preloadScriptFileNames.push(nextFile);
      
            // just in case they've changed it at the load time
            this._preloadScriptFileNames[0] = this.defaultLibFilename;
      
            this._service.getSemanticDiagnostics(nextFile);
      
            this._preloadTimeout = setTimeout(() => {
              this._continuePreload();
            }, 10);
          }
      
          private _createRegistry() {
            return ts.createDocumentRegistry();
          }
        
          private _createHost(): /*ts.LanguageServiceHost*/ any {
            return {
              getCompilationSettings: () => this.compilerOptions,
              getScriptFileNames: () => {
                if (this._preloadScriptFileNames)
                  return this._preloadScriptFileNames;
      
                if (!this._scriptFileNames) {
                  this._scriptFileNames = objectKeys(this._scripts);
                  this._scriptFileNames.push(this.defaultLibFilename);
                  this._scriptFileNames.sort();
                }
                return this._scriptFileNames;
              },
              getScriptVersion: (file) => {
                if (file === this.defaultLibFilename)
                  return 0;
      
                var script = this._scripts[file];
                return script.getScriptVersion();
              },
              getScriptIsOpen: () => true,
              getScriptSnapshot: (file) => {
                if (file === this.defaultLibFilename) {
                  if (!this._defaultLibSnapshot) {
                    var scriptElement = <HTMLScriptElement>document.getElementById('lib.d.ts');
                    if (scriptElement == null)
                      return null;
                    this._defaultLibSnapshot = ts.ScriptSnapshot.fromString(scriptElement.text || scriptElement.textContent || scriptElement.innerText);
                  }
                  return this._defaultLibSnapshot;
                }
      
                return this._scripts[file].getScriptSnapshot();
              },
              getLocalizedDiagnosticMessages: () => null,
              getCancellationToken: () => this.cancellation,
              getCurrentDirectory: () => this.currentDirectory,
              getDefaultLibFilename: () => this.defaultLibFilename,
              log: (text) => {
                if (this.log) {
                  this.log(text);
                }
                else {
                  if (typeof console !== 'undefined')
                    console.log(text);
                }
              }
            };
            
          }
          
        }
      
      }
  • typings
    • codemirror.addons.d.ts
      interface CodeMirror {
      
        showHint(options: CodeMirror.showHint.Options);
      
      }
      
      declare module CodeMirror {
      
        module showHint {
          
          interface Options {
            
            /**
             * A hinting function. It is possible to set the async property on a hinting function to true,
             * in which case it will be called with arguments (cm, callback, ?options),
             * and the completion interface will only be popped up when the hinting function calls the callback,
             * passing it the object holding the completions.
             */
            hint: Function;
      
            /**
             * Determines whether, when only a single completion is available, it is completed without showing the dialog.
             * Defaults to true.
             */
            completeSingle?: boolean;
      
            /**
             * Whether the pop - up should be horizontally aligned with the start of the word (true, default),
             * or with the cursor (false).
             */
            alignWithWord?: boolean;
      
            /**
             * When enabled (which is the default), the pop - up will close when the editor is unfocused.
             */
            closeOnUnfocus?: boolean;
      
            /**
             * Allows you to provide a custom key map of keys to be active when the pop - up is active.
             * The handlers will be called with an extra argument, a handle to the completion menu,
             * which has moveFocus(n), setFocus(n), pick(), and close() methods (see the source for details),
             * that can be used to change the focused element, pick the current element or close the menu.
             * Additionnaly menuSize() can give you access to the size of the current dropdown menu,
             * length give you the number of availlable completions,
             * and data give you full access to the completion returned by the hinting function.
             */
            customKeys?: any;
      
            /**
             * Like customKeys above, but the bindings will be added to the set of default bindings,
             * instead of replacing them.
             */
            extraKeys?: any;
      
          }
            
          interface CompletionResult {
            list: Completion[];
            from: CodeMirror.Pos;
            to: CodeMirror.Pos;
          }
      
          interface Completion {
            
            /** The completion text. This is the only required property. */
            text: string;
      
            /** The text that should be displayed in the menu. */
            displayText?: string;
      
            /** A CSS class name to apply to the completion's line in the menu. */
            className?: string;
      
            /** A method used to create the DOM structure for showing the completion
             * by appending it to its first argument. */
            render?: (element: HTMLElement, self, data) => void;
      
            /** A method used to actually apply the completion, instead of the default behavior. */
            hint?: (cm: CodeMirror, self, data) => void;
      
            /** Optional from position that will be used by pick()
             * instead of the global one passed with the full list of completions. */
            from?: CodeMirror.Pos;
      
            /** Optional to position that will be used by pick() instead of the global one
             * passed with the full list of completions. */
            to?: CodeMirror.Pos;
      
          }
          
        }
      
        interface CodeMirrorStatic {
          
          /** Fired when the pop-up is shown. */
          on(completion: showHint.Options, eventName: 'shown', handler: (instance: showHint.CompletionResult) => void);
          off(completion: showHint.Options, eventName: 'shown', handler: (instance: showHint.CompletionResult) => void);
      
          /**
           * Fired when a completion is selected.
           * Passed the completion value (string or object) and the DOM node that represents it in the menu.
           */
          on(completion: showHint.Options, eventName: 'select', handler: (instance: showHint.CompletionResult, completion: showHint.Completion, element: HTMLElement) => void);
          off(completion: showHint.Options, eventName: 'select', handler: (instance: showHint.CompletionResult, completion: showHint.Completion, element: HTMLElement) => void);
      
          /**
           * Fired when a completion is picked. Passed the completion value (string or object).
           */
          on(completion: showHint.Options, eventName: 'pick', handler: (instance: showHint.CompletionResult, completion: showHint.Completion) => void);
          off(completion: showHint.Options, eventName: 'pick', handler: (instance: showHint.CompletionResult, completion: showHint.Completion) => void);
      
          /** Fired when the completion is finished. */
          on(completion: showHint.Options, eventName: 'close', handler: (instance: showHint.CompletionResult) => void);
          off(completion: showHint.Options, eventName: 'close', handler: (instance: showHint.CompletionResult) => void);
      
        }
      
      }
    • codemirror.d.ts
      declare var CodeMirror : CodeMirror.CodeMirrorStatic;
      
      interface CodeMirror {
      
        /** Tells you whether the editor currently has focus. */
        hasFocus(): boolean;
      
        /** Used to find the target position for horizontal cursor motion.start is a { line , ch } object,
        amount an integer(may be negative), and unit one of the string "char", "column", or "word".
        Will return a position that is produced by moving amount times the distance specified by unit.
        When visually is true , motion in right - to - left text will be visual rather than logical.
        When the motion was clipped by hitting the end or start of the document, the returned value will have a hitSide property set to true. */
        findPosH(start: CodeMirror.Pos, amount: number, unit: string, visually: boolean): { line: number; ch: number; hitSide?: boolean; };
      
        /** Similar to findPosH , but used for vertical motion.unit may be "line" or "page".
        The other arguments and the returned value have the same interpretation as they have in findPosH. */
        findPosV(start: CodeMirror.Pos, amount: number, unit: string): { line: number; ch: number; hitSide?: boolean; };
      
      
        /** Change the configuration of the editor. option should the name of an option, and value should be a valid value for that option. */
        setOption(option: string, value: any);
      
        /** Retrieves the current value of the given option for this editor instance. */
        getOption(option: string): any;
      
        /** Attach an additional keymap to the editor.
        This is mostly useful for add - ons that need to register some key handlers without trampling on the extraKeys option.
        Maps added in this way have a higher precedence than the extraKeys and keyMap options, and between them,
        the maps added earlier have a lower precedence than those added later, unless the bottom argument was passed,
        in which case they end up below other keymaps added with this method. */
        addKeyMap(map: any, bottom?: boolean);
      
        /** Disable a keymap added with addKeyMap.Either pass in the keymap object itself , or a string,
        which will be compared against the name property of the active keymaps. */
        removeKeyMap(map: any);
      
        /** Enable a highlighting overlay.This is a stateless mini - mode that can be used to add extra highlighting.
        For example, the search add - on uses it to highlight the term that's currently being searched.
        mode can be a mode spec or a mode object (an object with a token method). The options parameter is optional. If given, it should be an object.
        Currently, only the opaque option is recognized. This defaults to off, but can be given to allow the overlay styling, when not null,
        to override the styling of the base mode entirely, instead of the two being applied together. */
        addOverlay(mode: any, options?: any);
      
        /** Pass this the exact argument passed for the mode parameter to addOverlay to remove an overlay again. */
        removeOverlay(mode: any);
      
      
        /** Retrieve the currently active document from an editor. */
        getDoc(): CodeMirror.Doc;
      
        /** Attach a new document to the editor. Returns the old document, which is now no longer associated with an editor. */
        swapDoc(doc: CodeMirror.Doc): CodeMirror.Doc;
      
      
      
        /** Sets the gutter marker for the given gutter (identified by its CSS class, see the gutters option) to the given value.
        Value can be either null, to clear the marker, or a DOM element, to set it. The DOM element will be shown in the specified gutter next to the specified line. */
        setGutterMarker(line: any, gutterID: string, value: HTMLElement): CodeMirror.LineHandle;
      
        /** Remove all gutter markers in the gutter with the given ID. */
        clearGutter(gutterID: string);
      
        /** Set a CSS class name for the given line.line can be a number or a line handle.
        where determines to which element this class should be applied, can can be one of "text" (the text element, which lies in front of the selection),
        "background"(a background element that will be behind the selection),
        or "wrap" (the wrapper node that wraps all of the line's elements, including gutter elements).
        class should be the name of the class to apply. */
        addLineClass(line: any, where: string, _class_: string): CodeMirror.LineHandle;
      
        /** Remove a CSS class from a line.line can be a line handle or number.
        where should be one of "text", "background", or "wrap"(see addLineClass).
        class can be left off to remove all classes for the specified node, or be a string to remove only a specific class. */
        removeLineClass(line: any, where: string, class_: string): CodeMirror.LineHandle;
      
        /** Returns the line number, text content, and marker status of the given line, which can be either a number or a line handle. */
        lineInfo(line: any): {
            line: any;
            handle: any;
            text: string;
            /** Object mapping gutter IDs to marker elements. */
            gutterMarks: any;
            textClass: string;
            bgClass: string;
            wrapClass: string;
            /** Array of line widgets attached to this line. */
            widgets: any;
        };
      
        /** Puts node, which should be an absolutely positioned DOM node, into the editor, positioned right below the given { line , ch } position.
        When scrollIntoView is true, the editor will ensure that the entire node is visible (if possible).
        To remove the widget again, simply use DOM methods (move it somewhere else, or call removeChild on its parent). */
        addWidget(pos: CodeMirror.Pos, node: HTMLElement, scrollIntoView: boolean);
      
        /** Adds a line widget, an element shown below a line, spanning the whole of the editor's width, and moving the lines below it downwards.
        line should be either an integer or a line handle, and node should be a DOM node, which will be displayed below the given line.
        options, when given, should be an object that configures the behavior of the widget.
        Note that the widget node will become a descendant of nodes with CodeMirror-specific CSS classes, and those classes might in some cases affect it. */
        addLineWidget(line: any, node: HTMLElement, options?: {
            /** Whether the widget should cover the gutter. */
            coverGutter: boolean;
            /** Whether the widget should stay fixed in the face of horizontal scrolling. */
            noHScroll: boolean;
            /** Causes the widget to be placed above instead of below the text of the line. */
            above: boolean;
            /** When true, will cause the widget to be rendered even if the line it is associated with is hidden. */
            showIfHidden: boolean;
        }): CodeMirror.LineWidget;
      
      
        /** Programatically set the size of the editor (overriding the applicable CSS rules).
        width and height height can be either numbers(interpreted as pixels) or CSS units ("100%", for example).
        You can pass null for either of them to indicate that that dimension should not be changed. */
        setSize(width: any, height: any);
      
        /** Scroll the editor to a given(pixel) position.Both arguments may be left as null or undefined to have no effect. */
        scrollTo(x: number, y: number);
      
        /** Get an { left , top , width , height , clientWidth , clientHeight } object that represents the current scroll position, the size of the scrollable area,
        and the size of the visible area(minus scrollbars). */
        getScrollInfo(): CodeMirror.ScrollInfo;
      
        /** Scrolls the given element into view. pos is a { line , ch } position, referring to a given character, null, to refer to the cursor.
        The margin parameter is optional. When given, it indicates the amount of pixels around the given area that should be made visible as well. */
        scrollIntoView(pos: CodeMirror.Pos, margin?: number);
      
        /** Scrolls the given element into view. pos is a { left , top , right , bottom } object, in editor-local coordinates.
        The margin parameter is optional. When given, it indicates the amount of pixels around the given area that should be made visible as well. */
        scrollIntoView(pos: { left: number; top: number; right: number; bottom: number; }, margin: number);
      
        /** Returns an { left , top , bottom } object containing the coordinates of the cursor position.
        If mode is "local" , they will be relative to the top-left corner of the editable document.
        If it is "page" or not given, they are relative to the top-left corner of the page.
        where is a boolean indicating whether you want the start(true) or the end(false) of the selection. */
        cursorCoords(where: boolean, mode: string): { left: number; top: number; bottom: number; };
      
        /** Returns an { left , top , bottom } object containing the coordinates of the cursor position.
        If mode is "local" , they will be relative to the top-left corner of the editable document.
        If it is "page" or not given, they are relative to the top-left corner of the page.
        where specifies the precise position at which you want to measure. */
        cursorCoords(where: CodeMirror.Pos, mode: string): { left: number; top: number; bottom: number; };
      
        /** Returns the position and dimensions of an arbitrary character.pos should be a { line , ch } object.
        This differs from cursorCoords in that it'll give the size of the whole character,
        rather than just the position that the cursor would have when it would sit at that position. */
        charCoords(pos: CodeMirror.Pos, mode: string): { left: number; right: number; top: number; bottom: number; };
      
        /** Given an { left , top } object , returns the { line , ch } position that corresponds to it.
        The optional mode parameter determines relative to what the coordinates are interpreted. It may be "window" , "page"(the default) , or "local". */
        coordsChar(object: { left: number; top: number; }, mode?: string): CodeMirror.Pos;
      
        lineAtHeight(height: number, mode?: string): number;
        heightAtLine(line: number, mode?: string): number;
      
        /** Returns the line height of the default font for the editor. */
        defaultTextHeight(): number;
      
        /** Returns the pixel width of an 'x' in the default font for the editor.
        (Note that for non - monospace fonts , this is mostly useless, and even for monospace fonts, non - ascii characters might have a different width). */
        defaultCharWidth(): number;
      
        /** Returns a { from , to } object indicating the start (inclusive) and end (exclusive) of the currently rendered part of the document.
        In big documents, when most content is scrolled out of view, CodeMirror will only render the visible part, and a margin around it.
        See also the viewportChange event. */
        getViewport(): { from: number; to: number };
      
        /** If your code does something to change the size of the editor element (window resizes are already listened for), or unhides it,
        you should probably follow up by calling this method to ensure CodeMirror is still looking as intended. */
        refresh();
      
      
        /** Retrieves information about the token the current mode found before the given position (a {line, ch} object). */
        getTokenAt(pos: CodeMirror.Pos): {
            /** The character(on the given line) at which the token starts. */
            start: number;
            /** The character at which the token ends. */
            end: number;
            /** The token's string. */
            string: string;
            /** The token type the mode assigned to the token, such as "keyword" or "comment" (may also be null). */
            type: string;
            /** The mode's state at the end of this token. */
            state: any;            
        };
      
        /** Returns the mode's parser state, if any, at the end of the given line number.
        If no line number is given, the state at the end of the document is returned.
        This can be useful for storing parsing errors in the state, or getting other kinds of contextual information for a line. */
        getStateAfter(line?: number): any;
      
        /** CodeMirror internally buffers changes and only updates its DOM structure after it has finished performing some operation.
        If you need to perform a lot of operations on a CodeMirror instance, you can call this method with a function argument.
        It will call the function, buffering up all changes, and only doing the expensive update after the function returns.
        This can be a lot faster. The return value from this method will be the return value of your function. */
        operation<T>(fn: ()=> T): T;
      
        /** Adjust the indentation of the given line.
        The second argument (which defaults to "smart") may be one of:
        "prev" Base indentation on the indentation of the previous line.
        "smart" Use the mode's smart indentation if available, behave like "prev" otherwise.
        "add" Increase the indentation of the line by one indent unit.
        "subtract" Reduce the indentation of the line. */
        indentLine(line: number, dir?: string);
      
      
        /** Give the editor focus. */
        focus();
      
        /** Returns the hidden textarea used to read input. */
        getInputField(): HTMLTextAreaElement;
      
        /** Returns the DOM node that represents the editor, and controls its size. Remove this from your tree to delete an editor instance. */
        getWrapperElement(): HTMLElement;
      
        /** Returns the DOM node that is responsible for the scrolling of the editor. */
        getScrollerElement(): HTMLElement;
      
        /** Fetches the DOM node that contains the editor gutters. */
        getGutterElement(): HTMLElement;
      
      
      
        /** Events are registered with the on method (and removed with the off method).
        These are the events that fire on the instance object. The name of the event is followed by the arguments that will be passed to the handler.
        The instance argument always refers to the editor instance. */
        on(eventName: string, handler: (instance: CodeMirror) => void );
        off(eventName: string, handler: (instance: CodeMirror) => void );
      
        /** Fires every time the content of the editor is changed. */
        on(eventName: 'change', handler: (instance: CodeMirror, change: CodeMirror.EditorChange) => void );
        off(eventName: 'change', handler: (instance: CodeMirror, change: CodeMirror.EditorChange) => void );
      
        /** Fires every time the content of the editor is changed. */
        on(eventName: 'changes', handler: (instance: CodeMirror, change: CodeMirror.EditorChange[]) => void );
        off(eventName: 'changes', handler: (instance: CodeMirror, change: CodeMirror.EditorChange[]) => void );
      
        /** This event is fired before a change is applied, and its handler may choose to modify or cancel the change.
        The changeObj never has a next property, since this is fired for each individual change, and not batched per operation.
        Note: you may not do anything from a "beforeChange" handler that would cause changes to the document or its visualization.
        Doing so will, since this handler is called directly from the bowels of the CodeMirror implementation,
        probably cause the editor to become corrupted. */
        on(eventName: 'beforeChange', handler: (instance: CodeMirror, change: CodeMirror.EditorChangeCancellable) => void );
        off(eventName: 'beforeChange', handler: (instance: CodeMirror, change: CodeMirror.EditorChangeCancellable) => void );
      
        /** Will be fired when the cursor or selection moves, or any change is made to the editor content. */
        on(eventName: 'cursorActivity', handler: (instance: CodeMirror) => void );
        off(eventName: 'cursorActivity', handler: (instance: CodeMirror) => void );
      
        /** This event is fired before the selection is moved. Its handler may modify the resulting selection head and anchor.
        Handlers for this event have the same restriction as "beforeChange" handlers: they should not do anything to directly update the state of the editor. */
        on(eventName: 'beforeSelectionChange', handler: (instance: CodeMirror, selection: { head: CodeMirror.Pos; anchor: CodeMirror.Pos; }) => void );
        off(eventName: 'beforeSelectionChange', handler: (instance: CodeMirror, selection: { head: CodeMirror.Pos; anchor: CodeMirror.Pos; }) => void );
      
        /** Fires whenever the view port of the editor changes (due to scrolling, editing, or any other factor).
        The from and to arguments give the new start and end of the viewport. */
        on(eventName: 'viewportChange', handler: (instance: CodeMirror, from: number, to: number) => void );
        off(eventName: 'viewportChange', handler: (instance: CodeMirror, from: number, to: number) => void );
      
        /** Fires when the editor gutter (the line-number area) is clicked. Will pass the editor instance as first argument,
        the (zero-based) number of the line that was clicked as second argument, the CSS class of the gutter that was clicked as third argument,
        and the raw mousedown event object as fourth argument. */
        on(eventName: 'gutterClick', handler: (instance: CodeMirror, line: number, gutter: string, clickEvent: Event) => void );
        off(eventName: 'gutterClick', handler: (instance: CodeMirror, line: number, gutter: string, clickEvent: Event) => void );
      
        /** Fires whenever the editor is focused. */
        on(eventName: 'focus', handler: (instance: CodeMirror) => void );
        off(eventName: 'focus', handler: (instance: CodeMirror) => void );
      
        /** Fires whenever the editor is unfocused. */
        on(eventName: 'blur', handler: (instance: CodeMirror) => void );
        off(eventName: 'blur', handler: (instance: CodeMirror) => void );
      
        /** Fires when the editor is scrolled. */
        on(eventName: 'scroll', handler: (instance: CodeMirror) => void );
        off(eventName: 'scroll', handler: (instance: CodeMirror) => void );
      
        /** Will be fired whenever CodeMirror updates its DOM display. */
        on(eventName: 'update', handler: (instance: CodeMirror) => void );
        off(eventName: 'update', handler: (instance: CodeMirror) => void );
      
        /** Fired whenever a line is (re-)rendered to the DOM. Fired right after the DOM element is built, before it is added to the document.
        The handler may mess with the style of the resulting element, or add event handlers, but should not try to change the state of the editor. */
        on(eventName: 'renderLine', handler: (instance: CodeMirror, line: number, element: HTMLElement) => void );
        off(eventName: 'renderLine', handler: (instance: CodeMirror, line: number, element: HTMLElement) => void );
      }
      
      declare module CodeMirror {
        
        export interface ScrollInfo {
          left: any;
          top: any;
          width: any;
          height: any;
          clientWidth: any;
          clientHeight: any;
        }
        
        export interface CodeMirrorStatic {
          
          Pass: any;
      
          new (host: HTMLElement, options?: CodeMirror.Options): CodeMirror;
          new (callback: (host: HTMLElement) => void , options?: CodeMirror.Options): CodeMirror;
      
          (host: HTMLElement, options?: CodeMirror.Options): CodeMirror;
          (callback: (host: HTMLElement) => void , options?: CodeMirror.Options): CodeMirror;
      
          Doc: {
            (text: string, mode?: any, firstLineNumber?: number): Doc;
            new (text: string, mode?: any, firstLineNumber?: number): Doc;
          };
      
          Pos: {
            (line: number, ch?: number): Pos;
            new (line: number, ch?: number): Pos;
          };
      
          fromTextArea(host: HTMLTextAreaElement, options?: Options): CodeMirror;
      
          version: string;
      
          /** If you want to define extra methods in terms of the CodeMirror API, it is possible to use defineExtension.
          This will cause the given value(usually a method) to be added to all CodeMirror instances created from then on. */
          defineExtension(name: string, value: any);
      
          /** Like defineExtension, but the method will be added to the interface for Doc objects instead. */
          defineDocExtension(name: string, value: any);
      
          /** Similarly, defineOption can be used to define new options for CodeMirror.
          The updateFunc will be called with the editor instance and the new value when an editor is initialized,
          and whenever the option is modified through setOption. */
          defineOption(name: string, default_: any, updateFunc: Function);
      
          /** If your extention just needs to run some code whenever a CodeMirror instance is initialized, use CodeMirror.defineInitHook.
          Give it a function as its only argument, and from then on, that function will be called (with the instance as argument)
          whenever a new CodeMirror instance is initialized. */
          defineInitHook(func: Function);
      
      
      
          on(element: any, eventName: string, handler: Function);
          off(element: any, eventName: string, handler: Function);
      
          /** Fired whenever a change occurs to the document. changeObj has a similar type as the object passed to the editor's "change" event,
          but it never has a next property, because document change events are not batched (whereas editor change events are). */
          on(doc: Doc, eventName: 'change', handler: (instance: Doc, change: EditorChange) => void);
          off(doc: Doc, eventName: 'change', handler: (instance: Doc, change: EditorChange) => void);
      
          /** See the description of the same event on editor instances. */
          on(doc: Doc, eventName: 'beforeChange', handler: (instance: Doc, change: EditorChangeCancellable) => void);
          off(doc: Doc, eventName: 'beforeChange', handler: (instance: Doc, change: EditorChangeCancellable) => void);
      
          /** Fired whenever the cursor or selection in this document changes. */
          on(doc: Doc, eventName: 'cursorActivity', handler: (instance: CodeMirror) => void);
          off(doc: Doc, eventName: 'cursorActivity', handler: (instance: CodeMirror) => void);
      
          /** Equivalent to the event by the same name as fired on editor instances. */
          on(doc: Doc, eventName: 'beforeSelectionChange', handler: (instance: CodeMirror, selection: { head: Pos; anchor: Pos; }) => void);
          off(doc: Doc, eventName: 'beforeSelectionChange', handler: (instance: CodeMirror, selection: { head: Pos; anchor: Pos; }) => void);
      
          /** Will be fired when the line object is deleted. A line object is associated with the start of the line.
          Mostly useful when you need to find out when your gutter markers on a given line are removed. */
          on(line: LineHandle, eventName: 'delete', handler: () => void);
          off(line: LineHandle, eventName: 'delete', handler: () => void);
      
          /** Fires when the line's text content is changed in any way (but the line is not deleted outright).
          The change object is similar to the one passed to change event on the editor object. */
          on(line: LineHandle, eventName: 'change', handler: (line: LineHandle, change: EditorChange) => void);
          off(line: LineHandle, eventName: 'change', handler: (line: LineHandle, change: EditorChange) => void);
      
          /** Fired when the cursor enters the marked range. From this event handler, the editor state may be inspected but not modified,
          with the exception that the range on which the event fires may be cleared. */
          on(marker: TextMarker, eventName: 'beforeCursorEnter', handler: () => void);
          off(marker: TextMarker, eventName: 'beforeCursorEnter', handler: () => void);
      
          /** Fired when the range is cleared, either through cursor movement in combination with clearOnEnter or through a call to its clear() method.
          Will only be fired once per handle. Note that deleting the range through text editing does not fire this event,
          because an undo action might bring the range back into existence. */
          on(marker: TextMarker, eventName: 'clear', handler: () => void);
          off(marker: TextMarker, eventName: 'clear', handler: () => void);
      
          /** Fired when the last part of the marker is removed from the document by editing operations. */
          on(marker: TextMarker, eventName: 'hide', handler: () => void);
          off(marker: TextMarker, eventName: 'hide', handler: () => void);
      
          /** Fired when, after the marker was removed by editing, a undo operation brought the marker back. */
          on(marker: TextMarker, eventName: 'unhide', handler: () => void);
          off(marker: TextMarker, eventName: 'unhide', handler: () => void);
      
          /** Fired whenever the editor re-adds the widget to the DOM. This will happen once right after the widget is added (if it is scrolled into view),
          and then again whenever it is scrolled out of view and back in again, or when changes to the editor options
          or the line the widget is on require the widget to be redrawn. */
          on(line: LineWidget, eventName: 'redraw', handler: () => void);
          off(line: LineWidget, eventName: 'redraw', handler: () => void);
        }
        
        export interface Doc {
      
          /** Get the current editor content. You can pass it an optional argument to specify the string to be used to separate lines (defaults to "\n"). */
          getValue(seperator?: string): string;
      
          /** Set the editor content. */
          setValue(content: string);
      
          /** Get the text between the given points in the editor, which should be {line, ch} objects.
          An optional third argument can be given to indicate the line separator string to use (defaults to "\n"). */
          getRange(from: Pos, to: CodeMirror.Pos, seperator?: string): string;
      
          /** Replace the part of the document between from and to with the given string.
          from and to must be {line, ch} objects. to can be left off to simply insert the string at position from. */
          replaceRange(replacement: string, from: CodeMirror.Pos, to: CodeMirror.Pos);
      
          /** Get the content of line n. */
          getLine(n: number): string;
      
          /** Set the content of line n. */
          setLine(n: number, text: string);
      
          /** Remove the given line from the document. */
          removeLine(n: number);
      
          /** Get the number of lines in the editor. */
          lineCount(): number;
      
          /** Get the first line of the editor. This will usually be zero but for linked sub-views,
          or documents instantiated with a non-zero first line, it might return other values. */
          firstLine(): number;
      
          /** Get the last line of the editor. This will usually be lineCount() - 1, but for linked sub-views, it might return other values. */
          lastLine(): number;
      
          /** Fetches the line handle for the given line number. */
          getLineHandle(num: number): CodeMirror.LineHandle;
      
          /** Given a line handle, returns the current position of that line (or null when it is no longer in the document). */
          getLineNumber(handle: CodeMirror.LineHandle): number;
      
          /** Iterate over the whole document, and call f for each line, passing the line handle.
          This is a faster way to visit a range of line handlers than calling getLineHandle for each of them.
          Note that line handles have a text property containing the line's content (as a string). */
          eachLine(f: (line: CodeMirror.LineHandle) => void);
      
          /** Iterate over the range from start up to (not including) end, and call f for each line, passing the line handle.
          This is a faster way to visit a range of line handlers than calling getLineHandle for each of them.
          Note that line handles have a text property containing the line's content (as a string). */
          eachLine(start: number, end: number, f: (line: CodeMirror.LineHandle) => void);
      
          /** Set the editor content as 'clean', a flag that it will retain until it is edited, and which will be set again when such an edit is undone again.
          Useful to track whether the content needs to be saved. */
          markClean();
      
          /** Returns whether the document is currently clean (not modified since initialization or the last call to markClean). */
          isClean(): boolean;
      
      
      
          /** Get the currently selected code. */
          getSelection(): string;
      
          /** Replace the selection with the given string. By default, the new selection will span the inserted text.
          The optional collapse argument can be used to change this passing "start" or "end" will collapse the selection to the start or end of the inserted text. */
          replaceSelection(replacement: string, collapse?: string)
      
          /** start is a an optional string indicating which end of the selection to return.
          It may be "start" , "end" , "head"(the side of the selection that moves when you press shift + arrow),
          or "anchor"(the fixed side of the selection).Omitting the argument is the same as passing "head".A { line , ch } object will be returned. */
          getCursor(start?: string): CodeMirror.Pos;
      
          /** Return true if any text is selected. */
          somethingSelected(): boolean;
      
          /** Set the cursor position.You can either pass a single { line , ch } object , or the line and the character as two separate parameters. */
          setCursor(pos: CodeMirror.Pos);
      
          /** Set the selection range.anchor and head should be { line , ch } objects.head defaults to anchor when not given. */
          setSelection(anchor: CodeMirror.Pos, head: CodeMirror.Pos);
      
          /** Similar to setSelection , but will, if shift is held or the extending flag is set,
          move the head of the selection while leaving the anchor at its current place.
          pos2 is optional , and can be passed to ensure a region (for example a word or paragraph) will end up selected
          (in addition to whatever lies between that region and the current anchor). */
          extendSelection(from: CodeMirror.Pos, to?: CodeMirror.Pos);
      
          /** Sets or clears the 'extending' flag , which acts similar to the shift key,
          in that it will cause cursor movement and calls to extendSelection to leave the selection anchor in place. */
          setExtending(value: boolean);
      
      
          /** Retrieve the editor associated with a document. May return null. */
          getEditor(): CodeMirror;
      
      
          /** Create an identical copy of the given doc. When copyHistory is true , the history will also be copied.Can not be called directly on an editor. */
          copy(copyHistory: boolean): CodeMirror.Doc;
      
          /** Create a new document that's linked to the target document. Linked documents will stay in sync (changes to one are also applied to the other) until unlinked. */
          linkedDoc(options: {
            /** When turned on, the linked copy will share an undo history with the original.
            Thus, something done in one of the two can be undone in the other, and vice versa. */
            sharedHist?: boolean;
            from?: number;
            /** Can be given to make the new document a subview of the original. Subviews only show a given range of lines.
            Note that line coordinates inside the subview will be consistent with those of the parent,
            so that for example a subview starting at line 10 will refer to its first line as line 10, not 0. */
            to?: number;
            /** By default, the new document inherits the mode of the parent. This option can be set to a mode spec to give it a different mode. */
            mode: any;
          }): CodeMirror.Doc;
      
          /** Break the link between two documents. After calling this , changes will no longer propagate between the documents,
          and, if they had a shared history, the history will become separate. */
          unlinkDoc(doc: CodeMirror.Doc);
      
          /** Will call the given function for all documents linked to the target document. It will be passed two arguments,
          the linked document and a boolean indicating whether that document shares history with the target. */
          iterLinkedDocs(fn: (doc: CodeMirror.Doc, sharedHist: boolean) => void);
      
          /** Undo one edit (if any undo events are stored). */
          undo();
      
          /** Redo one undone edit. */
          redo();
      
          /** Returns an object with {undo, redo } properties , both of which hold integers , indicating the amount of stored undo and redo operations. */
          historySize(): { undo: number; redo: number; };
      
          /** Clears the editor's undo history. */
          clearHistory();
      
          /** Get a(JSON - serializeable) representation of the undo history. */
          getHistory(): any;
      
          /** Replace the editor's undo history with the one provided, which must be a value as returned by getHistory.
          Note that this will have entirely undefined results if the editor content isn't also the same as it was when getHistory was called. */
          setHistory(history: any);
      
      
          /** Can be used to mark a range of text with a specific CSS class name. from and to should be { line , ch } objects. */
          markText(from: CodeMirror.Pos, to: CodeMirror.Pos, options?: CodeMirror.TextMarkerOptions): TextMarker;
      
          /** Inserts a bookmark, a handle that follows the text around it as it is being edited, at the given position.
          A bookmark has two methods find() and clear(). The first returns the current position of the bookmark, if it is still in the document,
          and the second explicitly removes the bookmark. */
          setBookmark(pos: CodeMirror.Pos, options?: {
            /** Can be used to display a DOM node at the current location of the bookmark (analogous to the replacedWith option to markText). */
            widget?: HTMLElement;
      
            /** By default, text typed when the cursor is on top of the bookmark will end up to the right of the bookmark.
            Set this option to true to make it go to the left instead. */
            insertLeft?: boolean;
          }): CodeMirror.TextMarker;
      
          /** Returns an array of all the bookmarks and marked ranges present at the given position. */
          findMarksAt(pos: CodeMirror.Pos): TextMarker[];
      
          /** Returns an array containing all marked ranges in the document. */
          getAllMarks(): CodeMirror.TextMarker[];
      
      
          /** Gets the mode object for the editor. Note that this is distinct from getOption("mode"), which gives you the mode specification,
          rather than the resolved, instantiated mode object. */
          getMode(): any;
      
          /** Calculates and returns a { line , ch } object for a zero-based index whose value is relative to the start of the editor's text.
          If the index is out of range of the text then the returned object is clipped to start or end of the text respectively. */
          posFromIndex(index: number): CodeMirror.Pos;
      
          /** The reverse of posFromIndex. */
          indexFromPos(object: CodeMirror.Pos): number;
      
        }
      
        export interface LineHandle {
          text: string;
        }
      
        export interface TextMarker {
          /** Remove the mark. */
          clear();
      
          /** Returns a {from, to} object (both holding document positions), indicating the current position of the marked range,
          or undefined if the marker is no longer in the document. */
          find(): { from: CodeMirror.Pos; to: CodeMirror.Pos; };
      
          /**  Returns an object representing the options for the marker. If copyWidget is given true, it will clone the value of the replacedWith option, if any. */
          getOptions(copyWidget: boolean): CodeMirror.TextMarkerOptions;
        }
      
        export interface LineWidget {
          /** Removes the widget. */
          clear(): void;
      
          /** Call this if you made some change to the widget's DOM node that might affect its height.
          It'll force CodeMirror to update the height of the line that contains the widget. */
          changed();
        }
      
        export interface EditorChange {
          /** Position (in the pre-change coordinate system) where the change started. */
          from: CodeMirror.Pos;
          /** Position (in the pre-change coordinate system) where the change ended. */
          to: CodeMirror.Pos;
          /** Array of strings representing the text that replaced the changed range (split by line). */
          text: string[];
          /**  Text that used to be between from and to, which is overwritten by this change. */
          removed: string[];
        }
      
        export interface EditorChangeCancellable extends CodeMirror.EditorChange {
          /** may be used to modify the change. All three arguments to update are optional, and can be left off to leave the existing value for that field intact. */
          update(from?: CodeMirror.Pos, to?: CodeMirror.Pos, text?: string);
      
          cancel();
        }
      
        export interface Pos {
          ch: number;
          line: number;
        }
      
        export interface Options {
          /** string| The starting value of the editor. Can be a string, or a document object. */
          value?: any;
      
          /** string|object. The mode to use. When not given, this will default to the first mode that was loaded.
          It may be a string, which either simply names the mode or is a MIME type associated with the mode.
          Alternatively, it may be an object containing configuration options for the mode,
          with a name property that names the mode (for example {name: "javascript", json: true}). */
          mode?: any;
      
          /** The theme to style the editor with. You must make sure the CSS file defining the corresponding .cm-s-[name] styles is loaded.
          The default is "default". */
          theme?: string;
      
          /** How many spaces a block (whatever that means in the edited language) should be indented. The default is 2. */
          indentUnit?: number;
      
          /** Whether to use the context-sensitive indentation that the mode provides (or just indent the same as the line before). Defaults to true. */
          smartIndent?: boolean;
      
          /** The width of a tab character. Defaults to 4. */
          tabSize?: number;
      
          /** Whether, when indenting, the first N*tabSize spaces should be replaced by N tabs. Default is false. */
          indentWithTabs?: boolean;
      
          /** Configures whether the editor should re-indent the current line when a character is typed
          that might change its proper indentation (only works if the mode supports indentation). Default is true. */
          electricChars?: boolean;
      
          /** Determines whether horizontal cursor movement through right-to-left (Arabic, Hebrew) text
          is visual (pressing the left arrow moves the cursor left)
          or logical (pressing the left arrow moves to the next lower index in the string, which is visually right in right-to-left text).
          The default is false on Windows, and true on other platforms. */
          rtlMoveVisually?: boolean;
      
          /** Configures the keymap to use. The default is "default", which is the only keymap defined in codemirror.js itself.
          Extra keymaps are found in the keymap directory. See the section on keymaps for more information. */
          keyMap?: string;
      
          /** Can be used to specify extra keybindings for the editor, alongside the ones defined by keyMap. Should be either null, or a valid keymap value. */
          extraKeys?: any;
      
          /** Whether CodeMirror should scroll or wrap for long lines. Defaults to false (scroll). */
          lineWrapping?: boolean;
      
          /** Whether to show line numbers to the left of the editor. */
          lineNumbers?: boolean;
      
          /** At which number to start counting lines. Default is 1. */
          firstLineNumber?: number;
      
          /** A function used to format line numbers. The function is passed the line number, and should return a string that will be shown in the gutter. */
          lineNumberFormatter?: (line: number) => string;
      
          /** Can be used to add extra gutters (beyond or instead of the line number gutter).
          Should be an array of CSS class names, each of which defines a width (and optionally a background),
          and which will be used to draw the background of the gutters.
          May include the CodeMirror-linenumbers class, in order to explicitly set the position of the line number gutter
          (it will default to be to the right of all other gutters). These class names are the keys passed to setGutterMarker. */
          gutters?: string[];
      
          /** Determines whether the gutter scrolls along with the content horizontally (false)
          or whether it stays fixed during horizontal scrolling (true, the default). */
          fixedGutter?: boolean;
      
          /** boolean|string. This disables editing of the editor content by the user. If the special value "nocursor" is given (instead of simply true), focusing of the editor is also disallowed. */
          readOnly?: any;
      
          /**Whether the cursor should be drawn when a selection is active. Defaults to false. */
          showCursorWhenSelecting?: boolean;
      
          /** The maximum number of undo levels that the editor stores. Defaults to 40. */
          undoDepth?: number;
      
          /** The period of inactivity (in milliseconds) that will cause a new history event to be started when typing or deleting. Defaults to 500. */
          historyEventDelay?: number;
      
          /** The tab index to assign to the editor. If not given, no tab index will be assigned. */
          tabindex?: number;
      
          /** Can be used to make CodeMirror focus itself on initialization. Defaults to off.
          When fromTextArea is used, and no explicit value is given for this option, it will be set to true when either the source textarea is focused,
          or it has an autofocus attribute and no other element is focused. */
          autofocus?: boolean;
      
          /** Controls whether drag-and - drop is enabled. On by default. */
          dragDrop?: boolean;
      
          /** When given , this will be called when the editor is handling a dragenter , dragover , or drop event.
          It will be passed the editor instance and the event object as arguments.
          The callback can choose to handle the event itself , in which case it should return true to indicate that CodeMirror should not do anything further. */
          onDragEvent?: (instance: CodeMirror, event: Event) => boolean;
      
          /** This provides a rather low - level hook into CodeMirror's key handling.
          If provided, this function will be called on every keydown, keyup, and keypress event that CodeMirror captures.
          It will be passed two arguments, the editor instance and the key event.
          This key event is pretty much the raw key event, except that a stop() method is always added to it.
          You could feed it to, for example, jQuery.Event to further normalize it.
          This function can inspect the key event, and handle it if it wants to.
          It may return true to tell CodeMirror to ignore the event.
          Be wary that, on some browsers, stopping a keydown does not stop the keypress from firing, whereas on others it does.
          If you respond to an event, you should probably inspect its type property and only do something when it is keydown
          (or keypress for actions that need character data). */
          onKeyEvent?: (instance: CodeMirror, event: Event) => boolean;
      
          /** Half - period in milliseconds used for cursor blinking. The default blink rate is 530ms. */
          cursorBlinkRate?: number;
      
          /** Determines the height of the cursor. Default is 1 , meaning it spans the whole height of the line.
          For some fonts (and by some tastes) a smaller height (for example 0.85),
          which causes the cursor to not reach all the way to the bottom of the line, looks better */
          cursorHeight?: number;
      
          /** Highlighting is done by a pseudo background - thread that will work for workTime milliseconds,
          and then use timeout to sleep for workDelay milliseconds.
          The defaults are 200 and 300, you can change these options to make the highlighting more or less aggressive. */
          workTime?: number;
      
          /** See workTime. */
          workDelay?: number;
      
          /** Indicates how quickly CodeMirror should poll its input textarea for changes(when focused).
          Most input is captured by events, but some things, like IME input on some browsers, don't generate events that allow CodeMirror to properly detect it.
          Thus, it polls. Default is 100 milliseconds. */
          pollInterval?: number
      
              /** By default, CodeMirror will combine adjacent tokens into a single span if they have the same class.
              This will result in a simpler DOM tree, and thus perform better. With some kinds of styling(such as rounded corners),
              this will change the way the document looks. You can set this option to false to disable this behavior. */
              flattenSpans?: boolean;
      
          /** When highlighting long lines, in order to stay responsive, the editor will give up and simply style
          the rest of the line as plain text when it reaches a certain position. The default is 10000.
          You can set this to Infinity to turn off this behavior. */
          maxHighlightLength?: number;
      
          /** Specifies the amount of lines that are rendered above and below the part of the document that's currently scrolled into view.
          This affects the amount of updates needed when scrolling, and the amount of work that such an update does.
          You should usually leave it at its default, 10. Can be set to Infinity to make sure the whole document is always rendered,
          and thus the browser's text search works on it. This will have bad effects on performance of big documents. */
          viewportMargin?: number;
        }
      
        export interface TextMarkerOptions {
          /** Assigns a CSS class to the marked stretch of text. */
          className?: string;
      
          /** Determines whether text inserted on the left of the marker will end up inside or outside of it. */
          inclusiveLeft?: boolean;
      
          /** Like inclusiveLeft , but for the right side. */
          inclusiveRight?: boolean;
      
          /** Atomic ranges act as a single unit when cursor movement is concerned i.e. it is impossible to place the cursor inside of them.
          In atomic ranges, inclusiveLeft and inclusiveRight have a different meaning they will prevent the cursor from being placed
          respectively directly before and directly after the range. */
          atomic?: boolean;
      
          /** Collapsed ranges do not show up in the display.Setting a range to be collapsed will automatically make it atomic. */
          collapsed?: boolean;
      
          /** When enabled, will cause the mark to clear itself whenever the cursor enters its range.
          This is mostly useful for text - replacement widgets that need to 'snap open' when the user tries to edit them.
          The "clear" event fired on the range handle can be used to be notified when this happens. */
          clearOnEnter?: boolean;
      
          /** Use a given node to display this range.Implies both collapsed and atomic.
          The given DOM node must be an inline element(as opposed to a block element). */
          replacedWith?: HTMLElement;
      
          /** A read - only span can, as long as it is not cleared, not be modified except by calling setValue to reset the whole document.
          Note: adding a read - only span currently clears the undo history of the editor,
          because existing undo events being partially nullified by read - only spans would corrupt the history (in the current implementation). */
          readOnly?: boolean;
      
          /** When set to true (default is false), adding this marker will create an event in the undo history that can be individually undone(clearing the marker). */
          addToHistory?: boolean;
      
          /** Can be used to specify an extra CSS class to be applied to the leftmost span that is part of the marker. */
          startStyle?: string;
      
          /** Equivalent to startStyle, but for the rightmost span. */
          endStyle?: string;
      
          /** When the target document is linked to other documents, you can set shared to true to make the marker appear in all documents.
          By default, a marker appears only in its target document. */
          shared?: boolean;
        }
      }
    • knockout.d.ts
      // Type definitions for Knockout 2.3
      // Project: http://knockoutjs.com
      // Definitions by: Boris Yankov <https://github.com/borisyankov/>
      // Definitions: https://github.com/borisyankov/DefinitelyTyped
      
      
      declare module ko {
      
        export module utils {
      
          //////////////////////////////////
          // utils.domManipulation.js
          //////////////////////////////////
      
          export function simpleHtmlParse(html: string): any[];
      
          export function jQueryHtmlParse(html: string): any[];
      
          export function parseHtmlFragment(html: string): any[];
      
          export function setHtml(node: Element, html: string): void;
      
          export function setHtml(node: Element, html: () => string): void;
      
          //////////////////////////////////
          // utils.domData.js
          //////////////////////////////////
      
          export module domData {
            export function get(node: Element, key: string): any;
      
            export function set(node: Element, key: string, value: any): void;
      
            export function getAll(node: Element, createIfNotFound: boolean): any;
      
            export function clear(node: Element): boolean;
          }
      
          //////////////////////////////////
          // utils.domNodeDisposal.js
          //////////////////////////////////
      
          export module domNodeDisposal {
            export function addDisposeCallback(node: Element, callback: Function): void;
      
            export function removeDisposeCallback(node: Element, callback: Function): void;
      
            export function cleanNode(node: Element): Element;
      
            export function removeNode(node: Element): void;
          }
      
          //////////////////////////////////
          // utils.js
          //////////////////////////////////
      
          export var fieldsIncludedWithJsonPost: any[];
      
          export function compareArrays<T>(a: T[], b: T[]): Array<KnockoutArrayChange<T>>;
      
          export function arrayForEach<T>(array: T[], action: (item: T) => void): void;
      
          export function arrayIndexOf<T>(array: T[], item: T): number;
      
          export function arrayFirst<T>(array: T[], predicate: (item: T) => boolean, predicateOwner?: any): T;
      
          export function arrayRemoveItem(array: any[], itemToRemove: any): void;
      
          export function arrayGetDistinctValues<T>(array: T[]): T[];
      
          export function arrayMap<T, U>(array: T[], mapping: (item: T) => U): U[];
      
          export function arrayFilter<T>(array: T[], predicate: (item: T) => boolean): T[];
      
          export function arrayPushAll<T>(array: T[], valuesToPush: T[]): T[];
      
          export function arrayPushAll<T>(array: ObservableArray<T>, valuesToPush: T[]): T[];
      
          export function extend(target: Object, source: Object): Object;
      
          export function emptyDomNode(domNode: HTMLElement): void;
      
          export function moveCleanedNodesToContainerElement(nodes: any[]): HTMLElement;
      
          export function cloneNodes(nodesArray: any[], shouldCleanNodes: boolean): any[];
      
          export function setDomNodeChildren(domNode: any, childNodes: any[]): void;
      
          export function replaceDomNodes(nodeToReplaceOrNodeArray: any, newNodesArray: any[]): void;
      
          export function setOptionNodeSelectionState(optionNode: any, isSelected: boolean): void;
      
          export function stringTrim(str: string): string;
      
          export function stringTokenize(str: string, delimiter: string): string;
      
          export function stringStartsWith(str: string, startsWith: string): string;
      
          export function domNodeIsContainedBy(node: any, containedByNode: any): boolean;
      
          export function domNodeIsAttachedToDocument(node: any): boolean;
      
          export function tagNameLower(element: any): string;
      
          export function registerEventHandler(element: any, eventType: any, handler: Function): void;
      
          export function triggerEvent(element: any, eventType: any): void;
      
          export function unwrapObservable<T>(value: Observable<T>): T;
      
          export function peekObservable<T>(value: Observable<T>): T;
      
          export function toggleDomNodeCssClass(node: any, className: string, shouldHaveClass: boolean): void;
      
          //setTextContent(element: any, textContent: string): void; // NOT PART OF THE MINIFIED API SURFACE (ONLY IN knockout-{version}.debug.js) https://github.com/SteveSanderson/knockout/issues/670
      
          export function setElementName(element: any, name: string): void;
      
          export function forceRefresh(node: any): void;
      
          export function ensureSelectElementIsRenderedCorrectly(selectElement: any): void;
      
          export function range(min: any, max: any): any;
      
          export function makeArray(arrayLikeObject: any): any[];
      
          export function getFormFields(form: any, fieldName: string): any[];
      
          export function parseJson(jsonString: string): any;
      
          export function stringifyJson(data: any, replacer: Function, space: string): string;
      
          export function postJson(urlOrForm: any, data: any, options: any): void;
      
          export var ieVersion: number;
      
          export var isIe6: boolean;
      
          export var isIe7: boolean;
        }
      
        export module memoization {
      
        }
      
        export module bindingHandlers {
      
          // Controlling text and appearance
          export var visible: BindingHandler;
          export var text: BindingHandler;
          export var html: BindingHandler;
          export var css: BindingHandler;
          export var style: BindingHandler;
          export var attr: BindingHandler;
      
          // Control Flow
          export var foreach: BindingHandler;
          export var ifnot: BindingHandler;
      
          /*export var if: BindingHandler;*/
          /*export var with: BindingHandler;*/
      
          // Working with form fields
          export var click: BindingHandler;
          export var event: BindingHandler;
          export var submit: BindingHandler;
          export var enable: BindingHandler;
          export var disable: BindingHandler;
          export var value: BindingHandler;
          export var hasfocus: BindingHandler;
          export var checked: BindingHandler;
          export var options: BindingHandler;
          export var selectedOptions: BindingHandler;
          export var uniqueName: BindingHandler;
      
          // Rendering templates
          export var template: BindingHandler;
        }
      
        export module virtualElements {
        }
      
        export module extenders {
          export function throttle(target: any, timeout: number): ko.Computed<any>;
          export function notify(target: any, notifyWhen: string): any;
        }
      
        export function applyBindings(viewModel: any, rootNode?: any): void;
        export function applyBindingsToDescendants(viewModel: any, rootNode: any): void;
        export function applyBindingsToNode(node: Element, options: any, viewModel: any): void;
      
        export interface subscribable<T> extends subscribable.CustomFunctions<T> {
          subscribe(callback: (newValue: T) => void, target?: any, event?: string): Disposable;
          subscribe<TEvent>(callback: (newValue: TEvent) => void, target: any, event: string): Disposable;
          extend(requestedExtenders: { [key: string]: any; }): subscribable<T>;
          getSubscriptionsCount(): number;
        }
      
        export module subscribable {
      
          export var fn: CustomFunctions<any>;
      
          export interface CustomFunctions<T> {
            notifySubscribers(valueToWrite: T, event?: string): void;
          }
      
        }
      
        export interface Disposable {
          dispose(): void;
        }
      
        export function observable<T>(value?: T): Observable<T>;
      
        export interface Observable<T> extends observable.CustomFunctions, subscribable<T> {
      
          (): T;
          (value: T): void;
      
          peek(): T;
          valueHasMutated(): void;
          valueWillMutate(): void;
          extend(requestedExtenders: { [key: string]: any; }): Observable<T>;
        }
      
        export module observable {
      
          export var fn: CustomFunctions;
      
          export interface CustomFunctions {
            equalityComparer(a: any, b: any): boolean;
          }
        }
      
      
      
        export function computed<T>(): Computed<T>;
        export function computed<T>(read: () => T, context?: any, options?: any): Computed<T>;
        export function computed<T>(definition: computed.Definition<T>): Computed<T>;
        export function computed(options?: any): Computed<any>;
      
        export interface Computed<T> extends subscribable<T> {
          (): T;
          (value: T): void;
      
          peek(): T;
          dispose(): void;
          isActive(): boolean;
          getDependenciesCount(): number;
          extend(requestedExtenders: { [key: string]: any; }): Computed<T>;
        }
      
        export module computed {
      
          export var fn: CustomFunctions;
      
          export interface CustomFunctions {
          }
      
          export interface Definition<T> {
            read(): T;
            write? (value: T): void;
            disposeWhenNodeIsRemoved?: Node;
            disposeWhen? (): boolean;
            owner?: any;
            deferEvaluation?: boolean;
          }
        }
      
      
      
        export function observableArray<T>(value?: T[]): ObservableArray<T>;
      
        export interface ObservableArray<T> extends Observable<T[]>, observableArray.CustomFunctions<T> {
        }
      
        export module observableArray {
      
          export var fn: CustomFunctions<any>;
      
          export interface CustomFunctions<T> {
            indexOf(searchElement: T, fromIndex?: number): number;
            slice(start: number, end?: number): T[];
            splice(start: number): T[];
            splice(start: number, deleteCount: number, ...items: T[]): T[];
            pop(): T;
            push(...items: T[]): void;
            shift(): T;
            unshift(...items: T[]): number;
            reverse(): T[];
            sort(): void;
            sort(compareFunction: (left: T, right: T) => number): void;
      
            // Ko specific
            replace(oldItem: T, newItem: T): void;
      
            remove(item: T): T[];
            remove(removeFunction: (item: T) => boolean): T[];
            removeAll(items: T[]): T[];
            removeAll(): T[];
      
            destroy(item: T): void;
            destroyAll(items: T[]): void;
            destroyAll(): void;
          }
        }
      
        export function contextFor(node: any): any;
        export function isSubscribable(instance: any): boolean;
        export function toJSON(viewModel: any, replacer?: Function, space?: any): string;
        export function toJS(viewModel: any): any;
        export function isObservable(instance: any): boolean;
        export function isWriteableObservable(instance: any): boolean;
        export function isComputed(instance: any): boolean;
        export function dataFor(node: any): any;
        export function removeNode(node: Element): void;
        export function cleanNode(node: Element): Element;
        export function renderTemplate(template: Function, viewModel: any, options?: any, target?: any, renderMode?: any): any;
        export function renderTemplate(template: string, viewModel: any, options?: any, target?: any, renderMode?: any): any;
        export function unwrap(value: any): any;
      
        export module templateSources /* KnockoutTemplateSources */ {
      
        }
      
      
        export class templateEngine extends nativeTemplateEngine {
      
          createJavaScriptEvaluatorBlock(script: string): string;
      
          makeTemplateSource(template: any, templateDocument?: Document): any;
      
          renderTemplate(template: any, bindingContext: BindingContext, options: Object, templateDocument: Document): any;
      
          isTemplateRewritten(template: any, templateDocument: Document): boolean;
      
          rewriteTemplate(template: any, rewriterCallback: Function, templateDocument: Document): void;
      
        }
      
        //////////////////////////////////
        // templateRewriting.js
        //////////////////////////////////
      
        export module templateRewriting {
      
          export function ensureTemplateIsRewritten(template: Node, templateEngine: templateEngine, templateDocument: Document): any;
          export function ensureTemplateIsRewritten(template: string, templateEngine: templateEngine, templateDocument: Document): any;
      
          export function memoizeBindingAttributeSyntax(htmlString: string, templateEngine: templateEngine): any;
      
          export function applyMemoizedBindingsToNextSibling(bindings: any, nodeName: string): string;
        }
      
        //////////////////////////////////
        // nativeTemplateEngine.js
        //////////////////////////////////
      
        export class nativeTemplateEngine {
          renderTemplateSource(templateSource: Object, bindingContext?: BindingContext, options?: Object): any[];
        }
      
        //////////////////////////////////
        // jqueryTmplTemplateEngine.js
        //////////////////////////////////
      
        export class jqueryTmplTemplateEngine extends templateEngine {
      
          renderTemplateSource(templateSource: Object, bindingContext: BindingContext, options: Object): Node[];
      
          createJavaScriptEvaluatorBlock(script: string): string;
      
          addTemplate(templateName: string, templateMarkup: string): void;
      
        }
      
        //////////////////////////////////
        // templating.js
        //////////////////////////////////
      
        export function setTemplateEngine(templateEngine: nativeTemplateEngine): void;
      
        export function renderTemplate(template: Function, dataOrBindingContext: BindingContext, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
        export function renderTemplate(template: any, dataOrBindingContext: BindingContext, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
        export function renderTemplate(template: Function, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
        export function renderTemplate(template: any, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
        export function renderTemplate(template: Function, dataOrBindingContext: BindingContext, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
        export function renderTemplate(template: any, dataOrBindingContext: BindingContext, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
        export function renderTemplate(template: Function, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
        export function renderTemplate(template: any, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
      
        export function renderTemplateForEach(template: Function, arrayOrObservableArray: any[], options: Object, targetNode: Node, parentBindingContext: BindingContext): any;
        export function renderTemplateForEach(template: any, arrayOrObservableArray: any[], options: Object, targetNode: Node, parentBindingContext: BindingContext): any;
        export function renderTemplateForEach(template: Function, arrayOrObservableArray: Observable<any>, options: Object, targetNode: Node, parentBindingContext: BindingContext): any;
        export function renderTemplateForEach(template: any, arrayOrObservableArray: Observable<any>, options: Object, targetNode: Node, parentBindingContext: BindingContext): any;
      
        export module expressionRewriting {
          export var bindingRewriteValidators: any;
        }
      
        /////////////////////////////////
      
        export module bindingProvider {
      
        }
      
        /////////////////////////////////
        // selectExtensions.js
        /////////////////////////////////
      
        export module selectExtensions {
      
          export function readValue(element: HTMLElement): any;
      
          export function writeValue(element: HTMLElement, value: any): void;
        }
      
        export interface BindingContext {
          $parent: any;
          $parents: any[];
          $root: any;
          $data: any;
          $index?: number;
          $parentContext?: BindingContext;
      
          extend(properties: any): any;
          createChildContext(dataItemOrAccessor: any, dataItemAlias?: any, extendCallback?: Function): any;
        }
      
        export interface BindingHandler {
          init? (element: any, valueAccessor: () => any, allBindingsAccessor: () => any, viewModel: any, bindingContext: BindingContext): void;
          update? (element: any, valueAccessor: () => any, allBindingsAccessor: () => any, viewModel: any, bindingContext: BindingContext): void;
          options?: any;
        }
      
      }
      
      
      
      interface KnockoutMemoization {
          memoize(callback: () => string): string;
          unmemoize(memoId: string, callbackParams: any[]): boolean;
          unmemoizeDomNodeAndDescendants(domNode: any, extraCallbackParamsArray: any[]): boolean;
          parseMemoText(memoText: string): string;
      }
      
      interface KnockoutVirtualElement {}
      
      interface KnockoutVirtualElements {
      	allowedBindings: { [bindingName: string]: boolean; };
          emptyNode(node: KnockoutVirtualElement ): void;
          firstChild(node: KnockoutVirtualElement ): KnockoutVirtualElement;
      	insertAfter( container: KnockoutVirtualElement, nodeToInsert: HTMLElement, insertAfter: HTMLElement ): void;
          nextSibling(node: KnockoutVirtualElement): HTMLElement;
          prepend(node: KnockoutVirtualElement, toInsert: HTMLElement ): void;
          setDomNodeChildren(node: KnockoutVirtualElement, newChildren: { length: number;[index: number]: HTMLElement; } ): void;
          childNodes(node: KnockoutVirtualElement ): HTMLElement[];
      }
      
      
      
      interface KnockoutArrayChange<T> {
          status: string;
          value: T;
          index: number;
      }
      
      //////////////////////////////////
      // templateSources.js
      //////////////////////////////////
      
      interface KnockoutTemplateSourcesDomElement {
      
          text(valueToWrite?: any): any;
      
          data(key: string, valueToWrite?: any): any;
      }
      
      
      interface KnockoutTemplateSources {
      
        domElement: KnockoutTemplateSourcesDomElement;
      
        anonymousTemplate: {
      
          prototype: KnockoutTemplateSourcesDomElement;
      
          new (element: Element): KnockoutTemplateSourcesDomElement;
        };
      }
      
      
      
      declare module "knockout" {
      	export = ko;
      }
      
    • marked.d.ts
      declare var marked;
    • typescriptServices.d.ts
      declare module ts {
          interface TextRange {
              pos: number;
              end: number;
          }
          const enum SyntaxKind {
              Unknown = 0,
              EndOfFileToken = 1,
              SingleLineCommentTrivia = 2,
              MultiLineCommentTrivia = 3,
              NewLineTrivia = 4,
              WhitespaceTrivia = 5,
              NumericLiteral = 6,
              StringLiteral = 7,
              RegularExpressionLiteral = 8,
              NoSubstitutionTemplateLiteral = 9,
              TemplateHead = 10,
              TemplateMiddle = 11,
              TemplateTail = 12,
              OpenBraceToken = 13,
              CloseBraceToken = 14,
              OpenParenToken = 15,
              CloseParenToken = 16,
              OpenBracketToken = 17,
              CloseBracketToken = 18,
              DotToken = 19,
              DotDotDotToken = 20,
              SemicolonToken = 21,
              CommaToken = 22,
              LessThanToken = 23,
              GreaterThanToken = 24,
              LessThanEqualsToken = 25,
              GreaterThanEqualsToken = 26,
              EqualsEqualsToken = 27,
              ExclamationEqualsToken = 28,
              EqualsEqualsEqualsToken = 29,
              ExclamationEqualsEqualsToken = 30,
              EqualsGreaterThanToken = 31,
              PlusToken = 32,
              MinusToken = 33,
              AsteriskToken = 34,
              SlashToken = 35,
              PercentToken = 36,
              PlusPlusToken = 37,
              MinusMinusToken = 38,
              LessThanLessThanToken = 39,
              GreaterThanGreaterThanToken = 40,
              GreaterThanGreaterThanGreaterThanToken = 41,
              AmpersandToken = 42,
              BarToken = 43,
              CaretToken = 44,
              ExclamationToken = 45,
              TildeToken = 46,
              AmpersandAmpersandToken = 47,
              BarBarToken = 48,
              QuestionToken = 49,
              ColonToken = 50,
              EqualsToken = 51,
              PlusEqualsToken = 52,
              MinusEqualsToken = 53,
              AsteriskEqualsToken = 54,
              SlashEqualsToken = 55,
              PercentEqualsToken = 56,
              LessThanLessThanEqualsToken = 57,
              GreaterThanGreaterThanEqualsToken = 58,
              GreaterThanGreaterThanGreaterThanEqualsToken = 59,
              AmpersandEqualsToken = 60,
              BarEqualsToken = 61,
              CaretEqualsToken = 62,
              Identifier = 63,
              BreakKeyword = 64,
              CaseKeyword = 65,
              CatchKeyword = 66,
              ClassKeyword = 67,
              ConstKeyword = 68,
              ContinueKeyword = 69,
              DebuggerKeyword = 70,
              DefaultKeyword = 71,
              DeleteKeyword = 72,
              DoKeyword = 73,
              ElseKeyword = 74,
              EnumKeyword = 75,
              ExportKeyword = 76,
              ExtendsKeyword = 77,
              FalseKeyword = 78,
              FinallyKeyword = 79,
              ForKeyword = 80,
              FunctionKeyword = 81,
              IfKeyword = 82,
              ImportKeyword = 83,
              InKeyword = 84,
              InstanceOfKeyword = 85,
              NewKeyword = 86,
              NullKeyword = 87,
              ReturnKeyword = 88,
              SuperKeyword = 89,
              SwitchKeyword = 90,
              ThisKeyword = 91,
              ThrowKeyword = 92,
              TrueKeyword = 93,
              TryKeyword = 94,
              TypeOfKeyword = 95,
              VarKeyword = 96,
              VoidKeyword = 97,
              WhileKeyword = 98,
              WithKeyword = 99,
              ImplementsKeyword = 100,
              InterfaceKeyword = 101,
              LetKeyword = 102,
              PackageKeyword = 103,
              PrivateKeyword = 104,
              ProtectedKeyword = 105,
              PublicKeyword = 106,
              StaticKeyword = 107,
              YieldKeyword = 108,
              AnyKeyword = 109,
              BooleanKeyword = 110,
              ConstructorKeyword = 111,
              DeclareKeyword = 112,
              GetKeyword = 113,
              ModuleKeyword = 114,
              RequireKeyword = 115,
              NumberKeyword = 116,
              SetKeyword = 117,
              StringKeyword = 118,
              TypeKeyword = 119,
              Missing = 120,
              QualifiedName = 121,
              ComputedPropertyName = 122,
              TypeParameter = 123,
              Parameter = 124,
              Property = 125,
              Method = 126,
              Constructor = 127,
              GetAccessor = 128,
              SetAccessor = 129,
              CallSignature = 130,
              ConstructSignature = 131,
              IndexSignature = 132,
              TypeReference = 133,
              FunctionType = 134,
              ConstructorType = 135,
              TypeQuery = 136,
              TypeLiteral = 137,
              ArrayType = 138,
              TupleType = 139,
              UnionType = 140,
              ParenType = 141,
              ArrayLiteral = 142,
              ObjectLiteral = 143,
              PropertyAssignment = 144,
              ShorthandPropertyAssignment = 145,
              PropertyAccess = 146,
              IndexedAccess = 147,
              CallExpression = 148,
              NewExpression = 149,
              TaggedTemplateExpression = 150,
              TypeAssertion = 151,
              ParenExpression = 152,
              FunctionExpression = 153,
              ArrowFunction = 154,
              PrefixOperator = 155,
              PostfixOperator = 156,
              BinaryExpression = 157,
              ConditionalExpression = 158,
              TemplateExpression = 159,
              TemplateSpan = 160,
              YieldExpression = 161,
              OmittedExpression = 162,
              Block = 163,
              VariableStatement = 164,
              EmptyStatement = 165,
              ExpressionStatement = 166,
              IfStatement = 167,
              DoStatement = 168,
              WhileStatement = 169,
              ForStatement = 170,
              ForInStatement = 171,
              ContinueStatement = 172,
              BreakStatement = 173,
              ReturnStatement = 174,
              WithStatement = 175,
              SwitchStatement = 176,
              CaseClause = 177,
              DefaultClause = 178,
              LabeledStatement = 179,
              ThrowStatement = 180,
              TryStatement = 181,
              TryBlock = 182,
              CatchBlock = 183,
              FinallyBlock = 184,
              DebuggerStatement = 185,
              VariableDeclaration = 186,
              FunctionDeclaration = 187,
              FunctionBlock = 188,
              ClassDeclaration = 189,
              InterfaceDeclaration = 190,
              TypeAliasDeclaration = 191,
              EnumDeclaration = 192,
              ModuleDeclaration = 193,
              ModuleBlock = 194,
              ImportDeclaration = 195,
              ExportAssignment = 196,
              EnumMember = 197,
              SourceFile = 198,
              Program = 199,
              SyntaxList = 200,
              Count = 201,
              FirstAssignment = 51,
              LastAssignment = 62,
              FirstReservedWord = 64,
              LastReservedWord = 99,
              FirstKeyword = 64,
              LastKeyword = 119,
              FirstFutureReservedWord = 100,
              LastFutureReservedWord = 108,
              FirstTypeNode = 133,
              LastTypeNode = 141,
              FirstPunctuation = 13,
              LastPunctuation = 62,
              FirstToken = 1,
              LastToken = 119,
              FirstTriviaToken = 2,
              LastTriviaToken = 5,
              FirstLiteralToken = 6,
              LastLiteralToken = 9,
              FirstTemplateToken = 9,
              LastTemplateToken = 12,
              FirstOperator = 21,
              LastOperator = 62,
              FirstBinaryOperator = 23,
              LastBinaryOperator = 62,
          }
          const enum NodeFlags {
              Export = 1,
              Ambient = 2,
              QuestionMark = 4,
              Rest = 8,
              Public = 16,
              Private = 32,
              Protected = 64,
              Static = 128,
              MultiLine = 256,
              Synthetic = 512,
              DeclarationFile = 1024,
              Let = 2048,
              Const = 4096,
              OctalLiteral = 8192,
              Modifier = 243,
              AccessibilityModifier = 112,
              BlockScoped = 6144,
          }
          const enum ParserContextFlags {
              StrictMode = 1,
              DisallowIn = 2,
              Yield = 4,
              GeneratorParameter = 8,
          }
          interface Node extends TextRange {
              kind: SyntaxKind;
              flags: NodeFlags;
              parserContextFlags?: ParserContextFlags;
              id?: number;
              parent?: Node;
              symbol?: Symbol;
              locals?: SymbolTable;
              nextContainer?: Node;
              localSymbol?: Symbol;
              modifiers?: ModifiersArray;
          }
          interface NodeArray<T> extends Array<T>, TextRange {
              hasTrailingComma?: boolean;
          }
          interface ModifiersArray extends Array<Node> {
              flags: number;
          }
          interface Identifier extends Node {
              text: string;
          }
          interface QualifiedName extends Node {
              left: EntityName;
              right: Identifier;
          }
          type EntityName = Identifier | QualifiedName;
          interface ParsedSignature {
              typeParameters?: NodeArray<TypeParameterDeclaration>;
              parameters: NodeArray<ParameterDeclaration>;
              type?: TypeNode;
          }
          type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName;
          interface Declaration extends Node {
              name?: DeclarationName;
          }
          interface ComputedPropertyName extends Node {
              expression: Expression;
          }
          interface TypeParameterDeclaration extends Declaration {
              name: Identifier;
              constraint?: TypeNode;
              expression?: Expression;
          }
          interface SignatureDeclaration extends Declaration, ParsedSignature {
          }
          interface VariableDeclaration extends Declaration {
              name: Identifier;
              type?: TypeNode;
              initializer?: Expression;
          }
          interface PropertyDeclaration extends Declaration {
              type?: TypeNode;
              initializer?: Expression;
          }
          interface ShortHandPropertyDeclaration extends Declaration {
              name: Identifier;
          }
          interface ParameterDeclaration extends VariableDeclaration {
          }
          interface FunctionLikeDeclaration extends SignatureDeclaration {
              asteriskToken?: Node;
              body?: Block | Expression;
          }
          interface FunctionDeclaration extends FunctionLikeDeclaration {
              name: Identifier;
              body?: Block;
          }
          interface MethodDeclaration extends FunctionLikeDeclaration {
              body?: Block;
          }
          interface ConstructorDeclaration extends Node, ParsedSignature {
              body?: Block;
          }
          interface AccessorDeclaration extends FunctionLikeDeclaration {
              body?: Block;
          }
          interface TypeNode extends Node {
          }
          interface TypeReferenceNode extends TypeNode {
              typeName: EntityName;
              typeArguments?: NodeArray<TypeNode>;
          }
          interface TypeQueryNode extends TypeNode {
              exprName: EntityName;
          }
          interface TypeLiteralNode extends TypeNode {
              members: NodeArray<Node>;
          }
          interface ArrayTypeNode extends TypeNode {
              elementType: TypeNode;
          }
          interface TupleTypeNode extends TypeNode {
              elementTypes: NodeArray<TypeNode>;
          }
          interface UnionTypeNode extends TypeNode {
              types: NodeArray<TypeNode>;
          }
          interface ParenTypeNode extends TypeNode {
              type: TypeNode;
          }
          interface StringLiteralTypeNode extends TypeNode {
              text: string;
          }
          interface Expression extends Node {
              contextualType?: Type;
          }
          interface UnaryExpression extends Expression {
              operator: SyntaxKind;
              operand: Expression;
          }
          interface YieldExpression extends Expression {
              asteriskToken?: Node;
              expression: Expression;
          }
          interface BinaryExpression extends Expression {
              left: Expression;
              operator: SyntaxKind;
              right: Expression;
          }
          interface ConditionalExpression extends Expression {
              condition: Expression;
              whenTrue: Expression;
              whenFalse: Expression;
          }
          interface FunctionExpression extends Expression, FunctionLikeDeclaration {
              name?: Identifier;
              body: Block | Expression;
          }
          interface LiteralExpression extends Expression {
              text: string;
          }
          interface TemplateExpression extends Expression {
              head: LiteralExpression;
              templateSpans: NodeArray<TemplateSpan>;
          }
          interface TemplateSpan extends Node {
              expression: Expression;
              literal: LiteralExpression;
          }
          interface ParenExpression extends Expression {
              expression: Expression;
          }
          interface ArrayLiteral extends Expression {
              elements: NodeArray<Expression>;
          }
          interface ObjectLiteral extends Expression {
              properties: NodeArray<Node>;
          }
          interface PropertyAccess extends Expression {
              left: Expression;
              right: Identifier;
          }
          interface IndexedAccess extends Expression {
              object: Expression;
              index: Expression;
          }
          interface CallExpression extends Expression {
              func: Expression;
              typeArguments?: NodeArray<TypeNode>;
              arguments: NodeArray<Expression>;
          }
          interface NewExpression extends CallExpression {
          }
          interface TaggedTemplateExpression extends Expression {
              tag: Expression;
              template: LiteralExpression | TemplateExpression;
          }
          type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression;
          interface TypeAssertion extends Expression {
              type: TypeNode;
              operand: Expression;
          }
          interface Statement extends Node {
          }
          interface Block extends Statement {
              statements: NodeArray<Statement>;
          }
          interface VariableStatement extends Statement {
              declarations: NodeArray<VariableDeclaration>;
          }
          interface ExpressionStatement extends Statement {
              expression: Expression;
          }
          interface IfStatement extends Statement {
              expression: Expression;
              thenStatement: Statement;
              elseStatement?: Statement;
          }
          interface IterationStatement extends Statement {
              statement: Statement;
          }
          interface DoStatement extends IterationStatement {
              expression: Expression;
          }
          interface WhileStatement extends IterationStatement {
              expression: Expression;
          }
          interface ForStatement extends IterationStatement {
              declarations?: NodeArray<VariableDeclaration>;
              initializer?: Expression;
              condition?: Expression;
              iterator?: Expression;
          }
          interface ForInStatement extends IterationStatement {
              declarations?: NodeArray<VariableDeclaration>;
              variable?: Expression;
              expression: Expression;
          }
          interface BreakOrContinueStatement extends Statement {
              label?: Identifier;
          }
          interface ReturnStatement extends Statement {
              expression?: Expression;
          }
          interface WithStatement extends Statement {
              expression: Expression;
              statement: Statement;
          }
          interface SwitchStatement extends Statement {
              expression: Expression;
              clauses: NodeArray<CaseOrDefaultClause>;
          }
          interface CaseOrDefaultClause extends Node {
              expression?: Expression;
              statements: NodeArray<Statement>;
          }
          interface LabeledStatement extends Statement {
              label: Identifier;
              statement: Statement;
          }
          interface ThrowStatement extends Statement {
              expression: Expression;
          }
          interface TryStatement extends Statement {
              tryBlock: Block;
              catchBlock?: CatchBlock;
              finallyBlock?: Block;
          }
          interface CatchBlock extends Block {
              variable: Identifier;
              type?: TypeNode;
          }
          interface ClassDeclaration extends Declaration {
              name: Identifier;
              typeParameters?: NodeArray<TypeParameterDeclaration>;
              baseType?: TypeReferenceNode;
              implementedTypes?: NodeArray<TypeReferenceNode>;
              members: NodeArray<Node>;
          }
          interface InterfaceDeclaration extends Declaration {
              name: Identifier;
              typeParameters?: NodeArray<TypeParameterDeclaration>;
              baseTypes?: NodeArray<TypeReferenceNode>;
              members: NodeArray<Node>;
          }
          interface TypeAliasDeclaration extends Declaration {
              name: Identifier;
              type: TypeNode;
          }
          interface EnumMember extends Declaration {
              name: DeclarationName;
              initializer?: Expression;
          }
          interface EnumDeclaration extends Declaration {
              name: Identifier;
              members: NodeArray<EnumMember>;
          }
          interface ModuleDeclaration extends Declaration {
              name: Identifier | LiteralExpression;
              body: Block | ModuleDeclaration;
          }
          interface ImportDeclaration extends Declaration {
              name: Identifier;
              entityName?: EntityName;
              externalModuleName?: LiteralExpression;
          }
          interface ExportAssignment extends Statement {
              exportName: Identifier;
          }
          interface FileReference extends TextRange {
              filename: string;
          }
          interface CommentRange extends TextRange {
              hasTrailingNewLine?: boolean;
          }
          interface SourceFile extends Block {
              filename: string;
              text: string;
              getLineAndCharacterFromPosition(position: number): LineAndCharacter;
              getPositionFromLineAndCharacter(line: number, character: number): number;
              getLineStarts(): number[];
              amdDependencies: string[];
              amdModuleName: string;
              referencedFiles: FileReference[];
              semanticDiagnostics: Diagnostic[];
              parseDiagnostics: Diagnostic[];
              grammarDiagnostics: Diagnostic[];
              getSyntacticDiagnostics(): Diagnostic[];
              hasNoDefaultLib: boolean;
              externalModuleIndicator: Node;
              nodeCount: number;
              identifierCount: number;
              symbolCount: number;
              isOpen: boolean;
              version: string;
              languageVersion: ScriptTarget;
              identifiers: Map<string>;
          }
          interface Program {
              getSourceFile(filename: string): SourceFile;
              getSourceFiles(): SourceFile[];
              getCompilerOptions(): CompilerOptions;
              getCompilerHost(): CompilerHost;
              getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
              getGlobalDiagnostics(): Diagnostic[];
              getTypeChecker(fullTypeCheckMode: boolean): TypeChecker;
              getCommonSourceDirectory(): string;
          }
          interface SourceMapSpan {
              emittedLine: number;
              emittedColumn: number;
              sourceLine: number;
              sourceColumn: number;
              nameIndex?: number;
              sourceIndex: number;
          }
          interface SourceMapData {
              sourceMapFilePath: string;
              jsSourceMappingURL: string;
              sourceMapFile: string;
              sourceMapSourceRoot: string;
              sourceMapSources: string[];
              inputSourceFileNames: string[];
              sourceMapNames?: string[];
              sourceMapMappings: string;
              sourceMapDecodedMappings: SourceMapSpan[];
          }
          enum EmitReturnStatus {
              Succeeded = 0,
              AllOutputGenerationSkipped = 1,
              JSGeneratedWithSemanticErrors = 2,
              DeclarationGenerationSkipped = 3,
              EmitErrorsEncountered = 4,
              CompilerOptionsErrors = 5,
          }
          interface EmitResult {
              emitResultStatus: EmitReturnStatus;
              diagnostics: Diagnostic[];
              sourceMaps: SourceMapData[];
          }
          interface TypeChecker {
              getProgram(): Program;
              getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
              getDeclarationDiagnostics(sourceFile: SourceFile): Diagnostic[];
              getGlobalDiagnostics(): Diagnostic[];
              getNodeCount(): number;
              getIdentifierCount(): number;
              getSymbolCount(): number;
              getTypeCount(): number;
              checkProgram(): void;
              emitFiles(targetSourceFile?: SourceFile): EmitResult;
              getParentOfSymbol(symbol: Symbol): Symbol;
              getNarrowedTypeOfSymbol(symbol: Symbol, node: Node): Type;
              getDeclaredTypeOfSymbol(symbol: Symbol): Type;
              getPropertiesOfType(type: Type): Symbol[];
              getPropertyOfType(type: Type, propertyName: string): Symbol;
              getSignaturesOfType(type: Type, kind: SignatureKind): Signature[];
              getIndexTypeOfType(type: Type, kind: IndexKind): Type;
              getReturnTypeOfSignature(signature: Signature): Type;
              getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
              getSymbolInfo(node: Node): Symbol;
              getShorthandAssignmentValueSymbol(location: Node): Symbol;
              getTypeOfNode(node: Node): Type;
              typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
              symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string;
              getSymbolDisplayBuilder(): SymbolDisplayBuilder;
              getFullyQualifiedName(symbol: Symbol): string;
              getAugmentedPropertiesOfType(type: Type): Symbol[];
              getRootSymbols(symbol: Symbol): Symbol[];
              getContextualType(node: Node): Type;
              getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature;
              getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature;
              isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
              isUndefinedSymbol(symbol: Symbol): boolean;
              isArgumentsSymbol(symbol: Symbol): boolean;
              isEmitBlocked(sourceFile?: SourceFile): boolean;
              getEnumMemberValue(node: EnumMember): number;
              isValidPropertyAccess(node: PropertyAccess, propertyName: string): boolean;
              getAliasedSymbol(symbol: Symbol): Symbol;
          }
          interface SymbolDisplayBuilder {
              buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
              buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void;
              buildSignatureDisplay(signatures: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
              buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
              buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
              buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags): void;
              buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
              buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
              buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
          }
          interface SymbolWriter {
              writeKeyword(text: string): void;
              writeOperator(text: string): void;
              writePunctuation(text: string): void;
              writeSpace(text: string): void;
              writeStringLiteral(text: string): void;
              writeParameter(text: string): void;
              writeSymbol(text: string, symbol: Symbol): void;
              writeLine(): void;
              increaseIndent(): void;
              decreaseIndent(): void;
              clear(): void;
              trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void;
          }
          const enum TypeFormatFlags {
              None = 0,
              WriteArrayAsGenericType = 1,
              UseTypeOfFunction = 2,
              NoTruncation = 4,
              WriteArrowStyleSignature = 8,
              WriteOwnNameForAnyLike = 16,
              WriteTypeArgumentsOfSignature = 32,
              InElementType = 64,
          }
          const enum SymbolFormatFlags {
              None = 0,
              WriteTypeParametersOrArguments = 1,
              UseOnlyExternalAliasing = 2,
          }
          const enum SymbolAccessibility {
              Accessible = 0,
              NotAccessible = 1,
              CannotBeNamed = 2,
          }
          interface SymbolVisibilityResult {
              accessibility: SymbolAccessibility;
              aliasesToMakeVisible?: ImportDeclaration[];
              errorSymbolName?: string;
              errorNode?: Node;
          }
          interface SymbolAccessiblityResult extends SymbolVisibilityResult {
              errorModuleName?: string;
          }
          interface EmitResolver {
              getProgram(): Program;
              getLocalNameOfContainer(container: ModuleDeclaration | EnumDeclaration): string;
              getExpressionNamePrefix(node: Identifier): string;
              getExportAssignmentName(node: SourceFile): string;
              isReferencedImportDeclaration(node: ImportDeclaration): boolean;
              isTopLevelValueImportWithEntityName(node: ImportDeclaration): boolean;
              getNodeCheckFlags(node: Node): NodeCheckFlags;
              getEnumMemberValue(node: EnumMember): number;
              hasSemanticErrors(): boolean;
              isDeclarationVisible(node: Declaration): boolean;
              isImplementationOfOverload(node: FunctionLikeDeclaration): boolean;
              writeTypeAtLocation(location: Node, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
              writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
              isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags): SymbolAccessiblityResult;
              isEntityNameVisible(entityName: EntityName, enclosingDeclaration: Node): SymbolVisibilityResult;
              getConstantValue(node: PropertyAccess | IndexedAccess): number;
              isEmitBlocked(sourceFile?: SourceFile): boolean;
          }
          const enum SymbolFlags {
              FunctionScopedVariable = 1,
              BlockScopedVariable = 2,
              Property = 4,
              EnumMember = 8,
              Function = 16,
              Class = 32,
              Interface = 64,
              ConstEnum = 128,
              RegularEnum = 256,
              ValueModule = 512,
              NamespaceModule = 1024,
              TypeLiteral = 2048,
              ObjectLiteral = 4096,
              Method = 8192,
              Constructor = 16384,
              GetAccessor = 32768,
              SetAccessor = 65536,
              CallSignature = 131072,
              ConstructSignature = 262144,
              IndexSignature = 524288,
              TypeParameter = 1048576,
              TypeAlias = 2097152,
              ExportValue = 4194304,
              ExportType = 8388608,
              ExportNamespace = 16777216,
              Import = 33554432,
              Instantiated = 67108864,
              Merged = 134217728,
              Transient = 268435456,
              Prototype = 536870912,
              UnionProperty = 1073741824,
              Enum = 384,
              Variable = 3,
              Value = 107455,
              Type = 3152352,
              Namespace = 1536,
              Module = 1536,
              Accessor = 98304,
              Signature = 917504,
              FunctionScopedVariableExcludes = 107454,
              BlockScopedVariableExcludes = 107455,
              ParameterExcludes = 107455,
              PropertyExcludes = 107455,
              EnumMemberExcludes = 107455,
              FunctionExcludes = 106927,
              ClassExcludes = 3258879,
              InterfaceExcludes = 3152288,
              RegularEnumExcludes = 3258623,
              ConstEnumExcludes = 3259263,
              ValueModuleExcludes = 106639,
              NamespaceModuleExcludes = 0,
              MethodExcludes = 99263,
              GetAccessorExcludes = 41919,
              SetAccessorExcludes = 74687,
              TypeParameterExcludes = 2103776,
              TypeAliasExcludes = 3152352,
              ImportExcludes = 33554432,
              ModuleMember = 35653619,
              ExportHasLocal = 944,
              HasLocals = 1041936,
              HasExports = 1952,
              HasMembers = 6240,
              IsContainer = 1048560,
              PropertyOrAccessor = 98308,
              Export = 29360128,
          }
          interface Symbol {
              flags: SymbolFlags;
              name: string;
              id?: number;
              mergeId?: number;
              declarations?: Declaration[];
              parent?: Symbol;
              members?: SymbolTable;
              exports?: SymbolTable;
              exportSymbol?: Symbol;
              valueDeclaration?: Declaration;
              constEnumOnlyModule?: boolean;
          }
          interface SymbolLinks {
              target?: Symbol;
              type?: Type;
              declaredType?: Type;
              mapper?: TypeMapper;
              referenced?: boolean;
              exportAssignSymbol?: Symbol;
              unionType?: UnionType;
          }
          interface TransientSymbol extends Symbol, SymbolLinks {
          }
          interface SymbolTable {
              [index: string]: Symbol;
          }
          const enum NodeCheckFlags {
              TypeChecked = 1,
              LexicalThis = 2,
              CaptureThis = 4,
              EmitExtends = 8,
              SuperInstance = 16,
              SuperStatic = 32,
              ContextChecked = 64,
              EnumValuesComputed = 128,
          }
          interface NodeLinks {
              resolvedType?: Type;
              resolvedSignature?: Signature;
              resolvedSymbol?: Symbol;
              flags?: NodeCheckFlags;
              enumMemberValue?: number;
              isIllegalTypeReferenceInConstraint?: boolean;
              isVisible?: boolean;
              localModuleName?: string;
              assignmentChecks?: Map<boolean>;
          }
          const enum TypeFlags {
              Any = 1,
              String = 2,
              Number = 4,
              Boolean = 8,
              Void = 16,
              Undefined = 32,
              Null = 64,
              Enum = 128,
              StringLiteral = 256,
              TypeParameter = 512,
              Class = 1024,
              Interface = 2048,
              Reference = 4096,
              Tuple = 8192,
              Union = 16384,
              Anonymous = 32768,
              FromSignature = 65536,
              Intrinsic = 127,
              StringLike = 258,
              NumberLike = 132,
              ObjectType = 48128,
              Structured = 65025,
          }
          interface Type {
              flags: TypeFlags;
              id: number;
              symbol?: Symbol;
          }
          interface IntrinsicType extends Type {
              intrinsicName: string;
          }
          interface StringLiteralType extends Type {
              text: string;
          }
          interface ObjectType extends Type {
          }
          interface InterfaceType extends ObjectType {
              typeParameters: TypeParameter[];
              baseTypes: ObjectType[];
              declaredProperties: Symbol[];
              declaredCallSignatures: Signature[];
              declaredConstructSignatures: Signature[];
              declaredStringIndexType: Type;
              declaredNumberIndexType: Type;
          }
          interface TypeReference extends ObjectType {
              target: GenericType;
              typeArguments: Type[];
          }
          interface GenericType extends InterfaceType, TypeReference {
              instantiations: Map<TypeReference>;
              openReferenceTargets: GenericType[];
              openReferenceChecks: Map<boolean>;
          }
          interface TupleType extends ObjectType {
              elementTypes: Type[];
              baseArrayType: TypeReference;
          }
          interface UnionType extends Type {
              types: Type[];
              resolvedProperties: SymbolTable;
          }
          interface ResolvedType extends ObjectType, UnionType {
              members: SymbolTable;
              properties: Symbol[];
              callSignatures: Signature[];
              constructSignatures: Signature[];
              stringIndexType: Type;
              numberIndexType: Type;
          }
          interface TypeParameter extends Type {
              constraint: Type;
              target?: TypeParameter;
              mapper?: TypeMapper;
          }
          const enum SignatureKind {
              Call = 0,
              Construct = 1,
          }
          interface Signature {
              declaration: SignatureDeclaration;
              typeParameters: TypeParameter[];
              parameters: Symbol[];
              resolvedReturnType: Type;
              minArgumentCount: number;
              hasRestParameter: boolean;
              hasStringLiterals: boolean;
              target?: Signature;
              mapper?: TypeMapper;
              unionSignatures?: Signature[];
              erasedSignatureCache?: Signature;
              isolatedSignatureType?: ObjectType;
          }
          const enum IndexKind {
              String = 0,
              Number = 1,
          }
          interface TypeMapper {
              (t: Type): Type;
          }
          interface TypeInferences {
              primary: Type[];
              secondary: Type[];
          }
          interface InferenceContext {
              typeParameters: TypeParameter[];
              inferUnionTypes: boolean;
              inferences: TypeInferences[];
              inferredTypes: Type[];
              failedTypeParameterIndex?: number;
          }
          interface DiagnosticMessage {
              key: string;
              category: DiagnosticCategory;
              code: number;
              isEarly?: boolean;
          }
          interface DiagnosticMessageChain {
              messageText: string;
              category: DiagnosticCategory;
              code: number;
              next?: DiagnosticMessageChain;
          }
          interface Diagnostic {
              file: SourceFile;
              start: number;
              length: number;
              messageText: string;
              category: DiagnosticCategory;
              code: number;
              isEarly?: boolean;
              isParseError?: boolean;
          }
          enum DiagnosticCategory {
              Warning = 0,
              Error = 1,
              Message = 2,
          }
          interface CompilerOptions {
              charset?: string;
              codepage?: number;
              declaration?: boolean;
              diagnostics?: boolean;
              emitBOM?: boolean;
              help?: boolean;
              locale?: string;
              mapRoot?: string;
              module?: ModuleKind;
              noEmitOnError?: boolean;
              noErrorTruncation?: boolean;
              noImplicitAny?: boolean;
              noLib?: boolean;
              noLibCheck?: boolean;
              noResolve?: boolean;
              out?: string;
              outDir?: string;
              removeComments?: boolean;
              sourceMap?: boolean;
              sourceRoot?: string;
              target?: ScriptTarget;
              version?: boolean;
              watch?: boolean;
              preserveConstEnums?: boolean;
              [option: string]: string | number | boolean;
          }
          const enum ModuleKind {
              None = 0,
              CommonJS = 1,
              AMD = 2,
          }
          interface LineAndCharacter {
              line: number;
              character: number;
          }
          const enum ScriptTarget {
              ES3 = 0,
              ES5 = 1,
              ES6 = 2,
              Latest = 2,
          }
          interface ParsedCommandLine {
              options: CompilerOptions;
              filenames: string[];
              errors: Diagnostic[];
          }
          interface CommandLineOption {
              name: string;
              type: string | Map<number>;
              shortName?: string;
              description?: DiagnosticMessage;
              paramName?: DiagnosticMessage;
              error?: DiagnosticMessage;
          }
          const enum CharacterCodes {
              nullCharacter = 0,
              maxAsciiCharacter = 127,
              lineFeed = 10,
              carriageReturn = 13,
              lineSeparator = 8232,
              paragraphSeparator = 8233,
              nextLine = 133,
              space = 32,
              nonBreakingSpace = 160,
              enQuad = 8192,
              emQuad = 8193,
              enSpace = 8194,
              emSpace = 8195,
              threePerEmSpace = 8196,
              fourPerEmSpace = 8197,
              sixPerEmSpace = 8198,
              figureSpace = 8199,
              punctuationSpace = 8200,
              thinSpace = 8201,
              hairSpace = 8202,
              zeroWidthSpace = 8203,
              narrowNoBreakSpace = 8239,
              ideographicSpace = 12288,
              mathematicalSpace = 8287,
              ogham = 5760,
              _ = 95,
              $ = 36,
              _0 = 48,
              _1 = 49,
              _2 = 50,
              _3 = 51,
              _4 = 52,
              _5 = 53,
              _6 = 54,
              _7 = 55,
              _8 = 56,
              _9 = 57,
              a = 97,
              b = 98,
              c = 99,
              d = 100,
              e = 101,
              f = 102,
              g = 103,
              h = 104,
              i = 105,
              j = 106,
              k = 107,
              l = 108,
              m = 109,
              n = 110,
              o = 111,
              p = 112,
              q = 113,
              r = 114,
              s = 115,
              t = 116,
              u = 117,
              v = 118,
              w = 119,
              x = 120,
              y = 121,
              z = 122,
              A = 65,
              B = 66,
              C = 67,
              D = 68,
              E = 69,
              F = 70,
              G = 71,
              H = 72,
              I = 73,
              J = 74,
              K = 75,
              L = 76,
              M = 77,
              N = 78,
              O = 79,
              P = 80,
              Q = 81,
              R = 82,
              S = 83,
              T = 84,
              U = 85,
              V = 86,
              W = 87,
              X = 88,
              Y = 89,
              Z = 90,
              ampersand = 38,
              asterisk = 42,
              at = 64,
              backslash = 92,
              backtick = 96,
              bar = 124,
              caret = 94,
              closeBrace = 125,
              closeBracket = 93,
              closeParen = 41,
              colon = 58,
              comma = 44,
              dot = 46,
              doubleQuote = 34,
              equals = 61,
              exclamation = 33,
              greaterThan = 62,
              lessThan = 60,
              minus = 45,
              openBrace = 123,
              openBracket = 91,
              openParen = 40,
              percent = 37,
              plus = 43,
              question = 63,
              semicolon = 59,
              singleQuote = 39,
              slash = 47,
              tilde = 126,
              backspace = 8,
              formFeed = 12,
              byteOrderMark = 65279,
              tab = 9,
              verticalTab = 11,
          }
          interface CancellationToken {
              isCancellationRequested(): boolean;
          }
          interface CompilerHost {
              getSourceFile(filename: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile;
              getDefaultLibFilename(): string;
              getCancellationToken?(): CancellationToken;
              writeFile(filename: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void): void;
              getCurrentDirectory(): string;
              getCanonicalFileName(fileName: string): string;
              useCaseSensitiveFileNames(): boolean;
              getNewLine(): string;
          }
      }
      declare module ts {
          const enum Ternary {
              False = 0,
              Maybe = 1,
              True = -1,
          }
          interface Map<T> {
              [index: string]: T;
          }
          const enum Comparison {
              LessThan = -1,
              EqualTo = 0,
              GreaterThan = 1,
          }
          interface StringSet extends Map<any> {
          }
          function forEach<T, U>(array: T[], callback: (element: T) => U): U;
          function contains<T>(array: T[], value: T): boolean;
          function indexOf<T>(array: T[], value: T): number;
          function countWhere<T>(array: T[], predicate: (x: T) => boolean): number;
          function filter<T>(array: T[], f: (x: T) => boolean): T[];
          function map<T, U>(array: T[], f: (x: T) => U): U[];
          function concatenate<T>(array1: T[], array2: T[]): T[];
          function deduplicate<T>(array: T[]): T[];
          function sum(array: any[], prop: string): number;
          function lastOrUndefined<T>(array: T[]): T;
          function binarySearch(array: number[], value: number): number;
          function hasProperty<T>(map: Map<T>, key: string): boolean;
          function getProperty<T>(map: Map<T>, key: string): T;
          function isEmpty<T>(map: Map<T>): boolean;
          function clone<T>(object: T): T;
          function forEachValue<T, U>(map: Map<T>, callback: (value: T) => U): U;
          function forEachKey<T, U>(map: Map<T>, callback: (key: string) => U): U;
          function lookUp<T>(map: Map<T>, key: string): T;
          function mapToArray<T>(map: Map<T>): T[];
          function arrayToMap<T>(array: T[], makeKey: (value: T) => string): Map<T>;
          var localizedDiagnosticMessages: Map<string>;
          function getLocaleSpecificMessage(message: string): string;
          function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic;
          function createCompilerDiagnostic(message: DiagnosticMessage, ...args: any[]): Diagnostic;
          function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain;
          function concatenateDiagnosticMessageChains(headChain: DiagnosticMessageChain, tailChain: DiagnosticMessageChain): DiagnosticMessageChain;
          function flattenDiagnosticChain(file: SourceFile, start: number, length: number, diagnosticChain: DiagnosticMessageChain, newLine: string): Diagnostic;
          function compareValues<T>(a: T, b: T): Comparison;
          function compareDiagnostics(d1: Diagnostic, d2: Diagnostic): number;
          function deduplicateSortedDiagnostics(diagnostics: Diagnostic[]): Diagnostic[];
          function normalizeSlashes(path: string): string;
          function getRootLength(path: string): number;
          var directorySeparator: string;
          function normalizePath(path: string): string;
          function getDirectoryPath(path: string): string;
          function isUrl(path: string): boolean;
          function isRootedDiskPath(path: string): boolean;
          function getNormalizedPathComponents(path: string, currentDirectory: string): string[];
          function getNormalizedAbsolutePath(filename: string, currentDirectory: string): string;
          function getNormalizedPathFromPathComponents(pathComponents: string[]): string;
          function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, getCanonicalFileName: (fileName: string) => string, isAbsolutePathAnUrl: boolean): string;
          function getBaseFilename(path: string): string;
          function combinePaths(path1: string, path2: string): string;
          function fileExtensionIs(path: string, extension: string): boolean;
          function removeFileExtension(path: string): string;
          function escapeString(s: string): string;
          interface ObjectAllocator {
              getNodeConstructor(kind: SyntaxKind): new () => Node;
              getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
              getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
              getSignatureConstructor(): new (checker: TypeChecker) => Signature;
          }
          var objectAllocator: ObjectAllocator;
          const enum AssertionLevel {
              None = 0,
              Normal = 1,
              Aggressive = 2,
              VeryAggressive = 3,
          }
          module Debug {
              function shouldAssert(level: AssertionLevel): boolean;
              function assert(expression: boolean, message?: string, verboseDebugInfo?: () => string): void;
              function fail(message?: string): void;
          }
      }
      declare module ts {
          var Diagnostics: {
              Unterminated_string_literal: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Identifier_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_file_cannot_have_a_reference_to_itself: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Trailing_comma_not_allowed: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Asterisk_Slash_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Unexpected_token: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Catch_clause_parameter_cannot_have_a_type_annotation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_rest_parameter_must_be_last_in_a_parameter_list: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_cannot_have_question_mark_and_initializer: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_required_parameter_cannot_follow_an_optional_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_index_signature_cannot_have_a_rest_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_index_signature_parameter_cannot_have_an_accessibility_modifier: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_index_signature_parameter_cannot_have_a_question_mark: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_index_signature_parameter_cannot_have_an_initializer: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_index_signature_must_have_a_type_annotation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_index_signature_parameter_must_have_a_type_annotation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_index_signature_parameter_type_must_be_string_or_number: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_class_or_interface_declaration_can_only_have_one_extends_clause: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_extends_clause_must_precede_an_implements_clause: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_class_can_only_extend_a_single_class: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_class_declaration_can_only_have_one_implements_clause: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Accessibility_modifier_already_seen: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_modifier_must_precede_1_modifier: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_modifier_already_seen: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_modifier_cannot_appear_on_a_class_element: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_interface_declaration_cannot_have_an_implements_clause: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              super_must_be_followed_by_an_argument_list_or_member_access: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Only_ambient_modules_can_use_quoted_names: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Statements_are_not_allowed_in_ambient_contexts: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_function_implementation_cannot_be_declared_in_an_ambient_context: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_declare_modifier_cannot_be_used_in_an_already_ambient_context: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Initializers_are_not_allowed_in_ambient_contexts: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_modifier_cannot_appear_on_a_module_element: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_declare_modifier_cannot_be_used_with_an_interface_declaration: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_rest_parameter_cannot_be_optional: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_rest_parameter_cannot_have_an_initializer: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_set_accessor_must_have_exactly_one_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_set_accessor_cannot_have_an_optional_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_set_accessor_parameter_cannot_have_an_initializer: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_set_accessor_cannot_have_rest_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_get_accessor_cannot_have_parameters: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Enum_member_must_have_initializer: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_export_assignment_cannot_be_used_in_an_internal_module: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Ambient_enum_elements_can_only_have_integer_literal_initializers: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Unexpected_token_A_constructor_method_accessor_or_property_was_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_declare_modifier_cannot_be_used_with_an_import_declaration: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Invalid_reference_directive_syntax: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_accessor_cannot_be_declared_in_an_ambient_context: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_modifier_cannot_appear_on_a_constructor_declaration: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_modifier_cannot_appear_on_a_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameters_cannot_appear_on_a_constructor_declaration: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_annotation_cannot_appear_on_a_constructor_declaration: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_accessor_cannot_have_type_parameters: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_set_accessor_cannot_have_a_return_type_annotation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_index_signature_must_have_exactly_one_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_list_cannot_be_empty: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_list_cannot_be_empty: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_argument_list_cannot_be_empty: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Invalid_use_of_0_in_strict_mode: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              with_statements_are_not_allowed_in_strict_mode: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              delete_cannot_be_called_on_an_identifier_in_strict_mode: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Jump_target_cannot_cross_function_boundary: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_return_statement_can_only_be_used_within_a_function_body: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Expression_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_constructor_implementation_cannot_be_declared_in_an_ambient_context: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_class_member_cannot_be_declared_optional: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Duplicate_label_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_object_literal_cannot_have_property_and_accessor_with_the_same_name: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_export_assignment_cannot_have_modifiers: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Octal_literals_are_not_allowed_in_strict_mode: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_tuple_type_element_list_cannot_be_empty: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Variable_declaration_list_cannot_be_empty: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Digit_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Hexadecimal_digit_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Unexpected_end_of_text: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Invalid_character: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Declaration_or_statement_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Statement_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              case_or_default_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_or_signature_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Enum_member_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_reference_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Variable_declaration_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Argument_expression_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_assignment_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Expression_or_comma_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_declaration_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_declaration_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_argument_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              String_literal_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Line_break_not_permitted_here: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              catch_or_finally_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Block_or_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Modifiers_not_permitted_on_index_signature_members: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Declaration_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Import_declarations_in_an_internal_module_cannot_reference_an_external_module: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Cannot_compile_external_modules_unless_the_module_flag_is_provided: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Filename_0_differs_from_already_included_filename_1_only_in_casing: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              var_let_or_const_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              const_declarations_must_be_initialized: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              const_declarations_can_only_be_declared_inside_a_block: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              let_declarations_can_only_be_declared_inside_a_block: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Invalid_template_literal_expected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Unterminated_template_literal: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Unterminated_regular_expression_literal: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_object_member_cannot_be_declared_optional: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              yield_expression_must_be_contained_within_a_generator_declaration: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Computed_property_names_are_not_allowed_in_enums: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Computed_property_names_are_not_allowed_in_an_ambient_context: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Computed_property_names_are_not_allowed_in_class_property_declarations: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Computed_property_names_are_only_available_when_targeting_ECMAScript_6_and_higher: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Computed_property_names_are_not_allowed_in_method_overloads: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Computed_property_names_are_not_allowed_in_interfaces: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Computed_property_names_are_not_allowed_in_type_literals: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_comma_expression_is_not_allowed_in_a_computed_property_name: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Duplicate_identifier_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Static_members_cannot_reference_class_type_parameters: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Circular_definition_of_import_alias_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Cannot_find_name_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Module_0_has_no_exported_member_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              File_0_is_not_an_external_module: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Cannot_find_external_module_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_module_cannot_have_more_than_one_export_assignment: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_0_recursively_references_itself_as_a_base_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_class_may_only_extend_another_class: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_interface_may_only_extend_a_class_or_another_interface: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Constraint_of_a_type_parameter_cannot_reference_any_type_parameter_from_the_same_type_parameter_list: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Generic_type_0_requires_1_type_argument_s: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_0_is_not_generic: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Global_type_0_must_be_a_class_or_interface_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Global_type_0_must_have_1_type_parameter_s: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Cannot_find_global_type_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Named_properties_0_of_types_1_and_2_are_not_identical: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Interface_0_cannot_simultaneously_extend_types_1_and_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Excessive_stack_depth_comparing_types_0_and_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_0_is_not_assignable_to_type_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_is_missing_in_type_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_is_private_in_type_1_but_not_in_type_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Types_of_property_0_are_incompatible: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_is_optional_in_type_1_but_required_in_type_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Types_of_parameters_0_and_1_are_incompatible: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Index_signature_is_missing_in_type_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Index_signatures_are_incompatible: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              this_cannot_be_referenced_in_a_module_body: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              this_cannot_be_referenced_in_current_location: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              this_cannot_be_referenced_in_constructor_arguments: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              this_cannot_be_referenced_in_a_static_property_initializer: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              super_can_only_be_referenced_in_a_derived_class: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              super_cannot_be_referenced_in_constructor_arguments: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_does_not_exist_on_type_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_is_private_and_only_accessible_within_class_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_index_expression_argument_must_be_of_type_string_number_or_any: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_0_does_not_satisfy_the_constraint_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Supplied_parameters_do_not_match_any_signature_of_call_target: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Untyped_function_calls_may_not_accept_type_arguments: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Cannot_invoke_an_expression_whose_type_lacks_a_call_signature: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Only_a_void_function_can_be_called_with_the_new_keyword: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Neither_type_0_nor_type_1_is_assignable_to_the_other: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              No_best_common_type_exists_among_return_expressions: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_or_consist_of_a_single_throw_statement: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Invalid_left_hand_side_of_assignment_expression: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Operator_0_cannot_be_applied_to_types_1_and_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_name_cannot_be_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_parameter_property_is_only_allowed_in_a_constructor_implementation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_rest_parameter_must_be_of_an_array_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_cannot_be_referenced_in_its_initializer: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Duplicate_string_index_signature: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Duplicate_number_index_signature: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Constructors_for_derived_classes_must_contain_a_super_call: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_get_accessor_must_return_a_value_or_consist_of_a_single_throw_statement: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Getter_and_setter_accessors_do_not_agree_in_visibility: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              get_and_set_accessor_must_have_the_same_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_signature_with_an_implementation_cannot_use_a_string_literal_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Overload_signatures_must_all_be_exported_or_not_exported: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Overload_signatures_must_all_be_ambient_or_non_ambient: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Overload_signatures_must_all_be_public_private_or_protected: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Overload_signatures_must_all_be_optional_or_required: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Function_overload_must_be_static: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Function_overload_must_not_be_static: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Function_implementation_name_must_be_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Constructor_implementation_is_missing: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Function_implementation_is_missing_or_not_immediately_following_the_declaration: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Multiple_constructor_implementations_are_not_allowed: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Duplicate_function_implementation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Overload_signature_is_not_compatible_with_function_implementation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Duplicate_identifier_i_Compiler_uses_i_to_initialize_rest_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Expression_resolves_to_variable_declaration_i_that_compiler_uses_to_initialize_rest_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Invalid_left_hand_side_in_for_in_statement: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Setters_cannot_return_a_value: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              All_symbols_within_a_with_block_will_be_resolved_to_any: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_of_type_1_is_not_assignable_to_string_index_type_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Numeric_index_type_0_is_not_assignable_to_string_index_type_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Class_name_cannot_be_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Class_0_incorrectly_extends_base_class_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Class_static_side_0_incorrectly_extends_base_class_static_side_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_name_0_in_extends_clause_does_not_reference_constructor_function_for_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Class_0_incorrectly_implements_interface_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_class_may_only_implement_another_class_or_interface: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Interface_name_cannot_be_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              All_declarations_of_an_interface_must_have_identical_type_parameters: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Interface_0_incorrectly_extends_interface_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Enum_name_cannot_be_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_module_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              A_module_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Ambient_external_modules_cannot_be_nested_in_other_modules: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Ambient_external_module_declaration_cannot_specify_relative_module_name: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Module_0_is_hidden_by_a_local_declaration_with_the_same_name: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Import_name_cannot_be_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Import_declaration_in_an_ambient_external_module_declaration_cannot_reference_external_module_through_relative_external_module_name: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Import_declaration_conflicts_with_local_declaration_of_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_an_external_module: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Types_have_separate_declarations_of_a_private_property_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_is_protected_in_type_1_but_public_in_type_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Block_scoped_variable_0_used_before_its_declaration: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
                  isEarly: boolean;
              };
              The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
                  isEarly: boolean;
              };
              Left_hand_side_of_assignment_expression_cannot_be_a_constant: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
                  isEarly: boolean;
              };
              Cannot_redeclare_block_scoped_variable_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
                  isEarly: boolean;
              };
              An_enum_member_cannot_have_a_numeric_name: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_alias_0_circularly_references_itself: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_alias_name_cannot_be_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              An_AMD_module_cannot_have_multiple_name_assignments: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Import_declaration_0_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Type_parameter_0_of_exported_function_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Implements_clause_of_exported_class_0_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Extends_clause_of_exported_class_0_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Extends_clause_of_exported_interface_0_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Exported_variable_0_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Exported_variable_0_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Public_static_property_0_of_exported_class_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Public_property_0_of_exported_class_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_of_exported_interface_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_public_static_property_setter_from_exported_class_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_public_property_setter_from_exported_class_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_static_property_getter_from_exported_class_has_or_is_using_private_name_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_property_getter_from_exported_class_has_or_is_using_name_0_from_private_module_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_property_getter_from_exported_class_has_or_is_using_private_name_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Return_type_of_exported_function_has_or_is_using_private_name_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_of_exported_function_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Exported_type_alias_0_has_or_is_using_private_name_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Enum_declarations_must_all_be_const_or_non_const: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              In_const_enum_declarations_member_initializer_must_be_constant_expression: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
                  isEarly: boolean;
              };
              const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Index_expression_arguments_in_const_enums_must_be_of_type_string: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              const_enum_member_initializer_was_evaluated_to_a_non_finite_value: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              The_current_host_does_not_support_the_0_option: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Cannot_find_the_common_subdirectory_path_for_the_input_files: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Cannot_read_file_0_Colon_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Unsupported_file_encoding: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Unknown_compiler_option_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Could_not_write_file_0_Colon_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Concatenate_and_emit_output_to_single_file: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Generates_corresponding_d_ts_file: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Watch_input_files: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Redirect_output_structure_to_the_directory: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Do_not_erase_const_enum_declarations_in_generated_code: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Do_not_emit_outputs_if_any_type_checking_errors_were_reported: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Do_not_emit_comments_to_output: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES6_experimental: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Specify_module_code_generation_Colon_commonjs_or_amd: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Print_this_message: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Print_the_compiler_s_version: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Syntax_Colon_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              options: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              file: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Examples_Colon_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Options_Colon: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Version_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Insert_command_line_options_and_files_from_a_file: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              File_change_detected_Compiling: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              KIND: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              FILE: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              VERSION: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              LOCATION: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              DIRECTORY: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Compilation_complete_Watching_for_file_changes: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Generates_corresponding_map_file: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Compiler_option_0_expects_an_argument: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Unterminated_quoted_string_in_response_file_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Argument_for_module_option_must_be_commonjs_or_amd: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Argument_for_target_option_must_be_es3_es5_or_es6: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Unsupported_locale_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Unable_to_open_file_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Corrupted_locale_file_0: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Warn_on_expressions_and_declarations_with_an_implied_any_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              File_0_not_found: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              File_0_must_have_extension_ts_or_d_ts: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Variable_0_implicitly_has_an_1_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Parameter_0_implicitly_has_an_1_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Member_0_implicitly_has_an_1_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_type_annotation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Index_signature_of_object_type_implicitly_has_an_any_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Object_literal_s_property_0_implicitly_has_an_1_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Rest_parameter_0_implicitly_has_an_any_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_implicitly_has_type_any_because_it_is_referenced_directly_or_indirectly_in_its_own_type_annotation: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              You_cannot_rename_this_element: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              yield_expressions_are_not_currently_supported: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
              generators_are_not_currently_supported: {
                  code: number;
                  category: DiagnosticCategory;
                  key: string;
              };
          };
      }
      declare module ts {
          interface ErrorCallback {
              (message: DiagnosticMessage): void;
          }
          interface CommentCallback {
              (pos: number, end: number): void;
          }
          interface Scanner {
              getStartPos(): number;
              getToken(): SyntaxKind;
              getTextPos(): number;
              getTokenPos(): number;
              getTokenText(): string;
              getTokenValue(): string;
              hasPrecedingLineBreak(): boolean;
              isIdentifier(): boolean;
              isReservedWord(): boolean;
              reScanGreaterToken(): SyntaxKind;
              reScanSlashToken(): SyntaxKind;
              reScanTemplateToken(): SyntaxKind;
              scan(): SyntaxKind;
              setText(text: string): void;
              setTextPos(textPos: number): void;
              tryScan<T>(callback: () => T): T;
          }
          function tokenToString(t: SyntaxKind): string;
          function computeLineStarts(text: string): number[];
          function getPositionFromLineAndCharacter(lineStarts: number[], line: number, character: number): number;
          function getLineAndCharacterOfPosition(lineStarts: number[], position: number): {
              line: number;
              character: number;
          };
          function positionToLineAndCharacter(text: string, pos: number): {
              line: number;
              character: number;
          };
          function isWhiteSpace(ch: number): boolean;
          function isLineBreak(ch: number): boolean;
          function isOctalDigit(ch: number): boolean;
          function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean): number;
          function getLeadingCommentRanges(text: string, pos: number): CommentRange[];
          function getTrailingCommentRanges(text: string, pos: number): CommentRange[];
          function isIdentifierStart(ch: number, languageVersion: ScriptTarget): boolean;
          function isIdentifierPart(ch: number, languageVersion: ScriptTarget): boolean;
          function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, text?: string, onError?: ErrorCallback, onComment?: CommentCallback): Scanner;
      }
      declare module ts {
          function getNodeConstructor(kind: SyntaxKind): new () => Node;
          function getSourceFileOfNode(node: Node): SourceFile;
          function nodePosToString(node: Node): string;
          function getStartPosOfNode(node: Node): number;
          function getTokenPosOfNode(node: Node, sourceFile?: SourceFile): number;
          function getSourceTextOfNodeFromSourceFile(sourceFile: SourceFile, node: Node): string;
          function getTextOfNodeFromSourceText(sourceText: string, node: Node): string;
          function getTextOfNode(node: Node): string;
          function escapeIdentifier(identifier: string): string;
          function unescapeIdentifier(identifier: string): string;
          function declarationNameToString(name: DeclarationName): string;
          function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic;
          function createDiagnosticForNodeFromMessageChain(node: Node, messageChain: DiagnosticMessageChain, newLine: string): Diagnostic;
          function getErrorSpanForNode(node: Node): Node;
          function isExternalModule(file: SourceFile): boolean;
          function isDeclarationFile(file: SourceFile): boolean;
          function isConstEnumDeclaration(node: Declaration): boolean;
          function isConst(node: Declaration): boolean;
          function isLet(node: Declaration): boolean;
          function isPrologueDirective(node: Node): boolean;
          function getLeadingCommentRangesOfNode(node: Node, sourceFileOfNode?: SourceFile): CommentRange[];
          function getJsDocComments(node: Declaration, sourceFileOfNode: SourceFile): CommentRange[];
          var fullTripleSlashReferencePathRegEx: RegExp;
          function forEachChild<T>(node: Node, cbNode: (node: Node) => T, cbNodes?: (nodes: Node[]) => T): T;
          function forEachReturnStatement<T>(body: Block, visitor: (stmt: ReturnStatement) => T): T;
          function isAnyFunction(node: Node): boolean;
          function getContainingFunction(node: Node): SignatureDeclaration;
          function getThisContainer(node: Node, includeArrowFunctions: boolean): Node;
          function getSuperContainer(node: Node): Node;
          function getInvokedExpression(node: CallLikeExpression): Expression;
          function isExpression(node: Node): boolean;
          function hasRestParameters(s: SignatureDeclaration): boolean;
          function isLiteralKind(kind: SyntaxKind): boolean;
          function isTextualLiteralKind(kind: SyntaxKind): boolean;
          function isTemplateLiteralKind(kind: SyntaxKind): boolean;
          function isInAmbientContext(node: Node): boolean;
          function isDeclaration(node: Node): boolean;
          function isStatement(n: Node): boolean;
          function isDeclarationOrFunctionExpressionOrCatchVariableName(name: Node): boolean;
          function tryResolveScriptReference(program: Program, sourceFile: SourceFile, reference: FileReference): SourceFile;
          function getAncestor(node: Node, kind: SyntaxKind): Node;
          interface ReferencePathMatchResult {
              fileReference?: FileReference;
              diagnostic?: DiagnosticMessage;
              isNoDefaultLib?: boolean;
          }
          function getFileReferenceFromReferencePath(comment: string, commentRange: CommentRange): ReferencePathMatchResult;
          function isKeyword(token: SyntaxKind): boolean;
          function isTrivia(token: SyntaxKind): boolean;
          function isUnterminatedTemplateEnd(node: LiteralExpression): boolean;
          function isModifier(token: SyntaxKind): boolean;
          function createSourceFile(filename: string, sourceText: string, languageVersion: ScriptTarget, version: string, isOpen?: boolean): SourceFile;
          function createProgram(rootNames: string[], options: CompilerOptions, host: CompilerHost): Program;
      }
      declare module ts {
          const enum ModuleInstanceState {
              NonInstantiated = 0,
              Instantiated = 1,
              ConstEnumOnly = 2,
          }
          function getModuleInstanceState(node: Node): ModuleInstanceState;
          function hasComputedNameButNotSymbol(declaration: Declaration): boolean;
          function bindSourceFile(file: SourceFile): void;
      }
      declare module ts {
          function getIndentString(level: number): string;
          function shouldEmitToOwnFile(sourceFile: SourceFile, compilerOptions: CompilerOptions): boolean;
          function isExternalModuleOrDeclarationFile(sourceFile: SourceFile): boolean;
          function getDeclarationDiagnostics(program: Program, resolver: EmitResolver, targetSourceFile: SourceFile): Diagnostic[];
          function emitFiles(resolver: EmitResolver, targetSourceFile?: SourceFile): EmitResult;
      }
      declare module ts {
          function getDeclarationOfKind(symbol: Symbol, kind: SyntaxKind): Declaration;
          interface StringSymbolWriter extends SymbolWriter {
              string(): string;
          }
          function getSingleLineStringWriter(): StringSymbolWriter;
          function createTypeChecker(program: Program, fullTypeCheck: boolean): TypeChecker;
      }
      declare module ts {
          class TextSpan {
              private _start;
              private _length;
              constructor(start: number, length: number);
              toJSON(key: any): any;
              start(): number;
              length(): number;
              end(): number;
              isEmpty(): boolean;
              containsPosition(position: number): boolean;
              containsTextSpan(span: TextSpan): boolean;
              overlapsWith(span: TextSpan): boolean;
              overlap(span: TextSpan): TextSpan;
              intersectsWithTextSpan(span: TextSpan): boolean;
              intersectsWith(start: number, length: number): boolean;
              intersectsWithPosition(position: number): boolean;
              intersection(span: TextSpan): TextSpan;
              static fromBounds(start: number, end: number): TextSpan;
          }
          class TextChangeRange {
              static unchanged: TextChangeRange;
              private _span;
              private _newLength;
              constructor(span: TextSpan, newLength: number);
              span(): TextSpan;
              newLength(): number;
              newSpan(): TextSpan;
              isUnchanged(): boolean;
              static collapseChangesAcrossMultipleVersions(changes: TextChangeRange[]): TextChangeRange;
          }
      }
      declare module ts {
          interface OutliningSpan {
              textSpan: TextSpan;
              hintSpan: TextSpan;
              bannerText: string;
              autoCollapse: boolean;
          }
          module OutliningElementsCollector {
              function collectElements(sourceFile: SourceFile): OutliningSpan[];
          }
      }
      declare module ts.NavigationBar {
          function getNavigationBarItems(sourceFile: SourceFile): ts.NavigationBarItem[];
      }
      declare module ts.SignatureHelp {
          function getSignatureHelpItems(sourceFile: SourceFile, position: number, typeInfoResolver: TypeChecker, cancellationToken: CancellationTokenObject): SignatureHelpItems;
      }
      declare module ts {
          interface ListItemInfo {
              listItemIndex: number;
              list: Node;
          }
          function getEndLinePosition(line: number, sourceFile: SourceFile): number;
          function getStartPositionOfLine(line: number, sourceFile: SourceFile): number;
          function getStartLinePositionForPosition(position: number, sourceFile: SourceFile): number;
          function rangeContainsRange(r1: TextRange, r2: TextRange): boolean;
          function startEndContainsRange(start: number, end: number, range: TextRange): boolean;
          function rangeContainsStartEnd(range: TextRange, start: number, end: number): boolean;
          function rangeOverlapsWithStartEnd(r1: TextRange, start: number, end: number): boolean;
          function startEndOverlapsWithStartEnd(start1: number, end1: number, start2: number, end2: number): boolean;
          function findListItemInfo(node: Node): ListItemInfo;
          function findChildOfKind(n: Node, kind: SyntaxKind, sourceFile?: SourceFile): Node;
          function findContainingList(node: Node): Node;
          function findListItemIndexContainingPosition(list: Node, position: number): number;
          function getTouchingWord(sourceFile: SourceFile, position: number): Node;
          function getTouchingPropertyName(sourceFile: SourceFile, position: number): Node;
          function getTouchingToken(sourceFile: SourceFile, position: number, includeItemAtEndPosition?: (n: Node) => boolean): Node;
          function getTokenAtPosition(sourceFile: SourceFile, position: number): Node;
          function findTokenOnLeftOfPosition(file: SourceFile, position: number): Node;
          function findNextToken(previousToken: Node, parent: Node): Node;
          function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node): Node;
          function getTypeArgumentOrTypeParameterList(node: Node): NodeArray<Node>;
          function isToken(n: Node): boolean;
          function isComment(kind: SyntaxKind): boolean;
          function isPunctuation(kind: SyntaxKind): boolean;
          function isInsideTemplateLiteral(node: LiteralExpression, position: number): boolean;
      }
      declare module ts.formatting {
          module SmartIndenter {
              function getIndentation(position: number, sourceFile: SourceFile, options: EditorOptions): number;
              function getIndentationForNode(n: Node, ignoreActualIndentationRange: TextRange, sourceFile: SourceFile, options: FormatCodeOptions): number;
              function childStartsOnTheSameLineWithElseInIfStatement(parent: Node, child: TextRangeWithKind, childStartLine: number, sourceFile: SourceFile): boolean;
              function findFirstNonWhitespaceColumn(startPos: number, endPos: number, sourceFile: SourceFile, options: EditorOptions): number;
              function shouldIndentChildNode(parent: SyntaxKind, child: SyntaxKind): boolean;
          }
      }
      declare module ts.formatting {
          function getIndentationString(indentation: number, options: FormatCodeOptions): string;
      }
      declare module ts.formatting {
          interface FormattingScanner {
              advance(): void;
              isOnToken(): boolean;
              readTokenInfo(n: Node): TokenInfo;
              lastTrailingTriviaWasNewLine(): boolean;
              close(): void;
          }
          function getFormattingScanner(sourceFile: SourceFile, startPos: number, endPos: number): FormattingScanner;
      }
      declare module ts.formatting {
          class FormattingContext {
              private sourceFile;
              formattingRequestKind: FormattingRequestKind;
              currentTokenSpan: TextRangeWithKind;
              nextTokenSpan: TextRangeWithKind;
              contextNode: Node;
              currentTokenParent: Node;
              nextTokenParent: Node;
              private contextNodeAllOnSameLine;
              private nextNodeAllOnSameLine;
              private tokensAreOnSameLine;
              private contextNodeBlockIsOnOneLine;
              private nextNodeBlockIsOnOneLine;
              constructor(sourceFile: SourceFile, formattingRequestKind: FormattingRequestKind);
              updateContext(currentRange: TextRangeWithKind, currentTokenParent: Node, nextRange: TextRangeWithKind, nextTokenParent: Node, commonParent: Node): void;
              ContextNodeAllOnSameLine(): boolean;
              NextNodeAllOnSameLine(): boolean;
              TokensAreOnSameLine(): boolean;
              ContextNodeBlockIsOnOneLine(): boolean;
              NextNodeBlockIsOnOneLine(): boolean;
              private NodeIsOnOneLine(node);
              private BlockIsOnOneLine(node);
          }
      }
      declare module ts.formatting {
          const enum FormattingRequestKind {
              FormatDocument = 0,
              FormatSelection = 1,
              FormatOnEnter = 2,
              FormatOnSemicolon = 3,
              FormatOnClosingCurlyBrace = 4,
          }
      }
      declare module ts.formatting {
          class Rule {
              Descriptor: RuleDescriptor;
              Operation: RuleOperation;
              Flag: RuleFlags;
              constructor(Descriptor: RuleDescriptor, Operation: RuleOperation, Flag?: RuleFlags);
              toString(): string;
          }
      }
      declare module ts.formatting {
          const enum RuleAction {
              Ignore = 1,
              Space = 2,
              NewLine = 4,
              Delete = 8,
          }
      }
      declare module ts.formatting {
          class RuleDescriptor {
              LeftTokenRange: Shared.TokenRange;
              RightTokenRange: Shared.TokenRange;
              constructor(LeftTokenRange: Shared.TokenRange, RightTokenRange: Shared.TokenRange);
              toString(): string;
              static create1(left: SyntaxKind, right: SyntaxKind): RuleDescriptor;
              static create2(left: Shared.TokenRange, right: SyntaxKind): RuleDescriptor;
              static create3(left: SyntaxKind, right: Shared.TokenRange): RuleDescriptor;
              static create4(left: Shared.TokenRange, right: Shared.TokenRange): RuleDescriptor;
          }
      }
      declare module ts.formatting {
          const enum RuleFlags {
              None = 0,
              CanDeleteNewLines = 1,
          }
      }
      declare module ts.formatting {
          class RuleOperation {
              Context: RuleOperationContext;
              Action: RuleAction;
              constructor();
              toString(): string;
              static create1(action: RuleAction): RuleOperation;
              static create2(context: RuleOperationContext, action: RuleAction): RuleOperation;
          }
      }
      declare module ts.formatting {
          class RuleOperationContext {
              private customContextChecks;
              constructor(...funcs: {
                  (context: FormattingContext): boolean;
              }[]);
              static Any: RuleOperationContext;
              IsAny(): boolean;
              InContext(context: FormattingContext): boolean;
          }
      }
      declare module ts.formatting {
          class Rules {
              getRuleName(rule: Rule): any;
              [name: string]: any;
              IgnoreBeforeComment: Rule;
              IgnoreAfterLineComment: Rule;
              NoSpaceBeforeSemicolon: Rule;
              NoSpaceBeforeColon: Rule;
              NoSpaceBeforeQMark: Rule;
              SpaceAfterColon: Rule;
              SpaceAfterQMark: Rule;
              SpaceAfterSemicolon: Rule;
              SpaceAfterCloseBrace: Rule;
              SpaceBetweenCloseBraceAndElse: Rule;
              SpaceBetweenCloseBraceAndWhile: Rule;
              NoSpaceAfterCloseBrace: Rule;
              NoSpaceBeforeDot: Rule;
              NoSpaceAfterDot: Rule;
              NoSpaceBeforeOpenBracket: Rule;
              NoSpaceAfterOpenBracket: Rule;
              NoSpaceBeforeCloseBracket: Rule;
              NoSpaceAfterCloseBracket: Rule;
              SpaceAfterOpenBrace: Rule;
              SpaceBeforeCloseBrace: Rule;
              NoSpaceBetweenEmptyBraceBrackets: Rule;
              NewLineAfterOpenBraceInBlockContext: Rule;
              NewLineBeforeCloseBraceInBlockContext: Rule;
              NoSpaceAfterUnaryPrefixOperator: Rule;
              NoSpaceAfterUnaryPreincrementOperator: Rule;
              NoSpaceAfterUnaryPredecrementOperator: Rule;
              NoSpaceBeforeUnaryPostincrementOperator: Rule;
              NoSpaceBeforeUnaryPostdecrementOperator: Rule;
              SpaceAfterPostincrementWhenFollowedByAdd: Rule;
              SpaceAfterAddWhenFollowedByUnaryPlus: Rule;
              SpaceAfterAddWhenFollowedByPreincrement: Rule;
              SpaceAfterPostdecrementWhenFollowedBySubtract: Rule;
              SpaceAfterSubtractWhenFollowedByUnaryMinus: Rule;
              SpaceAfterSubtractWhenFollowedByPredecrement: Rule;
              NoSpaceBeforeComma: Rule;
              SpaceAfterCertainKeywords: Rule;
              NoSpaceBeforeOpenParenInFuncCall: Rule;
              SpaceAfterFunctionInFuncDecl: Rule;
              NoSpaceBeforeOpenParenInFuncDecl: Rule;
              SpaceAfterVoidOperator: Rule;
              NoSpaceBetweenReturnAndSemicolon: Rule;
              SpaceBetweenStatements: Rule;
              SpaceAfterTryFinally: Rule;
              SpaceAfterGetSetInMember: Rule;
              SpaceBeforeBinaryKeywordOperator: Rule;
              SpaceAfterBinaryKeywordOperator: Rule;
              NoSpaceAfterConstructor: Rule;
              NoSpaceAfterModuleImport: Rule;
              SpaceAfterCertainTypeScriptKeywords: Rule;
              SpaceBeforeCertainTypeScriptKeywords: Rule;
              SpaceAfterModuleName: Rule;
              SpaceAfterArrow: Rule;
              NoSpaceAfterEllipsis: Rule;
              NoSpaceAfterOptionalParameters: Rule;
              NoSpaceBeforeOpenAngularBracket: Rule;
              NoSpaceBetweenCloseParenAndAngularBracket: Rule;
              NoSpaceAfterOpenAngularBracket: Rule;
              NoSpaceBeforeCloseAngularBracket: Rule;
              NoSpaceAfterCloseAngularBracket: Rule;
              NoSpaceBetweenEmptyInterfaceBraceBrackets: Rule;
              HighPriorityCommonRules: Rule[];
              LowPriorityCommonRules: Rule[];
              SpaceAfterComma: Rule;
              NoSpaceAfterComma: Rule;
              SpaceBeforeBinaryOperator: Rule;
              SpaceAfterBinaryOperator: Rule;
              NoSpaceBeforeBinaryOperator: Rule;
              NoSpaceAfterBinaryOperator: Rule;
              SpaceAfterKeywordInControl: Rule;
              NoSpaceAfterKeywordInControl: Rule;
              FunctionOpenBraceLeftTokenRange: Shared.TokenRange;
              SpaceBeforeOpenBraceInFunction: Rule;
              NewLineBeforeOpenBraceInFunction: Rule;
              TypeScriptOpenBraceLeftTokenRange: Shared.TokenRange;
              SpaceBeforeOpenBraceInTypeScriptDeclWithBlock: Rule;
              NewLineBeforeOpenBraceInTypeScriptDeclWithBlock: Rule;
              ControlOpenBraceLeftTokenRange: Shared.TokenRange;
              SpaceBeforeOpenBraceInControl: Rule;
              NewLineBeforeOpenBraceInControl: Rule;
              SpaceAfterSemicolonInFor: Rule;
              NoSpaceAfterSemicolonInFor: Rule;
              SpaceAfterOpenParen: Rule;
              SpaceBeforeCloseParen: Rule;
              NoSpaceBetweenParens: Rule;
              NoSpaceAfterOpenParen: Rule;
              NoSpaceBeforeCloseParen: Rule;
              SpaceAfterAnonymousFunctionKeyword: Rule;
              NoSpaceAfterAnonymousFunctionKeyword: Rule;
              constructor();
              static IsForContext(context: FormattingContext): boolean;
              static IsNotForContext(context: FormattingContext): boolean;
              static IsBinaryOpContext(context: FormattingContext): boolean;
              static IsNotBinaryOpContext(context: FormattingContext): boolean;
              static IsSameLineTokenOrBeforeMultilineBlockContext(context: FormattingContext): boolean;
              static IsBeforeMultilineBlockContext(context: FormattingContext): boolean;
              static IsMultilineBlockContext(context: FormattingContext): boolean;
              static IsSingleLineBlockContext(context: FormattingContext): boolean;
              static IsBlockContext(context: FormattingContext): boolean;
              static IsBeforeBlockContext(context: FormattingContext): boolean;
              static NodeIsBlockContext(node: Node): boolean;
              static IsFunctionDeclContext(context: FormattingContext): boolean;
              static IsTypeScriptDeclWithBlockContext(context: FormattingContext): boolean;
              static NodeIsTypeScriptDeclWithBlockContext(node: Node): boolean;
              static IsAfterCodeBlockContext(context: FormattingContext): boolean;
              static IsControlDeclContext(context: FormattingContext): boolean;
              static IsObjectContext(context: FormattingContext): boolean;
              static IsFunctionCallContext(context: FormattingContext): boolean;
              static IsNewContext(context: FormattingContext): boolean;
              static IsFunctionCallOrNewContext(context: FormattingContext): boolean;
              static IsSameLineTokenContext(context: FormattingContext): boolean;
              static IsNotFormatOnEnter(context: FormattingContext): boolean;
              static IsModuleDeclContext(context: FormattingContext): boolean;
              static IsObjectTypeContext(context: FormattingContext): boolean;
              static IsTypeArgumentOrParameter(token: TextRangeWithKind, parent: Node): boolean;
              static IsTypeArgumentOrParameterContext(context: FormattingContext): boolean;
              static IsVoidOpContext(context: FormattingContext): boolean;
          }
      }
      declare module ts.formatting {
          class RulesMap {
              map: RulesBucket[];
              mapRowLength: number;
              constructor();
              static create(rules: Rule[]): RulesMap;
              Initialize(rules: Rule[]): RulesBucket[];
              FillRules(rules: Rule[], rulesBucketConstructionStateList: RulesBucketConstructionState[]): void;
              private GetRuleBucketIndex(row, column);
              private FillRule(rule, rulesBucketConstructionStateList);
              GetRule(context: FormattingContext): Rule;
          }
          enum RulesPosition {
              IgnoreRulesSpecific = 0,
              IgnoreRulesAny,
              ContextRulesSpecific,
              ContextRulesAny,
              NoContextRulesSpecific,
              NoContextRulesAny,
          }
          class RulesBucketConstructionState {
              private rulesInsertionIndexBitmap;
              constructor();
              GetInsertionIndex(maskPosition: RulesPosition): number;
              IncreaseInsertionIndex(maskPosition: RulesPosition): void;
          }
          class RulesBucket {
              private rules;
              constructor();
              Rules(): Rule[];
              AddRule(rule: Rule, specificTokens: boolean, constructionState: RulesBucketConstructionState[], rulesBucketIndex: number): void;
          }
      }
      declare module ts.formatting {
          module Shared {
              interface ITokenAccess {
                  GetTokens(): SyntaxKind[];
                  Contains(token: SyntaxKind): boolean;
              }
              class TokenRangeAccess implements ITokenAccess {
                  private tokens;
                  constructor(from: SyntaxKind, to: SyntaxKind, except: SyntaxKind[]);
                  GetTokens(): SyntaxKind[];
                  Contains(token: SyntaxKind): boolean;
              }
              class TokenValuesAccess implements ITokenAccess {
                  private tokens;
                  constructor(tks: SyntaxKind[]);
                  GetTokens(): SyntaxKind[];
                  Contains(token: SyntaxKind): boolean;
              }
              class TokenSingleValueAccess implements ITokenAccess {
                  token: SyntaxKind;
                  constructor(token: SyntaxKind);
                  GetTokens(): SyntaxKind[];
                  Contains(tokenValue: SyntaxKind): boolean;
              }
              class TokenAllAccess implements ITokenAccess {
                  GetTokens(): SyntaxKind[];
                  Contains(tokenValue: SyntaxKind): boolean;
                  toString(): string;
              }
              class TokenRange {
                  tokenAccess: ITokenAccess;
                  constructor(tokenAccess: ITokenAccess);
                  static FromToken(token: SyntaxKind): TokenRange;
                  static FromTokens(tokens: SyntaxKind[]): TokenRange;
                  static FromRange(f: SyntaxKind, to: SyntaxKind, except?: SyntaxKind[]): TokenRange;
                  static AllTokens(): TokenRange;
                  GetTokens(): SyntaxKind[];
                  Contains(token: SyntaxKind): boolean;
                  toString(): string;
                  static Any: TokenRange;
                  static AnyIncludingMultilineComments: TokenRange;
                  static Keywords: TokenRange;
                  static Operators: TokenRange;
                  static BinaryOperators: TokenRange;
                  static BinaryKeywordOperators: TokenRange;
                  static ReservedKeywords: TokenRange;
                  static UnaryPrefixOperators: TokenRange;
                  static UnaryPrefixExpressions: TokenRange;
                  static UnaryPreincrementExpressions: TokenRange;
                  static UnaryPostincrementExpressions: TokenRange;
                  static UnaryPredecrementExpressions: TokenRange;
                  static UnaryPostdecrementExpressions: TokenRange;
                  static Comments: TokenRange;
                  static TypeNames: TokenRange;
              }
          }
      }
      declare module ts.formatting {
          class TokenSpan extends TextSpan {
              kind: SyntaxKind;
              constructor(kind: SyntaxKind, start: number, length: number);
          }
      }
      declare module ts.formatting {
          class RulesProvider {
              private logger;
              private globalRules;
              private options;
              private activeRules;
              private rulesMap;
              constructor(logger: Logger);
              getRuleName(rule: Rule): string;
              getRuleByName(name: string): Rule;
              getRulesMap(): RulesMap;
              ensureUpToDate(options: ts.FormatCodeOptions): void;
              private createActiveRules(options);
          }
      }
      declare module ts.formatting {
          interface TextRangeWithKind extends TextRange {
              kind: SyntaxKind;
          }
          interface TokenInfo {
              leadingTrivia: TextRangeWithKind[];
              token: TextRangeWithKind;
              trailingTrivia: TextRangeWithKind[];
          }
          function formatOnEnter(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeOptions): TextChange[];
          function formatOnSemicolon(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeOptions): TextChange[];
          function formatOnClosingCurly(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeOptions): TextChange[];
          function formatDocument(sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeOptions): TextChange[];
          function formatSelection(start: number, end: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeOptions): TextChange[];
      }
      declare module ts {
          interface Node {
              getSourceFile(): SourceFile;
              getChildCount(sourceFile?: SourceFile): number;
              getChildAt(index: number, sourceFile?: SourceFile): Node;
              getChildren(sourceFile?: SourceFile): Node[];
              getStart(sourceFile?: SourceFile): number;
              getFullStart(): number;
              getEnd(): number;
              getWidth(sourceFile?: SourceFile): number;
              getFullWidth(): number;
              getLeadingTriviaWidth(sourceFile?: SourceFile): number;
              getFullText(sourceFile?: SourceFile): string;
              getText(sourceFile?: SourceFile): string;
              getFirstToken(sourceFile?: SourceFile): Node;
              getLastToken(sourceFile?: SourceFile): Node;
          }
          interface Symbol {
              getFlags(): SymbolFlags;
              getName(): string;
              getDeclarations(): Declaration[];
              getDocumentationComment(): SymbolDisplayPart[];
          }
          interface Type {
              getFlags(): TypeFlags;
              getSymbol(): Symbol;
              getProperties(): Symbol[];
              getProperty(propertyName: string): Symbol;
              getApparentProperties(): Symbol[];
              getCallSignatures(): Signature[];
              getConstructSignatures(): Signature[];
              getStringIndexType(): Type;
              getNumberIndexType(): Type;
          }
          interface Signature {
              getDeclaration(): SignatureDeclaration;
              getTypeParameters(): Type[];
              getParameters(): Symbol[];
              getReturnType(): Type;
              getDocumentationComment(): SymbolDisplayPart[];
          }
          interface SourceFile {
              getScriptSnapshot(): IScriptSnapshot;
              getNamedDeclarations(): Declaration[];
              update(scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TextChangeRange): SourceFile;
          }
          interface IScriptSnapshot {
              getText(start: number, end: number): string;
              getLength(): number;
              getLineStartPositions(): number[];
              getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange;
          }
          module ScriptSnapshot {
              function fromString(text: string): IScriptSnapshot;
          }
          interface PreProcessedFileInfo {
              referencedFiles: FileReference[];
              importedFiles: FileReference[];
              isLibFile: boolean;
          }
          interface Logger {
              log(s: string): void;
          }
          interface LanguageServiceHost extends Logger {
              getCompilationSettings(): CompilerOptions;
              getScriptFileNames(): string[];
              getScriptVersion(fileName: string): string;
              getScriptIsOpen(fileName: string): boolean;
              getScriptSnapshot(fileName: string): IScriptSnapshot;
              getLocalizedDiagnosticMessages(): any;
              getCancellationToken(): CancellationToken;
              getCurrentDirectory(): string;
              getDefaultLibFilename(): string;
          }
          interface LanguageService {
              cleanupSemanticCache(): void;
              getSyntacticDiagnostics(fileName: string): Diagnostic[];
              getSemanticDiagnostics(fileName: string): Diagnostic[];
              getCompilerOptionsDiagnostics(): Diagnostic[];
              getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[];
              getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[];
              getCompletionsAtPosition(fileName: string, position: number, isMemberCompletion: boolean): CompletionInfo;
              getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails;
              getQuickInfoAtPosition(fileName: string, position: number): QuickInfo;
              getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan;
              getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan;
              getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems;
              getRenameInfo(fileName: string, position: number): RenameInfo;
              findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[];
              getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[];
              getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[];
              getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[];
              getNavigateToItems(searchValue: string): NavigateToItem[];
              getNavigationBarItems(fileName: string): NavigationBarItem[];
              getOutliningSpans(fileName: string): OutliningSpan[];
              getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[];
              getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[];
              getIndentationAtPosition(fileName: string, position: number, options: EditorOptions): number;
              getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[];
              getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[];
              getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): TextChange[];
              getEmitOutput(fileName: string): EmitOutput;
              getSourceFile(filename: string): SourceFile;
              dispose(): void;
          }
          interface ClassifiedSpan {
              textSpan: TextSpan;
              classificationType: string;
          }
          interface NavigationBarItem {
              text: string;
              kind: string;
              kindModifiers: string;
              spans: TextSpan[];
              childItems: NavigationBarItem[];
              indent: number;
              bolded: boolean;
              grayed: boolean;
          }
          interface TodoCommentDescriptor {
              text: string;
              priority: number;
          }
          interface TodoComment {
              descriptor: TodoCommentDescriptor;
              message: string;
              position: number;
          }
          class TextChange {
              span: TextSpan;
              newText: string;
          }
          interface RenameLocation {
              textSpan: TextSpan;
              fileName: string;
          }
          interface ReferenceEntry {
              textSpan: TextSpan;
              fileName: string;
              isWriteAccess: boolean;
          }
          interface NavigateToItem {
              name: string;
              kind: string;
              kindModifiers: string;
              matchKind: string;
              fileName: string;
              textSpan: TextSpan;
              containerName: string;
              containerKind: string;
          }
          interface EditorOptions {
              IndentSize: number;
              TabSize: number;
              NewLineCharacter: string;
              ConvertTabsToSpaces: boolean;
          }
          interface FormatCodeOptions extends EditorOptions {
              InsertSpaceAfterCommaDelimiter: boolean;
              InsertSpaceAfterSemicolonInForStatements: boolean;
              InsertSpaceBeforeAndAfterBinaryOperators: boolean;
              InsertSpaceAfterKeywordsInControlFlowStatements: boolean;
              InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean;
              InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
              PlaceOpenBraceOnNewLineForFunctions: boolean;
              PlaceOpenBraceOnNewLineForControlBlocks: boolean;
          }
          interface DefinitionInfo {
              fileName: string;
              textSpan: TextSpan;
              kind: string;
              name: string;
              containerKind: string;
              containerName: string;
          }
          enum SymbolDisplayPartKind {
              aliasName = 0,
              className = 1,
              enumName = 2,
              fieldName = 3,
              interfaceName = 4,
              keyword = 5,
              lineBreak = 6,
              numericLiteral = 7,
              stringLiteral = 8,
              localName = 9,
              methodName = 10,
              moduleName = 11,
              operator = 12,
              parameterName = 13,
              propertyName = 14,
              punctuation = 15,
              space = 16,
              text = 17,
              typeParameterName = 18,
              enumMemberName = 19,
              functionName = 20,
              regularExpressionLiteral = 21,
          }
          interface SymbolDisplayPart {
              text: string;
              kind: string;
          }
          interface QuickInfo {
              kind: string;
              kindModifiers: string;
              textSpan: TextSpan;
              displayParts: SymbolDisplayPart[];
              documentation: SymbolDisplayPart[];
          }
          interface RenameInfo {
              canRename: boolean;
              localizedErrorMessage: string;
              displayName: string;
              fullDisplayName: string;
              kind: string;
              kindModifiers: string;
              triggerSpan: TextSpan;
          }
          interface SignatureHelpParameter {
              name: string;
              documentation: SymbolDisplayPart[];
              displayParts: SymbolDisplayPart[];
              isOptional: boolean;
          }
          interface SignatureHelpItem {
              isVariadic: boolean;
              prefixDisplayParts: SymbolDisplayPart[];
              suffixDisplayParts: SymbolDisplayPart[];
              separatorDisplayParts: SymbolDisplayPart[];
              parameters: SignatureHelpParameter[];
              documentation: SymbolDisplayPart[];
          }
          interface SignatureHelpItems {
              items: SignatureHelpItem[];
              applicableSpan: TextSpan;
              selectedItemIndex: number;
              argumentIndex: number;
              argumentCount: number;
          }
          interface CompletionInfo {
              isMemberCompletion: boolean;
              entries: CompletionEntry[];
          }
          interface CompletionEntry {
              name: string;
              kind: string;
              kindModifiers: string;
          }
          interface CompletionEntryDetails {
              name: string;
              kind: string;
              kindModifiers: string;
              displayParts: SymbolDisplayPart[];
              documentation: SymbolDisplayPart[];
          }
          interface EmitOutput {
              outputFiles: OutputFile[];
              emitOutputStatus: EmitReturnStatus;
          }
          const enum OutputFileType {
              JavaScript = 0,
              SourceMap = 1,
              Declaration = 2,
          }
          interface OutputFile {
              name: string;
              writeByteOrderMark: boolean;
              text: string;
          }
          const enum EndOfLineState {
              Start = 0,
              InMultiLineCommentTrivia = 1,
              InSingleQuoteStringLiteral = 2,
              InDoubleQuoteStringLiteral = 3,
          }
          enum TokenClass {
              Punctuation = 0,
              Keyword = 1,
              Operator = 2,
              Comment = 3,
              Whitespace = 4,
              Identifier = 5,
              NumberLiteral = 6,
              StringLiteral = 7,
              RegExpLiteral = 8,
          }
          interface ClassificationResult {
              finalLexState: EndOfLineState;
              entries: ClassificationInfo[];
          }
          interface ClassificationInfo {
              length: number;
              classification: TokenClass;
          }
          interface Classifier {
              getClassificationsForLine(text: string, lexState: EndOfLineState, classifyKeywordsInGenerics?: boolean): ClassificationResult;
          }
          interface DocumentRegistry {
              acquireDocument(filename: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean): SourceFile;
              updateDocument(sourceFile: SourceFile, filename: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TextChangeRange): SourceFile;
              releaseDocument(filename: string, compilationSettings: CompilerOptions): void;
          }
          class ScriptElementKind {
              static unknown: string;
              static keyword: string;
              static scriptElement: string;
              static moduleElement: string;
              static classElement: string;
              static interfaceElement: string;
              static typeElement: string;
              static enumElement: string;
              static variableElement: string;
              static localVariableElement: string;
              static functionElement: string;
              static localFunctionElement: string;
              static memberFunctionElement: string;
              static memberGetAccessorElement: string;
              static memberSetAccessorElement: string;
              static memberVariableElement: string;
              static constructorImplementationElement: string;
              static callSignatureElement: string;
              static indexSignatureElement: string;
              static constructSignatureElement: string;
              static parameterElement: string;
              static typeParameterElement: string;
              static primitiveType: string;
              static label: string;
              static alias: string;
              static constElement: string;
              static letElement: string;
          }
          class ScriptElementKindModifier {
              static none: string;
              static publicMemberModifier: string;
              static privateMemberModifier: string;
              static protectedMemberModifier: string;
              static exportedModifier: string;
              static ambientModifier: string;
              static staticModifier: string;
          }
          class ClassificationTypeNames {
              static comment: string;
              static identifier: string;
              static keyword: string;
              static numericLiteral: string;
              static operator: string;
              static stringLiteral: string;
              static whiteSpace: string;
              static text: string;
              static punctuation: string;
              static className: string;
              static enumName: string;
              static interfaceName: string;
              static moduleName: string;
              static typeParameterName: string;
          }
          function displayPartsToString(displayParts: SymbolDisplayPart[]): string;
          interface DisplayPartsSymbolWriter extends SymbolWriter {
              displayParts(): SymbolDisplayPart[];
          }
          function spacePart(): SymbolDisplayPart;
          function keywordPart(kind: SyntaxKind): SymbolDisplayPart;
          function punctuationPart(kind: SyntaxKind): SymbolDisplayPart;
          function operatorPart(kind: SyntaxKind): SymbolDisplayPart;
          function textPart(text: string): SymbolDisplayPart;
          function lineBreakPart(): SymbolDisplayPart;
          function symbolPart(text: string, symbol: Symbol): SymbolDisplayPart;
          function mapToDisplayParts(writeDisplayParts: (writer: DisplayPartsSymbolWriter) => void): SymbolDisplayPart[];
          function typeToDisplayParts(typechecker: TypeChecker, type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): SymbolDisplayPart[];
          function symbolToDisplayParts(typeChecker: TypeChecker, symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): SymbolDisplayPart[];
          function getDefaultCompilerOptions(): CompilerOptions;
          function compareDataObjects(dst: any, src: any): boolean;
          class OperationCanceledException {
          }
          class CancellationTokenObject {
              private cancellationToken;
              static None: CancellationTokenObject;
              constructor(cancellationToken: CancellationToken);
              isCancellationRequested(): boolean;
              throwIfCancellationRequested(): void;
          }
          function createDocumentRegistry(): DocumentRegistry;
          function preProcessFile(sourceText: string, readImportFiles?: boolean): PreProcessedFileInfo;
          function getNodeModifiers(node: Node): string;
          function createLanguageService(host: LanguageServiceHost, documentRegistry: DocumentRegistry): LanguageService;
          function createClassifier(host: Logger): Classifier;
      }
      declare module ts.BreakpointResolver {
          function spanInSourceFileAtLocation(sourceFile: SourceFile, position: number): TextSpan;
      }
      declare var debugObjectHost: any;
      declare module ts {
          interface ScriptSnapshotShim {
              getText(start: number, end: number): string;
              getLength(): number;
              getLineStartPositions(): string;
              getChangeRange(oldSnapshot: ScriptSnapshotShim): string;
          }
          interface LanguageServiceShimHost extends Logger {
              getCompilationSettings(): string;
              getScriptFileNames(): string;
              getScriptVersion(fileName: string): string;
              getScriptIsOpen(fileName: string): boolean;
              getScriptSnapshot(fileName: string): ScriptSnapshotShim;
              getLocalizedDiagnosticMessages(): string;
              getCancellationToken(): CancellationToken;
              getCurrentDirectory(): string;
              getDefaultLibFilename(): string;
          }
          interface IFileReference {
              path: string;
              position: number;
              length: number;
          }
          interface ShimFactory {
              registerShim(shim: Shim): void;
              unregisterShim(shim: Shim): void;
          }
          interface Shim {
              dispose(dummy: any): void;
          }
          interface LanguageServiceShim extends Shim {
              languageService: LanguageService;
              dispose(dummy: any): void;
              refresh(throwOnError: boolean): void;
              cleanupSemanticCache(): void;
              getSyntacticDiagnostics(fileName: string): string;
              getSemanticDiagnostics(fileName: string): string;
              getCompilerOptionsDiagnostics(): string;
              getSyntacticClassifications(fileName: string, start: number, length: number): string;
              getCompletionsAtPosition(fileName: string, position: number, isMemberCompletion: boolean): string;
              getCompletionEntryDetails(fileName: string, position: number, entryName: string): string;
              getQuickInfoAtPosition(fileName: string, position: number): string;
              getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): string;
              getBreakpointStatementAtPosition(fileName: string, position: number): string;
              getSignatureHelpItems(fileName: string, position: number): string;
              getRenameInfo(fileName: string, position: number): string;
              findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): string;
              getDefinitionAtPosition(fileName: string, position: number): string;
              getReferencesAtPosition(fileName: string, position: number): string;
              getOccurrencesAtPosition(fileName: string, position: number): string;
              getNavigateToItems(searchValue: string): string;
              getNavigationBarItems(fileName: string): string;
              getOutliningSpans(fileName: string): string;
              getTodoComments(fileName: string, todoCommentDescriptors: string): string;
              getBraceMatchingAtPosition(fileName: string, position: number): string;
              getIndentationAtPosition(fileName: string, position: number, options: string): string;
              getFormattingEditsForRange(fileName: string, start: number, end: number, options: string): string;
              getFormattingEditsForDocument(fileName: string, options: string): string;
              getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: string): string;
              getEmitOutput(fileName: string): string;
          }
          interface ClassifierShim extends Shim {
              getClassificationsForLine(text: string, lexState: EndOfLineState, classifyKeywordsInGenerics?: boolean): string;
          }
          interface CoreServicesShim extends Shim {
              getPreProcessedFileInfo(fileName: string, sourceText: IScriptSnapshot): string;
              getDefaultCompilationSettings(): string;
          }
          const enum LanguageVersion {
              EcmaScript3 = 0,
              EcmaScript5 = 1,
              EcmaScript6 = 2,
          }
          const enum ModuleGenTarget {
              Unspecified = 0,
              Synchronous = 1,
              Asynchronous = 2,
          }
          interface CompilationSettings {
              propagateEnumConstants?: boolean;
              removeComments?: boolean;
              watch?: boolean;
              noResolve?: boolean;
              allowAutomaticSemicolonInsertion?: boolean;
              noImplicitAny?: boolean;
              noLib?: boolean;
              codeGenTarget?: LanguageVersion;
              moduleGenTarget?: ModuleGenTarget;
              outFileOption?: string;
              outDirOption?: string;
              mapSourceFiles?: boolean;
              mapRoot?: string;
              sourceRoot?: string;
              generateDeclarationFiles?: boolean;
              useCaseSensitiveFileResolution?: boolean;
              gatherDiagnostics?: boolean;
              codepage?: number;
              emitBOM?: boolean;
              [index: string]: any;
          }
          class LanguageServiceShimHostAdapter implements LanguageServiceHost {
              private shimHost;
              constructor(shimHost: LanguageServiceShimHost);
              log(s: string): void;
              getCompilationSettings(): CompilerOptions;
              getScriptFileNames(): string[];
              getScriptSnapshot(fileName: string): IScriptSnapshot;
              getScriptVersion(fileName: string): string;
              getScriptIsOpen(fileName: string): boolean;
              getLocalizedDiagnosticMessages(): any;
              getCancellationToken(): CancellationToken;
              getDefaultLibFilename(): string;
              getCurrentDirectory(): string;
          }
          class TypeScriptServicesFactory implements ShimFactory {
              private _shims;
              private documentRegistry;
              createLanguageServiceShim(host: LanguageServiceShimHost): LanguageServiceShim;
              createClassifierShim(logger: Logger): ClassifierShim;
              createCoreServicesShim(logger: Logger): CoreServicesShim;
              close(): void;
              registerShim(shim: Shim): void;
              unregisterShim(shim: Shim): void;
          }
      }
      declare module TypeScript.Services {
          var TypeScriptServicesFactory: typeof ts.TypeScriptServicesFactory;
      }
      
    • websql.d.ts
      declare function openDatabase(
        name: string,
        version: any,
        displayName: string,
        size: number,
        upgrade?: DatabaseCallback): Database;
      
      interface DatabaseCallback {
        (database: Database): void;
      }
      
      interface Database {
        transaction(
          callback: (transaction: SQLTransaction) => void,
          errorCallback?: (error: SQLError) => void,
          successCallback?: () => void);
      
        readTransaction(
          callback: (transaction: SQLTransaction) => void,
          errorCallback?: (error: SQLError) => void,
          successCallback?: () => void);
      
        version: string;
      
        changeVersion(
          oldVersion: string,
          newVersion: string,
          callback: (transaction: SQLTransaction) => void,
          errorCallback?: (error: SQLError) => void,
          successCallback?: () => void);
      }
      
      interface SQLTransaction {
        executeSql(
          sqlStatement: string,
          arguments?: any[],
          callback?: (transaction: SQLTransaction, result: SQLResultSet) => void,
          errorCallback?: (transaction: SQLTransaction, error: SQLError) => void): void;
      }
      
      interface SQLError {
        /**
         * UNKNOWN_ERR = 0;
         * DATABASE_ERR = 1;
         * VERSION_ERR = 2;
         * TOO_LARGE_ERR = 3;
         * QUOTA_ERR = 4;
         * SYNTAX_ERR = 5;
         * CONSTRAINT_ERR = 6;
        * TIMEOUT_ERR = 7;
         */
        code: number;
        message: string
      }
      
      interface SQLResultSet {
        insertId: number;
        rowsAffected: number;
        rows: SQLResultSetRowList;
      }
      
      interface SQLResultSetRowList {
        length: number;
        item(index: number): any;
      }
    • zip.d.ts
      declare module zip {
      
        export var useWebWorkers: boolean;
      
        export function createReader(reader: Reader, callback: (reader: ZipReader) => void, onerror?);
        export function createWriter(writer: Writer, callback: (writer: ZipWriter) => void, onerror?);
      
        export interface Reader {
        }
      
        export interface Writer {
        }
      
        export interface ZipReader {
          getEntries(callback: (entries: Entry[]) => void);
          close(callback: () => void);
        }
      
        export interface ZipWriter {
          add(
            name: string,
            reader: Reader,
            onend,
            onprogress?: (index: number, max: number) => void,
            options?: { directory?: boolean; level?: number; comment?: string; lastModDate?: Date; version?: number; });
      
          close(callback);
        }
      
        export interface Entry {
          filename: string;
          directory: boolean;
          compressedSize: number;
          uncompressedSize: number;
          lastModDate: number;
          lastModDateRaw: number;
          comment: string;
          crc32: number;
      
          getData(writer: Writer, onend?, onprogress?: (index: number, maxValue: number) => void, checkCrc32?: boolean);
        }
      
        export class BlobWriter implements Writer {
        }
          
        export class TextWriter implements Writer {
        }
      
        export class TextReader implements Reader {
          constructor(text: string);
        }
      
        export class BlobReader implements Reader {
          constructor(arg: any);
        }
      }
  • errors.js
    var _errorCache = [];
    _errorCache.byText = {};
    
    window.onerror = function(errObj, file, line, ch, err) {
      var txt = err.stack;
      var firstTrigger = _errorCache.length === 0;
      if (_errorCache.byText[txt]) {
        _errorCache.byText[txt]++;
      }
      else {
        _errorCache.byText[txt]=1;
        _errorCache.push(txt);
      }
    
      if (firstTrigger)
        setTimeout(function() {
          var errorText = _errorCache.map(function(txt){return _errorCache.byText[txt]+' - '+txt}).join('\n');
          _errorCache = [];
          _errorCache.byText = {};
          alert(errorText);
        }, 100);
    };
    
  • functions.ts
    module teapo {
    
      /** Stoppable timer with methods specifically targeting debouncing. */
      export class Timer {
    
        private _timeout = 0;
        private _maxTimeout = 0;
        private _tickClosure = () => this._tick();
    
        constructor() {
        }
    
        interval = 300;
        maxInterval = 1000;
    
        ontick: () => void = null;
      
        reset() {
          if (this._timeout)
            clearTimeout(this._timeout);
    
          if (!this._maxTimeout && this.maxInterval)
            this._maxTimeout = setTimeout(this._tickClosure, this.maxInterval);
    
          if (this.interval)
            this._timeout = setTimeout(this._tickClosure, this.interval);
        }
    
        stop() {
          if (this._timeout)
            clearTimeout(this._timeout);
          if (this._maxTimeout)
            clearTimeout(this._maxTimeout);
          this._timeout = 0;
          this._maxTimeout = 0;
        }
      
        endWaiting() {
          if (this.isWaiting())
            this._tick();
        }
      
        isWaiting() {
          return this._timeout || this._maxTimeout ? true : false;
        }
    
        private _tick() {
          this.stop();
          if (this.ontick) {
            var t = this.ontick;
            t();
          }
        }
        
      }
      
      export function asyncForEach<T, TResult>(
        array: T[], 
        handleElement: (element: T, index: number , callback: (error: Error, res: TResult) => void) => void,
        callback: (error: Error, res: TResult[]) => void) {
        
        if (!array || !array.length) {
          callback(null, []);
          return;
        }
          
        var res: TResult[] = [];
        var stop = false;
        var completeCount = 0;
        forEach(array, (element, index) => {
          if (stop) return;
          handleElement(element[index], index, (error, resElement) => {
            if (stop) return;
            if (error) {
              stop = true;
              callback(error, null);
              return;
            }
            res[index] = resElement;
            completeCount++;
            if (completeCount === array.length) {
              stop = true;
              callback(null, res);
            }
          });
        });
      }
    
      export function forEach<T>(array: T[], callback: (x: T, index: number) => void) {
        if (array.forEach) {
          array.forEach(callback);
        }
        else {
          for (var i = 0; i < array.length; i++) {
            callback(array[i], i);
          }
        }
      }
    
      export function find<T, R>(array: T[], predicate: (x: T, index: number) => R): R {
        var result = null;
        for (var i = 0; i < array.length; i++) {
          var x = array[i];
          var p = predicate(x, i);
          if (p) return p;
        }
      }
    
      /**
     * Escape unsafe character sequences like a closing script tag.
     */
      export function encodeForInnerHTML(content: string): string {
        // matching script closing tag with *one* or more consequtive slashes
        return content.replace(/<\/+script/g, (match) => {
          return '</' + match.slice(1); // skip angle bracket, inject bracket and extra slash
        });
      }
    
      /**
       * Unescape character sequences wrapped with encodeForInnerHTML for safety.
       */
      export function decodeFromInnerHTML(innerHTML: string): string {
        // matching script closing tag with *t*wo or more consequtive slashes
        return innerHTML.replace(/<\/\/+script/g, (match) => {
          return '<' + match.slice(2); // skip angle bracket and one slash, inject bracket
        });
      }
    
      export function encodeForAttributeName(value: string): string {
        var codes: number[] = [];
        var passableOnly = true;
    
        for (var i = 0; i < value.length; i++) {
          var c = value.charAt(i);
          var cc = value.charCodeAt(i);
          codes.push(cc);
          if (passableOnly)
            passableOnly = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z' || c === '_' || c === '-');
        }
    
        if (passableOnly)
          return 's-' + value;
        else
          return 'n-' + codes.join('-');
      }
    
      export function decodeFromAttributeName(attributeNamePart: string): string {
        if (attributeNamePart.slice(0, 2) === 's-')
          return attributeNamePart.slice(2);
    
        var codes = attributeNamePart.slice(2).split('-');
        var result: string[] = [];
        for (var i = 0; i < codes.length; i++) {
          try {
            result[i] = String.fromCharCode(parseInt(codes[i]));
          }
          catch (error) {
            console.log('Parsing attribute name error: ' + attributeNamePart + ' has non-numeric chunk ' + i + ' (' + codes[i] + ').');
            return null;
          }
        }
        return result.join('');
      }
    
      export function startsWith(str: string, prefix: string) {
        if (!str) return !prefix;
        if (!prefix) return false;
        if (str.length < prefix.length) return false;
        if (str.charCodeAt(0) !== prefix.charCodeAt(0)) return false;
        if (str.slice(0, prefix.length) !== prefix) return false;
        else return true;
      }
    
      export function dateNow(): number {
        if (Date.now)
          return Date.now();
        else
          return new Date().valueOf();
      }
    
      export var objectKeys = (obj: any): string[] => {
        if (typeof Object.keys === 'function')
          objectKeys = Object.keys;
        else
          objectKeys = (obj: any): string[] => {
            var result: string[] = [];
            for (var k in obj) if (obj.hasOwnProperty(k)) {
              result.push(k);
            }
            return result;
          };
        
        return objectKeys(obj);
      };
        
      export function addEventListener(element: any, type: string, listener: (event: Event) => void) {
        if (element.addEventListener) {
          element.addEventListener(type, listener, true);
        }
        else {
          var ontype = 'on' + type;
    
          if (element.attachEvent) {
            element.attachEvent('on' + type, listener);
          }
          else if (ontype in element) {
            element[ontype] = listener;
          }
        }
      }
    
      export function removeEventListener(element: any, type: string, listener: (event: Event) => void) {
        if (element.addEventListener) {
          element.removeEventListener(type, listener, true);
        }
        else {
          var ontype = 'on' + type;
    
          if (element.detachEvent) {
            element.detachEvent('on' + type, listener);
          }
          else if (ontype in element) {
            element[ontype] = null;
          }
        }
      }
    
      export function setTextContent(element: HTMLElement, textContent: string) {
        if (!_textContent)
          _textContent = detectTextContent(element);
        if (_textContent === 1)
          element.textContent = textContent;
        else
          element.innerText = textContent;
      }
    
      var _textContent = 0;
      function detectTextContent(element: HTMLElement) {
        if ('textContent' in element)
          return 1;
        else      
          return 2;
      }
      
    
    }
  • index.html
    <!doctype html><html><head>
    <meta charset="utf-8">
    <title>Teapo - [teapo v0.5a]</title>
    
    <style><%=embedFile('imports/codemirror/codemirror.css')%></style>
    <style><%=embedFile('imports/codemirror/show-hint.css')%></style>
    <style><%=embedFile('imports/codemirror/tern.css')%></style>
    <style><%=embedFile('imports/codemirror/dialog.css')%></style>
    
    
    <style><%=embedFile('app/body.css')%></style>
    <style><%=embedFile('app/flyout.css')%></style>
    <style><%=embedFile('app/flyout-branding.css')%></style>
    <style><%=embedFile('app/tree-and-bar.css')%></style>
    <style><%=embedFile('app/status.css')%></style>
    
    <style><%=embedFile('files/FileTree.css')%></style>
    <style><%=embedFile('docs/types/text/CodeMirror-ext.css')%></style>
    <style><%=embedFile('app/moreDialog/style.css')%></style>
    
    <style><%=embedFile('docs/types/text/scrollerView/style.css')%></style>
    
    
    
    <style><%=embedFile('docs/types/text/ts/style.css')%></style>
    
    <style><%=embedFile('app/loading.css')%></style>
    
    
    </head>
    <body
        data-bind="event: {keydown:keydown}">
    
    <div id=teapo-loading-host>
      <div id=teapo-loading-title>
        Booting...
      </div>
      <div id=teapo-loading-progress>
      </div>
    </div>
    
    <script data-legit=teapo>try { <%=typescriptBuild()%> } catch(bootError) { alert(bootError+' '+bootError.stack) }</script>
    
    <script data-legit=teapo>try { teapo.app.loading('Page layout...'); } catch (err) { alert(err+' '+err.stack); }</script>
    
    <div class=teapo-flyout-scroller
       data-bind="load: flyoutScroller = $element">
      <div class=teapo-flyout-scroller-bg>
    
        <div class=teapo-main-content
           data-bind="loadRaw: docHostRegions.content = $element"></div>
    
        <div class=teapo-flyout>
    
          <div class=teapo-thick-bar-host>
            <button class=teapo-more-button data-bind="click: moreClick"> ... </button>
            <div class=teapo-thick-bar-bg>
              <div class=teapo-thick-bar
                   data-bind="event: { mousedown: thickbarMouseDown }, loadRaw: docHostRegions.scroller = $element">
              </div>
            </div>
          </div>
    
    <script data-legit=teapo>try { teapo.app.loading('Files...'); } catch (err) { alert(err+' '+err.stack); }</script>
    
          <div class=teapo-file-tree
             data-bind="loadRaw: fileTreeHost = $element">
    
            <ul>
    
    <!--
    -->
              <%=embedTree()%>
              
            </ul>
          </div>
    
    <script data-legit=teapo>try { teapo.app.loading('Controls...'); } catch (err) { alert(err+' '+err.stack); }</script>
    
          <div class=teapo-extra-content>
            
            <div class=teapo-branding-area
                 data-bind="loadRaw: brandingArea=$element "></div>
    
    
           <div class=teapo-scrollable-bottom>
    
              <div class=teapo-links>
                <button data-bind="click: deleteClick" style="min-width: 7em; margin-bottom: 0.3em;"> Delete </button> <br>
                <button data-bind="click: buildClick" style="min-width: 7em;"> Build </button> <br>
                <br>
                <a href=# data-bind="click: exportAllHTML"> Save whole page </a><br>
                <a href=# data-bind="click: exportAllZIP"> Export to ZIP </a><br>
                <a href=# data-bind="click: exportCurrentFile"> Save current file </a><br>
                <br>
                <a href=# data-bind="click: importText"> Add file </a><br>
                <a href=# data-bind="click: importBase64"> Add binary (base64) </a><br>
                <a href=# data-bind="click: importZIP"> Import files from ZIP </a><br>
    
              </div>
    
              <div class=teapo-credits>
    
                Teapo v0.5a by Oleg Mihailik. <br>
                <br>
    
                <div style="font-size: 90%;">
                  Used Open Source libraries:<br>
                  <a href="https://github.com/Microsoft/TypeScript">TypeScript</a> (Microsoft, with Apache 2.0 license) <br>
                  <a href="https://github.com/codemirror/CodeMirror">CodeMirror</a> (Marijn Haverbeke, with MIT license) <br>
                  <a href="https://github.com/knockout/knockout">Knockout.js</a> (Ryan Niemeyer, with MIT license) <br>
                  <a href="https://github.com/gildas-lormeau/zip.js">Zip.js</a> (Gildas Lormeau, with BSD license) <br>
                  <a href="https://github.com/chjj/marked">Marked</a> (Christopher Jeffrey, with MIT license) <br>
                  - main contributors mentioned where applicable.
                </div>
    
              </div>
    
            </div>
    
          </div>
    
          
          
        </div>
    
      </div>
    </div>
    
    <div class=teapo-status-bar
       data-bind="loadRaw: docHostRegions.status = $element">
    </div>
    
    <script data-legit=teapo>try { teapo.app.loading('Libraries...'); } catch (err) { alert(err+' '+err.stack); }</script>
    
    
    <script data-legit=teapo><%=embedFile('imports/acorn/acorn.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/acorn/acorn_loose.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/acorn/walk.js')%></script>
    
    <script data-legit=teapo><%=embedFile('imports/tern/signal.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/tern/tern.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/tern/def.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/tern/comment.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/tern/infer.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/tern/doc_comment.js')%></script>
    
    
    
    <script data-legit=teapo><%=embedFile('imports/codemirror/codemirror.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/dialog.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/search.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/searchcursor.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/show-hint.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/javascript.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/tern.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/javascript-hint.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/css.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/css-hint.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/sass.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/xml.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/xml-hint.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/htmlmixed.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/htmlembedded.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/html-hint.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/markdown.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/matchbrackets.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/codemirror/active-line.js')%></script>
    
    <script data-legit=teapo><%=embedFile('imports/knockout/knockout-3.2.0.js')%></script>
    
    <script data-legit=teapo><%=embedFile('imports/zip.js/zip.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/zip.js/deflate.js')%></script>
    <script data-legit=teapo><%=embedFile('imports/zip.js/inflate.js')%></script>
    
    <script data-legit=teapo><%=embedFile('imports/marked/marked.js')%></script>
    
    <script data-legit=teapo><%=embedFile('errors.js')%></script>
    
    <script type=text/html id=MoreDialogView data-legit=teapo><%=embedFile('app/moreDialog/layout.html')%></script>
    <script type=text/html id=ScrollerView data-legit=teapo><%=embedFile('docs/types/text/scrollerView/ScrollerView.html')%></script>
    
    <script data-legit=teapo><%=embedFile('imports/typescript/typescriptServices.js')%></script>
    <script data-legit=teapo id=lib.d.ts type=text/typescriptdefinition><%=embedFile('imports/typescript/lib.d.ts.text')%></script>
    
    
    <script data-legit=teapo>try { teapo.app.start(); } catch (err) { alert(err+' '+err.stack); }</script>
    
    <!--
    <script data-legit=teapo type="text/javascript" src="https://getfirebug.com/firebug-lite.js">
    {
        overrideConsole: true,
        startInNewWindow: false,
        startOpened: true
    }
    </script>
    -->
    
    
    <div id=teapo-last-element></div>
    
    </body>
    </html>
    
  • readme.md
    # teapo v0.5a
    
    Self-editing filesystem embedded in a single HTML file.
    
    The idea, all of the painstaking implementation and the vision by [Oleg Mihailik](mihailik@gmail.com).
    See the credits section for the used libraries and respective licences. 
    
    ### Outstanding tasks:
     * Better internal API for doc handler and for the app itself
     * Highlight of the changed files (comparing local storage and the original DOM)
     * Styles and colours (planning for pale seaside 'Whitstable' blue).
     * Scrollbar to use syntax-highlighted document lines.
     * TypeScript extra features: current signature/symbol in the status, navigate to, search integration, tooltips.
     * More local storage adapters.
     * Delete folder.
     * Rename file/folder.
     * Upload to GitHub, GDrive, Dropbox etc.
     * Stronger browser support (the target is ALL).
     * FS integration in Chrome app, node-webkit, HTMLA-ie7.
     * node emulation over teapo-Drive.
     * Toast popup/fadeout messages for key events: opening, building, import-export completion.
     * Sub-domains for doc handlers (separate contexts in TS/JS for selected subdirectories)
     * Demos in the repository: itself, TypeScript whole, PE.js, dummy sample
    
    The next big version cut is planned for Christmas.
  • try.js
    var __resizeTimer = 0;
    if (false)
    window.onresize = function() {
      if (!__resizeTimer)
        clearTimeout(__resizeTimer);
      __resizeTimer = setTimeout(function(){
        alert('Resize!')
      }, 700);
    }
    
    var doss = document.createElement('pre');
    doss.textContent = '<pre>abcdef    1\n2      2\n\n </pre>';
    alert(doss.innerHTML)
    alert(doss.textContent)

teapo v0.5a

Self-editing filesystem embedded in a single HTML file.

The idea, all of the painstaking implementation and the vision by Oleg Mihailik. See the credits section for the used libraries and respective licences.

Outstanding tasks:

  • Better internal API for doc handler and for the app itself
  • Highlight of the changed files (comparing local storage and the original DOM)
  • Styles and colours (planning for pale seaside 'Whitstable' blue).
  • Scrollbar to use syntax-highlighted document lines.
  • TypeScript extra features: current signature/symbol in the status, navigate to, search integration, tooltips.
  • More local storage adapters.
  • Delete folder.
  • Rename file/folder.
  • Upload to GitHub, GDrive, Dropbox etc.
  • Stronger browser support (the target is ALL).
  • FS integration in Chrome app, node-webkit, HTMLA-ie7.
  • node emulation over teapo-Drive.
  • Toast popup/fadeout messages for key events: opening, building, import-export completion.
  • Sub-domains for doc handlers (separate contexts in TS/JS for selected subdirectories)
  • Demos in the repository: itself, TypeScript whole, PE.js, dummy sample

The next big version cut is planned for Christmas.

Teapo v0.5a by Oleg Mihailik.

Used Open Source libraries:
TypeScript (Microsoft, with Apache 2.0 license)
CodeMirror (Marijn Haverbeke, with MIT license)
Knockout.js (Ryan Niemeyer, with MIT license)
Zip.js (Gildas Lormeau, with BSD license)
Marked (Christopher Jeffrey, with MIT license)
- main contributors mentioned where applicable.
/readme.md