<commit_before>import WebTiledLayer from 'esri/layers/WebTiledLayer';
import layerFactory from 'helpers/LayerFactory';
import LayersHelper from 'helpers/LayersHelper';
import {layersConfig, errors} from 'js/config';
import Point from 'esri/geometry/Point';
import Symbols from 'helpers/Symbols';
import Deferred from 'dojo/Deferred';
import Graphic from 'esri/graphic';
import KEYS from 'js/constants';
import EsriMap from 'esri/map';
import alt from 'js/alt';

// Variable to hold the user location graphic, this is deinfed here to make it
// easier to remove at a later point
let userLocation;

class MapActions {

  createMap (mapConfig) {
    app.debug('MapActions >>> createMap');
    let deferred = new Deferred();
    app.map = new EsriMap(mapConfig.id, mapConfig.options);
    app.map.on('load', () => {
      // Clear out the phantom graphic that esri adds to the graphics layer before resolving
      app.map.graphics.clear();
      deferred.resolve();
    });
    // Add a custom web tiled layer as a basemap
    let customBasemap = new WebTiledLayer(mapConfig.customBasemap.url, mapConfig.customBasemap.options);
    app.map.addLayers([customBasemap]);
    return deferred;
  }

  createLayers () {
    app.debug('MapActions >>> createLayers');
    let layersToAdd = layersConfig.filter(layer => layer && layer.url);
    // Generate a list of layers and add it to the map
    let layers = layersToAdd.map(layerFactory);
    app.map.addLayers(layers);
    // If there is an error with a particular layer, handle that here
    app.map.on('layers-add-result', result => {
      let addedLayers = result.layers;
      // Check for Errors
      var layerErrors = addedLayers.filter(layer => layer.error);
      if (layerErrors.length > 0) { console.error(layerErrors); }
      // Connect events to the layers that need them
      LayersHelper.connectLayerEvents();
      // Reorder some layers here
      let baselineWaterStressLayer = app.map.getLayer(KEYS.waterStress);
      app.map.reorderLayer(baselineWaterStressLayer, 1);
    });
  }

  zoomToUserLocation () {
    app.debug('MapActions >>> zoomToUserLocation');
    if (navigator && navigator.geolocation && navigator.geolocation.getCurrentPosition) {
      navigator.geolocation.getCurrentPosition(geoposition => {
        let coords = geoposition.coords;
        // If there is alerady a location graphic present, remove it
        if (userLocation) { app.map.graphics.remove(userLocation); }
        // Add a graphic to the map and zoom to it
        userLocation = new Graphic(new Point([coords.longitude, coords.latitude]), Symbols.getSVGPointSymbol(), { id: 'userLocation' });
        app.map.centerAndZoom(userLocation.geometry, 18);
        app.map.graphics.add(userLocation);
      }, err => {
        alert(errors.geolocationFailure(err.message));
      });
    } else {
      alert(errors.geolocationUnavailable);
    }
  }

  setBasemap (basemap) {
    this.dispatch(basemap);
  }

  changeBasemap (basemap) {
    app.debug(`MapActions >>> setBasemap - ${basemap}`);
    let layer, labelLayer, baseLayer;
    // Basemap can only be one of two options, wri or satellite
    if (basemap === KEYS.wriBasemap) {
      layer = app.map.getLayer(basemap);
      labelLayer = app.map.getLayer(KEYS.wriBasemapLabel);
      if (layer) { layer.show(); }
      if (labelLayer) { labelLayer.show(); }
      // Remove the satellite layer if its present, wri-basemap should be first in layer ids,
      // if not, then the first layer is satellite
      if (app.map.layerIds[0] !== basemap) {
        baseLayer = app.map.getLayer(app.map.layerIds[0]);
        app.map.removeLayer(baseLayer);
      }
    } else {
      // Hide the wri basemap and show the satellite basemap, KEYS.wriBasemap
      app.map.setBasemap(basemap);
      layer = app.map.getLayer(KEYS.wriBasemap);
      labelLayer = app.map.getLayer(KEYS.wriBasemapLabel);
      if (layer) { layer.hide(); }
      if (labelLayer) { labelLayer.hide(); }
    }
  }

  reset () {
    app.debug('MapActions >>> reset');
    // Reset the Store, this will also reset layers, layer definitions, and all React components
    alt.recycle();
    // Reset the Canopy Density slider
    var slider = $('#tree-cover-slider').data('ionRangeSlider');
    if (slider) { slider.reset(); }
  }

}

export const mapActions = alt.createActions(MapActions);
<commit_msg>added comments for what to do with layer ordering<commit_after>import WebTiledLayer from 'esri/layers/WebTiledLayer';
import layerFactory from 'helpers/LayerFactory';
import LayersHelper from 'helpers/LayersHelper';
import {layersConfig, errors} from 'js/config';
import Point from 'esri/geometry/Point';
import Symbols from 'helpers/Symbols';
import Deferred from 'dojo/Deferred';
import Graphic from 'esri/graphic';
import KEYS from 'js/constants';
import EsriMap from 'esri/map';
import alt from 'js/alt';

// Variable to hold the user location graphic, this is deinfed here to make it
// easier to remove at a later point
let userLocation;

class MapActions {

  createMap (mapConfig) {
    app.debug('MapActions >>> createMap');
    let deferred = new Deferred();
    app.map = new EsriMap(mapConfig.id, mapConfig.options);
    app.map.on('load', () => {
      // Clear out the phantom graphic that esri adds to the graphics layer before resolving
      app.map.graphics.clear();
      deferred.resolve();
    });
    // Add a custom web tiled layer as a basemap
    let customBasemap = new WebTiledLayer(mapConfig.customBasemap.url, mapConfig.customBasemap.options);
    app.map.addLayers([customBasemap]);
    return deferred;
  }

  createLayers () {
    app.debug('MapActions >>> createLayers');
    let layersToAdd = layersConfig.filter(layer => layer && layer.url);
    // Generate a list of layers and add it to the map
    let layers = layersToAdd.map(layerFactory);
    app.map.addLayers(layers);
    // If there is an error with a particular layer, handle that here
    app.map.on('layers-add-result', result => {
      let addedLayers = result.layers;
      // Check for Errors
      var layerErrors = addedLayers.filter(layer => layer.error);
      if (layerErrors.length > 0) { console.error(layerErrors); }
      // Connect events to the layers that need them
      LayersHelper.connectLayerEvents();
      // Reorder some layers here

      // TODO: DONT DO THIS, GIVE LAYER CONFIG AN ORDER PROOPERTY,
      // SORT THE LAYERS RETURNED FROM LAYER FACTORY BEFORE WE ADD THEM
      let baselineWaterStressLayer = app.map.getLayer(KEYS.waterStress);
      app.map.reorderLayer(baselineWaterStressLayer, 1);
    });
  }

  zoomToUserLocation () {
    app.debug('MapActions >>> zoomToUserLocation');
    if (navigator && navigator.geolocation && navigator.geolocation.getCurrentPosition) {
      navigator.geolocation.getCurrentPosition(geoposition => {
        let coords = geoposition.coords;
        // If there is alerady a location graphic present, remove it
        if (userLocation) { app.map.graphics.remove(userLocation); }
        // Add a graphic to the map and zoom to it
        userLocation = new Graphic(new Point([coords.longitude, coords.latitude]), Symbols.getSVGPointSymbol(), { id: 'userLocation' });
        app.map.centerAndZoom(userLocation.geometry, 18);
        app.map.graphics.add(userLocation);
      }, err => {
        alert(errors.geolocationFailure(err.message));
      });
    } else {
      alert(errors.geolocationUnavailable);
    }
  }

  setBasemap (basemap) {
    this.dispatch(basemap);
  }

  changeBasemap (basemap) {
    app.debug(`MapActions >>> setBasemap - ${basemap}`);
    let layer, labelLayer, baseLayer;
    // Basemap can only be one of two options, wri or satellite
    if (basemap === KEYS.wriBasemap) {
      layer = app.map.getLayer(basemap);
      labelLayer = app.map.getLayer(KEYS.wriBasemapLabel);
      if (layer) { layer.show(); }
      if (labelLayer) { labelLayer.show(); }
      // Remove the satellite layer if its present, wri-basemap should be first in layer ids,
      // if not, then the first layer is satellite
      if (app.map.layerIds[0] !== basemap) {
        baseLayer = app.map.getLayer(app.map.layerIds[0]);
        app.map.removeLayer(baseLayer);
      }
    } else {
      // Hide the wri basemap and show the satellite basemap, KEYS.wriBasemap
      app.map.setBasemap(basemap);
      layer = app.map.getLayer(KEYS.wriBasemap);
      labelLayer = app.map.getLayer(KEYS.wriBasemapLabel);
      if (layer) { layer.hide(); }
      if (labelLayer) { labelLayer.hide(); }
    }
  }

  reset () {
    app.debug('MapActions >>> reset');
    // Reset the Store, this will also reset layers, layer definitions, and all React components
    alt.recycle();
    // Reset the Canopy Density slider
    var slider = $('#tree-cover-slider').data('ionRangeSlider');
    if (slider) { slider.reset(); }
  }

}

export const mapActions = alt.createActions(MapActions);
<|endoftext|>


<commit_before>'use strict';

var Reflux = require('reflux');

var actions = require('../actions');

module.exports = Reflux.createStore({
    listenables: actions,

    onSignin: function() {
        this.trigger({pending: true});
    },

    onSigninCompleted: function(user) {
        this.trigger({errors: null, pending: false, user: user});
    },

    onSigninFailed: function(errors) {
        this.trigger({errors: errors, pending: false});
    },

    onSignup: function() {
        this.trigger({pending: true});
    },

    onSignupFailed: function(errors) {
        this.trigger({errors: errors, pending: false});
    },

    onSignout: function() {
        this.trigger({pending: true});
    },

    onSignoutCompleted: function() {
        this.trigger({errors: null, pending: false, user: null});
    }
});
<commit_msg>Updated user store to trigger change on user load completed or failed.<commit_after>'use strict';

var Reflux = require('reflux');

var actions = require('../actions');

module.exports = Reflux.createStore({
    listenables: actions,

    onSignin: function() {
        this.trigger({pending: true});
    },

    onSigninCompleted: function(user) {
        this.trigger({errors: null, pending: false, user: user});
    },

    onSigninFailed: function(errors) {
        this.trigger({errors: errors, pending: false});
    },

    onSignup: function() {
        this.trigger({pending: true});
    },

    onSignupFailed: function(errors) {
        this.trigger({errors: errors, pending: false});
    },

    onSignout: function() {
        this.trigger({pending: true});
    },

    onSignoutCompleted: function() {
        this.trigger({errors: null, pending: false, user: null});
    },

    onUserCompleted: function(user) {
        this.trigger({user: user});
    },

    onUserFailed: function() {
        this.trigger({user: null});
    }
});
<|endoftext|>


<commit_before>// Overwrites native 'children' prototype.
// Adds Document & DocumentFragment support for IE9 & Safari.
// Returns array instead of HTMLCollection.
( function( constructor ) {
    if ( constructor &&
        constructor.prototype &&
        constructor.prototype.children == null ) {
        Object.defineProperty( constructor.prototype, 'children', {
            get: function() {
                var i = 0,
                    node, nodes = this.childNodes,
                    children = [];
                while ( ( node = nodes[ i++ ] ) ) {
                    if ( node.nodeType === 1 ) {
                        children.push( node );
                    }
                }
                return children;
            }
        } );
    }
} )( window.Node || window.Element );
<commit_msg>fixed: IE11 default values not shown in view, closes #565<commit_after>// Overwrites native 'children' prototype.
// Adds Document & DocumentFragment support for IE9 & Safari.
// Returns array instead of HTMLCollection.
( function( constructor ) {
    if ( constructor &&
        constructor.prototype &&
        constructor.prototype.children == null ) {
        Object.defineProperty( constructor.prototype, 'children', {
            get: function() {
                var i = 0,
                    node, nodes = this.childNodes,
                    children = [];
                while ( ( node = nodes[ i++ ] ) ) {
                    if ( node.nodeType === 1 ) {
                        children.push( node );
                    }
                }
                return children;
            }
        } );
    }
} )( window.Node || window.Element );

/**
 * A spec-compliant polyfill for 'parentElement'.
 * @author Frederik Wessberg <https://github.com/wessberg>
 * @version 1.0.0
 */

( function() {
    // Environment doesn't support 'parentElement' or only supports it on nodes that are Elements themselves.
    // To unify behavior between all browsers and to be spec-compliant, parentElement should be supported on any Node.
    function implementation() {
        return this.parentNode instanceof Element ? this.parentNode : null;
    }

    if ( !( 'parentElement' in Document.prototype ) || !( 'parentElement' in Text.prototype ) || !( 'parentElement' in Attr.prototype ) ) {

        try {
            Object.defineProperty( Attr.prototype, 'parentElement', { configurable: false, enumerable: false, get: implementation } );
        } catch ( e ) {
            // IE8
            Attr.prototype.parentElement = implementation;
        }

        try {
            Object.defineProperty( Text.prototype, 'parentElement', { configurable: false, enumerable: false, get: implementation } );
        } catch ( e ) {
            // IE8
            Text.prototype.parentElement = implementation;
        }

        try {
            Object.defineProperty( Element.prototype, 'parentElement', { configurable: false, enumerable: false, get: implementation } );
        } catch ( e ) {
            // IE8
            Element.prototype.parentElement = implementation;
        }

        try {
            Object.defineProperty( Document.prototype, 'parentElement', { configurable: false, enumerable: false, get: implementation } );
        } catch ( e ) {
            // IE8
            Document.prototype.parentElement = implementation;
        }

    }
}() );
<|endoftext|>


<commit_before>let data = {}

function init(tags) {
  data = {
    count: 0,
    tags: {},
    countries: {},
    sentimentByTags: {}
  }

  tags.forEach(tag => {
    data.tags[tag.toLowerCase()] = {
      count: 0
    }
  })
}

function reset() {
  data = {
    count: 0,
    tags: {},
    countries: {},
    sentiment: {
      "Anger": 0.0,
      "Fear": 0.0,
      "Disgust": 0.0,
      "Joy": 0.0,
      "Sadness": 0.0
    }
  }

  for (let tag in data.tags) {
    if (data.tags.hasOwnProperty(tag)) {
      data.tags[tag] = {
        count: 0
      }
    }
  }
}

function processTweet(tweet) {
  data.count++;
  let parsedSentiment = JSON.parse(tweet.sentiment);
  let emotionArr = parsedSentiment.document_tone.tone_categories[0].tones;
  console.log("Main tag: ", tweet.mainTags);

    tweet.mainTags.forEach(tag =>{

      	if (data.sentimentByTags.hasOwnProperty(tag.text.toLowerCase())) {
	      	console.log('has tag')
	        let existingSentimentObjectForKey = data.sentimentByTags[tag.text.toLowerCase()];

	        for (let i = 0; i < emotionArr.length; i++) {

	          let currEmotion = emotionArr[i];
	          console.log('currEmotion: ', currEmotion);
	          existingSentimentObjectForKey[currEmotion.tone_name] += currEmotion.score;
	        }
   		} else {
   			console.log('does not have tag');
   			let sentimentsForTag = {};

   			for (let i = 0; i < emotionArr.length; i++) {
	          let currEmotion = emotionArr[i];
	          sentimentsForTag[currEmotion.tone_name] = currEmotion.score;
	        }

	        data.sentimentByTags[tag.text.toLowerCase()] = sentimentsForTag;
   		}

   		console.log('data.sentimentByTags: ', data.sentimentByTags);
  	});

    if (tweet.place && tweet.place.country_code) {
      let code = tweet.place.country_code
      if (!data.countries[code]) {
        data.countries[code] = {
          count: 0
        }
      }

      data.countries[code].count++
    }

  let tags = tweet.entities.hashtags.map(obj => {
    return obj.text.toLowerCase()
  })

  tags.forEach(tag => {
    if (!!tag && data.tags.hasOwnProperty(tag)) {
      data.tags[tag].count++
    }
  })
}

self.addEventListener('message', (e) => {
  let d = e.data

  switch (d.cmd) {
    case 'init':
      init(d.tags)
      break
    case 'reset':
    case 'stop':
      reset()
      break
    case 'close':
      self.close()
      break
    case 'tweet':
      processTweet(d.tweet)
      break
    case 'broadcast':
      self.postMessage({
        cmd: 'data',
        data
      })
      break
  };
}, false)
<commit_msg>fix lower case errors<commit_after>let data = {}

function init(tags) {
  data = {
    count: 0,
    tags: {},
    countries: {},
    sentimentByTags: {}
  }

  tags.forEach(tag => {
    data.tags[tag.toLowerCase()] = {
      count: 0
    }
  })
}

function reset() {
  data = {
    count: 0,
    tags: {},
    countries: {},
    sentiment: {
      "Anger": 0.0,
      "Fear": 0.0,
      "Disgust": 0.0,
      "Joy": 0.0,
      "Sadness": 0.0
    }
  }

  for (let tag in data.tags) {
    if (data.tags.hasOwnProperty(tag)) {
      data.tags[tag] = {
        count: 0
      }
    }
  }
}

function processTweet(tweet) {
  data.count++;
  let parsedSentiment = JSON.parse(tweet.sentiment);
  let emotionArr = parsedSentiment.document_tone.tone_categories[0].tones;
  console.log("Main tag: ", tweet.mainTags);

    tweet.mainTags.forEach(tag =>{

      	if (data.sentimentByTags.hasOwnProperty(tag.toLowerCase())) {
	      	console.log('has tag')
	        let existingSentimentObjectForKey = data.sentimentByTags[tag.toLowerCase()];

	        for (let i = 0; i < emotionArr.length; i++) {

	          let currEmotion = emotionArr[i];
	          console.log('currEmotion: ', currEmotion);
	          existingSentimentObjectForKey[currEmotion.tone_name] += currEmotion.score;
	        }
   		} else {
   			console.log('does not have tag');
   			let sentimentsForTag = {};

   			for (let i = 0; i < emotionArr.length; i++) {
	          let currEmotion = emotionArr[i];
	          sentimentsForTag[currEmotion.tone_name] = currEmotion.score;
	        }

	        data.sentimentByTags[tag.toLowerCase()] = sentimentsForTag;
   		}

   		console.log('data.sentimentByTags: ', data.sentimentByTags);
  	});

    if (tweet.place && tweet.place.country_code) {
      let code = tweet.place.country_code
      if (!data.countries[code]) {
        data.countries[code] = {
          count: 0
        }
      }

      data.countries[code].count++
    }

  let tags = tweet.entities.hashtags.map(obj => {
    return obj.text.toLowerCase()
  })

  tags.forEach(tag => {
    if (!!tag && data.tags.hasOwnProperty(tag)) {
      data.tags[tag].count++
    }
  })
}

self.addEventListener('message', (e) => {
  let d = e.data

  switch (d.cmd) {
    case 'init':
      init(d.tags)
      break
    case 'reset':
    case 'stop':
      reset()
      break
    case 'close':
      self.close()
      break
    case 'tweet':
      processTweet(d.tweet)
      break
    case 'broadcast':
      self.postMessage({
        cmd: 'data',
        data
      })
      break
  };
}, false)
<|endoftext|>


<commit_before>//> This file is part of Ymacs, an Emacs-like editor for the Web
//> http://www.ymacs.org/
//>
//> Copyright (c) 2009-2010, Mihai Bazon, Dynarch.com.  All rights reserved.
//>
//> Redistribution and use in source and binary forms, with or without
//> modification, are permitted provided that the following conditions are
//> met:
//>
//>     * Redistributions of source code must retain the above copyright
//>       notice, this list of conditions and the following disclaimer.
//>
//>     * 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.
//>
//>     * Neither the name of Dynarch.com nor the names of its contributors
//>       may be used to endorse or promote products derived from this
//>       software without specific prior written permission.
//>
//> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
//> EXPRESS 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 THE COPYRIGHT HOLDER 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.

// @require ymacs-buffer.js
// @require ymacs-tokenizer.js

DEFINE_SINGLETON("Ymacs_Keymap_ParenMatch", Ymacs_Keymap, function(D, P) {

        D.KEYS = {
                "C-c \\"         : "goto_matching_paren",
                "C-M-q"          : "indent_sexp",
                "C-M-f && C-M-n" : "forward_sexp",
                "C-M-b && C-M-p" : "backward_sexp",
                "M-C-k"          : "kill_sexp",
                "M-C-SPACE"      : "mark_sexp",
                "M-C-t"          : "transpose_sexps",
                "M-("            : [ "paredit_wrap_round", "(" ],
                "M-["            : [ "paredit_wrap_round", "[" ],
                "M-{"            : [ "paredit_wrap_round", "{" ],
                'M-"'            : [ "paredit_wrap_round", '"' ],
                "M-'"            : [ "paredit_wrap_round", "'" ]
        };

        /* -----[ new commands ]----- */

        function compareRowCol(p1, p2) {
                return (p1.line < p2.line)
                        ? -1
                        : p1.line > p2.line
                        ? 1
                        : p1.col - p2.col;
        };

        var PARENS = {
                "(" : ")",
                "[" : "]",
                "{" : "}",
                '"' : { close: '"', backslash: /\x22/g },
                "'" : { close: "'", backslash: /\x27/g }
        };

        Ymacs_Buffer.newCommands({

                matching_paren: function() {
                        var p = this.tokenizer.getLastParser(), rc = this._rowcol;
                        if (p) {
                                var parens = p.context.passedParens;
                                return parens.foreach(function(p){
                                        var match = p.closed;
                                        if (p.line == rc.row && p.col == rc.col) {
                                                $RETURN( this._rowColToPosition(match.line, match.col + 1) );
                                        } else if (match.line == rc.row && match.col == rc.col - 1) {
                                                $RETURN( this._rowColToPosition(p.line, p.col) );
                                        }
                                }, this);
                        }
                },

                indent_sexp: Ymacs_Interactive(function() {
                        var pos = this.cmd("matching_paren");
                        if (pos != null) {
                                this.cmd("indent_region", this.point(), pos);
                        } else {
                                this.signalError("Balanced expression not found");
                        }
                }),

                goto_matching_paren: Ymacs_Interactive(function() {
                        var pos = this.cmd("matching_paren");
                        if (pos != null) {
                                this.cmd("goto_char", pos);
                                this.cmd("recenter_top_bottom");
                                return true;
                        }
                }),

                forward_sexp: Ymacs_Interactive(function() {
                        var rc = this._rowcol, p = this.tokenizer.finishParsing();
                        if (p) {
                                // find next paren
                                var parens = p.context.passedParens.mergeSort(compareRowCol);
                                var next = parens.foreach(function(p){
                                        if (p.line > rc.row || (p.line == rc.row && p.col >= rc.col)) {
                                                $RETURN(p);
                                        }
                                }, this);
                                if (!next || !next.closed) {
                                        this.signalError("Balanced expression not found");
                                        return;
                                }
                                var start = this._rowColToPosition(next.line, next.col);
                                if ((this._rowcol.row == next.line && this._rowcol.col == next.col)
                                    || !/\S/.test(this._bufferSubstring(null, start)))
                                        this.cmd("goto_char", this._rowColToPosition(next.closed.line, next.closed.col) + 1);
                                else
                                        this.cmd("goto_char", start);
                                return true;
                        }
                }),

                backward_sexp: Ymacs_Interactive(function() {
                        var rc = this._rowcol, p = this.tokenizer.finishParsing();
                        if (p) {
                                // find next paren
                                var parens = p.context.passedParens.grep("closed").map("closed").mergeSort(compareRowCol);
                                var prev = parens.r_foreach(function(p){
                                        if (p.line < rc.row || (p.line == rc.row && p.col < rc.col))
                                                $RETURN(p);
                                }, this);
                                if (!prev) {
                                        this.signalError("Balanced expression not found");
                                        return;
                                }
                                this.cmd("goto_char", this._rowColToPosition(prev.opened.line, prev.opened.col));
                                return true;
                        }
                }),

                mark_sexp: Ymacs_Interactive("^r", function(begin, end){
                        this.cmd("save_excursion", function(){
                                if (this.transientMarker)
                                        this.cmd("goto_char", end);
                                this.ensureTransientMark();
                                this.cmd("forward_sexp");
                                this.cmd("set_mark_command", this.point());
                                this.transientMarker.swap(this.caretMarker);
                        });
                        this.ensureTransientMark();
                }),

                kill_sexp: Ymacs_Interactive(function() {
                        this._killingAction(
                                this.point(),
                                this.cmd("save_excursion", function() {
                                        this.cmd("forward_sexp");
                                        return this.point();
                                })
                        );
                }),

                transpose_sexps: Ymacs_Interactive(function() {
                        var a = [];
                        this.cmd("forward_sexp"); a.push(this.point());
                        this.cmd("backward_sexp"); a.push(this.point());
                        this.cmd("backward_sexp"); a.push(this.point());
                        this.cmd("forward_sexp"); a.push(this.point());
                        this.cmd("goto_char", this._swapAreas(a));
                }),

                paredit_wrap_round: Ymacs_Interactive("^", function(paren){
                        if (!paren)
                                paren = "(";
                        var closing = PARENS[paren],
                            r = this.transientMarker
                                ? this.getRegion()
                                : this.cmd("save_excursion", function(){
                                        var begin = this.point();
                                        this.cmd("forward_sexp");
                                        return { begin: begin, end: this.point() };
                                }),
                            txt = this._bufferSubstring(r.begin, r.end),
                            before = this.point() < r.end;
                        if (typeof closing != "string") {
                                txt = txt.replace(closing.backslash, function(s){
                                        return "\\" + s;
                                });
                                closing = closing.close;
                        }
                        var m = this.createMarker(r.end);
                        this.cmd("save_excursion", function(){
                                this._replaceText(r.begin, r.end, paren + txt + closing);
                        }, before);
                        this.cmd("forward_char", before ? 1 : -1);
                        this.clearTransientMark();
                        this.cmd("indent_region", r.begin, m.getPosition());
                        m.destroy();
                })

        });

});

Ymacs_Buffer.newMode("paren_match_mode", function(){

        var keymap = Ymacs_Keymap_ParenMatch();
        this.pushKeymap(keymap);

        var active = false,
            clearOvl = function() {
                    if (active)
                            this.deleteOverlay("match-paren");
            }.clearingTimeout(500, this);

        var events = {
                beforeInteractiveCommand: function() {
                        clearOvl.doItNow();
                },
                afterInteractiveCommand: function() {
                        var p = this.tokenizer.getLastParser(), rc = this._rowcol;
                        if (p) {
                                p.context.passedParens.foreach(function(p){
                                        var match = p.closed;
                                        if ((p.line == rc.row && p.col == rc.col) ||
                                            (match.line == rc.row && match.col == rc.col - 1)) {
                                                active = true;
                                                this.setOverlay("match-paren", {
                                                        line1: p.line, line2: match.line,
                                                        col1: p.col, col2: match.col + 1
                                                });
                                                clearOvl();
                                        }
                                }, this);
                        }
                }.clearingTimeout(100)
        };
        this.addEventListener(events);

        return function() {
                clearOvl.doItNow();
                this.popKeymap(keymap);
                this.removeEventListener(events);
        };

});
<commit_msg>minor: don't forward_sexp in paredit_wrap_round for " and '<commit_after>//> This file is part of Ymacs, an Emacs-like editor for the Web
//> http://www.ymacs.org/
//>
//> Copyright (c) 2009-2010, Mihai Bazon, Dynarch.com.  All rights reserved.
//>
//> Redistribution and use in source and binary forms, with or without
//> modification, are permitted provided that the following conditions are
//> met:
//>
//>     * Redistributions of source code must retain the above copyright
//>       notice, this list of conditions and the following disclaimer.
//>
//>     * 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.
//>
//>     * Neither the name of Dynarch.com nor the names of its contributors
//>       may be used to endorse or promote products derived from this
//>       software without specific prior written permission.
//>
//> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
//> EXPRESS 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 THE COPYRIGHT HOLDER 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.

// @require ymacs-buffer.js
// @require ymacs-tokenizer.js

DEFINE_SINGLETON("Ymacs_Keymap_ParenMatch", Ymacs_Keymap, function(D, P) {

        D.KEYS = {
                "C-c \\"         : "goto_matching_paren",
                "C-M-q"          : "indent_sexp",
                "C-M-f && C-M-n" : "forward_sexp",
                "C-M-b && C-M-p" : "backward_sexp",
                "M-C-k"          : "kill_sexp",
                "M-C-SPACE"      : "mark_sexp",
                "M-C-t"          : "transpose_sexps",
                "M-("            : [ "paredit_wrap_round", "(" ],
                "M-["            : [ "paredit_wrap_round", "[" ],
                "M-{"            : [ "paredit_wrap_round", "{" ],
                'M-"'            : [ "paredit_wrap_round", '"', true ],
                "M-'"            : [ "paredit_wrap_round", "'", true ]
        };

        /* -----[ new commands ]----- */

        function compareRowCol(p1, p2) {
                return (p1.line < p2.line)
                        ? -1
                        : p1.line > p2.line
                        ? 1
                        : p1.col - p2.col;
        };

        var PARENS = {
                "(" : ")",
                "[" : "]",
                "{" : "}",
                '"' : { close: '"', backslash: /\x22/g },
                "'" : { close: "'", backslash: /\x27/g }
        };

        Ymacs_Buffer.newCommands({

                matching_paren: function() {
                        var p = this.tokenizer.getLastParser(), rc = this._rowcol;
                        if (p) {
                                var parens = p.context.passedParens;
                                return parens.foreach(function(p){
                                        var match = p.closed;
                                        if (p.line == rc.row && p.col == rc.col) {
                                                $RETURN( this._rowColToPosition(match.line, match.col + 1) );
                                        } else if (match.line == rc.row && match.col == rc.col - 1) {
                                                $RETURN( this._rowColToPosition(p.line, p.col) );
                                        }
                                }, this);
                        }
                },

                indent_sexp: Ymacs_Interactive(function() {
                        var pos = this.cmd("matching_paren");
                        if (pos != null) {
                                this.cmd("indent_region", this.point(), pos);
                        } else {
                                this.signalError("Balanced expression not found");
                        }
                }),

                goto_matching_paren: Ymacs_Interactive(function() {
                        var pos = this.cmd("matching_paren");
                        if (pos != null) {
                                this.cmd("goto_char", pos);
                                this.cmd("recenter_top_bottom");
                                return true;
                        }
                }),

                forward_sexp: Ymacs_Interactive(function() {
                        var rc = this._rowcol, p = this.tokenizer.finishParsing();
                        if (p) {
                                // find next paren
                                var parens = p.context.passedParens.mergeSort(compareRowCol);
                                var next = parens.foreach(function(p){
                                        if (p.line > rc.row || (p.line == rc.row && p.col >= rc.col)) {
                                                $RETURN(p);
                                        }
                                }, this);
                                if (!next || !next.closed) {
                                        this.signalError("Balanced expression not found");
                                        return;
                                }
                                var start = this._rowColToPosition(next.line, next.col);
                                if ((this._rowcol.row == next.line && this._rowcol.col == next.col)
                                    || !/\S/.test(this._bufferSubstring(null, start)))
                                        this.cmd("goto_char", this._rowColToPosition(next.closed.line, next.closed.col) + 1);
                                else
                                        this.cmd("goto_char", start);
                                return true;
                        }
                }),

                backward_sexp: Ymacs_Interactive(function() {
                        var rc = this._rowcol, p = this.tokenizer.finishParsing();
                        if (p) {
                                // find next paren
                                var parens = p.context.passedParens.grep("closed").map("closed").mergeSort(compareRowCol);
                                var prev = parens.r_foreach(function(p){
                                        if (p.line < rc.row || (p.line == rc.row && p.col < rc.col))
                                                $RETURN(p);
                                }, this);
                                if (!prev) {
                                        this.signalError("Balanced expression not found");
                                        return;
                                }
                                this.cmd("goto_char", this._rowColToPosition(prev.opened.line, prev.opened.col));
                                return true;
                        }
                }),

                mark_sexp: Ymacs_Interactive("^r", function(begin, end){
                        this.cmd("save_excursion", function(){
                                if (this.transientMarker)
                                        this.cmd("goto_char", end);
                                this.ensureTransientMark();
                                this.cmd("forward_sexp");
                                this.cmd("set_mark_command", this.point());
                                this.transientMarker.swap(this.caretMarker);
                        });
                        this.ensureTransientMark();
                }),

                kill_sexp: Ymacs_Interactive(function() {
                        this._killingAction(
                                this.point(),
                                this.cmd("save_excursion", function() {
                                        this.cmd("forward_sexp");
                                        return this.point();
                                })
                        );
                }),

                transpose_sexps: Ymacs_Interactive(function() {
                        var a = [];
                        this.cmd("forward_sexp"); a.push(this.point());
                        this.cmd("backward_sexp"); a.push(this.point());
                        this.cmd("backward_sexp"); a.push(this.point());
                        this.cmd("forward_sexp"); a.push(this.point());
                        this.cmd("goto_char", this._swapAreas(a));
                }),

                paredit_wrap_round: Ymacs_Interactive("^", function(paren, nosexp){
                        if (!paren)
                                paren = "(";
                        var closing = PARENS[paren],
                            r = this.transientMarker
                                ? this.getRegion()
                                : this.cmd("save_excursion", function(){
                                        var begin = this.point();
                                        if (!nosexp)
                                                this.cmd("forward_sexp");
                                        return { begin: begin, end: this.point() };
                                }),
                            txt = this._bufferSubstring(r.begin, r.end),
                            before = this.point() < r.end;
                        if (typeof closing != "string") {
                                txt = txt.replace(closing.backslash, function(s){
                                        return "\\" + s;
                                });
                                closing = closing.close;
                        }
                        var m = this.createMarker(r.end);
                        this.cmd("save_excursion", function(){
                                this._replaceText(r.begin, r.end, paren + txt + closing);
                        }, before);
                        this.cmd("forward_char", before ? 1 : -1);
                        this.clearTransientMark();
                        this.cmd("indent_region", r.begin, m.getPosition());
                        m.destroy();
                })

        });

});

Ymacs_Buffer.newMode("paren_match_mode", function(){

        var keymap = Ymacs_Keymap_ParenMatch();
        this.pushKeymap(keymap);

        var active = false,
            clearOvl = function() {
                    if (active)
                            this.deleteOverlay("match-paren");
            }.clearingTimeout(500, this);

        var events = {
                beforeInteractiveCommand: function() {
                        clearOvl.doItNow();
                },
                afterInteractiveCommand: function() {
                        var p = this.tokenizer.getLastParser(), rc = this._rowcol;
                        if (p) {
                                p.context.passedParens.foreach(function(p){
                                        var match = p.closed;
                                        if ((p.line == rc.row && p.col == rc.col) ||
                                            (match.line == rc.row && match.col == rc.col - 1)) {
                                                active = true;
                                                this.setOverlay("match-paren", {
                                                        line1: p.line, line2: match.line,
                                                        col1: p.col, col2: match.col + 1
                                                });
                                                clearOvl();
                                        }
                                }, this);
                        }
                }.clearingTimeout(100)
        };
        this.addEventListener(events);

        return function() {
                clearOvl.doItNow();
                this.popKeymap(keymap);
                this.removeEventListener(events);
        };

});
<|endoftext|>


<commit_before>'use strict';

const { memoize } = require('../../../utilities');

// Rules to validate JSL defined in IDL file.
// Each type is a node type.
// If the node type is missing, it means it is not allowed.
// Node types can be functions to create custom validation per type.
// General idea:
//  - functions should be pure, so we can memoize them, and to prevent
//    security risks
//     - no side-effects, including assignments and declarations
//     - no access to global state
//  - functions should be synchronous
//  - functions should be short and simple.
//    If one needs more complexity, use non-inline function instead.
//    This is also to prevent security risks (DDoS with expensive or
//    long-running operations)
//     - single expression
//     - no structures
//     - functions must be arrow functions
//     - function calls must be `func()` or `obj.func()`
//     - no classes, generators, ArrayBuffer, TypedArray, Map, Set, SIMD, Proxy,
//       Reflect or debugger
const getRules = memoize(({ globalKeys }) => ({

  Program({ start, body }) {
    if (start !== 0) {
      return 'Top-level expression is invalid';
    }
    if (body.length === 0) {
      return 'Must include at least one expression';
    }
    if (body.length > 1) {
      return 'Cannot include several statements';
    }
    const statement = body[0];
    if (statement.type !== 'ExpressionStatement') {
      return 'Top-level must be simple expression';
    }
  },

  Expression: true,
  Statement: true,
  ExpressionStatement({ expression: { type, value } }) {
    if (type === 'Literal' && value === 'use strict') {
      return 'Cannot use "use strict"';
    }
  },

  // Functions are allowed, but only arrow functions because no declarations
  Function: true,
  ArrowFunctionExpression: true,

  Pattern: true,
  Identifier({ name }) {
    if (globalKeys.includes(name)) {
      return `No access to global state: cannot use '${name}'`;
    }
  },
  MemberExpression: true,
  ObjectPattern: true,
  Property: true,
  AssignmentProperty: true,
  ArrayPattern: true,
  RestElement: true,
  AssignmentPattern: true,
  SpreadElement: true,

  Literal: true,
  TemplateLiteral: true,
  TemplateElement: true,
  ArrayExpression: true,
  ObjectExpression: true,

  UnaryExpression({ operator }) {
    if (operator === 'delete') {
      return 'No side-effects: cannot use \'delete\'';
    }
  },
  BinaryExpression: true,
  LogicalExpression: true,
  ConditionalExpression: true,

  // Blacklist which function can be called
  CallExpression({ callee: { type, property, name }, arguments: args }) {
    const usesIdentifier = type === 'Identifier';
    const usesMemberExpression = type === 'MemberExpression' &&
      property.type === 'Identifier';
    if (!usesIdentifier && !usesMemberExpression) {
      return 'Function calls must be like: \'func()\' or \'obj.func()\'';
    }
    const funcName = usesMemberExpression ? property.name : name;
    if (functionFuncNames.includes(funcName)) {
      return `Cannot call '${funcName}()'`;
    }
    if (sideEffectsFuncNames.includes(funcName)) {
      return `No side-effects: cannot call '${funcName}()'`;
    }
    if (globalFuncNames.includes(funcName)) {
      return `No access to global state: cannot call '${funcName}()'`;
    }
    if (asyncFuncNames.includes(funcName)) {
      return `Must be synchronous: cannot call '${funcName}()'`;
    }
    const isWrongAssign = funcName === 'assign' &&
      (!args[0] || args[0].type !== 'ObjectExpression');
    if (isWrongAssign) {
      return 'No side-effects: \'Object.assign()\' first argument must be a literal object';
    }
  },
  // Whitelist which constructor can be called
  NewExpression({ callee: { type, name } }) {
    const usesIdentifier = type === 'Identifier';
    if (!usesIdentifier) {
      return 'Constructor calls must be like: \'new Type()\'';
    }
    if (!allowedConstructors.includes(name)) {
      return `Cannot call 'new ${name}()'`;
    }
  },

  ScopeExpression: true,
  ScopeBody: true,

  // TODO: remove when https://github.com/ternjs/acorn/pull/558 is fixed
  VariablePattern: true,
  MemberPattern: true,
}));

// We do not want things like eval() which could circumvent our restrictions
const functionFuncNames = ['eval', 'Function', 'bind', 'call', 'apply'];

// Those methods create side-effects, e.g. assignments
const sideEffectsFuncNames = [
  'defineProperty',
  'defineProperties',
  'preventExtensions',
  'seal',
  'freeze',
  'setPrototypeOf',
  'splice',
  'fill',
  'copyWithin',
  'push',
  'pop',
  'unshift',
  'shift',
  'setDate',
  'setFullYear',
  'setHours',
  'setMilliseconds',
  'setMinutes',
  'setMonth',
  'setSeconds',
  'setTime',
  'setUTCDate',
  'setUTCFullYear',
  'setUTCHours',
  'setUTCMilliseconds',
  'setUTCMinutes',
  'setUTCMonth',
  'setUTCSeconds',
  'setYear',
];

// Those methods access global state
const globalFuncNames = ['for', 'keyFor'];

// Those methods imply async code
const asyncFuncNames = ['then', 'catch'];

// Those are the only constructors that can be called with `new`
const allowedConstructors = ['Date', 'Array', 'RegExp'];

module.exports = {
  system: {
    getRules,
  },
  startup: {
    getRules,
  },
};
<commit_msg>Fix arg.filter crashing<commit_after>'use strict';

const { memoize } = require('../../../utilities');

// Rules to validate JSL defined in IDL file.
// Each type is a node type.
// If the node type is missing, it means it is not allowed.
// Node types can be functions to create custom validation per type.
// General idea:
//  - functions should be pure, so we can memoize them, and to prevent
//    security risks
//     - no side-effects, including assignments and declarations
//     - no access to global state
//  - functions should be synchronous
//  - functions should be short and simple.
//    If one needs more complexity, use non-inline function instead.
//    This is also to prevent security risks (DDoS with expensive or
//    long-running operations)
//     - single expression
//     - no structures
//     - functions must be arrow functions
//     - function calls must be `func()` or `obj.func()`
//     - no classes, generators, ArrayBuffer, TypedArray, Map, Set, SIMD, Proxy,
//       Reflect or debugger
const getRules = memoize(({ globalKeys }) => ({

  Program({ start, body }) {
    if (start !== 0) {
      return 'Top-level expression is invalid';
    }
    if (body.length === 0) {
      return 'Must include at least one expression';
    }
    if (body.length > 1) {
      return 'Cannot include several statements';
    }
    const statement = body[0];
    if (statement.type !== 'ExpressionStatement') {
      return 'Top-level must be simple expression';
    }
  },

  Expression: true,
  Statement: true,
  ExpressionStatement({ expression: { type, value } }) {
    if (type === 'Literal' && value === 'use strict') {
      return 'Cannot use "use strict"';
    }
  },

  // Functions are allowed, but only arrow functions because no declarations
  Function: true,
  ArrowFunctionExpression: true,

  Pattern: true,
  Identifier({ name }) {
    if (globalKeys.includes(name)) {
      return `No access to global state: cannot use '${name}'`;
    }
  },
  MemberExpression: true,
  ObjectPattern: true,
  Property: true,
  AssignmentProperty: true,
  ArrayPattern: true,
  RestElement: true,
  AssignmentPattern: true,
  SpreadElement: true,

  Literal: true,
  TemplateLiteral: true,
  TemplateElement: true,
  ArrayExpression: true,
  ObjectExpression: true,

  UnaryExpression({ operator }) {
    if (operator === 'delete') {
      return 'No side-effects: cannot use \'delete\'';
    }
  },
  BinaryExpression: true,
  LogicalExpression: true,
  ConditionalExpression: true,

  // Blacklist which function can be called
  CallExpression({ callee: { type, property, name }, arguments: args }) {
    const usesIdentifier = type === 'Identifier';
    const usesMemberExpression = type === 'MemberExpression' &&
      property.type === 'Identifier';
    if (!usesIdentifier && !usesMemberExpression) {
      return 'Function calls must be like: \'func()\' or \'obj.func()\'';
    }
    const funcName = usesMemberExpression ? property.name : name;
    if (functionFuncNames.includes(funcName)) {
      return `Cannot call '${funcName}()'`;
    }
    if (sideEffectsFuncNames.includes(funcName)) {
      return `No side-effects: cannot call '${funcName}()'`;
    }
    if (globalFuncNames.includes(funcName)) {
      return `No access to global state: cannot call '${funcName}()'`;
    }
    if (asyncFuncNames.includes(funcName)) {
      return `Must be synchronous: cannot call '${funcName}()'`;
    }
    const isWrongAssign = funcName === 'assign' &&
      (!args[0] || args[0].type !== 'ObjectExpression');
    if (isWrongAssign) {
      return 'No side-effects: \'Object.assign()\' first argument must be a literal object';
    }
  },
  // Whitelist which constructor can be called
  NewExpression({ callee: { type, name } }) {
    const usesIdentifier = type === 'Identifier';
    if (!usesIdentifier) {
      return 'Constructor calls must be like: \'new Type()\'';
    }
    if (!allowedConstructors.includes(name)) {
      return `Cannot call 'new ${name}()'`;
    }
  },

  ScopeExpression: true,
  ScopeBody: true,

  // TODO: remove when https://github.com/ternjs/acorn/pull/558 is fixed
  VariablePattern: true,
  MemberPattern: true,
}));

// We do not want things like eval() which could circumvent our restrictions
const functionFuncNames = ['eval', 'Function', 'bind', 'call', 'apply'];

// Those methods create side-effects, e.g. assignments
const sideEffectsFuncNames = [
  'defineProperty',
  'defineProperties',
  'preventExtensions',
  'seal',
  'freeze',
  'setPrototypeOf',
  'splice',
  'fill',
  'copyWithin',
  'push',
  'pop',
  'unshift',
  'shift',
  'setDate',
  'setFullYear',
  'setHours',
  'setMilliseconds',
  'setMinutes',
  'setMonth',
  'setSeconds',
  'setTime',
  'setUTCDate',
  'setUTCFullYear',
  'setUTCHours',
  'setUTCMilliseconds',
  'setUTCMinutes',
  'setUTCMonth',
  'setUTCSeconds',
  'setYear',
];

// Those methods access global state
const globalFuncNames = ['for', 'keyFor'];

// Those methods imply async code
const asyncFuncNames = ['then', 'catch'];

// Those are the only constructors that can be called with `new`
const allowedConstructors = ['Date', 'Array', 'RegExp'];

module.exports = {
  system: {
    getRules,
  },
  startup: {
    getRules,
  },
  // TODO: remove when we parse arg.filter into a database object
  filter: {
    getRules,
  },
};
<|endoftext|>


<commit_before>/***

  RESTly API Framework, based on Express

***/

var _       = require('underscore'),
    fs      = require('fs'),
    routes  = require('./lib/routes.js'),
    caching  = require('./lib/caching.js');

// global for exporting
var restly = {};

// set up express
var express = require('express');
var app = express();

// force express to parse posted and putted parameters
app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/tmp' }));

// define public directory for docs
app.use(express.static(__dirname+'/public'));

// wrapper for passing middleware to express
restly.use = function(mw) {
  app.use(mw);
}

// init
restly.init = function(r, opts) {

  // make sure all our defaults are set
  var opts = defaultOpts(opts);

  // get our routes
  var routesCollection = routes.getRoutes(r);

  // for each route
  for(var rc in routesCollection) {

    var apicall = routesCollection[rc];

    // add authentication object to apicall
    if (apicall.authentication) {

      // get authentication methods
      apicall.authentication = routes.getAuthentication(r, apicall.authentication);

      // combine api call params with authentication params
      apicall = routes.combineWithAuthentication(apicall);

      routesCollection[rc] = apicall;
    }

    // get the full and correct path for the library
    apicall.library = process.cwd()+"/"+opts.lib+apicall.library;

    // and for the authentication library, if required
    if (apicall.authentication && apicall.authentication.library) {
      apicall.authentication.library = process.cwd()+"/"+opts.lib+apicall.authentication.library;
    }

    // are we enabling caching?
    if (!opts.caching || !apicall.caching) {
      apicall.caching = false;
    }

    else {
      apicall.caching = caching.parseOptsCache(opts.caching);

      // add special _use_cache param to API call
      apicall.parameters._use_cache = {
        "required": false,
        "type": "bool",
        "description":"Do you want to read from the cache",
        "default": true
      }
    }

    // set up a express listener for each call
    switch(apicall.method) {
      case 'put':

        (function(ac) {
          app.put(ac.endpoint, function (req,res) {
            routes.parseRequest(ac, req, res);
          });
        })(apicall);
        break;

      case 'post':

        (function(ac) {
          app.post(ac.endpoint, function (req,res) {
            routes.parseRequest(ac, req, res);
          });
        })(apicall);
        break;

      case 'delete':

        (function(ac) {
          app.delete(ac.endpoint, function (req,res) {
            routes.parseRequest(ac, req, res);
          });
        })(apicall);
        break;

      case 'get':

        (function(ac) {
          app.get(ac.endpoint, function (req,res) {
            routes.parseRequest(ac, req, res);
          });
        })(apicall);
        break;
    }

  }

  // documentation page
  app.get(opts.docs_endpoint, function(req, res) {

    var sections = [];
    for (var r in routesCollection) {
      sections.push(routesCollection[r].section);
    }

    sections = _.uniq(sections)

    // prepare the page data
    var page = {
                  routes: routesCollection,
                  config: opts,
                  section: false,
                  sections: sections,
                  docs_endpoint: opts.docs_endpoint
                };

    // render the channel list page
    res.render(process.cwd()+"/node_modules/restly/views/index.jade", page);

  });

  // documentation page by section
  app.get(opts.docs_endpoint+"section/:section", function(req, res) {

    var sections = [];
    for (var r in routesCollection) {
      sections.push(routesCollection[r].section);
    }

    sections = _.uniq(sections)

    // prepare the page data
    var page = {
                  routes: routesCollection,
                  config: opts,
                  section: req.params.section,
                  sections: sections,
                  docs_endpoint: opts.docs_endpoint
                };

    // render the channel list page
    res.render(process.cwd()+"/node_modules/restly/views/index.jade", page);

  });

  // listen on the specified port
  if (opts.protocol == 'https') {
    // set up for secure server
    var fs = require('fs');
    var https = require('https');

    try {
        var privateKey  = fs.readFileSync(opts.ssl_private_key, 'utf8');
        var certificate = fs.readFileSync(opts.ssl_certificate, 'utf8');
    } catch (e) {
        if (e.code === 'ENOENT') {
            console.log('\n    Cannot find SSL private key or certificate file.');
            console.log('   Make sure "'+opts.ssl_private_key+'" and "'+opts.ssl_certificate+'" exist.')

            throw e;
        }
    }

    var credentials = { key: privateKey, cert: certificate };

    var server = https.createServer(credentials, app);

    server.listen(opts.port);
  } else {
      var server = app.listen(opts.port);
  }

  // this function is called when you want the server to die gracefully
  // i.e. wait for existing connections
  var gracefulShutdown = function() {
    console.log("Received kill signal, shutting down gracefully.");
    server.close(function() {
      console.log("Closed out remaining connections.");
      process.exit()
    });

    // if after
    setTimeout(function() {
        console.error("Could not close connections in time, forcefully shutting down");
        process.exit()
   }, 3*1000);

  }

  // listen for TERM signal .e.g. kill <pid>
  process.on ('SIGTERM', gracefulShutdown);

  // listen for INT signal e.g. Ctrl-C
  process.on ('SIGINT', gracefulShutdown);

}

// default options
var defaultOpts = function(opts) {

  // define defaults
  var defaults = {
    lib: "",
    protocol: "http",
    domain: "localhost",
    port: 8000,
    ssl_private_key: "sslcert/server.key",
    ssl_certificate: "sslcert/server.crt",
    name: "My API",
    description: "Interactive API docs",
    docs_endpoint: "/",
    caching: false
  }

  // change defaults with supplied opts
  if (!_.isUndefined(opts) && _.isObject(opts)) {

    for (var o in opts) {

      if (!_.isUndefined(defaults[o])) {
        defaults[o] = opts[o];
      }

    }

  }

  // check for sane protocol values
  if (!_.isString(defaults.protocol)) { defaults.protocol = "http"; }
  defaults.protocol = defaults.protocol.toLowerCase();
  if (defaults.protocol != 'http' && defaults.protocol != 'https') { defaults.protocol = 'http'; }

  // sane port values
  if (!_.isNumber(defaults.port)) {
    // sane secure server values
    if (defaults.protocol == 'https') {
      defaults.port = 8443;
    } else {
      defaults.port = 8000;
    }
  }

  // sane docs endpoints value
  if (defaults.docs_endpoint != "/") {
    if (defaults.docs_endpoint == "") {
      defaults.docs_endpoint = "/";
    } else {
      defaults.docs_endpoint = defaults.docs_endpoint.replace(/^\/?(.*?)\/?$/, '/$1/');
    }
  }

  // return
  return defaults;

}

// export
module.exports = restly
<commit_msg>Testing CORS headers<commit_after>/***

  RESTly API Framework, based on Express

***/

var _       = require('underscore'),
    fs      = require('fs'),
    routes  = require('./lib/routes.js'),
    caching  = require('./lib/caching.js');

// global for exporting
var restly = {};

// set up express
var express = require('express');
var app = express();

// force express to parse posted and putted parameters
app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/tmp' }));

// define public directory for docs
app.use(express.static(__dirname+'/public'));

// wrapper for passing middleware to express
restly.use = function(mw) {
  app.use(mw);
}

// init
restly.init = function(r, opts) {

  // make sure all our defaults are set
  var opts = defaultOpts(opts);

  // get our routes
  var routesCollection = routes.getRoutes(r);

  // for each route
  for(var rc in routesCollection) {

    var apicall = routesCollection[rc];

    // add authentication object to apicall
    if (apicall.authentication) {

      // get authentication methods
      apicall.authentication = routes.getAuthentication(r, apicall.authentication);

      // combine api call params with authentication params
      apicall = routes.combineWithAuthentication(apicall);

      routesCollection[rc] = apicall;
    }

    // get the full and correct path for the library
    apicall.library = process.cwd()+"/"+opts.lib+apicall.library;

    // and for the authentication library, if required
    if (apicall.authentication && apicall.authentication.library) {
      apicall.authentication.library = process.cwd()+"/"+opts.lib+apicall.authentication.library;
    }

    // are we enabling caching?
    if (!opts.caching || !apicall.caching) {
      apicall.caching = false;
    }

    else {
      apicall.caching = caching.parseOptsCache(opts.caching);

      // add special _use_cache param to API call
      apicall.parameters._use_cache = {
        "required": false,
        "type": "bool",
        "description":"Do you want to read from the cache",
        "default": true
      }
    }

    //Set up addition headers here
    if(apicall.cross_origin) {
      app.all('/', function(req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "X-Requested-With");
        next();
      });
    }

    // set up a express listener for each call
    switch(apicall.method) {
      case 'put':

        (function(ac) {
          app.put(ac.endpoint, function (req,res) {
            routes.parseRequest(ac, req, res);
          });
        })(apicall);
        break;

      case 'post':

        (function(ac) {
          app.post(ac.endpoint, function (req,res) {
            routes.parseRequest(ac, req, res);
          });
        })(apicall);
        break;

      case 'delete':

        (function(ac) {
          app.delete(ac.endpoint, function (req,res) {
            routes.parseRequest(ac, req, res);
          });
        })(apicall);
        break;

      case 'get':

        (function(ac) {
          app.get(ac.endpoint, function (req,res) {
            routes.parseRequest(ac, req, res);
          });
        })(apicall);
        break;
    }

  }

  // documentation page
  app.get(opts.docs_endpoint, function(req, res) {

    var sections = [];
    for (var r in routesCollection) {
      sections.push(routesCollection[r].section);
    }

    sections = _.uniq(sections)

    // prepare the page data
    var page = {
                  routes: routesCollection,
                  config: opts,
                  section: false,
                  sections: sections,
                  docs_endpoint: opts.docs_endpoint
                };

    // render the channel list page
    res.render(process.cwd()+"/node_modules/restly/views/index.jade", page);

  });

  // documentation page by section
  app.get(opts.docs_endpoint+"section/:section", function(req, res) {

    var sections = [];
    for (var r in routesCollection) {
      sections.push(routesCollection[r].section);
    }

    sections = _.uniq(sections)

    // prepare the page data
    var page = {
                  routes: routesCollection,
                  config: opts,
                  section: req.params.section,
                  sections: sections,
                  docs_endpoint: opts.docs_endpoint
                };

    // render the channel list page
    res.render(process.cwd()+"/node_modules/restly/views/index.jade", page);

  });

  // listen on the specified port
  if (opts.protocol == 'https') {
    // set up for secure server
    var fs = require('fs');
    var https = require('https');

    try {
        var privateKey  = fs.readFileSync(opts.ssl_private_key, 'utf8');
        var certificate = fs.readFileSync(opts.ssl_certificate, 'utf8');
    } catch (e) {
        if (e.code === 'ENOENT') {
            console.log('\n    Cannot find SSL private key or certificate file.');
            console.log('   Make sure "'+opts.ssl_private_key+'" and "'+opts.ssl_certificate+'" exist.')

            throw e;
        }
    }

    var credentials = { key: privateKey, cert: certificate };

    var server = https.createServer(credentials, app);

    server.listen(opts.port);
  } else {
      var server = app.listen(opts.port);
  }

  // this function is called when you want the server to die gracefully
  // i.e. wait for existing connections
  var gracefulShutdown = function() {
    console.log("Received kill signal, shutting down gracefully.");
    server.close(function() {
      console.log("Closed out remaining connections.");
      process.exit()
    });

    // if after
    setTimeout(function() {
        console.error("Could not close connections in time, forcefully shutting down");
        process.exit()
   }, 3*1000);

  }

  // listen for TERM signal .e.g. kill <pid>
  process.on ('SIGTERM', gracefulShutdown);

  // listen for INT signal e.g. Ctrl-C
  process.on ('SIGINT', gracefulShutdown);

}

// default options
var defaultOpts = function(opts) {

  // define defaults
  var defaults = {
    lib: "",
    protocol: "http",
    domain: "localhost",
    port: 8000,
    ssl_private_key: "sslcert/server.key",
    ssl_certificate: "sslcert/server.crt",
    name: "My API",
    description: "Interactive API docs",
    docs_endpoint: "/",
    caching: false
  }

  // change defaults with supplied opts
  if (!_.isUndefined(opts) && _.isObject(opts)) {

    for (var o in opts) {

      if (!_.isUndefined(defaults[o])) {
        defaults[o] = opts[o];
      }

    }

  }

  // check for sane protocol values
  if (!_.isString(defaults.protocol)) { defaults.protocol = "http"; }
  defaults.protocol = defaults.protocol.toLowerCase();
  if (defaults.protocol != 'http' && defaults.protocol != 'https') { defaults.protocol = 'http'; }

  // sane port values
  if (!_.isNumber(defaults.port)) {
    // sane secure server values
    if (defaults.protocol == 'https') {
      defaults.port = 8443;
    } else {
      defaults.port = 8000;
    }
  }

  // sane docs endpoints value
  if (defaults.docs_endpoint != "/") {
    if (defaults.docs_endpoint == "") {
      defaults.docs_endpoint = "/";
    } else {
      defaults.docs_endpoint = defaults.docs_endpoint.replace(/^\/?(.*?)\/?$/, '/$1/');
    }
  }

  // return
  return defaults;

}

// export
module.exports = restly
<|endoftext|>


<commit_before>// See https://github.com/myape/CodeMirror2/blob/0b109319eda1e12f9d1a7024c7be640eda21ae36/mode/sql/sql.js
CodeMirror.defineMode("sql", function (config, parserConfig) {
    var indentUnit = config.indentUnit,
        keywords = parserConfig.keywords,
        functions = parserConfig.functions,
        types = parserConfig.types,
        operators = parserConfig.operators,
        multiLineStrings = parserConfig.multiLineStrings;
    var isOperatorChar = /[+\-*&%=<>!?:\/|]/;

    function chain(stream, state, f) {
        state.tokenize = f;
        return f(stream, state);
    }

    var type;
    function ret(tp, style) {
        type = tp;
        return style;
    }

    function tokenBase(stream, state) {
        var ch = stream.next();
        // start of string?
        if (ch == '"' || ch == "'" || ch == "`") {
            return chain(stream, state, tokenString(ch));
        }
        // is it one of the special signs []{}().?
        else if (/[\[\]{}\(\)\.]/.test(ch)) {
            return ret(ch);
        }
        // Seperator?
        else if (ch == "," || ch == ";") {
            return "sql-separator";
        }
        // start of a number value?
        else if (/\d/.test(ch)) {
            stream.eatWhile(/[\w\.]/)
            return ret("number", "sql-number");
        }
        // multi line comment or simple operator?
        else if (ch == "/") {
            if (stream.eat("*")) {
                return chain(stream, state, tokenComment);
            }
            else {
                stream.eatWhile(isOperatorChar);
                return ret("operator", "sql-operator");
            }
        }
        // single line comment or simple operator?
        else if (ch == "-") {
            if (stream.eat("-")) {
                stream.skipToEnd();
                return ret("comment", "sql-comment");
            } else {
                stream.eatWhile(isOperatorChar);
                return ret("operator", "sql-operator");
            }
        }
        // another single line comment
        else if (ch == '#') {
            stream.skipToEnd();
            return ret("comment", "sql-comment");
        }
        // sql variable?
        else if (ch == "@" || ch == "$") {
            stream.eatWhile(/[\w\d\$_]/);
            return ret("word", "sql-var");
        }
        // is it a operator?
        else if (isOperatorChar.test(ch)) {
            stream.eatWhile(isOperatorChar);
            return ret("operator", "sql-operator");
        }
        // a punctuation?
        else if (/[()]/.test(ch)) {
            return "sql-punctuation";
        } else {
            // get the whole word
            stream.eatWhile(/[\w\$_]/);
            // is it one of the listed keywords?
            if (keywords && keywords.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "sql-keyword");
            // is it one of the listed functions?
            if (functions && functions.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "sql-function");
            // is it one of the listed types?
            if (types && types.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "sql-type");
            // is it one of the listed sqlplus keywords?
            if (operators && operators.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "sql-operators");
            // default: just a "word"
            return ret("word", "sql-word");
        }

    }

    function tokenString(quote) {
        return function (stream, state) {
            var escaped = false, next, end = false;
            while ((next = stream.next()) != null) {
                if (next == quote && !escaped) { end = true; break; }
                escaped = !escaped && next == "\\";
            }
            if (end || !(escaped || multiLineStrings))
                state.tokenize = tokenBase;
            var style = quote == "`" ? "sql-quoted-word" : "sql-literal";
            return ret("string", style);
        };
    }

    function tokenComment(stream, state) {
        var maybeEnd = false, ch;
        while (ch = stream.next()) {
            if (ch == "/" && maybeEnd) {
                state.tokenize = tokenBase;
                break;
            }
            maybeEnd = (ch == "*");
        }
        return ret("comment", "sql-comment");
    }

    // Interface

    return {
        startState: function (basecolumn) {
            return {
                tokenize: tokenBase,
                indented: 0,
                startOfLine: true
            };
        },

        token: function (stream, state) {
            if (stream.eatSpace()) return null;
            var style = state.tokenize(stream, state);
            return style;
        },
        electricChars: ")"

    };
});

(function () {
    function keywords(str) {
        var obj = {}, words = str.split(" ");
        for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
        return obj;
    }
    var cKeywords =
        "alter grant revoke primary key table start top " +
        "transaction select update insert delete create describe " +
        "from into values where join inner left natural and " +
        "or in not xor like using on order group by " +
        "asc desc limit offset union all as distinct set " +
        "commit rollback replace view database separator if " +
        "exists null truncate status show lock unique having " +
        "drop procedure begin end delimiter call else leave " +
        "declare temporary then case when with";

    var cFunctions =
        "abs acos adddate aes_encrypt aes_decrypt ascii " +
        "asin atan atan2 avg benchmark bin bit_and " +
        "bit_count bit_length bit_or cast ceil ceiling " +
        "char_length character_length coalesce concat concat_ws " +
        "connection_id conv convert cos cot count curdate " +
        "current_date current_time current_timestamp current_user " +
        "curtime database date_add date_format date_sub " +
        "dayname dayofmonth dayofweek dayofyear decode degrees " +
        "des_encrypt des_decrypt elt encode encrypt exp " +
        "export_set extract field find_in_set floor format " +
        "found_rows from_days from_unixtime get_lock greatest " +
        "group_unique_users hex ifnull inet_aton inet_ntoa instr " +
        "interval is_free_lock isnull last_insert_id lcase least " +
        "left length ln load_file locate log log2 log10 " +
        "lower lpad ltrim make_set master_pos_wait max md5 " +
        "mid min mod monthname now nullif oct octet_length " +
        "ord password period_add period_diff pi position " +
        "pow power quarter quote radians rand release_lock " +
        "repeat reverse right round rpad rtrim sec_to_time " +
        "session_user sha sha1 sign sin soundex space sqrt " +
        "std stddev strcmp subdate substring substring_index " +
        "sum sysdate system_user tan time_format time_to_sec " +
        "to_days trim ucase unique_users unix_timestamp upper " +
        "user version week weekday yearweek ntile";

    var cTypes =
        "bigint binary bit blob bool char character date " +
        "datetime dec decimal double enum float float4 float8 " +
        "int int1 int2 int3 int4 int8 integer long longblob " +
        "longtext mediumblob mediumint mediumtext middleint nchar " +
        "numeric real set smallint text time timestamp tinyblob " +
        "tinyint tinytext varbinary varchar year";

    var cOperators =
        ":= < <= == <> > >= like rlike in xor between";

    CodeMirror.defineMIME("text/x-t-sql", {
        name: "sql",
        keywords: keywords(cKeywords),
        functions: keywords(cFunctions),
        types: keywords(cTypes),
        operators: keywords(cOperators)
    });
} ());<commit_msg>Made the syntax highlighting a bit more correct for T-SQL<commit_after>// See https://github.com/myape/CodeMirror2/blob/0b109319eda1e12f9d1a7024c7be640eda21ae36/mode/sql/sql.js
CodeMirror.defineMode("sql", function (config, parserConfig) {
    var indentUnit = config.indentUnit,
        keywords = parserConfig.keywords,
        functions = parserConfig.functions,
        types = parserConfig.types,
        operators = parserConfig.operators,
        multiLineStrings = parserConfig.multiLineStrings;
    var isOperatorChar = /[+\-*&%=<>!?:\/|]/;

    function chain(stream, state, f) {
        state.tokenize = f;
        return f(stream, state);
    }

    var type;
    function ret(tp, style) {
        type = tp;
        return style;
    }

    function tokenBase(stream, state) {
        var ch = stream.next();
        // start of string?
        if (ch == "'") {
            return chain(stream, state, tokenString(ch));
        }
        // is it one of the special signs []{}().?
        else if (/[\[\]{}\(\)\.]/.test(ch)) {
            return ret(ch);
        }
        // Seperator?
        else if (ch == "," || ch == ";") {
            return "sql-separator";
        }
        // start of a number value?
        else if (/\d/.test(ch)) {
            stream.eatWhile(/[\w\.]/)
            return ret("number", "sql-number");
        }
        // multi line comment or simple operator?
        else if (ch == "/") {
            if (stream.eat("*")) {
                return chain(stream, state, tokenComment);
            }
            else {
                stream.eatWhile(isOperatorChar);
                return ret("operator", "sql-operator");
            }
        }
        // single line comment or simple operator?
        else if (ch == "-") {
            if (stream.eat("-")) {
                stream.skipToEnd();
                return ret("comment", "sql-comment");
            } else {
                stream.eatWhile(isOperatorChar);
                return ret("operator", "sql-operator");
            }
        }
        // another single line comment
        // Should turn this into a token for magic variables if we can
        /*
        else if (ch == '#') {
            stream.skipToEnd();
            return ret("comment", "sql-comment");
        }
        */
        // sql variable?
        else if (ch == "@" || ch == "$") {
            stream.eatWhile(/[\w\d\$_]/);
            return ret("word", "sql-var");
        }
        // is it a operator?
        else if (isOperatorChar.test(ch)) {
            stream.eatWhile(isOperatorChar);
            return ret("operator", "sql-operator");
        }
        // a punctuation?
        else if (/[()]/.test(ch)) {
            return "sql-punctuation";
        } else {
            // get the whole word
            stream.eatWhile(/[\w\$_]/);
            // is it one of the listed keywords?
            if (keywords && keywords.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "sql-keyword");
            // is it one of the listed functions?
            if (functions && functions.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "sql-function");
            // is it one of the listed types?
            if (types && types.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "sql-type");
            // is it one of the listed sqlplus keywords?
            if (operators && operators.propertyIsEnumerable(stream.current().toLowerCase())) return ret("keyword", "sql-operators");
            // default: just a "word"
            return ret("word", "sql-word");
        }

    }

    function tokenString(quote) {
        return function (stream, state) {
            var escaped = false, next, end = false;
            while ((next = stream.next()) != null) {
                // This isn't how T-SQL strings work, need to fix
                if (next == quote && !escaped) { end = true; break; }
                escaped = !escaped && next == "\\";
            }
            if (end || !(escaped || multiLineStrings))
                state.tokenize = tokenBase;
            var style = quote == "`" ? "sql-quoted-word" : "sql-literal";
            return ret("string", style);
        };
    }

    function tokenComment(stream, state) {
        var maybeEnd = false, ch;
        while (ch = stream.next()) {
            if (ch == "/" && maybeEnd) {
                state.tokenize = tokenBase;
                break;
            }
            maybeEnd = (ch == "*");
        }
        return ret("comment", "sql-comment");
    }

    // Interface

    return {
        startState: function (basecolumn) {
            return {
                tokenize: tokenBase,
                indented: 0,
                startOfLine: true
            };
        },

        token: function (stream, state) {
            if (stream.eatSpace()) return null;
            var style = state.tokenize(stream, state);
            return style;
        },
        electricChars: ")"

    };
});

(function () {
    function keywords(str) {
        var obj = {}, words = str.split(" ");
        for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
        return obj;
    }
    var cKeywords =
        "alter grant revoke primary key table start top " +
        "transaction select update insert delete create describe " +
        "from into values where join inner left natural and " +
        "or in not xor like using on order group by " +
        "asc desc limit offset union all as distinct set " +
        "commit rollback replace view database separator if " +
        "exists null truncate status show lock unique having " +
        "drop procedure begin end delimiter call else leave " +
        "declare temporary then case when with";

    var cFunctions =
        "abs acos adddate aes_encrypt aes_decrypt ascii " +
        "asin atan atan2 avg benchmark bin bit_and " +
        "bit_count bit_length bit_or cast ceil ceiling " +
        "char_length character_length coalesce concat concat_ws " +
        "connection_id conv convert cos cot count curdate " +
        "current_date current_time current_timestamp current_user " +
        "curtime database date_add date_format date_sub " +
        "dayname dayofmonth dayofweek dayofyear decode degrees " +
        "des_encrypt des_decrypt elt encode encrypt exp " +
        "export_set extract field find_in_set floor format " +
        "found_rows from_days from_unixtime get_lock greatest " +
        "group_unique_users hex ifnull inet_aton inet_ntoa instr " +
        "interval is_free_lock isnull last_insert_id lcase least " +
        "left length ln load_file locate log log2 log10 " +
        "lower lpad ltrim make_set master_pos_wait max md5 " +
        "mid min mod monthname now nullif oct octet_length " +
        "ord password period_add period_diff pi position " +
        "pow power quarter quote radians rand release_lock " +
        "repeat reverse right round rpad rtrim sec_to_time " +
        "session_user sha sha1 sign sin soundex space sqrt " +
        "std stddev strcmp subdate substring substring_index " +
        "sum sysdate system_user tan time_format time_to_sec " +
        "to_days trim ucase unique_users unix_timestamp upper " +
        "user version week weekday yearweek ntile";

    var cTypes =
        "bigint binary bit blob bool char character date " +
        "datetime dec decimal double enum float float4 float8 " +
        "int int1 int2 int3 int4 int8 integer long longblob " +
        "longtext mediumblob mediumint mediumtext middleint nchar " +
        "numeric real set smallint text time timestamp tinyblob " +
        "tinyint tinytext varbinary varchar year";

    var cOperators =
        ":= < <= == <> > >= like rlike in xor between";

    CodeMirror.defineMIME("text/x-t-sql", {
        name: "sql",
        keywords: keywords(cKeywords),
        functions: keywords(cFunctions),
        types: keywords(cTypes),
        operators: keywords(cOperators),
        multiLineStrings: true
    });
} ());<|endoftext|>