<commit_before>/**
 * jq.web.css3Animate - css3 animate class for html5 mobile apps
 * @copyright 2011 - AppMobi
 */
(function ($) {
	var cache = [];
	var objId=function(obj){
		if(!obj.jqmCSS3AnimateId) obj.jqmCSS3AnimateId=$.uuid();
		return obj.jqmCSS3AnimateId;
	}
	var getEl=function(elID){
        if (typeof elID == "string" || elID instanceof String) {
            return document.getElementById(elID);
        } else if($.is$(elID)){
        	return elID[0];
        } else {
            return elID;
        }
	}
	var getCSS3Animate=function(obj, options){
        var tmp, id, el = getEl(obj);
		//first one
		id = objId(el);
		if(cache[id]){
			cache[id].animate(options);
			tmp = cache[id];
		} else {
			tmp = css3Animate(el, options);
			cache[id] = tmp;
		}
		return tmp;
	}
    $.fn["css3Animate"] = function (opts) {
        var tmp;
		//first one
		tmp = getCSS3Animate(this[0], opts);
		opts.callback=null;
        for (var i = 1; i < this.length; i++) {
            tmp.link(this[i], opts);
        }
        return tmp;
    };

    $["css3AnimateQueue"] = function () {
        return new css3Animate.queue();
    }
    if (!window.WebKitCSSMatrix) return;
    var translateOpen = 'm11' in new WebKitCSSMatrix() ? "3d(" : "(";
    var translateClose = 'm11' in new WebKitCSSMatrix() ? ",0)" : ")";

	var css3Animate = (function () {

	    var css3Animate = function (elID, options) {
			if(!(this instanceof css3Animate)) return new css3Animate(elID, options);

			//start doing stuff
			this.callbacksStack = [];
			this.activeEvent = null;
			this.countStack = 0;
			this.isActive = false;
			this.el = elID;

	        if (!this.el) return;

			this.animate(options);

			var that = this;
			jq(this.el).bind('destroy', function(){
				var id = that.el.jqmCSS3AnimateId;
				that.callbacksStack = [];
				if(cache[id]) delete cache[id];
			});
	    };

	    css3Animate.prototype = {
			animate:function(options){

				//cancel current active animation on this object
				if(this.isActive) this.cancel();
				this.isActive = true;

		        if (!options) {
		            alert("Please provide configuration options for animation of " + this.el.id);
		            return;
		        }

				var callback = null;
		        if (options["callback"]) {
		            callback = options["callback"];
		        }

				var classMode = !!options["addClass"];

	            if(classMode){
	            	//class defines properties being changed
					if(options["removeClass"]){
						jq(this.el).replaceClass(options["removeClass"], options["addClass"]);
					} else {
						jq(this.el).addClass(options["addClass"]);
					}

	            } else {
	            	//property by property
					var timeNum = numOnly(options["time"]);
					if(timeNum==0) options["time"]=0;

			        if (!options["y"]) options["y"] = 0;
			        if (!options["x"]) options["x"] = 0;
			        if (options["previous"]) {
						var cssMatrix = new WebKitCSSMatrix(window.getComputedStyle(this.el).webkitTransform);
			            options.y += numOnly(cssMatrix.f);
			            options.x += numOnly(cssMatrix.e);
			        }
			        if (!options["origin"]) options.origin = "0% 0%";

			        if (!options["scale"]) options.scale = "1";

			        if (!options["rotateY"]) options.rotateY = "0";
			        if (!options["rotateX"]) options.rotateX = "0";
			        if (!options["skewY"]) options.skewY = "0";
			        if (!options["skewX"]) options.skewX = "0";

			        if (!options["timingFunction"]) options["timingFunction"] = "linear";

			        //check for percent or numbers
			        if (typeof (options.x) == "number" || (options.x.indexOf("%") == -1 && options.x.toLowerCase().indexOf("px") == -1 && options.x.toLowerCase().indexOf("deg") == -1)) options.x = parseInt(options.x) + "px";
			        if (typeof (options.y) == "number" || (options.y.indexOf("%") == -1 && options.y.toLowerCase().indexOf("px") == -1 && options.y.toLowerCase().indexOf("deg") == -1)) options.y = parseInt(options.y) + "px";

			        this.el.style.webkitTransform = "translate" + translateOpen + (options.x) + "," + (options.y) + translateClose + " scale(" + parseFloat(options.scale) + ") rotate(" + options.rotateX + ") rotateY(" + options.rotateY + ") skew(" + options.skewX + "," + options.skewY + ")";
			        this.el.style.webkitBackfaceVisiblity = "hidden";
					var properties = "-webkit-transform";
			        if (options["opacity"]!==undefined) {
			            this.el.style.opacity = options["opacity"];
						properties+=", opacity";
			        }
			        if (options["width"]) {
			            this.el.style.width = options["width"];
						properties = "all";
			        }
			        if (options["height"]) {
			            this.el.style.height = options["height"];
						properties = "all";
			        }
					this.el.style.webkitTransitionProperty = properties;

					if((""+options["time"]).indexOf("s")===-1) {
						var scale = 'ms';
						var time = options["time"]+scale;
					} else if(options["time"].indexOf("ms")!==-1){
						var scale = 'ms';
						var time = options["time"];
					} else {
						var scale = 's';
						var time = options["time"]+scale;
					}

					this.el.style.webkitTransitionDuration = time;
					this.el.style.webkitTransitionTimingFunction = options["timingFunction"];
			        this.el.style.webkitTransformOrigin = options.origin;
	            }

				//add callback to the stack
				this.callbacksStack.push(callback);
				this.countStack++;

				var that = this;
				if(classMode){
					//get the duration
					var duration = window.getComputedStyle(that.el).webkitTransitionDuration;
					var timeNum = numOnly(duration);
					if(duration.indexOf("ms")!==-1){
						var scale = 'ms';
					} else {
						var scale = 's';
					}
				}

				//finish asap
				if(timeNum==0 || (scale=='ms' && timeNum<5)){
					$.asap($.proxy(this.finishAnimation, this, [false]));
					//set transitionend event
				} else {
					//setup the event normally
					this.activeEvent = function(event){
						that.finishAnimation(event);
						that.el.removeEventListener("webkitTransitionEnd", that.activeEvent, false);
					};
					this.el.addEventListener("webkitTransitionEnd", this.activeEvent, false);
				}

			},
			addCallbackHook:function(callback){
				if(callback) this.callbacksStack.push(callback);
				this.countStack++;
				var that = this;
				return function(){that.finishAnimation();};
			},
	        finishAnimation: function (event) {
	            if(event) event.preventDefault();
				if(!this.isActive) return;

				this.countStack--;

	            if(this.countStack==0) this.fireCallbacks();
	        },
			fireCallbacks:function(){
				this.clearEvents();

				//keep callbacks after cleanup
				// (if any of the callbacks overrides this object, callbacks will keep on fire as expected)
				var callbacks = this.callbacksStack;

				//cleanup
				this.cleanup();

				//fire all callbacks
				for(var i=0; i<callbacks.length; i++) {
	                if (callbacks[i] && typeof (callbacks[i] == "function")) {
	                    callbacks[i]();
	                }
				}
			},
			cancel:function(){
				if(!this.isActive) return;
				this.clearEvents();
				this.cleanup();
			},
			cleanup:function(){
				this.callbacksStack=[];
				this.isActive = false;
				this.countStack = 0;
			},
			clearEvents:function(){
				if(this.activeEvent) {
					this.el.removeEventListener("webkitTransitionEnd", this.activeEvent, false);
				}
				this.activeEvent = null;
			},
	        link: function (elID, opts) {
				var oldCallback = opts.callback;
				opts.callback = this.addCallbackHook(oldCallback);
				getCSS3Animate(elID, opts);
				//set the old callback back in the obj to avoid strange stuff
				opts.callback = oldCallback;
				return this;
	        }
	    }

		// var tmp = new $.css3AnimateQueue();
		// tmp.push({id:"animate",x:20,y:30,time:"300ms"});
		// tmp.push({id:"animate",x:20,y:30,time:"500ms",previous:true});
		// tmp.push({id:"animate",x:0,y:0,time:"0ms"});
		// tmp.push({id:"animate",x:20,y:30,time:"300ms"});
		// tmp.push({id:"animate",x:20,y:30,time:"500ms",previous:true});
		// tmp.push(function(){reset()});
		// tmp.run();

		//uncomment for performance debug
		//css3Animate = $.debug.type(css3Animate, 'css3Animate');

        return css3Animate;
    })();

    css3Animate.queue = function () {
        return {
            elements: [],
            push: function (el) {
                this.elements.push(el);
            },
            pop: function () {
                return this.elements.pop();
            },
            run: function () {
                var that = this;
                if (this.elements.length == 0) return;
                if (typeof (this.elements[0]) == "function") {
                    var func = this.shift();
                    func();
                }
                if (this.elements.length == 0) return;
                var params = this.shift();
                if (this.elements.length > 0) params.callback = function () {
                    that.run();
                };
                css3Animate(params.id, params);
            },
            shift: function () {
                return this.elements.shift();
            }
        }
    };
})(jq);
<commit_msg>success/failure/complete callbacks to css3Animate - callback to complete hook for BC<commit_after>/**
 * jq.web.css3Animate - css3 animate class for html5 mobile apps
 * @copyright 2011 - AppMobi
 */
(function ($) {
	var cache = [];
	var objId=function(obj){
		if(!obj.jqmCSS3AnimateId) obj.jqmCSS3AnimateId=$.uuid();
		return obj.jqmCSS3AnimateId;
	}
	var getEl=function(elID){
        if (typeof elID == "string" || elID instanceof String) {
            return document.getElementById(elID);
        } else if($.is$(elID)){
        	return elID[0];
        } else {
            return elID;
        }
	}
	var getCSS3Animate=function(obj, options){
        var tmp, id, el = getEl(obj);
		//first one
		id = objId(el);
		if(cache[id]){
			cache[id].animate(options);
			tmp = cache[id];
		} else {
			tmp = css3Animate(el, options);
			cache[id] = tmp;
		}
		return tmp;
	}
    $.fn["css3Animate"] = function (opts) {
		//keep old callback system - backwards compatibility - should be deprecated in future versions
		if(!opts.complete && opts.callback) opts.complete = opts.callback;
        //first on
		var tmp = getCSS3Animate(this[0], opts);
		opts.complete=null;
		opts.sucess=null;
		opts.failure=null;
        for (var i = 1; i < this.length; i++) {
            tmp.link(this[i], opts);
        }
        return tmp;
    };

    $["css3AnimateQueue"] = function () {
        return new css3Animate.queue();
    }
    if (!window.WebKitCSSMatrix) return;
    var translateOpen = 'm11' in new WebKitCSSMatrix() ? "3d(" : "(";
    var translateClose = 'm11' in new WebKitCSSMatrix() ? ",0)" : ")";

	var css3Animate = (function () {

	    var css3Animate = function (elID, options) {
			if(!(this instanceof css3Animate)) return new css3Animate(elID, options);

			//start doing stuff
			this.callbacksStack = [];
			this.activeEvent = null;
			this.countStack = 0;
			this.isActive = false;
			this.el = elID;
			this.linkFinishedProxy_ = $.proxy(this.linkFinished, this);

	        if (!this.el) return;

			this.animate(options);

			var that = this;
			jq(this.el).bind('destroy', function(){
				var id = that.el.jqmCSS3AnimateId;
				that.callbacksStack = [];
				if(cache[id]) delete cache[id];
			});
	    };

	    css3Animate.prototype = {
			animate:function(options){

				//cancel current active animation on this object
				if(this.isActive) this.cancel();
				this.isActive = true;

		        if (!options) {
		            alert("Please provide configuration options for animation of " + this.el.id);
		            return;
		        }

				var classMode = !!options["addClass"];

	            if(classMode){
	            	//class defines properties being changed
					if(options["removeClass"]){
						jq(this.el).replaceClass(options["removeClass"], options["addClass"]);
					} else {
						jq(this.el).addClass(options["addClass"]);
					}

	            } else {
	            	//property by property
					var timeNum = numOnly(options["time"]);
					if(timeNum==0) options["time"]=0;

			        if (!options["y"]) options["y"] = 0;
			        if (!options["x"]) options["x"] = 0;
			        if (options["previous"]) {
						var cssMatrix = new WebKitCSSMatrix(window.getComputedStyle(this.el).webkitTransform);
			            options.y += numOnly(cssMatrix.f);
			            options.x += numOnly(cssMatrix.e);
			        }
			        if (!options["origin"]) options.origin = "0% 0%";

			        if (!options["scale"]) options.scale = "1";

			        if (!options["rotateY"]) options.rotateY = "0";
			        if (!options["rotateX"]) options.rotateX = "0";
			        if (!options["skewY"]) options.skewY = "0";
			        if (!options["skewX"]) options.skewX = "0";

			        if (!options["timingFunction"]) options["timingFunction"] = "linear";

			        //check for percent or numbers
			        if (typeof (options.x) == "number" || (options.x.indexOf("%") == -1 && options.x.toLowerCase().indexOf("px") == -1 && options.x.toLowerCase().indexOf("deg") == -1)) options.x = parseInt(options.x) + "px";
			        if (typeof (options.y) == "number" || (options.y.indexOf("%") == -1 && options.y.toLowerCase().indexOf("px") == -1 && options.y.toLowerCase().indexOf("deg") == -1)) options.y = parseInt(options.y) + "px";

			        this.el.style.webkitTransform = "translate" + translateOpen + (options.x) + "," + (options.y) + translateClose + " scale(" + parseFloat(options.scale) + ") rotate(" + options.rotateX + ") rotateY(" + options.rotateY + ") skew(" + options.skewX + "," + options.skewY + ")";
			        this.el.style.webkitBackfaceVisiblity = "hidden";
					var properties = "-webkit-transform";
			        if (options["opacity"]!==undefined) {
			            this.el.style.opacity = options["opacity"];
						properties+=", opacity";
			        }
			        if (options["width"]) {
			            this.el.style.width = options["width"];
						properties = "all";
			        }
			        if (options["height"]) {
			            this.el.style.height = options["height"];
						properties = "all";
			        }
					this.el.style.webkitTransitionProperty = properties;

					if((""+options["time"]).indexOf("s")===-1) {
						var scale = 'ms';
						var time = options["time"]+scale;
					} else if(options["time"].indexOf("ms")!==-1){
						var scale = 'ms';
						var time = options["time"];
					} else {
						var scale = 's';
						var time = options["time"]+scale;
					}

					this.el.style.webkitTransitionDuration = time;
					this.el.style.webkitTransitionTimingFunction = options["timingFunction"];
			        this.el.style.webkitTransformOrigin = options.origin;
	            }

				//add callback to the stack

				this.callbacksStack.push({
					complete : options["complete"],
					success : options["success"],
					failure : options["failure"]
				});
				this.countStack++;

				var that = this;
				var style = window.getComputedStyle(this.el);
				if(classMode){
					//get the duration
					var duration = style.webkitTransitionDuration;
					var timeNum = numOnly(duration);
					if(duration.indexOf("ms")!==-1){
						var scale = 'ms';
					} else {
						var scale = 's';
					}
				}

				//finish asap
				if(timeNum==0 || (scale=='ms' && timeNum<5) || style.display=='none'){
					//the duration is nearly 0 or the element is not displayed, finish immediatly
					$.asap($.proxy(this.finishAnimation, this, [false]));
					//set transitionend event
				} else {
					//setup the event normally
					this.activeEvent = function(event){
						that.finishAnimation(event);
						that.el.removeEventListener("webkitTransitionEnd", that.activeEvent, false);
					};
					this.el.addEventListener("webkitTransitionEnd", this.activeEvent, false);
				}

			},
			addCallbackHook:function(callback){
				if(callback) this.callbacksStack.push(callback);
				this.countStack++;
				return this.linkFinishedProxy_;
			},
			linkFinished:function(canceled){
				if(canceled) this.cancel();
				else this.finishAnimation();
			},
	        finishAnimation: function (event) {
	            if(event) event.preventDefault();
				if(!this.isActive) return;

				this.countStack--;

	            if(this.countStack==0) this.fireCallbacks(false);
	        },
			fireCallbacks:function(canceled){
				this.clearEvents();

				//keep callbacks after cleanup
				// (if any of the callbacks overrides this object, callbacks will keep on fire as expected)
				var callbacks = this.callbacksStack;

				//cleanup
				this.cleanup();

				//fire all callbacks
				for(var i=0; i<callbacks.length; i++) {
					var complete = callbacks[i]['complete'];
					var success = callbacks[i]['success'];
					var failure = callbacks[i]['failure'];
					//fire callbacks
	                if(complete && typeof (complete == "function")) complete(canceled);
					//success/failure
					if(canceled && failure && typeof (failure == "function")) failure();
					else if(success && typeof (success == "function")) success();
				}
			},
			cancel:function(){
				if(!this.isActive) return;
				this.fireCallbacks(true); //fire failure callbacks
			},
			cleanup:function(){
				this.callbacksStack=[];
				this.isActive = false;
				this.countStack = 0;
			},
			clearEvents:function(){
				if(this.activeEvent) {
					this.el.removeEventListener("webkitTransitionEnd", this.activeEvent, false);
				}
				this.activeEvent = null;
			},
	        link: function (elID, opts) {
				var callbacks = {complete:opts.complete,success:opts.success,failure:opts.failure};
				opts.complete = this.addCallbackHook(callbacks);
				opts.success = null;
				opts.failure = null;
				//run the animation with the replaced callbacks
				getCSS3Animate(elID, opts);
				//set the old callback back in the obj to avoid strange stuff
				opts.complete = callbacks.complete;
				opts.success = callbacks.success;
				opts.failure = callbacks.failure;
				return this;
	        }
	    }

		// var tmp = new $.css3AnimateQueue();
		// tmp.push({id:"animate",x:20,y:30,time:"300ms"});
		// tmp.push({id:"animate",x:20,y:30,time:"500ms",previous:true});
		// tmp.push({id:"animate",x:0,y:0,time:"0ms"});
		// tmp.push({id:"animate",x:20,y:30,time:"300ms"});
		// tmp.push({id:"animate",x:20,y:30,time:"500ms",previous:true});
		// tmp.push(function(){reset()});
		// tmp.run();

		//uncomment for performance debug
		//css3Animate = $.debug.type(css3Animate, 'css3Animate');

        return css3Animate;
    })();

    css3Animate.queue = function () {
        return {
            elements: [],
            push: function (el) {
                this.elements.push(el);
            },
            pop: function () {
                return this.elements.pop();
            },
            run: function () {
                var that = this;
                if (this.elements.length == 0) return;
                if (typeof (this.elements[0]) == "function") {
                    var func = this.shift();
                    func();
                }
                if (this.elements.length == 0) return;
                var params = this.shift();
                if (this.elements.length > 0) params.complete = function (canceled) {
                    if(!canceled) that.run();
                };
                css3Animate(params.id, params);
            },
            shift: function () {
                return this.elements.shift();
            }
        }
    };
})(jq);
<|endoftext|>


<commit_before>// Copyright 2014 Globo.com Player authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var UIPlugin = require('../../base/ui_plugin');
var Styler = require('../../base/styler');
var JST = require('../../base/jst');
var _ = require("underscore");

var Visibility = require('visibility');
var objectIE = '<object type="application/x-shockwave-flash" id="<%= cid %>" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" data-hls=""><param name="movie" value="<%= swfPath %>"> <param name="quality" value="autohigh"> <param name="swliveconnect" value="true"> <param name="allowScriptAccess" value="always"> <param name="bgcolor" value="#001122"> <param name="allowFullScreen" value="false"> <param name="wmode" value="transparent"> <param name="tabindex" value="1"> </object>';

var HLS = UIPlugin.extend({
  name: 'hls',
  tagName: 'object',
  template: JST.hls,
  attributes: {
    'data-hls': '',
    'type': 'application/x-shockwave-flash'
  },
  initialize: function(options) {
    this.src = options.src;
    this.swfPath = options.swfPath || "assets/HLSPlayer.swf";
    this.isLegacyIE = window.ActiveXObject;
    this.isChrome = navigator.userAgent.match(/chrome/i);
    this.isFirefox = navigator.userAgent.match(/firefox/i);
    this.isSafari = navigator.userAgent.match(/safari/i);
    this.autoPlay = options.autoPlay;
    this.visibility = new Visibility();
    this.visible = true;
    this.highDefinition = "unavailable"; // this will be changed on checkHighDefinition()
    this.settings = {
      left: ["playstop", "volume"],
      default: ["position", "seekbar", "duration"],
      right: ["fullscreen", "volume", "hd"]
    };
    this.checkIfFlashIsReady();
  },
  safe: function(fn) {
    if(this.el.globoGetState && this.el.globoGetDuration && this.el.globoGetPosition &&
       this.el.globoPlayerSmoothSetLevel && this.el.globoPlayerSetflushLiveURLCache) {
      return fn.apply(this);
    }
  },
  hiddenCallback: function() {
    this.hiddenId = this.safe(function() {
      return setTimeout(function() { this.el.globoPlayerSmoothSetLevel(0) }.bind(this), 10000);
    });
  },
  visibleCallback: function() {
    this.safe(function() {
      if (this.hiddenId) {
        clearTimeout(this.hiddenId);
      }
      this.el.globoPlayerSmoothSetLevel(-1);
    });
  },
  bootstrap: function() {
    this.el.width = "100%";
    this.el.height = "100%";
    this.trigger('playback:ready', this.name);
    clearInterval(this.bootstrapId);
    this.currentState = "IDLE";
    this.timedCheckState();
    this.el.globoPlayerSetflushLiveURLCache(true);
    this.el.globoPlayerSetstartFromLowestLevel(true); // decreases startup time
    this.autoPlay && this.play();
  },
  checkIfFlashIsReady: function() {
    this.bootstrapId = setInterval(function() {
      if(this.el.globoGetState) {
        this.bootstrap();
      }
    }.bind(this), 50);
  },
  updateTime: function(interval) {
    return this.safe(function() {
      return setInterval(function() {
        this.safe(function() {
          var previousDvrEnabled = this.dvrEnabled;
          var duration = this.el.globoGetDuration();
          this.dvrEnabled = (this.playbackType === 'live' && duration > 240);
          this.trigger('playback:timeupdate', this.el.globoGetPosition(), duration, this.name);
          if (this.dvrEnabled != previousDvrEnabled) {
            this.updateSettings();
          }
        });
      }.bind(this), interval);
    });
  },
  play: function() {
    this.safe(function() {
      if(this.el.globoGetState() === 'IDLE') {
        clearInterval(this.checkStateId)
        this.checkTimeId = this.updateTime(1000);
      }
      if(this.el.globoGetState() === 'PAUSED') {
        this.el.globoPlayerResume();
      } else {
        this.firstPlay();
      }
      this.trigger('playback:play', this.name);
    });
  },
  getPlaybackType: function() {
    if (this.playbackType)
      return this.playbackType;
    return null;
  },
  getCurrentBitrate: function() {
    return this.safe(function() {
      var currentLevel = this.getLevels()[this.el.globoGetLevel()];
      return currentLevel.bitrate;
    });
  },
  getLastProgramDate: function() {
    var programDate = this.el.globoGetLastProgramDate();
    // normalizing for BRT
    return programDate - 1.08e+7;
  },
  isHighDefinitionAvailable: function(levels) {
    return !!(levels.length > 0 && levels[levels.length-1].bitrate >= 3500000);
  },
  isHighDefinitionInUse: function() {
    return this.highDefinition === "available-in-use";
  },
  checkHighDefinition: function() {
    this.safe(function() {
      // this function is responsible to change media control settings
      // regarding the availability of HD level and if it's being used or not.
      // highDefinition attribute have 3 states: "available", "available-in-use", "unavailable"
      var changed = false;
      this.levels = this.getLevels();
      if (this.isHighDefinitionAvailable(this.levels)) {
        var lastLevel = this.levels.length -1;
        var currentLevel = this.el.globoGetLevel();
        if (currentLevel === lastLevel && this.highDefinition !== "available-in-use") {
          this.highDefinition = "available-in-use";
          changed = true;
        } else if (currentLevel !== lastLevel && this.highDefinition === "available-in-use") {
          this.highDefinition = "available";
          changed = true;
        } else if (this.highDefinition === "unavailable") {
          this.highDefinition = "available";
          changed = true;
        }
      }
      if (changed) {
        this.trigger('playback:highdefinitionupdate');
      }
    });
  },
  getLevels: function() {
    return this.safe(function() {
      if (!this.levels || this.levels.length === 0) {
        this.levels = this.el.globoGetLevels();
      }
      return this.levels;
    });
  },
  timedCheckState: function() {
    this.checkStateId = setInterval(this.checkState.bind(this), 250);
    this.checkHighDefinitionId = setInterval(this.checkHighDefinition.bind(this), 3000);
  },
  checkState: function() {
    this.safe(function() {
      this.updatePlaybackType();
      this.updatePlayerVisibility();
      if (this.el.globoGetState() === "PLAYING_BUFFERING" && this.el.globoGetbufferLength() < 1 && this.currentState !== "PLAYING_BUFFERING") {
        this.trigger('playback:buffering', this.name);
        this.currentState = "PLAYING_BUFFERING";
      } else if (this.currentState === "PLAYING_BUFFERING" && this.el.globoGetState() === "PLAYING") {
        this.trigger('playback:bufferfull', this.name);
        this.currentState = "PLAYING";
      } else if (this.el.globoGetState() === "IDLE") {
        this.trigger('playback:ended', this.name);
        this.trigger('playback:timeupdate', 0, this.el.globoGetDuration(), this.name);
        clearInterval(this.checkStateId);
        this.currentState = "IDLE";
      }
    });
  },
  updatePlayerVisibility: function() {
    if (this.visible && this.visibility.hidden()) {
      this.visible = false;
      this.hiddenCallback();
    } else if (!this.visible && this.visibility.visible()) {
      this.visible = true;
      this.visibleCallback();
    }
  },
  updatePlaybackType: function() {
    this.safe(function() {
      if (!this.playbackType) {
        this.playbackType = this.el.globoGetType();
        if (this.playbackType) {
          this.playbackType = this.playbackType.toLowerCase();
          this.updateSettings();
        }
      }
    });
  },
  firstPlay: function() {
    this.safe(function() {
      this.el.globoPlayerLoad(this.src);
      this.el.globoPlayerPlay();
    });
  },
  volume: function(value) {
    this.safe(function() {
      this.el.globoPlayerVolume(value);
    });
  },
  pause: function() {
    this.safe(function() {
      this.el.globoPlayerPause();
    });
  },
  stop: function() {
    this.safe(function() {
      this.el.globoPlayerStop();
      clearInterval(this.checkStateId);
      this.trigger('playback:timeupdate', 0, this.name);
    })
  },
  isPlaying: function() {
    return this.safe(function() {
      if (this.el.globoGetState())
        return !!(this.el.globoGetState().match(/playing/i));
      return false;
    })
  },
  getDuration: function() {
    return this.safe(function() {
      return this.el.globoGetDuration();
    });
  },
  seek: function(time) {
    this.safe(function() {
      if (time < 0) {
        this.updateDVRStatus(false);
        this.el.globoPlayerSeek(time);
      } else {
        if (this.getPlaybackType() == "live") {
          this.updateDVRStatus(true);
        }
        this.el.globoPlayerSeek(this.el.globoGetDuration() * time / 100);
      }
      clearInterval(this.checkStateId);
      this.checkTimeId = this.updateTime(1000);
    });
  },
  isPip: function(pipStatus) {
    if (pipStatus == true && this.getCurrentBitrate() > 750000) {
      this.el.globoPlayerSetStageScaleMode("exactFit");
      this.el.globoPlayerSmoothSetLevel(2);
    } else if (!this.el.globoGetAutoLevel()) {
      this.el.globoPlayerSetStageScaleMode("noScale");
      this.el.globoPlayerSetLevel(-1);
    }
  },
  timeUpdate: function(time, duration) {
    this.trigger('playback:timeupdate', time, duration, this.name);
  },
  destroy: function() {
    clearInterval(this.checkStateId);
    clearInterval(this.checkTimeId);
    clearInterval(this.checkHighDefinitionId);
    this.stopListening()
    this.$el.remove()
  },
  setupFirefox:function() {
    var $el = this.$('embed');
    $el.attr('data-hls', '');
    this.setElement($el[0]);
  },
  setupIE: function() {
    this.setElement($(_.template(objectIE)({cid: this.cid, swfPath: this.swfPath})));
  },
  updateSettings: function() {
    this.settings = {
      left: [((this.playbackType === "vod" || this.dvrEnabled) ? "playpause" : "playstop"), "volume"],
      default: ["position", "seekbar", (this.playbackType === "vod" ? "duration" : "live")],
      right: ["fullscreen", "hd"]
    };
    this.trigger('playback:settingsupdate', this.name);
  },
  render: function() {
    var style = Styler.getStyleFor(this.name);
    this.$el.html(this.template({cid: this.cid, swfPath: this.swfPath}));
    this.$el.append(style);
    this.el.id = this.cid;
    if(navigator.userAgent.match(/firefox/i)) { //FIXME remove it from here
      this.setupFirefox();
    } else if(window.ActiveXObject) {
      this.setupIE();
    }
    return this;
  }
});

HLS.canPlay = function(resource) {
  return !!resource.match(/(.*).m3u8/);
}

module.exports = HLS;
<commit_msg>hls: turn hd on for bitrates greater than 2500k<commit_after>// Copyright 2014 Globo.com Player authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var UIPlugin = require('../../base/ui_plugin');
var Styler = require('../../base/styler');
var JST = require('../../base/jst');
var _ = require("underscore");

var Visibility = require('visibility');
var objectIE = '<object type="application/x-shockwave-flash" id="<%= cid %>" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" data-hls=""><param name="movie" value="<%= swfPath %>"> <param name="quality" value="autohigh"> <param name="swliveconnect" value="true"> <param name="allowScriptAccess" value="always"> <param name="bgcolor" value="#001122"> <param name="allowFullScreen" value="false"> <param name="wmode" value="transparent"> <param name="tabindex" value="1"> </object>';

var HLS = UIPlugin.extend({
  name: 'hls',
  tagName: 'object',
  template: JST.hls,
  attributes: {
    'data-hls': '',
    'type': 'application/x-shockwave-flash'
  },
  initialize: function(options) {
    this.src = options.src;
    this.swfPath = options.swfPath || "assets/HLSPlayer.swf";
    this.isLegacyIE = window.ActiveXObject;
    this.isChrome = navigator.userAgent.match(/chrome/i);
    this.isFirefox = navigator.userAgent.match(/firefox/i);
    this.isSafari = navigator.userAgent.match(/safari/i);
    this.autoPlay = options.autoPlay;
    this.visibility = new Visibility();
    this.visible = true;
    this.highDefinition = "unavailable"; // this will be changed on checkHighDefinition()
    this.settings = {
      left: ["playstop", "volume"],
      default: ["position", "seekbar", "duration"],
      right: ["fullscreen", "volume", "hd"]
    };
    this.checkIfFlashIsReady();
  },
  safe: function(fn) {
    if(this.el.globoGetState && this.el.globoGetDuration && this.el.globoGetPosition &&
       this.el.globoPlayerSmoothSetLevel && this.el.globoPlayerSetflushLiveURLCache) {
      return fn.apply(this);
    }
  },
  hiddenCallback: function() {
    this.hiddenId = this.safe(function() {
      return setTimeout(function() { this.el.globoPlayerSmoothSetLevel(0) }.bind(this), 10000);
    });
  },
  visibleCallback: function() {
    this.safe(function() {
      if (this.hiddenId) {
        clearTimeout(this.hiddenId);
      }
      this.el.globoPlayerSmoothSetLevel(-1);
    });
  },
  bootstrap: function() {
    this.el.width = "100%";
    this.el.height = "100%";
    this.trigger('playback:ready', this.name);
    clearInterval(this.bootstrapId);
    this.currentState = "IDLE";
    this.timedCheckState();
    this.el.globoPlayerSetflushLiveURLCache(true);
    this.el.globoPlayerSetstartFromLowestLevel(true); // decreases startup time
    this.autoPlay && this.play();
  },
  checkIfFlashIsReady: function() {
    this.bootstrapId = setInterval(function() {
      if(this.el.globoGetState) {
        this.bootstrap();
      }
    }.bind(this), 50);
  },
  updateTime: function(interval) {
    return this.safe(function() {
      return setInterval(function() {
        this.safe(function() {
          var previousDvrEnabled = this.dvrEnabled;
          var duration = this.el.globoGetDuration();
          this.dvrEnabled = (this.playbackType === 'live' && duration > 240);
          this.trigger('playback:timeupdate', this.el.globoGetPosition(), duration, this.name);
          if (this.dvrEnabled != previousDvrEnabled) {
            this.updateSettings();
          }
        });
      }.bind(this), interval);
    });
  },
  play: function() {
    this.safe(function() {
      if(this.el.globoGetState() === 'IDLE') {
        clearInterval(this.checkStateId)
        this.checkTimeId = this.updateTime(1000);
      }
      if(this.el.globoGetState() === 'PAUSED') {
        this.el.globoPlayerResume();
      } else {
        this.firstPlay();
      }
      this.trigger('playback:play', this.name);
    });
  },
  getPlaybackType: function() {
    if (this.playbackType)
      return this.playbackType;
    return null;
  },
  getCurrentBitrate: function() {
    return this.safe(function() {
      var currentLevel = this.getLevels()[this.el.globoGetLevel()];
      return currentLevel.bitrate;
    });
  },
  getLastProgramDate: function() {
    var programDate = this.el.globoGetLastProgramDate();
    // normalizing for BRT
    return programDate - 1.08e+7;
  },
  isHighDefinitionAvailable: function(levels) {
    return !!(levels.length > 0 && levels[levels.length-1].bitrate >= 2500000);
  },
  isHighDefinitionInUse: function() {
    return this.highDefinition === "available-in-use";
  },
  checkHighDefinition: function() {
    this.safe(function() {
      // this function is responsible to change media control settings
      // regarding the availability of HD level and if it's being used or not.
      // highDefinition attribute have 3 states: "available", "available-in-use", "unavailable"
      var changed = false;
      this.levels = this.getLevels();
      if (this.isHighDefinitionAvailable(this.levels)) {
        var lastLevel = this.levels.length -1;
        var currentLevel = this.el.globoGetLevel();
        if (currentLevel === lastLevel && this.highDefinition !== "available-in-use") {
          this.highDefinition = "available-in-use";
          changed = true;
        } else if (currentLevel !== lastLevel && this.highDefinition === "available-in-use") {
          this.highDefinition = "available";
          changed = true;
        } else if (this.highDefinition === "unavailable") {
          this.highDefinition = "available";
          changed = true;
        }
      }
      if (changed) {
        this.trigger('playback:highdefinitionupdate');
      }
    });
  },
  getLevels: function() {
    return this.safe(function() {
      if (!this.levels || this.levels.length === 0) {
        this.levels = this.el.globoGetLevels();
      }
      return this.levels;
    });
  },
  timedCheckState: function() {
    this.checkStateId = setInterval(this.checkState.bind(this), 250);
    this.checkHighDefinitionId = setInterval(this.checkHighDefinition.bind(this), 3000);
  },
  checkState: function() {
    this.safe(function() {
      this.updatePlaybackType();
      this.updatePlayerVisibility();
      if (this.el.globoGetState() === "PLAYING_BUFFERING" && this.el.globoGetbufferLength() < 1 && this.currentState !== "PLAYING_BUFFERING") {
        this.trigger('playback:buffering', this.name);
        this.currentState = "PLAYING_BUFFERING";
      } else if (this.currentState === "PLAYING_BUFFERING" && this.el.globoGetState() === "PLAYING") {
        this.trigger('playback:bufferfull', this.name);
        this.currentState = "PLAYING";
      } else if (this.el.globoGetState() === "IDLE") {
        this.trigger('playback:ended', this.name);
        this.trigger('playback:timeupdate', 0, this.el.globoGetDuration(), this.name);
        clearInterval(this.checkStateId);
        this.currentState = "IDLE";
      }
    });
  },
  updatePlayerVisibility: function() {
    if (this.visible && this.visibility.hidden()) {
      this.visible = false;
      this.hiddenCallback();
    } else if (!this.visible && this.visibility.visible()) {
      this.visible = true;
      this.visibleCallback();
    }
  },
  updatePlaybackType: function() {
    this.safe(function() {
      if (!this.playbackType) {
        this.playbackType = this.el.globoGetType();
        if (this.playbackType) {
          this.playbackType = this.playbackType.toLowerCase();
          this.updateSettings();
        }
      }
    });
  },
  firstPlay: function() {
    this.safe(function() {
      this.el.globoPlayerLoad(this.src);
      this.el.globoPlayerPlay();
    });
  },
  volume: function(value) {
    this.safe(function() {
      this.el.globoPlayerVolume(value);
    });
  },
  pause: function() {
    this.safe(function() {
      this.el.globoPlayerPause();
    });
  },
  stop: function() {
    this.safe(function() {
      this.el.globoPlayerStop();
      clearInterval(this.checkStateId);
      this.trigger('playback:timeupdate', 0, this.name);
    })
  },
  isPlaying: function() {
    return this.safe(function() {
      if (this.el.globoGetState())
        return !!(this.el.globoGetState().match(/playing/i));
      return false;
    })
  },
  getDuration: function() {
    return this.safe(function() {
      return this.el.globoGetDuration();
    });
  },
  seek: function(time) {
    this.safe(function() {
      if (time < 0) {
        this.updateDVRStatus(false);
        this.el.globoPlayerSeek(time);
      } else {
        if (this.getPlaybackType() == "live") {
          this.updateDVRStatus(true);
        }
        this.el.globoPlayerSeek(this.el.globoGetDuration() * time / 100);
      }
      clearInterval(this.checkStateId);
      this.checkTimeId = this.updateTime(1000);
    });
  },
  isPip: function(pipStatus) {
    if (pipStatus == true && this.getCurrentBitrate() > 750000) {
      this.el.globoPlayerSetStageScaleMode("exactFit");
      this.el.globoPlayerSmoothSetLevel(2);
    } else if (!this.el.globoGetAutoLevel()) {
      this.el.globoPlayerSetStageScaleMode("noScale");
      this.el.globoPlayerSetLevel(-1);
    }
  },
  timeUpdate: function(time, duration) {
    this.trigger('playback:timeupdate', time, duration, this.name);
  },
  destroy: function() {
    clearInterval(this.checkStateId);
    clearInterval(this.checkTimeId);
    clearInterval(this.checkHighDefinitionId);
    this.stopListening()
    this.$el.remove()
  },
  setupFirefox:function() {
    var $el = this.$('embed');
    $el.attr('data-hls', '');
    this.setElement($el[0]);
  },
  setupIE: function() {
    this.setElement($(_.template(objectIE)({cid: this.cid, swfPath: this.swfPath})));
  },
  updateSettings: function() {
    this.settings = {
      left: [((this.playbackType === "vod" || this.dvrEnabled) ? "playpause" : "playstop"), "volume"],
      default: ["position", "seekbar", (this.playbackType === "vod" ? "duration" : "live")],
      right: ["fullscreen", "hd"]
    };
    this.trigger('playback:settingsupdate', this.name);
  },
  render: function() {
    var style = Styler.getStyleFor(this.name);
    this.$el.html(this.template({cid: this.cid, swfPath: this.swfPath}));
    this.$el.append(style);
    this.el.id = this.cid;
    if(navigator.userAgent.match(/firefox/i)) { //FIXME remove it from here
      this.setupFirefox();
    } else if(window.ActiveXObject) {
      this.setupIE();
    }
    return this;
  }
});

HLS.canPlay = function(resource) {
  return !!resource.match(/(.*).m3u8/);
}

module.exports = HLS;
<|endoftext|>


<commit_before>var app = angular.module('main');

app.controller('PlayerController', function($scope, $log, $stateParams, $sce) {
	console.log($stateParams);
	$scope.video = $sce.trustAsResourceUrl($stateParams.video);
});<commit_msg>Testing parameter reconstruction<commit_after>var app = angular.module('main');

app.controller('PlayerController', function($scope, $log, $stateParams, $sce) {
	$scope.video = $sce.trustAsResourceUrl($stateParams.video);
	console.log($scope.video);
});<|endoftext|>


<commit_before>var _       = require("underscore")._,
    async   = require("async"),
    fs      = require("fs"),
    exec    = require("child_process").exec,
    config  = require("../config.json");

// Better template format
_.templateSettings = {
    interpolate: /\{\{(.+?)\}\}/g,
    evaluate :   /\{\[([\s\S]+?)\]\}/g
};

// Helper function to write a given template to a file based on a given
// context
function write_template_to_file(template_path, file_name, context, callback) {
    async.waterfall([

        function read_template_file(next_step) {
            fs.readFile(template_path, {encoding: "utf8"}, next_step);
        },

        function update_file(file_txt, next_step) {
            var template = _.template(file_txt);
            fs.writeFile(file_name, template(context), next_step);
        }

    ], callback);
}
// DEl file
function del_config_file(file_name, callback) {
    async.waterfall([

        function del_file(next_step) {
          console.log("--Going to delete an existing file");
          fs.unlink(file_name, function(err) {
             if (err) {
                 return console.error(err);
             }
             console.log("--File deleted successfully!");
          }, next_step);
        },
    ], callback);
}

/*****************************************************************************\
    Return a set of functions which we can use to manage and check our wifi
    connection information
\*****************************************************************************/
module.exports = function() {
    // Detect which wifi driver we should use, the rtl871xdrv or the nl80211
    exec("sudo iw list", function(error, stdout, stderr) {
        if (stderr.match(/^nl80211 not found/)) {
            config.wifi_driver_type = "rtl871xdrv";
        }
        // console.log("config.wifi_driver_type = " + config.wifi_driver_type);
    });

    // Hack: this just assumes that the outbound interface will be "wlan0"

    // Define some globals
    var ifconfig_fields = {
        "hw_addr":         /HWaddr\s([^\s]+)/,
        "inet_addr":       /inet addr:([^\s]+)/,
    },  iwconfig_fields = {
        "ap_addr":         /Access Point:\s([^\s]+)/,
        "ap_ssid":         /ESSID:\"([^\"]+)\"/,
        "unassociated":    /(unassociated)\s+Nick/,
    },  last_wifi_info = null;

    // TODO: rpi-config-ap hardcoded, should derive from a constant

    // Get generic info on an interface
    var _get_wifi_info = function(callback) {
        var output = {
            hw_addr:      "<unknown>",
            inet_addr:    "<unknown>",
            unassociated: "<unknown>",
        };

        // Inner function which runs a given command and sets a bunch
        // of fields
        function run_command_and_set_fields(cmd, fields, callback) {
            exec(cmd, function(error, stdout, stderr) {
                if (error) return callback(error);
                for (var key in fields) {
                    re = stdout.match(fields[key]);
                    if (re && re.length > 1) {
                        output[key] = re[1];
                    }
                }
                callback(null);
            });
        }

        // Run a bunch of commands and aggregate info
        async.series([
            function run_ifconfig(next_step) {
                run_command_and_set_fields("sudo ifconfig wlan0", ifconfig_fields, next_step);
            },
            function run_iwconfig(next_step) {
                run_command_and_set_fields("sudo iwconfig wlan0", iwconfig_fields, next_step);
            },
        ], function(error) {
            last_wifi_info = output;
            return callback(error, output);
        });
    },

    _reboot_wireless_network = function(wlan_iface, callback) {
        async.series([
            function down(next_step) {
                exec("sudo ifdown " + wlan_iface, function(error, stdout, stderr) {
                    if (!error) console.log("ifdown " + wlan_iface + " successful...");
                    next_step();
                });
            },
            function up(next_step) {
                exec("sudo ifup " + wlan_iface, function(error, stdout, stderr) {
                    if (!error) console.log("ifup " + wlan_iface + " successful...");
                    next_step();
                });
            },
        ], callback);
    },

    // Wifi related functions
    _is_wifi_enabled_sync = function(info) {
        // If we are not an AP, and we have a valid
        // inet_addr - wifi is enabled!
        if (null        == _is_ap_enabled_sync(info) &&
            "<unknown>" != info["inet_addr"]         &&
            "<unknown>" == info["unassociated"] ) {
            return info["inet_addr"];
        }
        return null;
    },

    _is_wifi_enabled = function(callback) {
        _get_wifi_info(function(error, info) {
            if (error) return callback(error, null);
            return callback(null, _is_wifi_enabled_sync(info));
        });
    },

    // Access Point related functions
    _is_ap_enabled_sync = function(info) {
        // If the hw_addr matches the ap_addr
        // and the ap_ssid matches "rpi-config-ap"
        // then we are in AP mode
        if (info["ap_ssid"] === null || info["ap_ssid"] === undefined){
          info["ap_ssid"] = config.access_point.ssid
        }
        if (info["ap_addr"] === null || info["ap_addr"] === undefined || info["ap_addr"] == 'Not-Associated'){
          info["ap_addr"] = info["hw_addr"]
        }
        var is_ap  =
            info["hw_addr"] == info["ap_addr"] &&
            info["ap_ssid"] == config.access_point.ssid;

        return (is_ap) ? info["hw_addr"].toLowerCase() : null;
    },

    _is_ap_enabled = function(callback) {
        _get_wifi_info(function(error, info) {
            if (error) return callback(error, null);
            return callback(null, _is_ap_enabled_sync(info));
        });
    },

    // Enables the accesspoint w/ bcast_ssid. This assumes that both
    // dnsmasq and hostapd are installed using:
    // $sudo npm run-script provision
    _enable_ap_mode = function(bcast_ssid, callback) {
        _is_ap_enabled(function(error, result_addr) {
            if (error) {
                console.log("ERROR: " + error);
                return callback(error);
            }

            if (result_addr && !config.access_point.force_reconfigure) {
                console.log("\nAccess point is enabled with ADDR: " + result_addr);
                return callback(null);
            } else if (config.access_point.force_reconfigure) {
                console.log("\nForce reconfigure enabled - reset AP");
            } else {
                console.log("\nAP is not enabled yet... enabling...");
            }

            var context = config.access_point;
            context["enable_ap"] = true;
            context["wifi_driver_type"] = config.wifi_driver_type;

            // Here we need to actually follow the steps to enable the ap
            async.series([

                // Enable the access point ip and netmask + static
                // DHCP for the wlan0 interface
                function update_interfaces(next_step) {
                    write_template_to_file(
                        "./assets/etc/network/interfaces.ap.template",
                        "/etc/network/interfaces",
                        context, next_step);
                },

                // Enable DHCP conf, set authoritative mode and subnet
                function update_dhcpcd(next_step) {
                    var context = config.access_point;
                    // We must enable this to turn on the access point
                    write_template_to_file(
                        "./assets/etc/dhcp/dhcpcd.conf.template",
                        "/etc/dhcpcd.conf",
                        context, next_step);
                },

                // Enable the interface in the dhcp server
                function update_dns_interface(next_step) {
                    write_template_to_file(
                        "./assets/etc/dnsmasq/dnsmasq.conf.template",
                        "/etc/dnsmasq.conf",
                        context, next_step);
                },

                // Enable hostapd.conf file
                function update_hostapd_conf(next_step) {
                    write_template_to_file(
                        "./assets/etc/hostapd/hostapd.conf.template",
                        "/etc/hostapd/hostapd.conf",
                        context, next_step);
                },

                function update_hostapd_default(next_step) {
                    write_template_to_file(
                        "./assets/etc/default/hostapd.template",
                        "/etc/default/hostapd",
                        context, next_step);
                },

                function reboot_network_interfaces(next_step) {
                    _reboot_wireless_network(context.wifi_interface, next_step);
                },

                function restart_dhcp_service(next_step) {
                    exec("service dhcpcd restart", function(error, stdout, stderr) {
                        //console.log(stdout);
                        if (!error) console.log("... dhcpcd server restarted!");
                        next_step();
                    });
                },

                function restart_dns_service(next_step) {
                    exec("service dnsmasq restart", function(error, stdout, stderr) {
                        //console.log(stdout);
                        if (!error) console.log("... dnsmasq server restarted!");
                        next_step();
                    });
                },

                function restart_hostapd_service(next_step) {
                    exec("service hostapd restart", function(error, stdout, stderr) {
                        //console.log(stdout);
                        if (!error) console.log("... hostapd restarted!");
                        next_step();
                    });
                },

                // TODO: Do we need to issue a reboot here?

            ], callback);
        });
    },

    // Disables AP mode and reverts to wifi connection
    _enable_wifi_mode = function(connection_info, callback) {

        _is_wifi_enabled(function(error, result_ip) {
            if (error) return callback(error);

            if (result_ip) {
                console.log("\nWifi connection is enabled with IP: " + result_ip);
                return callback(null);
            }

            async.series([

                //
                function del_hostapd(next_step) {
                    del_config_file(
                        "/etc/hostapd/hostapd.conf",
                        next_step);
                },

                function update_dhcpcd(next_step) {
                    write_template_to_file(
                        "./assets/etc/default/dhcpcd.conf",
                        "/etc/dhcpcd.conf",
                        connection_info, next_step);
                },

                // Update /etc/network/interface with correct info...
                function update_dhcp(next_step) {
                    write_template_to_file(
                        "./assets/etc/network/interfaces.wifi.template",
                        "/etc/network/interfaces",
                        connection_info, next_step);
                },

                // Update /etc/network/interface with correct info...
                function update_wpa(next_step) {
                    write_template_to_file(
                        "./assets/etc/wpa_supplicant/wpa_supplicant.conf.template",
                        "/etc/wpa_supplicant/wpa_supplicant.conf",
                        connection_info, next_step);
                },

                // Stop the DHCP server...
                function restart_dhcp_service(next_step) {
                    exec("service dnsmasq stop", function(error, stdout, stderr) {
                        //console.log(stdout);
                        if (!error) console.log("... dhcp server stopped!");
                        next_step();
                    });
                },

                // Stop the hostapd server...
                function restart_hostapd_service(next_step) {
                    exec("service hostapd stop", function(error, stdout, stderr) {
                        //console.log(stdout);
                        if (!error) console.log("... hostapd stop!");
                        next_step();
                    });
                },

                function reboot_network_interfaces(next_step) {
                    _reboot_wireless_network(config.wifi_interface, next_step);
                },

            ], callback);
        });

    };

    return {
        get_wifi_info:           _get_wifi_info,
        reboot_wireless_network: _reboot_wireless_network,

        is_wifi_enabled:         _is_wifi_enabled,
        is_wifi_enabled_sync:    _is_wifi_enabled_sync,

        is_ap_enabled:           _is_ap_enabled,
        is_ap_enabled_sync:      _is_ap_enabled_sync,

        enable_ap_mode:          _enable_ap_mode,
        enable_wifi_mode:        _enable_wifi_mode,
    };
}
<commit_msg>no message<commit_after>var _       = require("underscore")._,
    async   = require("async"),
    fs      = require("fs"),
    exec    = require("child_process").exec,
    config  = require("../config.json");

// Better template format
_.templateSettings = {
    interpolate: /\{\{(.+?)\}\}/g,
    evaluate :   /\{\[([\s\S]+?)\]\}/g
};

// Helper function to write a given template to a file based on a given
// context
function write_template_to_file(template_path, file_name, context, callback) {
    async.waterfall([

        function read_template_file(next_step) {
            fs.readFile(template_path, {encoding: "utf8"}, next_step);
        },

        function update_file(file_txt, next_step) {
            var template = _.template(file_txt);
            fs.writeFile(file_name, template(context), next_step);
        }

    ], callback);
}
// DEl file
function del_config_file(file_name, callback) {
    async.waterfall([

        function del_file(next_step) {
          console.log("--Going to delete an existing file");
          fs.unlink(file_name, function(err) {
             if (err) {
                 return console.error(err);
             }
             console.log("--File deleted successfully!");
          }, next_step);
        }
    ], callback);
}

/*****************************************************************************\
    Return a set of functions which we can use to manage and check our wifi
    connection information
\*****************************************************************************/
module.exports = function() {
    // Detect which wifi driver we should use, the rtl871xdrv or the nl80211
    exec("sudo iw list", function(error, stdout, stderr) {
        if (stderr.match(/^nl80211 not found/)) {
            config.wifi_driver_type = "rtl871xdrv";
        }
        // console.log("config.wifi_driver_type = " + config.wifi_driver_type);
    });

    // Hack: this just assumes that the outbound interface will be "wlan0"

    // Define some globals
    var ifconfig_fields = {
        "hw_addr":         /HWaddr\s([^\s]+)/,
        "inet_addr":       /inet addr:([^\s]+)/,
    },  iwconfig_fields = {
        "ap_addr":         /Access Point:\s([^\s]+)/,
        "ap_ssid":         /ESSID:\"([^\"]+)\"/,
        "unassociated":    /(unassociated)\s+Nick/,
    },  last_wifi_info = null;

    // TODO: rpi-config-ap hardcoded, should derive from a constant

    // Get generic info on an interface
    var _get_wifi_info = function(callback) {
        var output = {
            hw_addr:      "<unknown>",
            inet_addr:    "<unknown>",
            unassociated: "<unknown>",
        };

        // Inner function which runs a given command and sets a bunch
        // of fields
        function run_command_and_set_fields(cmd, fields, callback) {
            exec(cmd, function(error, stdout, stderr) {
                if (error) return callback(error);
                for (var key in fields) {
                    re = stdout.match(fields[key]);
                    if (re && re.length > 1) {
                        output[key] = re[1];
                    }
                }
                callback(null);
            });
        }

        // Run a bunch of commands and aggregate info
        async.series([
            function run_ifconfig(next_step) {
                run_command_and_set_fields("sudo ifconfig wlan0", ifconfig_fields, next_step);
            },
            function run_iwconfig(next_step) {
                run_command_and_set_fields("sudo iwconfig wlan0", iwconfig_fields, next_step);
            },
        ], function(error) {
            last_wifi_info = output;
            return callback(error, output);
        });
    },

    _reboot_wireless_network = function(wlan_iface, callback) {
        async.series([
            function down(next_step) {
                exec("sudo ifdown " + wlan_iface, function(error, stdout, stderr) {
                    if (!error) console.log("ifdown " + wlan_iface + " successful...");
                    next_step();
                });
            },
            function up(next_step) {
                exec("sudo ifup " + wlan_iface, function(error, stdout, stderr) {
                    if (!error) console.log("ifup " + wlan_iface + " successful...");
                    next_step();
                });
            },
        ], callback);
    },

    // Wifi related functions
    _is_wifi_enabled_sync = function(info) {
        // If we are not an AP, and we have a valid
        // inet_addr - wifi is enabled!
        if (null        == _is_ap_enabled_sync(info) &&
            "<unknown>" != info["inet_addr"]         &&
            "<unknown>" == info["unassociated"] ) {
            return info["inet_addr"];
        }
        return null;
    },

    _is_wifi_enabled = function(callback) {
        _get_wifi_info(function(error, info) {
            if (error) return callback(error, null);
            return callback(null, _is_wifi_enabled_sync(info));
        });
    },

    // Access Point related functions
    _is_ap_enabled_sync = function(info) {
        // If the hw_addr matches the ap_addr
        // and the ap_ssid matches "rpi-config-ap"
        // then we are in AP mode
        if (info["ap_ssid"] === null || info["ap_ssid"] === undefined){
          info["ap_ssid"] = config.access_point.ssid
        }
        if (info["ap_addr"] === null || info["ap_addr"] === undefined || info["ap_addr"] == 'Not-Associated'){
          info["ap_addr"] = info["hw_addr"]
        }
        var is_ap  =
            info["hw_addr"] == info["ap_addr"] &&
            info["ap_ssid"] == config.access_point.ssid;

        return (is_ap) ? info["hw_addr"].toLowerCase() : null;
    },

    _is_ap_enabled = function(callback) {
        _get_wifi_info(function(error, info) {
            if (error) return callback(error, null);
            return callback(null, _is_ap_enabled_sync(info));
        });
    },

    // Enables the accesspoint w/ bcast_ssid. This assumes that both
    // dnsmasq and hostapd are installed using:
    // $sudo npm run-script provision
    _enable_ap_mode = function(bcast_ssid, callback) {
        _is_ap_enabled(function(error, result_addr) {
            if (error) {
                console.log("ERROR: " + error);
                return callback(error);
            }

            if (result_addr && !config.access_point.force_reconfigure) {
                console.log("\nAccess point is enabled with ADDR: " + result_addr);
                return callback(null);
            } else if (config.access_point.force_reconfigure) {
                console.log("\nForce reconfigure enabled - reset AP");
            } else {
                console.log("\nAP is not enabled yet... enabling...");
            }

            var context = config.access_point;
            context["enable_ap"] = true;
            context["wifi_driver_type"] = config.wifi_driver_type;

            // Here we need to actually follow the steps to enable the ap
            async.series([

                // Enable the access point ip and netmask + static
                // DHCP for the wlan0 interface
                function update_interfaces(next_step) {
                    write_template_to_file(
                        "./assets/etc/network/interfaces.ap.template",
                        "/etc/network/interfaces",
                        context, next_step);
                },

                // Enable DHCP conf, set authoritative mode and subnet
                function update_dhcpcd(next_step) {
                    var context = config.access_point;
                    // We must enable this to turn on the access point
                    write_template_to_file(
                        "./assets/etc/dhcp/dhcpcd.conf.template",
                        "/etc/dhcpcd.conf",
                        context, next_step);
                },

                // Enable the interface in the dhcp server
                function update_dns_interface(next_step) {
                    write_template_to_file(
                        "./assets/etc/dnsmasq/dnsmasq.conf.template",
                        "/etc/dnsmasq.conf",
                        context, next_step);
                },

                // Enable hostapd.conf file
                function update_hostapd_conf(next_step) {
                    write_template_to_file(
                        "./assets/etc/hostapd/hostapd.conf.template",
                        "/etc/hostapd/hostapd.conf",
                        context, next_step);
                },

                function update_hostapd_default(next_step) {
                    write_template_to_file(
                        "./assets/etc/default/hostapd.template",
                        "/etc/default/hostapd",
                        context, next_step);
                },

                function reboot_network_interfaces(next_step) {
                    _reboot_wireless_network(context.wifi_interface, next_step);
                },

                function restart_dhcp_service(next_step) {
                    exec("service dhcpcd restart", function(error, stdout, stderr) {
                        //console.log(stdout);
                        if (!error) console.log("... dhcpcd server restarted!");
                        next_step();
                    });
                },

                function restart_dns_service(next_step) {
                    exec("service dnsmasq restart", function(error, stdout, stderr) {
                        //console.log(stdout);
                        if (!error) console.log("... dnsmasq server restarted!");
                        next_step();
                    });
                },

                function restart_hostapd_service(next_step) {
                    exec("service hostapd restart", function(error, stdout, stderr) {
                        //console.log(stdout);
                        if (!error) console.log("... hostapd restarted!");
                        next_step();
                    });
                },

                // TODO: Do we need to issue a reboot here?

            ], callback);
        });
    },

    // Disables AP mode and reverts to wifi connection
    _enable_wifi_mode = function(connection_info, callback) {

        _is_wifi_enabled(function(error, result_ip) {
            if (error) return callback(error);

            if (result_ip) {
                console.log("\nWifi connection is enabled with IP: " + result_ip);
                return callback(null);
            }

            async.series([

                //
                function del_hostapd(next_step) {
                    del_config_file(
                        "/etc/hostapd/hostapd.conf",
                        next_step);
                },

                function update_dhcpcd(next_step) {
                    write_template_to_file(
                        "./assets/etc/default/dhcpcd.conf",
                        "/etc/dhcpcd.conf",
                        connection_info, next_step);
                },

                // Update /etc/network/interface with correct info...
                function update_dhcp(next_step) {
                    write_template_to_file(
                        "./assets/etc/network/interfaces.wifi.template",
                        "/etc/network/interfaces",
                        connection_info, next_step);
                },

                // Update /etc/network/interface with correct info...
                function update_wpa(next_step) {
                    write_template_to_file(
                        "./assets/etc/wpa_supplicant/wpa_supplicant.conf.template",
                        "/etc/wpa_supplicant/wpa_supplicant.conf",
                        connection_info, next_step);
                },

                // Stop the DHCP server...
                function restart_dhcp_service(next_step) {
                    exec("service dnsmasq stop", function(error, stdout, stderr) {
                        //console.log(stdout);
                        if (!error) console.log("... dhcp server stopped!");
                        next_step();
                    });
                },

                // Stop the hostapd server...
                function restart_hostapd_service(next_step) {
                    exec("service hostapd stop", function(error, stdout, stderr) {
                        //console.log(stdout);
                        if (!error) console.log("... hostapd stop!");
                        next_step();
                    });
                },

                function reboot_network_interfaces(next_step) {
                    _reboot_wireless_network(config.wifi_interface, next_step);
                },

            ], callback);
        });

    };

    return {
        get_wifi_info:           _get_wifi_info,
        reboot_wireless_network: _reboot_wireless_network,

        is_wifi_enabled:         _is_wifi_enabled,
        is_wifi_enabled_sync:    _is_wifi_enabled_sync,

        is_ap_enabled:           _is_ap_enabled,
        is_ap_enabled_sync:      _is_ap_enabled_sync,

        enable_ap_mode:          _enable_ap_mode,
        enable_wifi_mode:        _enable_wifi_mode,
    };
}
<|endoftext|>


<commit_before>import test from 'tape'
import ChunkifyOptions from './options'

test('should throw when receiving non-object literal options', t => {
  let WRONG_TYPES = [
    false,
    true,
    null,
    undefined,
    [],
    function() {}
  ];
  for (let thing of WRONG_TYPES) {
    t.throws(() => {
      ChunkifyOptions.of(thing)
    }, new RegExp(`Expected options object, got ${typeof thing}`))
  }
  t.end()
});

test('should have defaults', t => {
  let options = ChunkifyOptions.of({});
  t.equals(typeof options.delay, 'number');
  t.equals(typeof options.chunk, 'number');
  t.end()
});

test('should override all defaults', t => {
  let chunk = 50;
  let delay = 100;

  let options = ChunkifyOptions.of({chunk, delay});

  t.equals(options.chunk, chunk);
  t.equals(options.delay, delay);
  t.end()
});

test('should override some defaults', t => {
  let chunk = 50;
  let delay = 100;

  let options = ChunkifyOptions.of({chunk});

  t.equals(options.chunk, chunk);
  t.notEquals(options.delay, delay);

  options = ChunkifyOptions.of({delay});

  t.equals(options.delay, delay);
  t.notEquals(options.chunk, chunk);

  t.end()
});

test('should throw when an option override has the wrong type', t => {
  let chunk = function() {};
  let delay = [];

  t.throws(() => {
    ChunkifyOptions.of({chunk})
  }, /Expected 'chunk' to be 'number', got 'function'/);
  t.throws(() => {
    ChunkifyOptions.of({delay})
  }, /Expected 'delay' to be 'number', got 'object'/);
  t.end()
});

test('should be immutable', t => {
  let chunk = 50;
  let delay = 100;

  let options = ChunkifyOptions.of({chunk, delay});

  t.throws(() => {
    options.delay = 0
  }, /delay is immutable/);
  t.throws(() => {
    options.chunk = 1
  }, /chunk is immutable/);

  delete options.delay;
  delete options.chunk;

  t.ok(options.delay);
  t.ok(options.chunk);

  t.end()
});

<commit_msg>test wrong values<commit_after>import test from 'tape'
import ChunkifyOptions from './options'

test('should throw when receiving non-object literal options', t => {
  let WRONG_TYPES = [
    false,
    true,
    null,
    undefined,
    [],
    function() {}
  ];
  for (let thing of WRONG_TYPES) {
    t.throws(() => {
      ChunkifyOptions.of(thing)
    }, new RegExp(`Expected options object, got ${typeof thing}`))
  }
  t.end()
});

test('should have defaults', t => {
  let options = ChunkifyOptions.of({});
  t.equals(typeof options.delay, 'number');
  t.equals(typeof options.chunk, 'number');
  t.end()
});

test('should override all defaults', t => {
  let chunk = 50;
  let delay = 100;

  let options = ChunkifyOptions.of({chunk, delay});

  t.equals(options.chunk, chunk);
  t.equals(options.delay, delay);
  t.end()
});

test('should override some defaults', t => {
  let chunk = 50;
  let delay = 100;

  let options = ChunkifyOptions.of({chunk});

  t.equals(options.chunk, chunk);
  t.notEquals(options.delay, delay);

  options = ChunkifyOptions.of({delay});

  t.equals(options.delay, delay);
  t.notEquals(options.chunk, chunk);

  t.end()
});

test('should throw when an option override has the wrong type', t => {
  let chunk = function() {};
  let delay = [];

  t.throws(() => {
    ChunkifyOptions.of({chunk})
  }, /'chunk' should be a positive number/);
  t.throws(() => {
    ChunkifyOptions.of({delay})
  }, /'delay' should be a non-negative number/);
  t.end()
});

test('should throw when an option override has the wrong value', t => {
  let chunk = function() {};
  let delay = [];

  t.throws(() => {
    ChunkifyOptions.of({chunk})
  }, /'chunk' should be a positive number/);
  t.throws(() => {
    ChunkifyOptions.of({delay})
  }, /'delay' should be a non-negative number/);
  t.end()
});

test('should be immutable', t => {
  let chunk = 50;
  let delay = 100;

  let options = ChunkifyOptions.of({chunk, delay});

  t.throws(() => {
    options.delay = 0
  }, /delay is immutable/);
  t.throws(() => {
    options.chunk = 1
  }, /chunk is immutable/);

  delete options.delay;
  delete options.chunk;

  t.ok(options.delay);
  t.ok(options.chunk);

  t.end()
});

<|endoftext|>


<commit_before>/**
 *
 * @type {string}
 */
const Delimiter = ' و ';

/**
 *
 * @type {string}
 */
const Zero = 'صفر';

/**
 *
 * @type {*[]}
 */
const Letters = [
  ['', 'یک', 'دو', 'سه', 'چهار', 'پنج', 'شش', 'هفت', 'هشت', 'نه'],
  ['ده', 'یازده', 'دوازده', 'سیزده', 'چهارده', 'پانزده', 'شانزده', 'هفده', 'هجده', 'نوزده', 'بیست'],
  ['', '', 'بیست', 'سی', 'چهل', 'پنجاه', 'شصت', 'هفتاد', 'هشتاد', 'نود'],
  ['', 'یکصد', 'دویست', 'سیصد', 'چهارصد', 'پانصد', 'ششصد', 'هفتصد', 'هشتصد', 'نهصد'],
  ['', ' هزار', ' میلیون', ' میلیارد', ' بیلیون', ' بیلیارد', ' تریلیون', ' تریلیارد',
    'کوآدریلیون', ' کادریلیارد', ' کوینتیلیون', ' کوانتینیارد', ' سکستیلیون', ' سکستیلیارد', ' سپتیلیون',
    'سپتیلیارد', ' اکتیلیون', ' اکتیلیارد', ' نانیلیون', ' نانیلیارد', ' دسیلیون', ' دسیلیارد'],
];

/**
 * Clear number and split to 3 sections
 * @param {*} num
 */
const PrepareNumber = (num) => {
  let Out = num;
  if (typeof Out === 'number') {
    Out = Out.toString();
  }
  const NumberLength = Out.length % 3;
  if (NumberLength === 1) {
    Out = `00${Out}`;
  } else if (NumberLength === 2) {
    Out = `0${Out}`;
  }
  // Explode to array
  return Out.replace(/\d{3}(?=\d)/g, '$&*')
    .split('*');
};

const ThreeNumbersToLetter = (num) => {
  // return Zero
  if (parseInt(num, 0) === 0) {
    return '';
  }
  const parsedInt = parseInt(num, 0);
  if (parsedInt < 10) {
    return Letters[0][parsedInt];
  }
  if (parsedInt <= 20) {
    return Letters[1][parsedInt - 10];
  }
  if (parsedInt < 100) {
    const one = parsedInt % 10;
    const ten = (parsedInt - one) / 10;
    if (one > 0) {
      return Letters[2][ten] + Delimiter + Letters[0][one];
    }
    return Letters[2][ten];
  }
  const one = parsedInt % 10;
  const hundreds = (parsedInt - (parsedInt % 100)) / 100;
  const ten = (parsedInt - ((hundreds * 100) + one)) / 10;
  const out = [Letters[3][hundreds]];
  const SecondPart = ((ten * 10) + one);
  if (SecondPart > 0) {
    if (SecondPart < 10) {
      out.push(Letters[0][SecondPart]);
    } else if (SecondPart <= 20) {
      out.push(Letters[1][SecondPart - 10]);
    } else {
      out.push(Letters[2][ten]);
      if (one > 0) {
        out.push(Letters[0][one]);
      }
    }
  }
  return out.join(Delimiter);
};

const Num2persian = (num) => {
  // return Zero
  if (parseInt(num, 0) === 0) {
    return Zero;
  }
  if (num.length > 66) {
    return 'خارج از محدوده';
  }
  // Split to sections
  const SpitedNumber = PrepareNumber(num);
  // Fetch Sections and convert
  const Output = [];
  const SplitLength = SpitedNumber.length;
  for (let i = 0; i < SplitLength; i += 1) {
    const SectionTitle = Letters[4][SplitLength - (i + 1)];
    const converted = ThreeNumbersToLetter(SpitedNumber[i]);
    if (converted !== '') {
      Output.push(converted + SectionTitle);
    }
  }
  return Output.join(Delimiter);
};
String.prototype.toPersianLetter = function () {
  return Num2persian(this);
};
Number.prototype.toPersianLetter = function () {
  return Num2persian(parseInt(this).toString());
};
<commit_msg>add export default<commit_after>/**
 *
 * @type {string}
 */
const Delimiter = ' و ';

/**
 *
 * @type {string}
 */
const Zero = 'صفر';

/**
 *
 * @type {*[]}
 */
const Letters = [
  ['', 'یک', 'دو', 'سه', 'چهار', 'پنج', 'شش', 'هفت', 'هشت', 'نه'],
  ['ده', 'یازده', 'دوازده', 'سیزده', 'چهارده', 'پانزده', 'شانزده', 'هفده', 'هجده', 'نوزده', 'بیست'],
  ['', '', 'بیست', 'سی', 'چهل', 'پنجاه', 'شصت', 'هفتاد', 'هشتاد', 'نود'],
  ['', 'یکصد', 'دویست', 'سیصد', 'چهارصد', 'پانصد', 'ششصد', 'هفتصد', 'هشتصد', 'نهصد'],
  ['', ' هزار', ' میلیون', ' میلیارد', ' بیلیون', ' بیلیارد', ' تریلیون', ' تریلیارد',
    'کوآدریلیون', ' کادریلیارد', ' کوینتیلیون', ' کوانتینیارد', ' سکستیلیون', ' سکستیلیارد', ' سپتیلیون',
    'سپتیلیارد', ' اکتیلیون', ' اکتیلیارد', ' نانیلیون', ' نانیلیارد', ' دسیلیون', ' دسیلیارد'],
];

/**
 * Clear number and split to 3 sections
 * @param {*} num
 */
const PrepareNumber = (num) => {
  let Out = num;
  if (typeof Out === 'number') {
    Out = Out.toString();
  }
  const NumberLength = Out.length % 3;
  if (NumberLength === 1) {
    Out = `00${Out}`;
  } else if (NumberLength === 2) {
    Out = `0${Out}`;
  }
  // Explode to array
  return Out.replace(/\d{3}(?=\d)/g, '$&*')
    .split('*');
};

const ThreeNumbersToLetter = (num) => {
  // return Zero
  if (parseInt(num, 0) === 0) {
    return '';
  }
  const parsedInt = parseInt(num, 0);
  if (parsedInt < 10) {
    return Letters[0][parsedInt];
  }
  if (parsedInt <= 20) {
    return Letters[1][parsedInt - 10];
  }
  if (parsedInt < 100) {
    const one = parsedInt % 10;
    const ten = (parsedInt - one) / 10;
    if (one > 0) {
      return Letters[2][ten] + Delimiter + Letters[0][one];
    }
    return Letters[2][ten];
  }
  const one = parsedInt % 10;
  const hundreds = (parsedInt - (parsedInt % 100)) / 100;
  const ten = (parsedInt - ((hundreds * 100) + one)) / 10;
  const out = [Letters[3][hundreds]];
  const SecondPart = ((ten * 10) + one);
  if (SecondPart > 0) {
    if (SecondPart < 10) {
      out.push(Letters[0][SecondPart]);
    } else if (SecondPart <= 20) {
      out.push(Letters[1][SecondPart - 10]);
    } else {
      out.push(Letters[2][ten]);
      if (one > 0) {
        out.push(Letters[0][one]);
      }
    }
  }
  return out.join(Delimiter);
};

const Num2persian = (num) => {
  // return Zero
  if (parseInt(num, 0) === 0) {
    return Zero;
  }
  if (num.length > 66) {
    return 'خارج از محدوده';
  }
  // Split to sections
  const SpitedNumber = PrepareNumber(num);
  // Fetch Sections and convert
  const Output = [];
  const SplitLength = SpitedNumber.length;
  for (let i = 0; i < SplitLength; i += 1) {
    const SectionTitle = Letters[4][SplitLength - (i + 1)];
    const converted = ThreeNumbersToLetter(SpitedNumber[i]);
    if (converted !== '') {
      Output.push(converted + SectionTitle);
    }
  }
  return Output.join(Delimiter);
};
String.prototype.toPersianLetter = function () {
  return Num2persian(this);
};
Number.prototype.toPersianLetter = function () {
  return Num2persian(parseInt(this).toString());
};
export default Num2persian
<|endoftext|>


<commit_before>const bot = require('./bot');
const functions = require('./functions');

bot.on('message', message =>{
	if(!message.content.startsWith('~'))
	{return;}//base case
	var cmd  = message.content.split(' ')[0].substring(1).toLowerCase();
	commands[cmd].exec(message);
});
var commands={
	'pong': {
		description:'reply with a pong',
		syntax: '~ping',
		exec: function(message)
		{
			message.reply('pong');
		}
	},
	'yo':{
		description:'reply with a yo bro',
		syntax: '~yo',
		exec: function(message)
		{
			message.reply('yo bro');
		}
	},
	'link':{
		description:'link revive account to this discord account',
		syntax: '~link',
		exec: function(message){
			functions.integrate(message.author);
		}
	},
	'refresh':{
		description:'refresh a user discord link status',
		syntax: '~refresh',
		exec: function(message){
			if(message.content.subtring(9).trim()=='all'
				&& message.member.roles.find('moderator')!=undefined
				&& message.guild.name == 'Revive Netowrk')
			{
				functions.refreshAll(message.guild.members.array())
			}
			else
			{
				functions.refresh(message.user,message.member);
			}
		}
	},
	'bf2':{
		description:'finds a bf2 player',
		syntax: '~bf2 <PlayerName>',
		exec: function(message){
			if(message.mentions.users.first!=undefined)
			{

			}
			else
			{
				var nick = message.content.substring(5).trim();
				var plist = bf2.getPlayers(nick);
				console.log("BF2 in index.js gets executed");
				if (plist == null) {
					message.channel.sendMessage("API Down or invalid search");
					return;
					}
					if (plist.length >= 1) {
						//checking for exact matches
						var exact = plist.find(o => o.nick.toUpperCase().trim() === nick.toUpperCase());
						console.log(exact); var res = "**S.no.\tName \t PID \t Score**";
					}
					var start = 0;
					var past = 0;
					if (exact != null) {
						res = res + "\n" + (1) + "\t" + "\t" + exact.str();
						 start++ ;
						 }
						 for (var i = start; i < plist.length; i++)
						  {
						 	if (exact != null && i == plist.indexOf(exact))
						  	{
						  		past++;
						  		continue;
								}
							if (i == 26) {
  							res = res + "\n" + (plist.length - 25)
  							 + " more players found to Get a full list of players \n"
  							 + "<https://battlelog.co/player_search.php?q=" + nick + ">";
  							 break;
  							} else
  							{
  								 res = res + " \n" + (i + 1 - past)
  								 + "\t" + "\t" + plist[i].str();
  								message.channel.sendMessage(res);

  							}
  						}
  					if (plist.length == 0)
  					{ message.channel.sendMessage("Player not found"); }
			}
		}
	},
	'bf2142':{
		description:'finds a bf2142 player',
		syntax: '~bf2142 <PlayerName>',
		exec: function(message){
			if(message.mentions.users.first!=undefined)
			{

			}
			else
			{
				var nick = message.content.substring(7).trim();
				var plist = bf2142.getPlayers(nick);
				console.log("BF2142 in index.js gets executed");
				if (plist == null) {
					message.channel.sendMessage("API Down or invalid search");
					return;
					}
					if (plist.length >= 1) {
						//checking for exact matches
						var exact = plist.find(o => o.nick.toUpperCase().trim() === nick.toUpperCase());
						console.log(exact); var res = "**S.no.\tName \t PID**";
					}
					var start = 0;
					var past = 0;
					if (exact != null) {
						res = res + "\n" + (1) + "\t" + "\t" + exact.str();
						 start++ ;
						 }
						 for (var i = start; i < plist.length; i++)
						  {
						 	if (exact != null && i == plist.indexOf(exact))
						  	{
						  		past++;
						  		continue;
								}
							if (i == 26) {
  							res = res + "\n" + (plist.length - 25)
  							 + " more players found to Get a full list of players \n"
  							 + "<https://battlelog.co/player_search.php?q=" + nick + ">";
  							 break;
  							} else
  							{
  								 res = res + " \n" + (i + 1 - past)
  								 + "\t" + "\t" + plist[i].str();
  								message.channel.sendMessage(res);

  							}
  						}
  					if (plist.length == 0)
  					{ message.channel.sendMessage("Player not found"); }
			}
		}
	},
	'cookie':{
		description: 'eats a cookie',
		syntax: '~cookie',
		exec: function(message){
			message.reply('crunch crunch');
		}
	},
	'add':{
		description: 'adds a person to a role',
		syntax: '~add <UserMention> to <roleName>',
		exec: function(message){
			if (!message.member.hasPermission("MANAGE_ROLES_OR_PERMISSIONS")) {
				 message.channel.sendMessage("You aren't Worthy"); return; }
				 var member = message.guild.member(message.mentions.users.first());
				 var msg = message.content.split("to ");
				 member.addRole(message.guild.roles.find("name", msg[msg.length - 1]));
				 message.reply('done');
		}
	},
	'remove':{
		description: 'removes a person to a role',
		syntax: '~remove <UserMention> from <roleName>',
		exec: function(message){
			if (!message.member.hasPermission("MANAGE_ROLES_OR_PERMISSIONS")) {
				 message.channel.sendMessage("You aren't Worthy"); return; }
				 var member = message.guild.member(message.mentions.users.first());
				 var msg = message.content.split("to ");
				 member.removeRole(message.guild.roles.find("name", msg[msg.length - 1]));
				 message.reply('done');
		}
	},
	'help':{
		description: 'displays help',
		syntax: '~help',
		exec: function(message){
			var res = "";
			for(cmd in commands)
			{
				res  = res +"\n"+"**"+cmd+"** - "+"_"+ cmd.description+"_";
				res  = res +"\n"+"Syntax: *"+cmd.syntax+"*";
			}
			message.reply(res);
		}
	}
}<commit_msg>Fixed Typo<commit_after>const bot = require('./bot');
const functions = require('./functions');

bot.on('message', message =>{
	if(!message.content.startsWith('~'))
	{return;}//base case
	var cmd  = message.content.split(' ')[0].substring(1).toLowerCase();
	commands[cmd].exec(message);
});
var commands={
	'pong': {
		description:'reply with a pong',
		syntax: '~ping',
		exec: function(message)
		{
			message.reply('pong');
		}
	},
	'yo':{
		description:'reply with a yo bro',
		syntax: '~yo',
		exec: function(message)
		{
			message.reply('yo bro');
		}
	},
	'link':{
		description:'link revive account to this discord account',
		syntax: '~link',
		exec: function(message){
			functions.integrate(message.author);
		}
	},
	'refresh':{
		description:'refresh a user discord link status',
		syntax: '~refresh',
		exec: function(message){
			if(message.content.substring(9).trim()=='all'
				&& message.member.roles.find('moderator')!=undefined
				&& message.guild.name == 'Revive Netowrk')
			{
				functions.refreshAll(message.guild.members.array())
			}
			else
			{
				functions.refresh(message.user,message.member);
			}
		}
	},
	'bf2':{
		description:'finds a bf2 player',
		syntax: '~bf2 <PlayerName>',
		exec: function(message){
			if(message.mentions.users.first!=undefined)
			{

			}
			else
			{
				var nick = message.content.substring(5).trim();
				var plist = bf2.getPlayers(nick);
				console.log("BF2 in index.js gets executed");
				if (plist == null) {
					message.channel.sendMessage("API Down or invalid search");
					return;
					}
					if (plist.length >= 1) {
						//checking for exact matches
						var exact = plist.find(o => o.nick.toUpperCase().trim() === nick.toUpperCase());
						console.log(exact); var res = "**S.no.\tName \t PID \t Score**";
					}
					var start = 0;
					var past = 0;
					if (exact != null) {
						res = res + "\n" + (1) + "\t" + "\t" + exact.str();
						 start++ ;
						 }
						 for (var i = start; i < plist.length; i++)
						  {
						 	if (exact != null && i == plist.indexOf(exact))
						  	{
						  		past++;
						  		continue;
								}
							if (i == 26) {
  							res = res + "\n" + (plist.length - 25)
  							 + " more players found to Get a full list of players \n"
  							 + "<https://battlelog.co/player_search.php?q=" + nick + ">";
  							 break;
  							} else
  							{
  								 res = res + " \n" + (i + 1 - past)
  								 + "\t" + "\t" + plist[i].str();
  								message.channel.sendMessage(res);

  							}
  						}
  					if (plist.length == 0)
  					{ message.channel.sendMessage("Player not found"); }
			}
		}
	},
	'bf2142':{
		description:'finds a bf2142 player',
		syntax: '~bf2142 <PlayerName>',
		exec: function(message){
			if(message.mentions.users.first!=undefined)
			{

			}
			else
			{
				var nick = message.content.substring(7).trim();
				var plist = bf2142.getPlayers(nick);
				console.log("BF2142 in index.js gets executed");
				if (plist == null) {
					message.channel.sendMessage("API Down or invalid search");
					return;
					}
					if (plist.length >= 1) {
						//checking for exact matches
						var exact = plist.find(o => o.nick.toUpperCase().trim() === nick.toUpperCase());
						console.log(exact); var res = "**S.no.\tName \t PID**";
					}
					var start = 0;
					var past = 0;
					if (exact != null) {
						res = res + "\n" + (1) + "\t" + "\t" + exact.str();
						 start++ ;
						 }
						 for (var i = start; i < plist.length; i++)
						  {
						 	if (exact != null && i == plist.indexOf(exact))
						  	{
						  		past++;
						  		continue;
								}
							if (i == 26) {
  							res = res + "\n" + (plist.length - 25)
  							 + " more players found to Get a full list of players \n"
  							 + "<https://battlelog.co/player_search.php?q=" + nick + ">";
  							 break;
  							} else
  							{
  								 res = res + " \n" + (i + 1 - past)
  								 + "\t" + "\t" + plist[i].str();
  								message.channel.sendMessage(res);

  							}
  						}
  					if (plist.length == 0)
  					{ message.channel.sendMessage("Player not found"); }
			}
		}
	},
	'cookie':{
		description: 'eats a cookie',
		syntax: '~cookie',
		exec: function(message){
			message.reply('crunch crunch');
		}
	},
	'add':{
		description: 'adds a person to a role',
		syntax: '~add <UserMention> to <roleName>',
		exec: function(message){
			if (!message.member.hasPermission("MANAGE_ROLES_OR_PERMISSIONS")) {
				 message.channel.sendMessage("You aren't Worthy"); return; }
				 var member = message.guild.member(message.mentions.users.first());
				 var msg = message.content.split("to ");
				 member.addRole(message.guild.roles.find("name", msg[msg.length - 1]));
				 message.reply('done');
		}
	},
	'remove':{
		description: 'removes a person to a role',
		syntax: '~remove <UserMention> from <roleName>',
		exec: function(message){
			if (!message.member.hasPermission("MANAGE_ROLES_OR_PERMISSIONS")) {
				 message.channel.sendMessage("You aren't Worthy"); return; }
				 var member = message.guild.member(message.mentions.users.first());
				 var msg = message.content.split("to ");
				 member.removeRole(message.guild.roles.find("name", msg[msg.length - 1]));
				 message.reply('done');
		}
	},
	'help':{
		description: 'displays help',
		syntax: '~help',
		exec: function(message){
			var res = "";
			for(cmd in commands)
			{
				res  = res +"\n"+"**"+cmd+"** - "+"_"+ cmd.description+"_";
				res  = res +"\n"+"Syntax: *"+cmd.syntax+"*";
			}
			message.reply(res);
		}
	}
}<|endoftext|>