<commit_before>'use strict';

/**
 * @ngdoc function
 * @name MatchCalendarApp.controller:HeadergeneratorCtrl
 * @description
 * # HeadergeneratorCtrl
 * Controller of the MatchCalendarApp
 */
angular.module('MatchCalendarApp')
    .controller('HeadergeneratorCtrl', function ($scope, $window, $state, $interpolate, $modal, $localForage) {
        $scope.regions = {
            'AF': 'Africa',
            'AN': 'Antartica',
            'AS': 'Asia',
            'EU': 'Europe',
            'NA': 'North America',
            'OC': 'Oceania',
            'SA': 'South America'
        };

        $scope.templates = $scope.$new(true);

        $scope.templates.rawTemplate =
            '\n**Game Information**' +
            '\n---' +
            '\n\n**Opens:** {{ opensUTC() }}' +
            '\n\n**Starts:** {{ startsUTC() }}' +
            '\n\n**Gametype:** Random Teams of 3' +
            '\n\n**Scenario:** Vanilla+' +
            '\n\n**Map Size:** 2000x2000' +
            '\n\n**Nether:** Enabled' +
            '\n\n**Duration:** 90 Minutes + Meetup' +
            '\n\n**PvP:** 15 minutes in' +
            '\n\n**Perma Day:** 30 minutes prior to Meetup' +
            '\n\n**TeamSpeak 3 + Working Mic:** Required' +
            '\n\n**Winner(s):** TBD' +
            '\n___' +
            '\n\n**Server Information**' +
            '\n---' +
            '\n\n**Slots:** 40' +
            '\n\n___' +
            '\n\n**Features**' +
            '\n---' +
            '\n\n**Golden Heads:** Enabled (Heal: 4 hearts)' +
            '\n\n**Absorption:** Disabled' +
            '\n\n**Enderpearl Damage:** Disabled' +
            '\n\n**Death Lightning:** Enabled' +
            '\n\n**Strength II:** Enabled but nerfed' +
            '\n\n**Flint Rates:** Default' +
            '\n\n**Apple Rates:** Default' +
            '\n\n*To know more, /feature list in-game!*' +
            '\n\n___' +
            '\n\n**General Server Information**' +
            '\n---' +
            '\n\n**Location:** ' +
            '\n\n**Server Provider / RAM:** ' +
            '\n\n**IP:** {{ generator.address }}' +
            '\n\n**Version:** 1.7.x' +
            '\n\n___' +
            '\n\n\n**Scenarios**' +
            '\n---' +
            '\n\n* **Vanilla+:** Vanilla with minor tweaks';

        $scope.templates.generated = '';

        //save the template
        $localForage.bind($scope.templates, 'rawTemplate');

        $scope.generator = {
            address: '192.168.0.1',
            postTitle: 'Game Title',
            region: 'NA'
        };

        //save the settings
        $localForage.bind($scope, 'generator');

        //add utility functions
        $scope.opensUTC = function() {
            return $scope.T.format($scope.T.formats.REDDIT_POST, $scope.opens, true);
        };
        $scope.startsUTC = function() {
            return $scope.T.format($scope.T.formats.REDDIT_POST, $scope.starts, true);
        };

        //add the non-settings
        $scope.opens = $scope.T.currentTime();
        $scope.starts = $scope.T.currentTime();

        //minimum time for things to show
        $scope.minTime = $scope.T.currentTime();

        //update $scope.generatedLink with the matchpost link
        $scope.updateGenerated = function() {
            var generatedVersion = {
                opens: $scope.opens.utc().format('YYYY-MM-DDTHH:mm:ssZ'),
                starts: $scope.starts.utc().format('YYYY-MM-DDTHH:mm:ssZ'),
                address: $scope.generator.address.replace(/\[/g, '[').replace(/\]/g, ']'),
                title:  $scope.generator.postTitle.replace(/\[/g, '[').replace(/\]/g, ']'),
                region: $scope.generator.region
            };

            $scope.generatedLink = '[' + JSON.stringify(generatedVersion) + '](/matchpost)';
        };

        $scope.updateTemplate = function() {
            $scope.templates.generated = $interpolate($scope.templates.rawTemplate, false, null, true)($scope);
        };

        //open a new window to create a reddit post with the template
        $scope.openReddit = function() {
            $scope.updateGenerated();
            $scope.updateTemplate();
            window.open(
                    'https://reddit.com/r/ultrahardcore/submit?title='
                  + encodeURIComponent($scope.T.format($scope.T.formats.REDDIT_POST, $scope.starts.utc(), true) + ' [' + $scope.generator.region + '] - ' + $scope.generator.postTitle)
                  + '&text='
                  + encodeURIComponent($scope.templates.generated)
                  + encodeURIComponent('\n\n' + $scope.generatedLink)
                  + encodeURIComponent('\n\n*^created ^using ^the [^Match ^Calendar](' + $window.location.protocol + '//' + $window.location.host + ')*')
                , '_blank');
        };

        $scope.editTemplate = function() {
            $scope.updateTemplate();
            $modal.open({
                templateUrl: 'components/Generator/TemplateEditor.html',
                scope: $scope,
                size: 'lg'
            });
        };

        //opens a modal to copy/paste the link from
        $scope.openLinkModal = function() {
            $scope.updateGenerated();
            $modal.open({
                templateUrl: 'components/Generator/matchPostLink.html',
                scope: $scope
            });
        };
    });
<commit_msg>fix(Generator): Use the window object instead of global<commit_after>'use strict';

/**
 * @ngdoc function
 * @name MatchCalendarApp.controller:HeadergeneratorCtrl
 * @description
 * # HeadergeneratorCtrl
 * Controller of the MatchCalendarApp
 */
angular.module('MatchCalendarApp')
    .controller('HeadergeneratorCtrl', function ($scope, $window, $state, $interpolate, $modal, $localForage) {
        $scope.regions = {
            'AF': 'Africa',
            'AN': 'Antartica',
            'AS': 'Asia',
            'EU': 'Europe',
            'NA': 'North America',
            'OC': 'Oceania',
            'SA': 'South America'
        };

        $scope.templates = $scope.$new(true);

        $scope.templates.rawTemplate =
            '\n**Game Information**' +
            '\n---' +
            '\n\n**Opens:** {{ opensUTC() }}' +
            '\n\n**Starts:** {{ startsUTC() }}' +
            '\n\n**Gametype:** Random Teams of 3' +
            '\n\n**Scenario:** Vanilla+' +
            '\n\n**Map Size:** 2000x2000' +
            '\n\n**Nether:** Enabled' +
            '\n\n**Duration:** 90 Minutes + Meetup' +
            '\n\n**PvP:** 15 minutes in' +
            '\n\n**Perma Day:** 30 minutes prior to Meetup' +
            '\n\n**TeamSpeak 3 + Working Mic:** Required' +
            '\n\n**Winner(s):** TBD' +
            '\n___' +
            '\n\n**Server Information**' +
            '\n---' +
            '\n\n**Slots:** 40' +
            '\n\n___' +
            '\n\n**Features**' +
            '\n---' +
            '\n\n**Golden Heads:** Enabled (Heal: 4 hearts)' +
            '\n\n**Absorption:** Disabled' +
            '\n\n**Enderpearl Damage:** Disabled' +
            '\n\n**Death Lightning:** Enabled' +
            '\n\n**Strength II:** Enabled but nerfed' +
            '\n\n**Flint Rates:** Default' +
            '\n\n**Apple Rates:** Default' +
            '\n\n*To know more, /feature list in-game!*' +
            '\n\n___' +
            '\n\n**General Server Information**' +
            '\n---' +
            '\n\n**Location:** ' +
            '\n\n**Server Provider / RAM:** ' +
            '\n\n**IP:** {{ generator.address }}' +
            '\n\n**Version:** 1.7.x' +
            '\n\n___' +
            '\n\n\n**Scenarios**' +
            '\n---' +
            '\n\n* **Vanilla+:** Vanilla with minor tweaks';

        $scope.templates.generated = '';

        //save the template
        $localForage.bind($scope.templates, 'rawTemplate');

        $scope.generator = {
            address: '192.168.0.1',
            postTitle: 'Game Title',
            region: 'NA'
        };

        //save the settings
        $localForage.bind($scope, 'generator');

        //add utility functions
        $scope.opensUTC = function() {
            return $scope.T.format($scope.T.formats.REDDIT_POST, $scope.opens, true);
        };
        $scope.startsUTC = function() {
            return $scope.T.format($scope.T.formats.REDDIT_POST, $scope.starts, true);
        };

        //add the non-settings
        $scope.opens = $scope.T.currentTime();
        $scope.starts = $scope.T.currentTime();

        //minimum time for things to show
        $scope.minTime = $scope.T.currentTime();

        //update $scope.generatedLink with the matchpost link
        $scope.updateGenerated = function() {
            var generatedVersion = {
                opens: $scope.opens.utc().format('YYYY-MM-DDTHH:mm:ssZ'),
                starts: $scope.starts.utc().format('YYYY-MM-DDTHH:mm:ssZ'),
                address: $scope.generator.address.replace(/\[/g, '[').replace(/\]/g, ']'),
                title:  $scope.generator.postTitle.replace(/\[/g, '[').replace(/\]/g, ']'),
                region: $scope.generator.region
            };

            $scope.generatedLink = '[' + JSON.stringify(generatedVersion) + '](/matchpost)';
        };

        $scope.updateTemplate = function() {
            $scope.templates.generated = $interpolate($scope.templates.rawTemplate, false, null, true)($scope);
        };

        //open a new window to create a reddit post with the template
        $scope.openReddit = function() {
            $scope.updateGenerated();
            $scope.updateTemplate();
            $window.open(
                    'https://reddit.com/r/ultrahardcore/submit?title='
                  + encodeURIComponent($scope.T.format($scope.T.formats.REDDIT_POST, $scope.starts.utc(), true) + ' [' + $scope.generator.region + '] - ' + $scope.generator.postTitle)
                  + '&text='
                  + encodeURIComponent($scope.templates.generated)
                  + encodeURIComponent('\n\n' + $scope.generatedLink)
                  + encodeURIComponent('\n\n*^created ^using ^the [^Match ^Calendar](' + $window.location.protocol + '//' + $window.location.host + ')*')
                , '_blank');
        };

        $scope.editTemplate = function() {
            $scope.updateTemplate();
            $modal.open({
                templateUrl: 'components/Generator/TemplateEditor.html',
                scope: $scope,
                size: 'lg'
            });
        };

        //opens a modal to copy/paste the link from
        $scope.openLinkModal = function() {
            $scope.updateGenerated();
            $modal.open({
                templateUrl: 'components/Generator/matchPostLink.html',
                scope: $scope
            });
        };
    });
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;
var pg = require('pg');
var Q = require("q");
var request = require("request");
var newUser = require("./db");
var nlp = require("./nlp");
var pushConv = require("./push");

const scriptRules = require('./script.json');

function wait(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

module.exports = new Script({
    processing: {
        //prompt: (bot) => bot.say('Beep boop...'),
        receive: () => 'processing'
    },

    start: {
        receive: (bot) => {
            return bot.say('Hello!  I\'m A16, the Agile2016 EventBot Concierge.  To find out what I can help you with type MENU for options or KEY for Keywords.')
                .then(() => 'speak');
        }
    },

    speak: {
        receive: (bot, message) => {
            console.log("===bot user ");
            console.log("===receive step 1",message);
            let upperText = message.text.trim().toUpperCase();

            var botUser = bot.userId;
            var authUsers = ['a30fa820d0a0f0216fa26070'];

            //Undone - currently only creates new user
            //needs to create conversation record and update it throughout the prcoess
            console.log("===before db",bot);
            newUser(bot)
              .then (console.log("===after db", bot.userId))

              //undone - test for userid and or message
              //look at stacking messages in DB and looking them up
              //end conversation and do not send a response to the user that kicked things off
              //
              if (authUsers.indexOf(bot.userId) !== -1) {
                if (message.text.substr(0,5) == '/msg ') {
                  upperText = upperText.substr(0,4);
                  pushConv(bot, message.text.substr(5));
                  console.log("****after push msg:  ",message.text);
                }
              }

            function updateSilent() {
                switch (upperText) {
                    case "CONNECT ME":
                        return bot.setProp("silent", true);
                    case "/SUPPORT":
                        return bot.setProp("silent", true);
                    case "DISCONNECT":
                        return bot.setProp("silent", false);
                    case "/A16":
                        return bot.setProp("silent", false);
                    default:
                        return Promise.resolve();
                }
            }

            console.log("===receive step 2",upperText);

            function getSilent() {
                return bot.getProp("silent");
            }

            function processMessage(isSilent) {
                if (isSilent) {
                    return Promise.resolve("speak");
                }

                var promises = [];
                var source;
                var fulfillmentSpeech;
                var simplified;
                promises.push(nlp(message.text, bot.userId));

                Q.all(promises).then(function(responses) {
                    // response is the JSON from API.ai
                    responses.forEach(function(response) {
                        //console.log("===in Q.all");
                        console.log("===received result from API.ai",response);
                        source = response.result.source;
                        if (source && source !== 'agent')
                        {
                            fulfillmentSpeech = response.result.fulfillment.speech;
                            simplified = response.result.parameters.simplified;
                        }
                        console.log("source: ", source);
                        console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                        console.log("simplified: ", simplified);

                        respondMessage(source, fulfillmentSpeech, simplified);
                    });
                }, function(error) {
                    console.log("===Q all error ", error);
                });
                //return next();

            }

            function respondMessage(source, fulfillmentSpeech, simplified)
            {
                console.log("source: ", source);
                console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                console.log("simplified: ", simplified);
                console.log("===receive step 3",upperText);

              if (source != 'agent')
                {
                    console.log("===source is ", source);
                    if (fulfillmentSpeech)
                    {
                        console.log("fulfillmentSpeech is: ", fulfillmentSpeech);
                        //return bot.say(fulfillmentSpeech).then(() => 'speak');
                        upperText = simplified.trim().toUpperCase();
                    }
                    else if (simplified)
                    {
                        console.log("simplified is: ", simplified);
                        upperText = simplified.toUpperCase();
                    }
                }
                if (!_.has(scriptRules, upperText)) {
                    console.log("===no rule", upperText);
                    return bot.say(`I'm sorry that is not something I know.  Type MENU or KEY for a list of things I can help you with.`).then(() => 'speak');
                }

                console.log("===receive step 3",upperText);

                var response = scriptRules[upperText];
                var lines = response.split('\n');

                bot.userId = botUser;

                var p = Promise.resolve();
                _.each(lines, function(line) {
                    line = line.trim();
                    p = p.then(function() {
                        console.log("=== p line",line);
                        return wait(50).then(function() {
                            return bot.say(line);
                        });
                    });
                });
                return p.then(() => 'speak');
            }

            return updateSilent()
                .then(getSilent)
                .then(processMessage);
        }
    }
});
<commit_msg>testing text for turning back on bot<commit_after>'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;
var pg = require('pg');
var Q = require("q");
var request = require("request");
var newUser = require("./db");
var nlp = require("./nlp");
var pushConv = require("./push");

const scriptRules = require('./script.json');

function wait(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

module.exports = new Script({
    processing: {
        //prompt: (bot) => bot.say('Beep boop...'),
        receive: () => 'processing'
    },

    start: {
        receive: (bot) => {
            return bot.say('Hello!  I\'m A16, the Agile2016 EventBot Concierge.  To find out what I can help you with type MENU for options or KEY for Keywords.')
                .then(() => 'speak');
        }
    },

    speak: {
        receive: (bot, message) => {
            console.log("===bot user ");
            console.log("===receive step 1",message);
            let upperText = message.text.trim().toUpperCase();

            var botUser = bot.userId;
            var authUsers = ['a30fa820d0a0f0216fa26070'];

            //Undone - currently only creates new user
            //needs to create conversation record and update it throughout the prcoess
            console.log("===before db",bot);
            newUser(bot)
              .then (console.log("===after db", bot.userId))

              //undone - test for userid and or message
              //look at stacking messages in DB and looking them up
              //end conversation and do not send a response to the user that kicked things off
              //
              if (authUsers.indexOf(bot.userId) !== -1) {
                if (message.text.substr(0,5) == '/msg ') {
                  upperText = upperText.substr(0,4);
                  pushConv(bot, message.text.substr(5));
                  console.log("****after push msg:  ",message.text);
                }
              }

            function updateSilent() {
                switch (upperText) {
                    case "CONNECT ME":
                        return bot.setProp("silent", true);
                    case "/SUPPORT":
                        return bot.setProp("silent", true);
                    case "DISCONNECT":
                        return bot.setProp("silent", false);
                    case "/A16":
                        console.log("*** ",upperText," ***");
                        return bot.setProp("silent", false);
                    default:
                        return Promise.resolve();
                }
            }

            console.log("===receive step 2",upperText);

            function getSilent() {
                return bot.getProp("silent");
            }

            function processMessage(isSilent) {
                if (isSilent) {
                    return Promise.resolve("speak");
                }

                var promises = [];
                var source;
                var fulfillmentSpeech;
                var simplified;
                promises.push(nlp(message.text, bot.userId));

                Q.all(promises).then(function(responses) {
                    // response is the JSON from API.ai
                    responses.forEach(function(response) {
                        //console.log("===in Q.all");
                        console.log("===received result from API.ai",response);
                        source = response.result.source;
                        if (source && source !== 'agent')
                        {
                            fulfillmentSpeech = response.result.fulfillment.speech;
                            simplified = response.result.parameters.simplified;
                        }
                        console.log("source: ", source);
                        console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                        console.log("simplified: ", simplified);

                        respondMessage(source, fulfillmentSpeech, simplified);
                    });
                }, function(error) {
                    console.log("===Q all error ", error);
                });
                //return next();

            }

            function respondMessage(source, fulfillmentSpeech, simplified)
            {
                console.log("source: ", source);
                console.log("fulfillmentSpeech: ", fulfillmentSpeech);
                console.log("simplified: ", simplified);
                console.log("===receive step 3",upperText);

              if (source != 'agent')
                {
                    console.log("===source is ", source);
                    if (fulfillmentSpeech)
                    {
                        console.log("fulfillmentSpeech is: ", fulfillmentSpeech);
                        //return bot.say(fulfillmentSpeech).then(() => 'speak');
                        upperText = simplified.trim().toUpperCase();
                    }
                    else if (simplified)
                    {
                        console.log("simplified is: ", simplified);
                        upperText = simplified.toUpperCase();
                    }
                }
                if (!_.has(scriptRules, upperText)) {
                    console.log("===no rule", upperText);
                    return bot.say(`I'm sorry that is not something I know.  Type MENU or KEY for a list of things I can help you with.`).then(() => 'speak');
                }

                console.log("===receive step 3",upperText);

                var response = scriptRules[upperText];
                var lines = response.split('\n');

                bot.userId = botUser;

                var p = Promise.resolve();
                _.each(lines, function(line) {
                    line = line.trim();
                    p = p.then(function() {
                        console.log("=== p line",line);
                        return wait(50).then(function() {
                            return bot.say(line);
                        });
                    });
                });
                return p.then(() => 'speak');
            }

            return updateSilent()
                .then(getSilent)
                .then(processMessage);
        }
    }
});
<|endoftext|>


<commit_before>var docfilestore=require("../stores/docfile");
var stackwidgetaction=require("../actions/stackwidget");
var overlayaction=require("../actions/overlay");
var milestones=require("ksana-codemirror").milestones;
var ktxfilestore=require("../stores/ktxfile");

var gotoRangeOrMarkupID=function(file,range_mid,opts) {
	opts=opts||{};
	if (opts.below && !opts.autoOpen) opts.autoOpen=true;

	var targetdoc=docfilestore.docOf(file);

	if (targetdoc) {
		if (!targetdoc.getEditor().react.markupReady()) {
		//wait for this.state.markups ready, because markups is load later
		//see ksana-codemirror/src/codemirror-react.js componentDidMount
			setTimeout(function(){
				highlightDoc.call(this,targetdoc,range_mid,opts);
			}.bind(this),500);//wait for markups to load
		} else {
			highlightDoc.call(this,targetdoc,range_mid,opts);
		}
	} else {
		if (!opts.autoOpen) return;
		var target=ktxfilestore.findFile(file);
		if (target) {
			target.scrollTo=range_mid;
			stackwidgetaction.openWidget(target,"TextWidget",{below:opts.below});
		}
	}
}
var getLinkedBy=function(m){
	var others=m.target;
	if (!others)return;
	if (typeof others[0]==="string"){
		var file=others[0];
		var doc=docfilestore.docOf(file);
		var mid=others[1];
		var markup=doc.getEditor().react.getMarkup(mid);
		return markup;
	}
}

var getMarkupsInRange=function(doc,from,to) {
	if (!to) {
		var marks=doc.findMarksAt(from);
	} else {
		var marks=doc.findMarks(from,to);
	}

	var markups=[],getMarkup=doc.getEditor().react.getMarkup;
	marks.forEach(function(m){
		if (m.type!=="bookmark" && m.className.substring(0,13)!=="editingMarker" && !m.clearOnEnter) {
			var markup=getMarkup(m.key);
			markups.push({markup:markup,key:m.key,doc:doc});
		}
	});
	return markups;
}

var getMarkupRect=function(m){
	var cm=m.handle.doc.getEditor();
	var pos=m.handle.find();
	var x1y1=cm.charCoords(pos.from);
	var x2y2=cm.charCoords(pos.to);
	return {left:x1y1.left,top:x1y1.top,right:x2y2.right,bottom:x2y2.bottom};
}

var drawLink=function(m1,m2) {
	var rect1=getMarkupRect(m1);
	var rect2=getMarkupRect(m2);
	//console.log("drawlink",rect1,rect2)
	overlayaction.connect(rect1,rect2);
}
var highlights_handles=[];
var clearHighlights=function(){
	highlights_handles.map(function(h){h.clear()});
	highlights_handles=[];
}
var makeHighlights=function(doc,highlights,opts){
	if (!opts.noClear) clearHighlights();
	for (var i=0;i<highlights.length;i++) {
		var from=highlights[i][0],to=highlights[i][1];
		highlights_handles.push(doc.markText(from,to,{className:"highlight",clearOnEnter:true}));
		////var by=getLinkedBy(markup);
		//if (by) drawLink(markup,by);
	}

	clearTimeout(this.timerMarker);
	if (!opts.keep) {
		this.timerMarker=setTimeout(function(){
			clearHighlights();
		}.bind(this),1500);
	}
}
var	highlightDoc=function (doc,range_markupid,opts) {
	if (!range_markupid) return;
	opts=opts||{};
	var hl=range_markupid,highlights=[];
	//one or more key
	if (typeof range_markupid==="string" || typeof range_markupid[0]==="string") {
		var ranges=range_markupid;
		if (typeof range_markupid==="string") {
			ranges=[range_markupid];
		}
		highlights=[];
		for (var i=0;i<ranges.length;i++) {
			var markup=doc.getEditor().react.getMarkup(ranges[i]);
			if (!markup) {
				console.error("markup not found",ranges[i]);
			} else {
				var pos=markup.handle.find();
				var from=pos.from, to=pos.to;
				if (opts.moveCursor && i===0) doc.setCursor(from);
				highlights.push([from,to]);
			}
		}
	} else { //array format
		if (hl[0][0] instanceof Array) {
			//for quote , single range
			var newhl=milestones.unpack.call(doc,hl[0]);
			var from={line:newhl[0][1],ch:newhl[0][0]},to={line:newhl[1][1],ch:newhl[1][0]};
		} else {
			var newhl=milestones.unpack.call(doc,hl);
			var from={line:newhl[0][1],ch:newhl[0][0]},to={line:newhl[1][1],ch:newhl[1][0]};
		}

		highlights=[[from,to]];
		if (opts.moveCursor) doc.setCursor(from);
	}
	doc.getEditor().focus();
	var marker = document.createElement('span');

	if (highlights.length && !opts.noScroll) {
		doc.getEditor().scrollIntoView(highlights[0][0],50);
	}

	makeHighlights.call(this,doc,highlights,opts);
}

var getMarkupText=function(doc,m) {
	var pos=m.find();
	if (!pos) return;
	return doc.getRange(pos.from,pos.to);
}

var posInRange=function(pos,range) { //check if a pos in range, cm format
	if (pos.line>range.from.line && pos.line<range.to.line) return true;//in range , not on boundary
	if (pos.line<range.from.line||pos.line>range.to.line)return false; //out of range
	if (pos.line===range.from.line) {
		return pos.ch>=range.from.ch;
	}

	if (pos.line===range.to.line) {
		return pos.ch<range.from.ch;
	}
	return false;
}
var highlightRelatedMarkup=function(m) { //highlight markup and all related
	var filename=docfilestore.fileOf(m.handle.doc);
	if (!filename) return;

	var hilights={};//group by filename
	hilights[filename]=[];
	hilights[filename].push(m.key);

	if (m.master) hilights[filename].push(m.master);

	if (m.handle.others && m.handle.others[0]) {
		hilights[filename]=hilights[filename].concat(m.handle.others);
	}
	var targets=m.handle.target;
	if (targets) {
		if (!(targets[0] instanceof Array)) targets=[targets];
		targets.forEach(function(t){
			if (!hilights[t[0]]) hilights[t[0]]=[];
			hilights[t[0]].push(t[1]);
		});
	}
	clearHighlights();
	for (var file in hilights) {
		var doc=docfilestore.docOf(file);
		if (doc) highlightDoc.call(this,doc,hilights[file],{noScroll:true,noClear:true});
	}
}

module.exports={gotoRangeOrMarkupID:gotoRangeOrMarkupID,highlightDoc:highlightDoc
,getMarkupText:getMarkupText,posInRange:posInRange,getMarkupsInRange:getMarkupsInRange
,highlightRelatedMarkup:highlightRelatedMarkup};<commit_msg>stay highlight when markup on hover<commit_after>var docfilestore=require("../stores/docfile");
var stackwidgetaction=require("../actions/stackwidget");
var overlayaction=require("../actions/overlay");
var milestones=require("ksana-codemirror").milestones;
var ktxfilestore=require("../stores/ktxfile");
var markupstore=require("../stores/markup");
var gotoRangeOrMarkupID=function(file,range_mid,opts) {
	opts=opts||{};
	if (opts.below && !opts.autoOpen) opts.autoOpen=true;

	var targetdoc=docfilestore.docOf(file);

	if (targetdoc) {
		if (!targetdoc.getEditor().react.markupReady()) {
		//wait for this.state.markups ready, because markups is load later
		//see ksana-codemirror/src/codemirror-react.js componentDidMount
			setTimeout(function(){
				highlightDoc.call(this,targetdoc,range_mid,opts);
			}.bind(this),500);//wait for markups to load
		} else {
			highlightDoc.call(this,targetdoc,range_mid,opts);
		}
	} else {
		if (!opts.autoOpen) return;
		var target=ktxfilestore.findFile(file);
		if (target) {
			target.scrollTo=range_mid;
			stackwidgetaction.openWidget(target,"TextWidget",{below:opts.below});
		}
	}
}
var getLinkedBy=function(m){
	var others=m.target;
	if (!others)return;
	if (typeof others[0]==="string"){
		var file=others[0];
		var doc=docfilestore.docOf(file);
		var mid=others[1];
		var markup=doc.getEditor().react.getMarkup(mid);
		return markup;
	}
}

var getMarkupsInRange=function(doc,from,to) {
	if (!to) {
		var marks=doc.findMarksAt(from);
	} else {
		var marks=doc.findMarks(from,to);
	}

	var markups=[],getMarkup=doc.getEditor().react.getMarkup;
	marks.forEach(function(m){
		if (m.type!=="bookmark" && m.className.substring(0,13)!=="editingMarker" && !m.clearOnEnter) {
			var markup=getMarkup(m.key);
			markups.push({markup:markup,key:m.key,doc:doc});
		}
	});
	return markups;
}

var getMarkupRect=function(m){
	var cm=m.handle.doc.getEditor();
	var pos=m.handle.find();
	var x1y1=cm.charCoords(pos.from);
	var x2y2=cm.charCoords(pos.to);
	return {left:x1y1.left,top:x1y1.top,right:x2y2.right,bottom:x2y2.bottom};
}

var drawLink=function(m1,m2) {
	var rect1=getMarkupRect(m1);
	var rect2=getMarkupRect(m2);
	//console.log("drawlink",rect1,rect2)
	overlayaction.connect(rect1,rect2);
}
var highlights_handles=[];
var clearHighlights=function(){
	highlights_handles.map(function(h){h.clear()});
	highlights_handles=[];
}
var makeHighlights=function(doc,highlights,opts){
	if (!opts.noClear) clearHighlights();
	for (var i=0;i<highlights.length;i++) {
		var from=highlights[i][0],to=highlights[i][1];
		highlights_handles.push(doc.markText(from,to,{className:"highlight",clearOnEnter:true}));
		////var by=getLinkedBy(markup);
		//if (by) drawLink(markup,by);
	}

	clearInterval(this.timerMarker);
	if (!opts.keep) {
		this.timerMarker=setInterval(function(){

			if (!markupstore.getHovering()) clearHighlights();
		}.bind(this),1500);
	}
}
var	highlightDoc=function (doc,range_markupid,opts) {
	if (!range_markupid) return;
	opts=opts||{};
	var hl=range_markupid,highlights=[];
	//one or more key
	if (typeof range_markupid==="string" || typeof range_markupid[0]==="string") {
		var ranges=range_markupid;
		if (typeof range_markupid==="string") {
			ranges=[range_markupid];
		}
		highlights=[];
		for (var i=0;i<ranges.length;i++) {
			var markup=doc.getEditor().react.getMarkup(ranges[i]);
			if (!markup) {
				console.error("markup not found",ranges[i]);
			} else {
				var pos=markup.handle.find();
				var from=pos.from, to=pos.to;
				if (opts.moveCursor && i===0) doc.setCursor(from);
				highlights.push([from,to]);
			}
		}
	} else { //array format
		if (hl[0][0] instanceof Array) {
			//for quote , single range
			var newhl=milestones.unpack.call(doc,hl[0]);
			var from={line:newhl[0][1],ch:newhl[0][0]},to={line:newhl[1][1],ch:newhl[1][0]};
		} else {
			var newhl=milestones.unpack.call(doc,hl);
			var from={line:newhl[0][1],ch:newhl[0][0]},to={line:newhl[1][1],ch:newhl[1][0]};
		}

		highlights=[[from,to]];
		if (opts.moveCursor) doc.setCursor(from);
	}
	doc.getEditor().focus();
	var marker = document.createElement('span');

	if (highlights.length && !opts.noScroll) {
		doc.getEditor().scrollIntoView(highlights[0][0],50);
	}

	makeHighlights.call(this,doc,highlights,opts);
}

var getMarkupText=function(doc,m) {
	var pos=m.find();
	if (!pos) return;
	return doc.getRange(pos.from,pos.to);
}

var posInRange=function(pos,range) { //check if a pos in range, cm format
	if (pos.line>range.from.line && pos.line<range.to.line) return true;//in range , not on boundary
	if (pos.line<range.from.line||pos.line>range.to.line)return false; //out of range
	if (pos.line===range.from.line) {
		return pos.ch>=range.from.ch;
	}

	if (pos.line===range.to.line) {
		return pos.ch<range.from.ch;
	}
	return false;
}
var highlightRelatedMarkup=function(m) { //highlight markup and all related
	var filename=docfilestore.fileOf(m.handle.doc);
	if (!filename) return;

	var hilights={};//group by filename
	hilights[filename]=[];
	hilights[filename].push(m.key);

	if (m.master) hilights[filename].push(m.master);

	if (m.handle.others && m.handle.others[0]) {
		hilights[filename]=hilights[filename].concat(m.handle.others);
	}
	var targets=m.handle.target;
	if (targets) {
		if (!(targets[0] instanceof Array)) targets=[targets];
		targets.forEach(function(t){
			if (!hilights[t[0]]) hilights[t[0]]=[];
			hilights[t[0]].push(t[1]);
		});
	}
	clearHighlights();
	for (var file in hilights) {
		var doc=docfilestore.docOf(file);
		if (doc) highlightDoc.call(this,doc,hilights[file],{noScroll:true,noClear:true});
	}
}

module.exports={gotoRangeOrMarkupID:gotoRangeOrMarkupID,highlightDoc:highlightDoc
,getMarkupText:getMarkupText,posInRange:posInRange,getMarkupsInRange:getMarkupsInRange
,highlightRelatedMarkup:highlightRelatedMarkup};<|endoftext|>


<commit_before>var page = div();
var follow = function () {
};
on("mouseenter")(page, function () {
    var r = (page.offsetWidth + page.offsetHeight) / 4;
    page.style.transition = "none";

    var offmousemove = on("mousemove")(window, function (event) {
        var { layerX: x, layerY: y } = event;
        var dx = x - r;
        var dy = y - r;
        page.style.borderRadius = [-dx * r - dy * r, dx * r + dy * r, dx * r + dy * r, -dx * r + dy * r]
            .map(a => Math.abs(r - a / r).toFixed(2)).map(a => Math.max(a, 2) + "px").join(" ")
    });
    var offmouseleave = on('mouseleave')(page, function (event) {
        page.style.transition = "";
        page.style.borderRadius = "";
        offmousemove();
        offmouseleave();
    });
});

function main() {
    page.innerHTML = imk;
    document.body.appendChild(page);
    drag.on(page);

    return page;
}<commit_msg>去掉r系数<commit_after>var page = div();
var follow = function () {
};
on("mouseenter")(page, function () {
    var r = (page.offsetWidth + page.offsetHeight) / 4;
    page.style.transition = "none";

    var offmousemove = on("mousemove")(window, function (event) {
        var { layerX: x, layerY: y } = event;
        var dx = x - r;
        var dy = y - r;
        page.style.borderRadius = [-dx - dy, dx + dy, dx + dy, -dx + dy]
            .map(a => Math.abs(r - a).toFixed(2)).map(a => Math.max(a, 2) + "px").join(" ")
    });
    var offmouseleave = on('mouseleave')(page, function (event) {
        page.style.transition = "";
        page.style.borderRadius = "";
        offmousemove();
        offmouseleave();
    });
});

function main() {
    page.innerHTML = imk;
    document.body.appendChild(page);
    drag.on(page);

    return page;
}<|endoftext|>


<commit_before>var spawn = require('child_process').spawn,
    args = require('yargs').argv,
    through = require('through');

function usage() {
  console.log('usage: cliwrapper [--start startscript.js] [--signal #,signalscript.js] command arguments...');
  process.exit(1);
}

if(args._.length == 0) {
  usage();
}

console.log('X');

var proc = spawn(args._.join(' '));

proc.on('close', function(code, sig) {
  console.log('process closed with code ' + code + ' and signal ' + sig);
});

proc.on('error', function(err) {
  console.log(err);
});

proc.on('disconnect', function() {
  console.log('disconnected');
});

proc.on('exit', function(code, sig) {
  console.log('process exited with code ' + code + ' and signal ' + sig);
});

proc.stdout.on('data', function(chunk) {
  console.log(chunk);
});
<commit_msg>Using exec now<commit_after>var spawn = require('child_process').exec,
    args = require('yargs').argv,
    through = require('through');

function usage() {
  console.log('usage: cliwrapper [--start startscript.js] [--signal #,signalscript.js] command arguments...');
  process.exit(1);
}

if(args._.length == 0) {
  usage();
}

console.log('X');

var proc = spawn(args._.join(' '));

proc.on('close', function(code, sig) {
  console.log('process closed with code ' + code + ' and signal ' + sig);
});

proc.on('error', function(err) {
  console.log(err);
});

proc.on('disconnect', function() {
  console.log('disconnected');
});

proc.on('exit', function(code, sig) {
  console.log('process exited with code ' + code + ' and signal ' + sig);
});

proc.stdout.on('data', function(chunk) {
  console.log(chunk);
});
<|endoftext|>


<commit_before>angular.module("leaflet-directive")
.factory('leafletMarkerEvents', function ($rootScope, $q, $log, leafletHelpers, leafletEventsHelpersFactory, leafletLabelEvents) {
    var safeApply = leafletHelpers.safeApply,
        isDefined = leafletHelpers.isDefined,
        Helpers = leafletHelpers,
        lblHelp = leafletLabelEvents,
        EventsHelper = leafletEventsHelpersFactory;

    var MarkerEvents = function(){
      EventsHelper.call(this,'leafletDirectiveMarker', 'markers');
    };

    MarkerEvents.prototype =  new EventsHelper();

    MarkerEvents.prototype.genDispatchEvent = function(eventName, logic, leafletScope, lObject, name, model, layerName) {
        var handle = EventsHelper.prototype
            .genDispatchEvent.call(this, eventName, logic, leafletScope, lObject, name, model, layerName);
        return function(e){
            // Broadcast old marker click name for backwards compatibility
            if (eventName === "click") {
                safeApply(leafletScope, function () {
                    $rootScope.$broadcast('leafletDirectiveMarkersClick', name);
                });
            } else if (eventName === 'dragend') {
                safeApply(leafletScope, function () {
                    model.lat = lObject.getLatLng().lat;
                    model.lng = lObject.getLatLng().lng;
                });
                if (model.message && model.focus === true) {
                    lObject.openPopup();
                }
            }
            handle(e); //common
        };
    };

    MarkerEvents.prototype.getAvailableEvents = function(){ return [
        'click',
        'dblclick',
        'mousedown',
        'mouseover',
        'mouseout',
        'contextmenu',
        'dragstart',
        'drag',
        'dragend',
        'move',
        'remove',
        'popupopen',
        'popupclose'
        ];
    };

    MarkerEvents.prototype.bindEvents = function (lObject, name, model, leafletScope, layerName) {
      var logic = EventsHelper.prototype.bindEvents.call(this,lObject, name, model, leafletScope, layerName);

      if (Helpers.LabelPlugin.isLoaded() && isDefined(lObject.label)) {
          lblHelp.genEvents(name, logic, leafletScope, lObject, model, layerName);
      }
    };

    return new MarkerEvents();
});
<commit_msg>Update leafletMarkerEvents.js<commit_after>angular.module("leaflet-directive")
.factory('leafletMarkerEvents', function ($rootScope, $q, $log, leafletHelpers, leafletEventsHelpersFactory, leafletLabelEvents) {
    var safeApply = leafletHelpers.safeApply,
        isDefined = leafletHelpers.isDefined,
        Helpers = leafletHelpers,
        lblHelp = leafletLabelEvents,
        EventsHelper = leafletEventsHelpersFactory;

    var MarkerEvents = function(){
      EventsHelper.call(this,'leafletDirectiveMarker', 'markers');
    };

    MarkerEvents.prototype =  new EventsHelper();

    MarkerEvents.prototype.genDispatchEvent = function(eventName, logic, leafletScope, lObject, name, model, layerName) {
        var handle = EventsHelper.prototype
            .genDispatchEvent.call(this, eventName, logic, leafletScope, lObject, name, model, layerName);
        return function(e){
            // Broadcast old marker click name for backwards compatibility
            if (eventName === "click") {
                safeApply(leafletScope, function () {
                    $rootScope.$broadcast('leafletDirectiveMarkersClick', name);
                });
            } else if (eventName === 'dragend') {
                safeApply(leafletScope, function () {
                    model.lat = lObject.getLatLng().lat;
                    model.lng = lObject.getLatLng().lng;
                });
                if (model.message && model.focus === true) {
                    lObject.openPopup();
                }
            }
            handle(e); //common
        };
    };

    MarkerEvents.prototype.getAvailableEvents = function(){ return [
        'click',
        'dblclick',
        'mousedown',
        'mouseover',
        'mouseout',
        'contextmenu',
        'dragstart',
        'drag',
        'dragend',
        'move',
        'remove',
        'popupopen',
        'popupclose',
        'touchend',
        'touchstart',
        'touchmove',
        'touchcancel',
        'touchleave'
        ];
    };

    MarkerEvents.prototype.bindEvents = function (lObject, name, model, leafletScope, layerName) {
      var logic = EventsHelper.prototype.bindEvents.call(this,lObject, name, model, leafletScope, layerName);

      if (Helpers.LabelPlugin.isLoaded() && isDefined(lObject.label)) {
          lblHelp.genEvents(name, logic, leafletScope, lObject, model, layerName);
      }
    };

    return new MarkerEvents();
});
<|endoftext|>


<commit_before>import store from '@/store'
import fs from 'fs'
import { fixRaggedRows } from '@/ragged-rows.js'
import { includeHeadersInData } from '@/frictionlessUtilities.js'
import { toggleHeaderNoFeedback } from '@/headerRow.js'
import { pushCsvFormat } from '@/dialect.js'
import detectNewline from 'detect-newline'

var parse = require('csv-parse/lib/sync')
var stringify = require('csv-stringify/lib/sync')
var CSVSniffer = require('csv-sniffer')()

// { delimiter: ',', lineTerminator, quoteChar, doubleQuote, escapeChar, nullSequence, skipInitialSpace, header, caseSensitiveHeader, csvddfVersion }
const frictionlessToCsvmapper = {
  delimiter: 'delimiter',
  lineTerminator: 'rowDelimiter',
  quoteChar: 'quote',
  escapeChar: 'escape',
  skipInitialSpace: 'ltrim'
}

export function loadDataIntoHot (hot, data, format) {
  if (_.isArray(data)) {
    loadArrayDataIntoHot(hot, data, format)
  } else {
    loadCsvDataIntoHot(hot, data, format)
  }
}

export function loadCsvDataIntoHot (hot, data, format) {
  // do not handle errors here as caller can activate appropriate user feedback dialog
  let arrays
  // if no format specified, default to csv
  if (typeof format === 'undefined' || !format) {
    detectAndStoreQuoteChar(data, { rowDelimiter: '\n' }, hot.guid)
    arrays = parse(data)
  } else {
    let csvOptions = dialectToCsvOptions(format.dialect)
    detectAndStoreQuoteChar(data, csvOptions, hot.guid)
    // let csv parser handle the line terminators
    _.unset(csvOptions, 'rowDelimiter')
    // TODO: update to stream
    csvOptions.bom = false
    if (data.charCodeAt(0) === 0xFEFF) {
      store.commit('pushTableProperty', { hotId: hot.guid, key: `bom`, value: 0xFEFF })
    }
    console.dir(store)
    let hexdump = require('hexdump-nodejs')
    let buffer = Buffer.from(data)
    // buffer.write(data, 0x10)
    console.log('data before parse...')
    console.log(hexdump(buffer))
    arrays = parse(data, csvOptions)
    if (arrays[1] && arrays[1][0]) {
      buffer = Buffer.from(arrays[1][0])
      // buffer2.write(arrays[0], 0x10)
      console.log('array 0 after parse...')
      console.log(hexdump(buffer))
    }
    pushCsvFormat(hot.guid, format)
  }
  fixRaggedRows(arrays)
  hot.loadData(arrays)
  hot.render()
  // frictionless csv header default = true
  toggleHeaderNoFeedback(hot)
}

export function loadArrayDataIntoHot (hot, arrays, format) {
  pushCsvFormat(hot.guid, format)

  fixRaggedRows(arrays)
  hot.loadData(arrays)
  hot.render()
  // frictionless csv header default = true
  toggleHeaderNoFeedback(hot)
}

export function saveDataToFile (hot, format, filename, callback) {
  let tabId = store.getters.getActiveTab
  if (typeof filename === 'string') {
    store.commit('pushTabObject', { id: tabId, filename: filename })
  } else {
    filename = store.getters.getTabObjects(`${tabId}.filename`)
  }
  if (!filename) {
    return
  }
  if (typeof callback === 'undefined') {
    callback = (err) => {
      if (err) {
        console.error('There was a problem saving data to file.')
        throw err
      }
      // console.log('File saved successfully.')
    }
  }

  // unlike handsontable, in frictionless by default, headers should be included (http://frictionlessdata.io/specs/csv-dialect)
  let arrays = includeHeadersInData(hot)
  let data
  // if no format specified, default to csv
  if (typeof format === 'undefined' || !format) {
    // TODO: update to stream
    data = stringify(arrays)
    let hexdump = require('hexdump-nodejs')
    let buffer = Buffer.from(data)
    // buffer.write(data, 0x10)
    console.log('data after stringify...')
    console.log(hexdump(buffer))
  } else {
    let csvOptions = dialectToCsvOptions(format.dialect)
    if (store.getters.getTableProperty({ key: 'sampledQuoteChar', hotId: hot.guid })) {
      csvOptions.quoted = true
    }
    data = stringify(arrays, csvOptions)
    let hexdump = require('hexdump-nodejs')
    let buffer = Buffer.from(data)
    // buffer.write(data, 0x10)
    console.log('data after stringify...')
    console.log(hexdump(buffer))
    pushCsvFormat(hot.guid, format)
  }
  if (data.charCodeAt(0) !== 0xFEFF && store.getters.getTableProperty({ key: 'bom', hotId: hot.guid })) {
    data = String.fromCodePoint(0xFEFF) + data
  }
  fs.writeFile(filename, data, callback)
}

function dialectToCsvOptions (dialect) {
  let csvOptions = {}
  if (dialect) {
    _.forEach(frictionlessToCsvmapper, function (csvKey, frictionlessKey) {
      if (_.has(dialect, frictionlessKey)) {
        csvOptions[csvKey] = dialect[frictionlessKey]
      }
    })
  }
  return csvOptions
}

function detectAndStoreQuoteChar (data, csvOptions, hotId) {
  let sample = _.truncate(data, { length: 2000 })
  var sniffer = new CSVSniffer()
  // csv-sniffer will throw exception if there is no line terminator in sample
  let newLineString = detectNewline(sample) || csvOptions.rowDelimiter
  var sniffResult = sniffer.sniff(sample, { newlineStr: newLineString })
  if (sniffResult.quoteChar) {
    store.commit('pushTableProperty', { hotId: hotId, key: `sampledQuoteChar`, value: sniffResult.quoteChar })
  }
}
<commit_msg>updated debug testing.<commit_after>import store from '@/store'
import fs from 'fs'
import { fixRaggedRows } from '@/ragged-rows.js'
import { includeHeadersInData } from '@/frictionlessUtilities.js'
import { toggleHeaderNoFeedback } from '@/headerRow.js'
import { pushCsvFormat } from '@/dialect.js'
import detectNewline from 'detect-newline'

var parse = require('csv-parse/lib/sync')
var stringify = require('csv-stringify/lib/sync')
var CSVSniffer = require('csv-sniffer')()

// { delimiter: ',', lineTerminator, quoteChar, doubleQuote, escapeChar, nullSequence, skipInitialSpace, header, caseSensitiveHeader, csvddfVersion }
const frictionlessToCsvmapper = {
  delimiter: 'delimiter',
  lineTerminator: 'rowDelimiter',
  quoteChar: 'quote',
  escapeChar: 'escape',
  skipInitialSpace: 'ltrim'
}

export function loadDataIntoHot (hot, data, format) {
  if (_.isArray(data)) {
    loadArrayDataIntoHot(hot, data, format)
  } else {
    loadCsvDataIntoHot(hot, data, format)
  }
}

export function loadCsvDataIntoHot (hot, data, format) {
  // do not handle errors here as caller can activate appropriate user feedback dialog
  let arrays
  // if no format specified, default to csv
  if (typeof format === 'undefined' || !format) {
    detectAndStoreQuoteChar(data, { rowDelimiter: '\n' }, hot.guid)
    arrays = parse(data)
  } else {
    let csvOptions = dialectToCsvOptions(format.dialect)
    detectAndStoreQuoteChar(data, csvOptions, hot.guid)
    // let csv parser handle the line terminators
    _.unset(csvOptions, 'rowDelimiter')
    // TODO: update to stream
    csvOptions.bom = false
    if (data.charCodeAt(0) === 0xFEFF) {
      store.commit('pushTableProperty', { hotId: hot.guid, key: `bom`, value: 0xFEFF })
    }
    console.dir(store)
    let hexdump = require('hexdump-nodejs')
    let buffer = Buffer.from(data)
    // buffer.write(data, 0x10)
    console.log('data before parse...')
    console.log(hexdump(buffer))
    arrays = parse(data, csvOptions)
    if (arrays[1] && arrays[1][0]) {
      buffer = Buffer.from(arrays[1][0])
      // buffer2.write(arrays[0], 0x10)
      console.log('array 0 after parse...')
      console.log(hexdump(buffer))
    }
    pushCsvFormat(hot.guid, format)
  }
  fixRaggedRows(arrays)
  hot.loadData(arrays)
  hot.render()
  // frictionless csv header default = true
  toggleHeaderNoFeedback(hot)
}

export function loadArrayDataIntoHot (hot, arrays, format) {
  pushCsvFormat(hot.guid, format)

  fixRaggedRows(arrays)
  hot.loadData(arrays)
  hot.render()
  // frictionless csv header default = true
  toggleHeaderNoFeedback(hot)
}

export function saveDataToFile (hot, format, filename, callback) {
  let tabId = store.getters.getActiveTab
  if (typeof filename === 'string') {
    store.commit('pushTabObject', { id: tabId, filename: filename })
  } else {
    filename = store.getters.getTabObjects(`${tabId}.filename`)
  }
  if (!filename) {
    return
  }
  if (typeof callback === 'undefined') {
    callback = (err) => {
      if (err) {
        console.error('There was a problem saving data to file.')
        throw err
      }
      // console.log('File saved successfully.')
    }
  }

  // unlike handsontable, in frictionless by default, headers should be included (http://frictionlessdata.io/specs/csv-dialect)
  let arrays = includeHeadersInData(hot)
  let data
  // if no format specified, default to csv
  if (typeof format === 'undefined' || !format) {
    // TODO: update to stream
    data = stringify(arrays)
    let hexdump = require('hexdump-nodejs')
    let buffer = Buffer.from(data)
    console.log('data after stringify...')
    console.log(hexdump(buffer))
  } else {
    let csvOptions = dialectToCsvOptions(format.dialect)
    if (store.getters.getTableProperty({ key: 'sampledQuoteChar', hotId: hot.guid })) {
      csvOptions.quoted = true
    }
    data = stringify(arrays, csvOptions)
    let hexdump = require('hexdump-nodejs')
    let buffer = Buffer.from(data)
    console.log('data after stringify...')
    console.log(hexdump(buffer))
    pushCsvFormat(hot.guid, format)
  }
  if (data.charCodeAt(0) !== 0xFEFF && store.getters.getTableProperty({ key: 'bom', hotId: hot.guid })) {
    data = String.fromCodePoint(0xFEFF) + data
  }
  fs.writeFile(filename, data, callback)
}

function dialectToCsvOptions (dialect) {
  let csvOptions = {}
  if (dialect) {
    _.forEach(frictionlessToCsvmapper, function (csvKey, frictionlessKey) {
      if (_.has(dialect, frictionlessKey)) {
        csvOptions[csvKey] = dialect[frictionlessKey]
      }
    })
  }
  return csvOptions
}

function detectAndStoreQuoteChar (data, csvOptions, hotId) {
  let sample = _.truncate(data, { length: 2000 })
  var sniffer = new CSVSniffer()
  // csv-sniffer will throw exception if there is no line terminator in sample
  let newLineString = detectNewline(sample) || csvOptions.rowDelimiter
  var sniffResult = sniffer.sniff(sample, { newlineStr: newLineString })
  if (sniffResult.quoteChar) {
    store.commit('pushTableProperty', { hotId: hotId, key: `sampledQuoteChar`, value: sniffResult.quoteChar })
  }
}
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;
var pg = require('pg');
var Q = require("q");
var request = require("request");
var newUser = require("./db");
var logConversation = require("./conversation");
var nlp = require("./nlp");
var newBot_msg = require("./newBot");
//var findSession = require("./sessionsearch");

const scriptRules = require('./script.json');

var msgLog = {
    smoochId: '',
    received: '',
    usermessage: '',
    role: '',
    message_id: '',
    sourcetype: '',
    receivedtime: '',
    responsemessage: '',
    responsetype: '',
    responsetime: '',
    newUsercheck: 'false'
  };

function wait(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

module.exports = new Script({
    processing: {
        //prompt: (bot) => bot.say('Beep boop...'),
        receive: () => 'processing'
    },

    start: {
        receive: (bot) => {
            return bot.say('Hello!  I\'m A16, the Agile2016 EventBot Concierge.  To find out what I can help you with type MENU for options or KEY for Keywords.')
                .then(() => 'speak');
        }
    },

    speak: {
        receive: (bot, message) => {

            console.log("- bot message ", message);

            let upperText = message.text.trim().toUpperCase();

//TODO: don't try stateMachine; instead capture last text and if a search thing ie is search by speaker
//then the submit is speaker name and call speakersearch won't work for is session expires
//            if (msgLog.usermessage == 'SBSN') {
//                console.log("=== search string", upperText);
//                var msg = {};
//                findSession(upperText, msg);
//                return bot.setProp("silent", true);
//            }

            msgLog.smoochId = bot.userId;
            msgLog.received = message.received;
            msgLog.usermessage = message.text;
            msgLog.role = message.role;
            msgLog.message_id = message._id;
            msgLog.receivedtime = new Date();
            //this mess is my way around the fact that smooch completely
            //changes the structure of the message obj if it is a postback vs user entered text
            //console.log("===message.message",message.message);
            //switch to the inverse should be faster because it does not have to traverse the whole prototype chain
            switch (typeof message.message !== "undefined") {
              case true:
                  //This is appMaker - which means it is a postback
                  msgLog.sourcetype = message.action.type;
                break;
              default:
                // This is appUser - which means it is a message typed in by the user
                  msgLog.sourcetype = message.source.type;
                break;
            }

            //Not sure if this is the best way to accomplish not calling newUser everytime,
            //but it seems to work
            if(msgLog.newUsercheck == 'false') {
              console.log("- newUser check");
              newUser(bot)
                .then(msgLog.newUsercheck = 'true');
            } else {
              console.log("- newUser not checked");
            }

            //SK_ACCESS is a heroku config var that has the list of user/devices
            //smoochids for auth users to send ad hoc push conversations
            var authUsers = process.env.SK_ACCESS;
            //For ad hoc messages - scheduled messages are done differently in checkItems
            //-1 indicates that a user is not authorized to send broadcast messages
            if (upperText.substr(0,4) == '/SK ') {
              if (authUsers.indexOf(bot.userId) !== -1) {
                upperText = upperText.substr(0,3);
                newBot_msg(message.text.substr(4));
                console.log("- ad hoc msg: ",message.text," authUser:  ",authUsers);
              } else {
                upperText = "NO_SK";
              }
            }

//TODO: There is a bug with /support and /a16 now.  /support does not present message and /a16 sometimes doubles the message
            function updateSilent() {
                switch (upperText) {
                    case "CONNECT ME":
                        console.log('- Special Case: CONNECT ME'); //turns off bot
                        return bot.setProp("silent", true);
                    case "/SUPPORT":
                        console.log('- Special Case: /SUPPORT'); //turns off bot
                        return bot.setProp("silent", true);
                    case "DISCONNECT":
                        console.log('- Special Case: DISCONNECT'); //turns bot back on
                        return bot.setProp("silent", false);
                    case "/A16":
                        console.log('- Special Case: /A16'); //turns bot back on
                        //processMessage(false); TODO remove if bot works on /a16 test
                        return bot.setProp("silent", false);
                    default:
                        return Promise.resolve();
                }
            }

            function getSilent() {
                return bot.getProp("silent");
            }

            function processMessage(isSilent) {
                console.log("- processMessage ", upperText, "isSilent set to ",isSilent);
                if (isSilent) {
                    return Promise.resolve("speak");
                }

                var promises = [];
                var source;
                var fulfillmentSpeech;
                var simplified;
                promises.push(nlp(upperText, bot.userId));

                Q.all(promises).then(function(responses) {
                    // response is the JSON from API.ai
                    responses.forEach(function(response) {
                        console.log("- In Q.all");
                        console.log("- Received result from API.ai",response);
                        source = response.result.source;
                        if (source && source !== 'agent')
                        {
                            console.log("- Q all not agent");
                            fulfillmentSpeech = response.result.fulfillment.speech;
                            simplified = response.result.parameters.simplified;
                        } else if (response.result.fulfillment.speech && source == 'agent') {
                          console.log("- Source is agent ", response.result);
                          fulfillmentSpeech = response.result.fulfillment.speech;
                          //Is is done to capture if it is using an agent that we set up on API.ai
                          //API.ai sends agent back if !== domains; wish they had a 3rd state
                          simplified = response.result.parameters.event;
                        }
                        console.log("- Process meesage set source to: ", source);
                        console.log("- Process meesage set fulfillmentSpeech to: ", fulfillmentSpeech);
                        console.log("- Process meesage set simplified to: ", simplified);

                        respondMessage(source, fulfillmentSpeech, simplified);
                    });
                }, function(error) {
                    console.log("===Q all error ", error);
                });
            }

            function respondMessage(source, fulfillmentSpeech, simplified)
            {
              //switch (source) {
                //using smal.talk domain from api.ai because not all their responses are
                //appropriate we have implemented this case statement
              //  case 'domains':
              //      console.log("===why am I here? ", source);
                    //hello is a special case; we are using the smaltalk domains to narrow conversation down
                    //then using JSON to provide answer.
                    //the rest are answers that we intercept because we do not like the domain answers
                    //and it does not appear that we can customize these items
                    if (fulfillmentSpeech && source === 'domains')
                    {
                      switch (simplified) {
                        //moved response to API.ai
                        //case "hello":
                        //  console.log("===in hello");
                        //  upperText = simplified.trim().toUpperCase();
                        //  break;
                        case "do you know":
                        case "can you help":
                        case "do you have":
                        case "how does this app work":
                        case "how much time do you need":
                        case "how to open you":
                        case "what can you talk about":
                        case "what do you know":
                          console.log("-In domains, what do you know");
                          upperText = 'KNOW';
                          break;
                        case "what do you do":
                        case "how do you know":
                        case "job":
                          console.log("- In domains, what do you do");
                          upperText = "JOB";
                          break;
                        case "do you know me":
                        case "do you remember me":
                          console.log("- In domains, do you know me");
                          upperText = "ME";
                          break;
                        case "who named you":
                        console.log("- in domains, who named you");
                          upperText = "NAME";
                          break;
                        case "can you hear me":
                        case "can you speak":
                        case "change your":
                        case "hurry":
                        case "talk faster":
                        case "do you drink":
                        case "do you eat":
                          console.log("- In domains do you eat");
                          //in these cases we want to return 'not something I know about'
                          upperText = "";
                          break;
                        default:
                          console.log("- In domains switch default");
                          //evening is one of our keywords and also an answer in the small.talk domain
                          //as a synonym for 'good evening' which we want to keep
                          if (upperText == "EVENING") {break;}
                          //else let the domain answer be sent
                          msgLog.responsemessage = fulfillmentSpeech;
                          msgLog.responsetime = new Date();
                          msgLog.responsetype = 'API.AI Domain';
                          return bot.say(fulfillmentSpeech).then(() => 'speak');
                      }
                    }
                  //  break;
                  //case 'agent':
                    //custom agent set up on api.ai for this
                    //if (simplified == 'agile2017')
                    //  {
                    //      console.log("- In agent switch agile2017 ");
                    //      msgLog.responsemessage = fulfillmentSpeech;
                    //      msgLog.responsetime = new Date;
                    //      msgLog.responsetype = 'API.AI Intent';
                    //      return bot.say(fulfillmentSpeech).then(() => 'speak');
                    //  }
                    //break;
                  //default:
                  //  console.log("===finished switch, upperText now:",upperText);
                  //}

                if (!_.has(scriptRules, upperText)) {
                    console.log("===no rule", upperText);
                    return bot.say(`I'm sorry that is not something I know.  Type MENU or KEY for a list of things I can help you with.`).then(() => 'speak');
                }

                var response = scriptRules[upperText];
                var lines = response.split('\n');
                msgLog.responsemessage = response;
                msgLog.responsetime = new Date;
                msgLog.responsetype = 'JSON';
                console.log("=== msgLog  obj",msgLog);
                logConversation(msgLog);

                var p = Promise.resolve();
                _.each(lines, function(line) {
                    line = line.trim();
                    p = p.then(function() {
                        console.log("=== p line",line);
                        return wait(500).then(function() {
                            return bot.say(line);
                        });
                    });
                });
                return p.then(() => 'speak');
            }

            return updateSilent()
                //TODO may have to put a case statement in for /a16 processing
                .then(console.log('--updateSilent step 1'))
                .then(getSilent)
                .then(console.log('--updateSilent step 2'))
                .then(processMessage);
        }
    }
});
<commit_msg>See last build if issues with respondMessage<commit_after>'use strict';

const _ = require('lodash');
const Script = require('smooch-bot').Script;
var pg = require('pg');
var Q = require("q");
var request = require("request");
var newUser = require("./db");
var logConversation = require("./conversation");
var nlp = require("./nlp");
var newBot_msg = require("./newBot");
//var findSession = require("./sessionsearch");

const scriptRules = require('./script.json');

var msgLog = {
    smoochId: '',
    received: '',
    usermessage: '',
    role: '',
    message_id: '',
    sourcetype: '',
    receivedtime: '',
    responsemessage: '',
    responsetype: '',
    responsetime: '',
    newUsercheck: 'false'
  };

function wait(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

module.exports = new Script({
    processing: {
        //prompt: (bot) => bot.say('Beep boop...'),
        receive: () => 'processing'
    },

    start: {
        receive: (bot) => {
            return bot.say('Hello!  I\'m A16, the Agile2016 EventBot Concierge.  To find out what I can help you with type MENU for options or KEY for Keywords.')
                .then(() => 'speak');
        }
    },

    speak: {
        receive: (bot, message) => {

            console.log("- bot message ", message);

            let upperText = message.text.trim().toUpperCase();

//TODO: don't try stateMachine; instead capture last text and if a search thing ie is search by speaker
//then the submit is speaker name and call speakersearch won't work for is session expires
//            if (msgLog.usermessage == 'SBSN') {
//                console.log("=== search string", upperText);
//                var msg = {};
//                findSession(upperText, msg);
//                return bot.setProp("silent", true);
//            }

            msgLog.smoochId = bot.userId;
            msgLog.received = message.received;
            msgLog.usermessage = message.text;
            msgLog.role = message.role;
            msgLog.message_id = message._id;
            msgLog.receivedtime = new Date();
            //this mess is my way around the fact that smooch completely
            //changes the structure of the message obj if it is a postback vs user entered text
            //console.log("===message.message",message.message);
            //switch to the inverse should be faster because it does not have to traverse the whole prototype chain
            switch (typeof message.message !== "undefined") {
              case true:
                  //This is appMaker - which means it is a postback
                  msgLog.sourcetype = message.action.type;
                break;
              default:
                // This is appUser - which means it is a message typed in by the user
                  msgLog.sourcetype = message.source.type;
                break;
            }

            //Not sure if this is the best way to accomplish not calling newUser everytime,
            //but it seems to work
            if(msgLog.newUsercheck == 'false') {
              console.log("- newUser check");
              newUser(bot)
                .then(msgLog.newUsercheck = 'true');
            } else {
              console.log("- newUser not checked");
            }

            //SK_ACCESS is a heroku config var that has the list of user/devices
            //smoochids for auth users to send ad hoc push conversations
            var authUsers = process.env.SK_ACCESS;
            //For ad hoc messages - scheduled messages are done differently in checkItems
            //-1 indicates that a user is not authorized to send broadcast messages
            if (upperText.substr(0,4) == '/SK ') {
              if (authUsers.indexOf(bot.userId) !== -1) {
                upperText = upperText.substr(0,3);
                newBot_msg(message.text.substr(4));
                console.log("- ad hoc msg: ",message.text," authUser:  ",authUsers);
              } else {
                upperText = "NO_SK";
              }
            }

//TODO: There is a bug with /support and /a16 now.  /support does not present message and /a16 sometimes doubles the message
            function updateSilent() {
                switch (upperText) {
                    case "CONNECT ME":
                        console.log('- Special Case: CONNECT ME'); //turns off bot
                        return bot.setProp("silent", true);
                    case "/SUPPORT":
                        console.log('- Special Case: /SUPPORT'); //turns off bot
                        return bot.setProp("silent", true);
                    case "DISCONNECT":
                        console.log('- Special Case: DISCONNECT'); //turns bot back on
                        return bot.setProp("silent", false);
                    case "/A16":
                        console.log('- Special Case: /A16'); //turns bot back on
                        //processMessage(false); TODO remove if bot works on /a16 test
                        return bot.setProp("silent", false);
                    default:
                        return Promise.resolve();
                }
            }

            function getSilent() {
                return bot.getProp("silent");
            }

            function processMessage(isSilent) {
                console.log("- processMessage ", upperText, "isSilent set to ",isSilent);
                if (isSilent) {
                    return Promise.resolve("speak");
                }

                var promises = [];
                var source;
                var fulfillmentSpeech;
                var simplified;
                promises.push(nlp(upperText, bot.userId));

                Q.all(promises).then(function(responses) {
                    // response is the JSON from API.ai
                    responses.forEach(function(response) {
                        console.log("- In Q.all");
                        console.log("- Received result from API.ai",response);
                        source = response.result.source;
                        if (source && source !== 'agent')
                        {
                            console.log("- Q all not agent");
                            fulfillmentSpeech = response.result.fulfillment.speech;
                            simplified = response.result.parameters.simplified;
                        } else if (response.result.fulfillment.speech && source == 'agent') {
                          console.log("- Source is agent ", response.result);
                          fulfillmentSpeech = response.result.fulfillment.speech;
                          //Is is done to capture if it is using an agent that we set up on API.ai
                          //API.ai sends agent back if !== domains; wish they had a 3rd state
                          simplified = response.result.parameters.event;
                        }
                        console.log("- Process meesage set source to: ", source);
                        console.log("- Process meesage set fulfillmentSpeech to: ", fulfillmentSpeech);
                        console.log("- Process meesage set simplified to: ", simplified);

                        respondMessage(source, fulfillmentSpeech, simplified);
                    });
                }, function(error) {
                    console.log("===Q all error ", error);
                });
            }

            function respondMessage(source, fulfillmentSpeech, simplified)
            {
                    //these are answers that we intercept because we do not like the domain answers
                    //and it does not appear that we can customize these items
                    if (fulfillmentSpeech && source === 'domains')
                    {
                      switch (simplified) {
                        case "do you know":
                        case "can you help":
                        case "do you have":
                        case "how does this app work":
                        case "how much time do you need":
                        case "how to open you":
                        case "what can you talk about":
                        case "what do you know":
                          console.log("-In domains, what do you know");
                          upperText = 'KNOW';
                          break;
                        case "what do you do":
                        case "how do you know":
                        case "job":
                          console.log("- In domains, what do you do");
                          upperText = "JOB";
                          break;
                        case "do you know me":
                        case "do you remember me":
                          console.log("- In domains, do you know me");
                          upperText = "ME";
                          break;
                        case "who named you":
                        console.log("- in domains, who named you");
                          upperText = "NAME";
                          break;
                        case "can you hear me":
                        case "can you speak":
                        case "change your":
                        case "hurry":
                        case "talk faster":
                        case "do you drink":
                        case "do you eat":
                          console.log("- In domains do you eat");
                          //in these cases we want to return 'not something I know about'
                          upperText = "";
                          break;
                        default:
                          console.log("- In domains switch default");
                          //evening is one of our keywords and also an answer in the small.talk domain
                          //as a synonym for 'good evening' which we want to keep
                          if (upperText == "EVENING") {break;}
                          //else let the domain answer be sent
                          msgLog.responsemessage = fulfillmentSpeech;
                          msgLog.responsetime = new Date();
                          msgLog.responsetype = 'API.AI Domain';
                          return bot.say(fulfillmentSpeech).then(() => 'speak');
                      }
                    }

                if (!_.has(scriptRules, upperText)) {
                    console.log("===no rule", upperText);
                    return bot.say(`I'm sorry that is not something I know.  Type MENU or KEY for a list of things I can help you with.`).then(() => 'speak');
                }

                var response = scriptRules[upperText];
                var lines = response.split('\n');
                msgLog.responsemessage = response;
                msgLog.responsetime = new Date;
                msgLog.responsetype = 'JSON';
                console.log("=== msgLog  obj",msgLog);
                logConversation(msgLog);

                var p = Promise.resolve();
                _.each(lines, function(line) {
                    line = line.trim();
                    p = p.then(function() {
                        console.log("=== p line",line);
                        return wait(500).then(function() {
                            return bot.say(line);
                        });
                    });
                });
                return p.then(() => 'speak');
            }

            return updateSilent()
                //TODO may have to put a case statement in for /a16 processing
                .then(console.log('--updateSilent step 1'))
                .then(getSilent)
                .then(console.log('--updateSilent step 2'))
                .then(processMessage);
        }
    }
});
<|endoftext|>


<commit_before>/*
 * Copyright 2014 - 2015 Björn Ricks <bjoern.ricks@gmail.com>
 *
 */
(function() {
    'use strict';

    angular.module('angTutApp',
        ['ngRoute', 'ngMaterial']
    )
    .config(app_config)
    .factory('conf', conf)
    .factory('examples', examples)
    .factory('menu', menu)
    .directive('hl', hl)
    .directive('atHljs', at_hljs)
    .controller('HomeCtrl', home_ctrl)
    .controller('SectionCtrl', section_ctrl)
    .controller('ExampleDetailCtrl', example_detail_ctrl);

    app_config.$inject = ['$routeProvider'];

    function app_config($routeProvider) {
        $routeProvider.
        when('/', {
                templateUrl: 'home.html'
        }).
        when('/examples/:exampleNumber', {
                templateUrl: 'example-view.html',
                controller: 'ExampleDetailCtrl'
        }).
        when('/sections/:sectionNumber', {
                templateUrl: 'section-view.html',
                controller: 'SectionCtrl'
        }).
        otherwise({
                redirectTo: '/'
        });
    }

    function conf() {
        var service = {
            examplesPath: 'examples/',
        };
        return service;
    }

    examples.$inject = ['$http'];

    function examples($http) {
        function getData(callback) {
            $http({
                method: 'GET',
                url: 'examples.json',
                cache: true
            }).success(callback);
        }
        return {
            list: getData,
            find: function(exampleNumber, callback) {
                getData(function(data) {
                    var index = parseInt(exampleNumber);
                    angular.forEach(data, function(section, key) {
                        angular.forEach(section.examples, function(example, key) {
                            if (example.id == index) {
                                callback(example);
                            }
                        });
                    });
                });
            },
            findSection: function(sectionNumber, callback) {
                getData(function(data) {
                    var index = parseInt(sectionNumber);
                    angular.forEach(data, function(section, key) {
                        if (section.id == index) {
                            callback(section);
                        }
                    });
                });
            },
            findSectionFromExample: function(exampleNumber, callback) {
                getData(function(data) {
                    var index = parseInt(exampleNumber);
                    angular.forEach(data, function(section, key) {
                        angular.forEach(section.examples, function(example, key) {
                            if (example.id == index) {
                                callback(section);
                            }
                        });
                    });
                });
            },
        };
    }

    function menu() {
        return {
            selectSection: function(section) {
                self.openedSection = section;
            },
            toggleSelectSection: function(section) {
                self.openedSection = (self.openedSection === section ?
                        null : section);
            },
            isSectionSelected: function(section) {
                return self.openedSection === section;
            },
            getSectionName: function() {
                if (!self.openedSection) {
                    return "";
                }
                return self.openedSection.name;
            }
        };
    }

    home_ctrl.$inject = ['$scope', 'examples', 'menu'];

    function home_ctrl($scope, examples, menu) {
        $scope.menu = menu;
        examples.list(function(examples) {
            $scope.examples = examples;
        });
    }

    example_detail_ctrl.$inject = ['$scope', '$routeParams', '$http', '$sce', 'conf',
        'examples', 'menu'];

    function example_detail_ctrl($scope, $routeParams, $http, $sce, conf, examples, menu) {
        $scope.menu = menu;
        examples.find($routeParams.exampleNumber, function(example) {
            $scope.example = example;
            var examplePath = conf.examplesPath + example.id + '/';
            $scope.runUrl = examplePath + 'index.html';
            $scope.readme = examplePath + 'readme.html';
        });
    }

    section_ctrl = ['$scope', '$routeParams', '$http', '$sce', 'conf', 'examples', 'menu'];

    function section_ctrl($scope, $routeParams, $http, $sce, conf, examples, menu) {
        $scope.menu = menu;
        examples.findSection($routeParams.sectionNumber, function(section) {
            $scope.section = section;
            $scope.readme = conf.examplesPath + 'section' + section.id + '.html';
        });
    }

    at_hljs.$inject = ['conf'];

    function at_hljs(conf) {
        return {
            scope: { file: '=', example: '=' },
            restrict: 'A',
            controller: function($scope, $http) {
                var path = [
                    conf.examplesPath,
                    $scope.example.id,
                    $scope.file
                ].join('/');
                $http.get(path).success(function(data) {
                    if (typeof(data) === 'object') {
                        // un-parse auto-parsed JSON files for presentation as text
                        data = JSON.stringify(data, null, 2);
                    } else {
                        // Remove trailing newlines from code presentation
                        data = data.trim();
                    }
                    $scope.content = data;
                });
            },
            link: function(scope, element, attrs) {
                var contentParent = angular.element(
                    '

'
                );
                element.append(contentParent);
                scope.$watch('content', function(data) {
                    if (data) {
                        var codeElement = contentParent.find('code');
                        var highlightedCode = hljs.highlightAuto(data);
                        codeElement.append(
                            highlightedCode.value).addClass('highlight');
                    }
                });
            }
        };
    }

    function hl() {
        var directive = {
            restrict: 'A',
            link: link,
        };
        return directive;

        function link(scope, element, attrs) {
            var d = element.html();
            var contentParent = angular.element(
                '

'
            );
            var codeElement = contentParent.find('code');

            element.empty();
            element.append(contentParent);

            var highlightedCode = hljs.highlightAuto(d);
            console.log(highlightedCode);
            codeElement.html(highlightedCode.value).addClass('highlight');
        }
    }
})();
<commit_msg>Refactor menu service to store opened section<commit_after>/*
 * Copyright 2014 - 2015 Björn Ricks <bjoern.ricks@gmail.com>
 *
 */
(function() {
    'use strict';

    angular.module('angTutApp',
        ['ngRoute', 'ngMaterial']
    )
    .config(app_config)
    .factory('conf', conf)
    .factory('examples', examples)
    .factory('menu', menu)
    .directive('hl', hl)
    .directive('atHljs', at_hljs)
    .controller('HomeCtrl', home_ctrl)
    .controller('SectionCtrl', section_ctrl)
    .controller('ExampleDetailCtrl', example_detail_ctrl);

    app_config.$inject = ['$routeProvider'];

    function app_config($routeProvider) {
        $routeProvider.
        when('/', {
                templateUrl: 'home.html'
        }).
        when('/examples/:exampleNumber', {
                templateUrl: 'example-view.html',
                controller: 'ExampleDetailCtrl'
        }).
        when('/sections/:sectionNumber', {
                templateUrl: 'section-view.html',
                controller: 'SectionCtrl'
        }).
        otherwise({
                redirectTo: '/'
        });
    }

    function conf() {
        var service = {
            examplesPath: 'examples/',
        };
        return service;
    }

    examples.$inject = ['$http'];

    function examples($http) {
        function getData(callback) {
            $http({
                method: 'GET',
                url: 'examples.json',
                cache: true
            }).success(callback);
        }
        return {
            list: getData,
            find: function(exampleNumber, callback) {
                getData(function(data) {
                    var index = parseInt(exampleNumber);
                    angular.forEach(data, function(section, key) {
                        angular.forEach(section.examples, function(example, key) {
                            if (example.id == index) {
                                callback(example);
                            }
                        });
                    });
                });
            },
            findSection: function(sectionNumber, callback) {
                getData(function(data) {
                    var index = parseInt(sectionNumber);
                    angular.forEach(data, function(section, key) {
                        if (section.id == index) {
                            callback(section);
                        }
                    });
                });
            },
            findSectionFromExample: function(exampleNumber, callback) {
                getData(function(data) {
                    var index = parseInt(exampleNumber);
                    angular.forEach(data, function(section, key) {
                        angular.forEach(section.examples, function(example, key) {
                            if (example.id == index) {
                                callback(section);
                            }
                        });
                    });
                });
            },
        };
    }

    function menu() {
        var openedsection = null;
        var service = {
            selectSection: function(section) {
                openedsection = section;
            },
            toggleSelectSection: function(section) {
                openedsection = (openedsection === section ? null : section);
            },
            isSectionSelected: function(section) {
                return openedsection === section;
            },
            getSectionName: function() {
                if (!openedsection) {
                    return "";
                }
                return openedsection.name;
            }
        };
        return service;
    }

    home_ctrl.$inject = ['$scope', 'examples', 'menu'];

    function home_ctrl($scope, examples, menu) {
        $scope.menu = menu;
        examples.list(function(examples) {
            $scope.examples = examples;
        });
    }

    example_detail_ctrl.$inject = ['$scope', '$routeParams', '$http', '$sce', 'conf',
        'examples', 'menu'];

    function example_detail_ctrl($scope, $routeParams, $http, $sce, conf, examples, menu) {
        $scope.menu = menu;
        examples.find($routeParams.exampleNumber, function(example) {
            $scope.example = example;
            var examplePath = conf.examplesPath + example.id + '/';
            $scope.runUrl = examplePath + 'index.html';
            $scope.readme = examplePath + 'readme.html';
        });
    }

    section_ctrl = ['$scope', '$routeParams', '$http', '$sce', 'conf', 'examples', 'menu'];

    function section_ctrl($scope, $routeParams, $http, $sce, conf, examples, menu) {
        $scope.menu = menu;
        examples.findSection($routeParams.sectionNumber, function(section) {
            $scope.section = section;
            $scope.readme = conf.examplesPath + 'section' + section.id + '.html';
        });
    }

    at_hljs.$inject = ['conf'];

    function at_hljs(conf) {
        return {
            scope: { file: '=', example: '=' },
            restrict: 'A',
            controller: function($scope, $http) {
                var path = [
                    conf.examplesPath,
                    $scope.example.id,
                    $scope.file
                ].join('/');
                $http.get(path).success(function(data) {
                    if (typeof(data) === 'object') {
                        // un-parse auto-parsed JSON files for presentation as text
                        data = JSON.stringify(data, null, 2);
                    } else {
                        // Remove trailing newlines from code presentation
                        data = data.trim();
                    }
                    $scope.content = data;
                });
            },
            link: function(scope, element, attrs) {
                var contentParent = angular.element(
                    '

'
                );
                element.append(contentParent);
                scope.$watch('content', function(data) {
                    if (data) {
                        var codeElement = contentParent.find('code');
                        var highlightedCode = hljs.highlightAuto(data);
                        codeElement.append(
                            highlightedCode.value).addClass('highlight');
                    }
                });
            }
        };
    }

    function hl() {
        var directive = {
            restrict: 'A',
            link: link,
        };
        return directive;

        function link(scope, element, attrs) {
            var d = element.html();
            var contentParent = angular.element(
                '

'
            );
            var codeElement = contentParent.find('code');

            element.empty();
            element.append(contentParent);

            var highlightedCode = hljs.highlightAuto(d);
            console.log(highlightedCode);
            codeElement.html(highlightedCode.value).addClass('highlight');
        }
    }
})();
<|endoftext|>


<commit_before>var Templates = {};

Templates.members = [
'{{#with pageData}}',
    '{{#if members}}',
        '{{#each members}}',
            '
',
                '
',
                    '
{{ name }}
',
                    '{{#if position}}
{{ position }}
 {{/if}}',
                    '{{#if joined}}
Member since {{ joined }}
 {{/if}}',
                '
',
                '
',
                    '{{#if image}}  {{/if}}',
                '
',
                '
',
                    '
{{ description }}
',
                    '{{#if posts}}',
                        '
Blog posts:
',
                        '
',
                            '{{#each posts}}',
                                '
{{title}}
',
                            '{{/each}}',
                        '
',
                    '{{/if}}',
                '
',
            '
',
            '
',
        '{{/each}}',
    '{{else}}',
        'No members found.',
    '{{/if}}',
'{{/with}}'
].join('\n');

Templates.banner = [
'
',
    '',
'
',
'
',
    '{{#each buttons.banner}}',
    '{{ text }}',
    '{{/each}}',
'
'
].join('\n');

Templates.header = [
'{{#with pageData}}',
'
Stanford Sports Analytics Club: {{ header }}
',
'
{{ description }}
',
'{{/with}}'
].join('\n');

Templates.callToAction = [
'
',
    '
',
        '
',
            '
Get Involved
',
            '{{#with buttons.mailList}}',
            '{{ text }}',
            '{{/with}}',
        '
',
    '
',
'
'
].join('\n');

Templates.footer = [
'
',
    '
',
        '
',
            '
',
                '

',
                '

',
            '
',
            '
',
            '
Copyright © Stanford Sports Analytics Club {{ year }}
',
        '
',
    '
',
'
'
].join('\n');
<commit_msg>Added a sidebar template<commit_after>var Templates = {};

Templates.members = [
'{{#with pageData}}',
    '{{#if members}}',
        '{{#each members}}',
            '
',
                '
',
                    '
{{ name }}
',
                    '{{#if position}}
{{ position }}
 {{/if}}',
                    '{{#if joined}}
Member since {{ joined }}
 {{/if}}',
                '
',
                '
',
                    '{{#if image}}  {{/if}}',
                '
',
                '
',
                    '
{{ description }}
',
                    '{{#if posts}}',
                        '
Blog posts:
',
                        '
',
                            '{{#each posts}}',
                                '
{{title}}
',
                            '{{/each}}',
                        '
',
                    '{{/if}}',
                '
',
            '
',
            '
',
        '{{/each}}',
    '{{else}}',
        'No members found.',
    '{{/if}}',
'{{/with}}'
].join('\n');

Templates.banner = [
'
',
    '',
'
',
'
',
    '{{#each buttons.banner}}',
    '{{ text }}',
    '{{/each}}',
'
'
].join('\n');

Templates.header = [
'{{#with pageData}}',
'
Stanford Sports Analytics Club: {{ header }}
',
'
{{ description }}
',
'{{/with}}'
].join('\n');

Templates.callToAction = [
'
',
    '
',
        '
',
            '
Get Involved
',
            '{{#with buttons.mailList}}',
            '{{ text }}',
            '{{/with}}',
        '
',
    '
',
'
'
].join('\n');

Templates.footer = [
'
',
    '
',
        '
',
            '
',
                '

',
                '

',
            '
',
            '
',
            '
Copyright © Stanford Sports Analytics Club {{ year }}
',
        '
',
    '
',
'
'
].join('\n');

Templates.sidebar = [
'
',
    '
About
',
    '
Stanford Sports Analytics Club is devoted to fostering a community of serious quantitative research into sports. If you are interested in joining, please add yourself to our mailing list below, or attend our weekly meetings.
',
'
',
'
',
    '
Elsewhere
',
    '
',
        '
{{ links.twitter.name}}
',
        '
{{ links.facebook.name }}
',
        '
{{ links.blog.name }}
',
    '
',
'
',
].join('\n');
<|endoftext|>