<commit_before>'use strict';

// Shop fruits controller
angular.module('shop-fruits').controller('ShopFruitsController', ['$scope', '$stateParams', '$location', 'Authentication', 'ShopFruits','$http','$state',
	function($scope, $stateParams, $location, Authentication, ShopFruits, $http, $state) {
		$scope.authentication = Authentication;

		// Create new Shop fruit
		$scope.create = function() {
			// Create new Shop fruit object
			var shopFruit = new ShopFruits ({
				name: this.name
			});

			// Redirect after save
			shopFruit.$save(function(response) {
				$location.path('shop-fruits/' + response._id);

				// Clear form fields
				$scope.name = '';
			}, function(errorResponse) {
				$scope.error = errorResponse.data.message;
			});
		};

    $scope.removeSpecific = function(shopFruit) {
      if(confirm('Please Explain about App before Deleting')) {
        $http({
          method: 'DELETE',
          data: shopFruit,
          url: 'http://getmeher.com:3000/shop-fruits/' + shopFruit._id
        }).then(function successCallback(response) {
          console.log(response)
          alert("removed");
          for (var i in $scope.shopFruits) {
            if ($scope.shopFruits [i] === shopFruit) {
              $scope.shopFruits.splice(i, 1);
            }
          }
        }, function errorCallback(response) {
          console.log(response)
          alert("error" + response);
        });
      }
    };

    //$scope.removeSpecific = function(shopFruit) {
    //  if(confirm('Please Explain about App before Deleting')) {
    //    if (shopFruit) {
    //      shopFruit.$remove();
    //      for (var i in $scope.shopFruits) {
    //        if ($scope.shopFruits [i] === shopFruit) {
    //          $scope.shopFruits.splice(i, 1);
    //        }
    //      }
    //    } else {
    //      $scope.shopFruit.$remove(function () {
    //        $location.path('shop-groceries');
    //      });
    //    }
    //  }
    //};

    // Remove existing Shop fruit
		$scope.remove = function(shopFruit) {
			if ( shopFruit ) {
				shopFruit.$remove();

				for (var i in $scope.shopFruits) {
					if ($scope.shopFruits [i] === shopFruit) {
						$scope.shopFruits.splice(i, 1);
					}
				}
			} else {
				$scope.shopFruit.$remove(function() {
					$location.path('shop-fruits');
				});
			}
		};

		// Update existing Shop fruit
		$scope.update = function() {
			var shopFruit = $scope.shopFruit;

			shopFruit.$update(function() {
				$location.path('shop-fruits/' + shopFruit._id);
			}, function(errorResponse) {
				$scope.error = errorResponse.data.message;
			});
		};

		// Find a list of Shop fruits
		$scope.find = function() {
			$scope.shopFruits = ShopFruits.query();
		};

    $scope.findNearby = function() {
      //$scope.shopFruits = shopFruits.query();
      $scope.pageNumber = 0;
      console.log($scope.areaLocation);
      if ($scope.areaLocation) {
        $scope.areaLng = $scope.areaLocation.geometry.location.lng();
        $scope.areaLat = $scope.areaLocation.geometry.location.lat();
      }
      else{
        $scope.areaLng = 71;
        $scope.areaLat = 19;
      }
      $scope.pageNumber = 1;
      console.log($scope.pageNumber);
      $http.get('http://getmeher.com:3000/shop-fruits/near/' + $scope.areaLng + '/' + $scope.areaLat + '/' + $scope.pageNumber).
          then(function (response) {
            $scope.shopFruits = (response.data);
            $scope.$broadcast('scroll.infiniteScrollComplete');
          }, function (response) {
            // called asynchronously if an error occurs
            // or server returns response with an error status.
          });
    };

    $scope.loadmore = function() {
      //$scope.shopFruits = shopFruits.query();
      console.log($scope.areaLocation);
      if ($scope.areaLocation) {
        $scope.areaLng = $scope.areaLocation.geometry.location.lng();
        $scope.areaLat = $scope.areaLocation.geometry.location.lat();
      }
      else{
        $scope.areaLng = 71;
        $scope.areaLat = 19;
      }
      $scope.pageNumber = $scope.pageNumber + 1;
      console.log($scope.pageNumber);
      $http.get('http://getmeher.com:3000/shop-fruits/near/' + $scope.areaLng + '/' + $scope.areaLat + '/' + $scope.pageNumber).
          then(function (response) {
            $scope.shopFruits = (response.data);
            $scope.$broadcast('scroll.infiniteScrollComplete');
          }, function (response) {
            // called asynchronously if an error occurs
            // or server returns response with an error status.
          });
    };

    $scope.setReminder = function(shopFruitData){
      shopFruitData.url = $state.current.url;
      $scope.reminderPost = {
        store: shopFruitData,
        shopName: shopFruitData.name,
        url: shopFruitData.url,
        address: shopFruitData.address,
        mobile: shopFruitData.mobile,
        notes: shopFruitData.notes
      };
      $http({
        url: 'http://getmeher.com:3000/reminders',
        method: "POST",
        data: $scope.reminderPost
      }).then(function(response) {
            // success
            alert("Reminder Set");
            console.log(response);
          },
          function(response) { // optional
            // failed
            $scope.reminderPost = null;
            console.log(response);
          });
    };

    $scope.updateSpecific = function(shopFruitData) {
      if (shopFruitData.tempMobile)
        shopFruitData.mobile = shopFruitData.tempMobile;
      var shopFruit = shopFruitData;
      console.log(shopFruit);
      $http({
        method: 'PUT',
        data: shopFruitData,
        url: 'http://getmeher.com:3000/shop-fruits/'+shopFruitData._id
      }).then(function successCallback(response) {
        console.log(response)
        alert("updates saved")
      }, function errorCallback(response) {
        console.log(response)
        alert("error" + response);
      });

      //shopFruit.pushUpdates(function() {
      //  //$location.path('shop-groceries/' + shopFruit._id);
      //  alert("Saved!");
      //}, function(errorResponse) {
      //  $scope.error = errorResponse.data.message;
      //});

    };

    // Find existing Shop grocery
    $scope.findSpecific = function(shopFruitId) {
      alert("Fetching");
      $scope.shopFruit = shopFruits.get({
        shopFruitId: shopFruitId
      });
    };

    // Find existing Shop fruit
		$scope.findOne = function() {
			$scope.shopFruit = ShopFruits.get({
				shopFruitId: $stateParams.shopFruitId
			});
		};
	}
]);
<commit_msg>edit user auth<commit_after>'use strict';

// Shop fruits controller
angular.module('shop-fruits').controller('ShopFruitsController', ['$scope', '$stateParams', '$location', 'Authentication', 'ShopFruits','$http','$state',
	function($scope, $stateParams, $location, Authentication, ShopFruits, $http, $state) {
		$scope.authentication = Authentication;

		// Create new Shop fruit
		$scope.create = function() {
			// Create new Shop fruit object
			var shopFruit = new ShopFruits ({
				name: this.name
			});

			// Redirect after save
			shopFruit.$save(function(response) {
				$location.path('shop-fruits/' + response._id);

				// Clear form fields
				$scope.name = '';
			}, function(errorResponse) {
				$scope.error = errorResponse.data.message;
			});
		};

    $scope.removeSpecific = function(shopFruit) {
      if(confirm('Please Explain about App before Deleting')) {
        $http({
          method: 'DELETE',
          data: shopFruit,
          url: 'http://getmeher.com:3000/shop-fruits/' + shopFruit._id
        }).then(function successCallback(response) {
          console.log(response)
          alert("removed");
          for (var i in $scope.shopFruits) {
            if ($scope.shopFruits [i] === shopFruit) {
              $scope.shopFruits.splice(i, 1);
            }
          }
        }, function errorCallback(response) {
          console.log(response)
          alert("error" + response);
        });
      }
    };

    //$scope.removeSpecific = function(shopFruit) {
    //  if(confirm('Please Explain about App before Deleting')) {
    //    if (shopFruit) {
    //      shopFruit.$remove();
    //      for (var i in $scope.shopFruits) {
    //        if ($scope.shopFruits [i] === shopFruit) {
    //          $scope.shopFruits.splice(i, 1);
    //        }
    //      }
    //    } else {
    //      $scope.shopFruit.$remove(function () {
    //        $location.path('shop-groceries');
    //      });
    //    }
    //  }
    //};

    // Remove existing Shop fruit
		$scope.remove = function(shopFruit) {
			if ( shopFruit ) {
				shopFruit.$remove();

				for (var i in $scope.shopFruits) {
					if ($scope.shopFruits [i] === shopFruit) {
						$scope.shopFruits.splice(i, 1);
					}
				}
			} else {
				$scope.shopFruit.$remove(function() {
					$location.path('shop-fruits');
				});
			}
		};

		// Update existing Shop fruit
		$scope.update = function() {
			var shopFruit = $scope.shopFruit;

			shopFruit.$update(function() {
				//$location.path('shop-fruits/' + shopFruit._id);
				$location.path('reminders/');
			}, function(errorResponse) {
				$scope.error = errorResponse.data.message;
			});
		};

		// Find a list of Shop fruits
		$scope.find = function() {
			$scope.shopFruits = ShopFruits.query();
		};

    $scope.findNearby = function() {
      //$scope.shopFruits = shopFruits.query();
      $scope.pageNumber = 0;
      console.log($scope.areaLocation);
      if ($scope.areaLocation) {
        $scope.areaLng = $scope.areaLocation.geometry.location.lng();
        $scope.areaLat = $scope.areaLocation.geometry.location.lat();
      }
      else{
        $scope.areaLng = 71;
        $scope.areaLat = 19;
      }
      $scope.pageNumber = 1;
      console.log($scope.pageNumber);
      $http.get('http://getmeher.com:3000/shop-fruits/near/' + $scope.areaLng + '/' + $scope.areaLat + '/' + $scope.pageNumber).
          then(function (response) {
            $scope.shopFruits = (response.data);
            $scope.$broadcast('scroll.infiniteScrollComplete');
          }, function (response) {
            // called asynchronously if an error occurs
            // or server returns response with an error status.
          });
    };

    $scope.loadmore = function() {
      //$scope.shopFruits = shopFruits.query();
      console.log($scope.areaLocation);
      if ($scope.areaLocation) {
        $scope.areaLng = $scope.areaLocation.geometry.location.lng();
        $scope.areaLat = $scope.areaLocation.geometry.location.lat();
      }
      else{
        $scope.areaLng = 71;
        $scope.areaLat = 19;
      }
      $scope.pageNumber = $scope.pageNumber + 1;
      console.log($scope.pageNumber);
      $http.get('http://getmeher.com:3000/shop-fruits/near/' + $scope.areaLng + '/' + $scope.areaLat + '/' + $scope.pageNumber).
          then(function (response) {
            $scope.shopFruits = (response.data);
            $scope.$broadcast('scroll.infiniteScrollComplete');
          }, function (response) {
            // called asynchronously if an error occurs
            // or server returns response with an error status.
          });
    };

    $scope.setReminder = function(shopFruitData){
      shopFruitData.url = $state.current.url;
      $scope.reminderPost = {
        store: shopFruitData,
        shopName: shopFruitData.name,
        url: shopFruitData.url,
        address: shopFruitData.address,
        mobile: shopFruitData.mobile,
        notes: shopFruitData.notes
      };
      $http({
        url: 'http://getmeher.com:3000/reminders',
        method: "POST",
        data: $scope.reminderPost
      }).then(function(response) {
            // success
            alert("Reminder Set");
            console.log(response);
          },
          function(response) { // optional
            // failed
            $scope.reminderPost = null;
            console.log(response);
          });
    };

    $scope.updateSpecific = function(shopFruitData) {
      if (shopFruitData.tempMobile)
        shopFruitData.mobile = shopFruitData.tempMobile;
      var shopFruit = shopFruitData;
      console.log(shopFruit);
      $http({
        method: 'PUT',
        data: shopFruitData,
        url: 'http://getmeher.com:3000/shop-fruits/'+shopFruitData._id
      }).then(function successCallback(response) {
        console.log(response)
        alert("updates saved")
      }, function errorCallback(response) {
        console.log(response)
        alert("error" + response);
      });

      //shopFruit.pushUpdates(function() {
      //  //$location.path('shop-groceries/' + shopFruit._id);
      //  alert("Saved!");
      //}, function(errorResponse) {
      //  $scope.error = errorResponse.data.message;
      //});

    };

    // Find existing Shop grocery
    $scope.findSpecific = function(shopFruitId) {
      alert("Fetching");
      $scope.shopFruit = shopFruits.get({
        shopFruitId: shopFruitId
      });
    };

    // Find existing Shop fruit
		$scope.findOne = function() {
			$scope.shopFruit = ShopFruits.get({
				shopFruitId: $stateParams.shopFruitId
			});
		};
	}
]);
<|endoftext|>


<commit_before>var ES_URL = 'localhost:9200';

var $ = require('jquery');
var elasticsearch = require('elasticsearch');
var client = new elasticsearch.Client({
  host: ES_URL,
  //log: 'trace'
});

function search(latLng, distance) {
  latLng = latLng || [30, -97];  // DEBUG
  distance = distance || '16km';  // DEBUG
  return client.search({
    // index: 'thc',
    // type: 'markers',
    body: {
      query:{
        filtered: {
          query: {match_all: {}},
          filter: {
            geo_distance: {
              distance: distance,
              'marker.location': {
                lat: latLng[0],
                lon: latLng[1]
              }
            }
          }
        }
      }
    }
  })
}

module.exports = search;
<commit_msg>Remove import jquery<commit_after>var ES_URL = 'localhost:9200';

var elasticsearch = require('elasticsearch');
var client = new elasticsearch.Client({
  host: ES_URL,
  //log: 'trace'
});

function search(latLng, distance) {
  latLng = latLng || [30, -97];  // DEBUG
  distance = distance || '16km';  // DEBUG
  return client.search({
    // index: 'thc',
    // type: 'markers',
    body: {
      query:{
        filtered: {
          query: {match_all: {}},
          filter: {
            geo_distance: {
              distance: distance,
              'marker.location': {
                lat: latLng[0],
                lon: latLng[1]
              }
            }
          }
        }
      }
    }
  })
}

module.exports = search;
<|endoftext|>


<commit_before>var startTime, currentTime;
var gl;
var cloudTexture, nameTexture;
var debugDiv;

/*requestAnimationFrame polyfill - https://gist.github.com/paulirish/1579671 */
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
    window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
                               || window[vendors[x]+'CancelRequestAnimationFrame'];
}

if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = function(callback, element) {
        var currTime = new Date().getTime();
        var timeToCall = Math.max(0, 16 - (currTime - lastTime));
        var id = window.setTimeout(function() { callback(currTime + timeToCall); },
          timeToCall);
        lastTime = currTime + timeToCall;
        return id;
    };
}

if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function(id) {
        clearTimeout(id);
    };
}());

function addEvent(elem, type, eventHandle) {
    if (elem == null || typeof(elem) == 'undefined') return;
    if ( elem.addEventListener ) {
        elem.addEventListener( type, eventHandle, false );
    } else if ( elem.attachEvent ) {
        elem.attachEvent( "on" + type, eventHandle );
    } else {
        elem["on"+type]=eventHandle;
    }
}

function clamp(x, min, max) {
    return Math.min(Math.max(x, min), max);
}

function onResize() {
    if (!gl) return;

    gl.canvas.width = window.innerWidth;
    gl.canvas.height = window.innerHeight;
    gl.viewportWidth = gl.canvas.width;
    gl.viewportHeight = gl.canvas.height;
};

function handleTextureLoaded(image, texture, wrap) {
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
    gl.bindTexture(gl.TEXTURE_2D, null);
}

var numBlockers = 0;

function block() {
    numBlockers++;
}

function unblock() {
    if (--numBlockers == 0) main2();
}

function initTextures() {
    block();
    cloudTexture = gl.createTexture();
    var cloudImage = new Image();
    $(cloudImage).one('load', function() {
        handleTextureLoaded(cloudImage, cloudTexture, gl.REPEAT);
        unblock();
    });
    cloudImage.src = "clouds.png";

    block();
    nameTexture = gl.createTexture();
    var nameImage = new Image();
    $(nameImage).one('load', function() {
        handleTextureLoaded(nameImage, nameTexture, gl.CLAMP_TO_EDGE);
        unblock();
    });
    nameImage.src = "name.png";
}

function getShader(url, type) {
    var req = new XMLHttpRequest();
    req.open("GET", url, false);
    req.send(null);
    var src = (req.status == 200) ? req.responseText : null;

    var shader = gl.createShader(type);

    gl.shaderSource(shader, src);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(shader));
        return null;
    }

    return shader;
}

var shaderProgram;

function initShaders() {
    var fragmentShader = getShader("shader.frag", gl.FRAGMENT_SHADER);
    var vertexShader = getShader("shader.vert", gl.VERTEX_SHADER);

    shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);

    if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
        alert("Could not initialise shaders");
    }

    gl.useProgram(shaderProgram);

    shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "in_pos");
    gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
    gl.uniform1i(gl.getUniformLocation(shaderProgram, "u_tex_clouds"), 0);
    gl.uniform1i(gl.getUniformLocation(shaderProgram, "u_tex_name"), 1);
}

var fsqBuffer;

function initBuffers() {
    fsqBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, fsqBuffer);
    vertices = [
        -1.0, -1.0,
         1.0, -1.0,
        -1.0,  1.0,
         1.0,  1.0
    ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    fsqBuffer.itemSize = 2;
    fsqBuffer.numItems = 4;
}

function drawScene() {
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.uniform1f(gl.getUniformLocation(shaderProgram, "u_time"), (currentTime - startTime)/1000.0);
    gl.uniform1f(gl.getUniformLocation(shaderProgram, "u_pageOffsetY"), window.pageYOffset);
    gl.uniform1f(gl.getUniformLocation(shaderProgram, "u_canvasHeight"), gl.viewportHeight);
    gl.uniform1f(gl.getUniformLocation(shaderProgram, "u_aspectRatio"), gl.viewportHeight/gl.viewportWidth);
    gl.bindBuffer(gl.ARRAY_BUFFER, fsqBuffer);
    gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, fsqBuffer.itemSize, gl.FLOAT, false, 0, 0);
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, cloudTexture);
    gl.activeTexture(gl.TEXTURE1);
    gl.bindTexture(gl.TEXTURE_2D, nameTexture);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, fsqBuffer.numItems);
}

function animloop(){
    var prevTime = currentTime;
    currentTime = (new Date).getTime();
    var fps = Math.round(1000.0/(currentTime - prevTime));
    debugDiv.innerHTML = "" + fps;

    //Reset clock at 20 minutes
    if (currentTime - startTime > 1200000) startTime = currentTime;
    drawScene();
    window.requestAnimationFrame(animloop);
};

function main() {
    debugDiv = document.getElementById("debug");
    var canvas = document.getElementById("webglcanvas");
    try {
        block();
        gl = canvas.getContext("experimental-webgl");
        onResize();
        initTextures();
        initShaders();
        initBuffers();
        unblock();
    } catch (e) {
        alert(e);
    }
}

function main2() {
    gl.clearColor(0.0, 0.0, 0.0, 1.0);

    var testStartTime = (new Date).getTime();
    for (i=0; i<30; i++) {
        drawScene();
    }
    var testEndTime = (new Date).getTime();
    alert(testEndTime - testStartTime); //...what?

    startTime = (new Date).getTime();
    addEvent(window, "resize", onResize);
    window.requestAnimationFrame(animloop);
}<commit_msg>Frame rate test<commit_after>var startTime, currentTime;
var gl;
var cloudTexture, nameTexture;
var debugDiv;

/*requestAnimationFrame polyfill - https://gist.github.com/paulirish/1579671 */
(function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
                                   || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame) {
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };
    }

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

function addEvent(elem, type, eventHandle) {
    if (elem == null || typeof(elem) == 'undefined') return;
    if ( elem.addEventListener ) {
        elem.addEventListener( type, eventHandle, false );
    } else if ( elem.attachEvent ) {
        elem.attachEvent( "on" + type, eventHandle );
    } else {
        elem["on"+type]=eventHandle;
    }
}

function clamp(x, min, max) {
    return Math.min(Math.max(x, min), max);
}

function onResize() {
    if (!gl) return;

    gl.canvas.width = window.innerWidth;
    gl.canvas.height = window.innerHeight;
    gl.viewportWidth = gl.canvas.width;
    gl.viewportHeight = gl.canvas.height;
}

function handleTextureLoaded(image, texture, wrap) {
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
    gl.bindTexture(gl.TEXTURE_2D, null);
}

var numBlockers = 0;

function block() {
    numBlockers++;
}

function unblock() {
    if (--numBlockers == 0) run();
}

function initTextures() {
    block();
    cloudTexture = gl.createTexture();
    var cloudImage = new Image();
    $(cloudImage).one('load', function() {
        handleTextureLoaded(cloudImage, cloudTexture, gl.REPEAT);
        unblock();
    });
    cloudImage.src = "clouds.png";

    block();
    nameTexture = gl.createTexture();
    var nameImage = new Image();
    $(nameImage).one('load', function() {
        handleTextureLoaded(nameImage, nameTexture, gl.CLAMP_TO_EDGE);
        unblock();
    });
    nameImage.src = "name.png";
}

function getShader(url, type) {
    var req = new XMLHttpRequest();
    req.open("GET", url, false);
    req.send(null);
    var src = (req.status == 200) ? req.responseText : null;

    var shader = gl.createShader(type);

    gl.shaderSource(shader, src);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(shader));
        return null;
    }

    return shader;
}

var shaderProgram;

function initShaders() {
    var fragmentShader = getShader("shader.frag", gl.FRAGMENT_SHADER);
    var vertexShader = getShader("shader.vert", gl.VERTEX_SHADER);

    shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);

    if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
        alert("Could not initialise shaders");
    }

    gl.useProgram(shaderProgram);

    shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "in_pos");
    gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
    gl.uniform1i(gl.getUniformLocation(shaderProgram, "u_tex_clouds"), 0);
    gl.uniform1i(gl.getUniformLocation(shaderProgram, "u_tex_name"), 1);
}

var fsqBuffer;

function initBuffers() {
    fsqBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, fsqBuffer);
    vertices = [
        -1.0, -1.0,
         1.0, -1.0,
        -1.0,  1.0,
         1.0,  1.0
    ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    fsqBuffer.itemSize = 2;
    fsqBuffer.numItems = 4;
}

function drawScene() {
    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);

    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.uniform1f(gl.getUniformLocation(shaderProgram, "u_time"), (currentTime - startTime)/1000.0);
    gl.uniform1f(gl.getUniformLocation(shaderProgram, "u_pageOffsetY"), window.pageYOffset);
    gl.uniform1f(gl.getUniformLocation(shaderProgram, "u_canvasHeight"), gl.viewportHeight);
    gl.uniform1f(gl.getUniformLocation(shaderProgram, "u_aspectRatio"), gl.viewportHeight/gl.viewportWidth);

    gl.bindBuffer(gl.ARRAY_BUFFER, fsqBuffer);
    gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, fsqBuffer.itemSize, gl.FLOAT, false, 0, 0);
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, cloudTexture);
    gl.activeTexture(gl.TEXTURE1);
    gl.bindTexture(gl.TEXTURE_2D, nameTexture);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, fsqBuffer.numItems);
}

var testFrame = 0;

function testLoop() {
    drawScene();
    currentTime = (new Date).getTime();

    if (++testFrame < 60) {
        window.requestAnimationFrame(testLoop);
    } else {
        alert((currentTime - startTime)/(1000.0/60.0));

        window.requestAnimationFrame(mainLoop);
    }
}

function mainLoop() {
    drawScene();

    var prevTime = currentTime;
    currentTime = (new Date).getTime();
    if (currentTime - startTime > 1200000) startTime = currentTime; //Reset clock at 20 minutes

    var fps = Math.round(1000.0/(currentTime - prevTime));
    debugDiv.innerHTML = "" + fps;

    window.requestAnimationFrame(mainLoop);
}

function main() {
    debugDiv = document.getElementById("debug");
    var canvas = document.getElementById("webglcanvas");
    try {
        block();
        gl = canvas.getContext("experimental-webgl");
        onResize();
        initTextures();
        initShaders();
        initBuffers();
        unblock();
    } catch (e) {
        alert(e);
    }
}

function run() {
    addEvent(window, "resize", onResize);
    startTime = (new Date).getTime();
    window.requestAnimationFrame(testLoop);
}<|endoftext|>


<commit_before>/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true, nonpropdel: true */
/*global require, ArangoConnection, print, SYS_ARANGO */

////////////////////////////////////////////////////////////////////////////////
/// @brief module "internal"
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                 Module "internal"
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// --SECTION--                                                 private variables
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoShell
/// @{
////////////////////////////////////////////////////////////////////////////////

(function () {
  var internal = require("internal");

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoShell
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief hide global variables
////////////////////////////////////////////////////////////////////////////////

    if (typeof ArangoConnection !== "undefined") {
      internal.ArangoConnection = ArangoConnection;
      delete ArangoConnection;
    }

    if (typeof SYS_ARANGO !== "undefined") {
      internal.arango = SYS_ARANGO;
      delete SYS_ARANGO;
    }

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                 private functions
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoShell
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief flushes the module cache of the server
////////////////////////////////////////////////////////////////////////////////

  internal.flushServerModules = function () {
    if (typeof internal.arango !== 'undefined') {
      internal.arango.POST("/_admin/modules/flush", "");
      return;
    }

    throw "not connected";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief rebuilds the routing cache
////////////////////////////////////////////////////////////////////////////////

  internal.reloadRouting = function () {
    if (typeof internal.arango !== 'undefined') {
      internal.arango.POST("/_admin/routing/reload", "");
      return;
    }

    throw "not connected";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief rebuilds the routing cache
////////////////////////////////////////////////////////////////////////////////

  internal.routingCache = function () {
    if (typeof internal.arango !== 'undefined') {
      return internal.arango.GET("/_admin/routing/routes", "");

    }

    throw "not connected";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief rebuilds the authentication cache
////////////////////////////////////////////////////////////////////////////////

  internal.reloadAuth = function () {
    if (typeof internal.arango !== 'undefined') {
      internal.arango.POST("/_admin/auth/reload", "");
      return;
    }

    throw "not connected";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief execute javascript file on the server
////////////////////////////////////////////////////////////////////////////////

  internal.executeServer = function (body) {
    if (typeof internal.arango !== 'undefined') {
      return internal.arango.POST("/_admin/execute", body);
    }

    throw "not connected";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief logs a request in curl format
////////////////////////////////////////////////////////////////////////////////

  internal.appendCurlRequest = function (appender) {
    return function (method, url, body) {
      var response;
      var curl;

      if (typeof body !== 'string') {
        body = JSON.stringify(body);
      }

      curl = "unix> curl ";

      if (method === 'POST') {
        response = internal.arango.POST_RAW(url, body);
        curl += "-X " + method + " ";
      }
      else if (method === 'PUT') {
        response = internal.arango.PUT_RAW(url, body);
        curl += "-X " + method + " ";
      }
      else if (method === 'GET') {
        response = internal.arango.GET_RAW(url, body);
      }
      else if (method === 'DELETE') {
        response = internal.arango.DELETE_RAW(url, body);
        curl += "-X " + method + " ";
      }
      else if (method === 'PATCH') {
        response = internal.arango.PATCH_RAW(url, body);
        curl += "-X " + method + " ";
      }
      else if (method === 'OPTION') {
        response = internal.arango.OPTION_RAW(url, body);
        curl += "-X " + method + " ";
      }

      if (body !== undefined && body !== "") {
        curl += "--data @- ";
      }

      curl += "--dump - http://localhost:8529" + url;

      appender(curl + "\n");

      if (body !== undefined && body !== "") {
        appender(body += "\n");
      }

      appender("\n");

      return response;
    };
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief logs a response in JSON
////////////////////////////////////////////////////////////////////////////////

  internal.appendJsonResponse = function (appender) {
    return function (response) {
      var key;
      var headers = response.headers;
      var output;

      // generate header
      appender("HTTP/1.1 " + headers['http/1.1'] + "\n");

      for (key in headers) {
        if (headers.hasOwnProperty(key)) {
          if (key !== 'http/1.1' && key !== 'server' && key !== 'connection'
              && key !== 'content-length') {
            appender(key + ": " + headers[key] + "\n");
          }
        }
      }

      appender("\n");

      // pretty print body
      internal.startCaptureMode();
      print(JSON.parse(response.body));
      output = internal.stopCaptureMode();
      appender(output);
      appender("\n");
    };
  };

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                  public functions
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoShell
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief log function
////////////////////////////////////////////////////////////////////////////////

  internal.log = function (level, msg) {
    internal.output(level, ": ", msg, "\n");
  };

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

}());

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint"
// End:
<commit_msg>generated file<commit_after>/*jslint indent: 2, nomen: true, maxlen: 120, sloppy: true, vars: true, white: true, plusplus: true, nonpropdel: true */
/*global require, ArangoConnection, print, SYS_ARANGO */

////////////////////////////////////////////////////////////////////////////////
/// @brief module "internal"
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                 Module "internal"
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// --SECTION--                                                 private variables
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoShell
/// @{
////////////////////////////////////////////////////////////////////////////////

(function () {
  var internal = require("internal");

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoShell
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief hide global variables
////////////////////////////////////////////////////////////////////////////////

    if (typeof ArangoConnection !== "undefined") {
      internal.ArangoConnection = ArangoConnection;
      delete ArangoConnection;
    }

    if (typeof SYS_ARANGO !== "undefined") {
      internal.arango = SYS_ARANGO;
      delete SYS_ARANGO;
    }

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                 private functions
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoShell
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief flushes the module cache of the server
////////////////////////////////////////////////////////////////////////////////

  internal.flushServerModules = function () {
    if (typeof internal.arango !== 'undefined') {
      internal.arango.POST("/_admin/modules/flush", "");
      return;
    }

    throw "not connected";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief rebuilds the routing cache
////////////////////////////////////////////////////////////////////////////////

  internal.reloadRouting = function () {
    if (typeof internal.arango !== 'undefined') {
      internal.arango.POST("/_admin/routing/reload", "");
      return;
    }

    throw "not connected";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief rebuilds the routing cache
////////////////////////////////////////////////////////////////////////////////

  internal.routingCache = function () {
    if (typeof internal.arango !== 'undefined') {
      return internal.arango.GET("/_admin/routing/routes", "");

    }

    throw "not connected";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief rebuilds the authentication cache
////////////////////////////////////////////////////////////////////////////////

  internal.reloadAuth = function () {
    if (typeof internal.arango !== 'undefined') {
      internal.arango.POST("/_admin/auth/reload", "");
      return;
    }

    throw "not connected";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief execute javascript file on the server
////////////////////////////////////////////////////////////////////////////////

  internal.executeServer = function (body) {
    if (typeof internal.arango !== 'undefined') {
      return internal.arango.POST("/_admin/execute", body);
    }

    throw "not connected";
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief logs a request in curl format
////////////////////////////////////////////////////////////////////////////////

  internal.appendCurlRequest = function (appender) {
    return function (method, url, body, headers) {
      var response;
      var curl;

      if (typeof body !== 'string') {
        body = JSON.stringify(body);
      }

      curl = "unix> curl ";

      if (method === 'POST') {
        response = internal.arango.POST_RAW(url, body);
        curl += "-X " + method + " ";
      }
      else if (method === 'PUT') {
        response = internal.arango.PUT_RAW(url, body);
        curl += "-X " + method + " ";
      }
      else if (method === 'GET') {
        response = internal.arango.GET_RAW(url, body);
      }
      else if (method === 'DELETE') {
        response = internal.arango.DELETE_RAW(url, body);
        curl += "-X " + method + " ";
      }
      else if (method === 'PATCH') {
        response = internal.arango.PATCH_RAW(url, body);
        curl += "-X " + method + " ";
      }
      else if (method === 'OPTION') {
        response = internal.arango.OPTION_RAW(url, body);
        curl += "-X " + method + " ";
      }

      if (headers !== undefined && headers !== "") {
        curl += "--header \'" + headers + "\' ";
      }

      if (body !== undefined && body !== "") {
        curl += "--data @- ";
      }

      curl += "--dump - http://localhost:8529" + url;

      appender(curl + "\n");

      if (body !== undefined && body !== "") {
        appender(body += "\n");
      }

      appender("\n");

      return response;
    };
  };

////////////////////////////////////////////////////////////////////////////////
/// @brief logs a response in JSON
////////////////////////////////////////////////////////////////////////////////

  internal.appendJsonResponse = function (appender) {
    return function (response) {
      var key;
      var headers = response.headers;
      var output;

      // generate header
      appender("HTTP/1.1 " + headers['http/1.1'] + "\n");

      for (key in headers) {
        if (headers.hasOwnProperty(key)) {
          if (key !== 'http/1.1' && key !== 'server' && key !== 'connection'
              && key !== 'content-length') {
            appender(key + ": " + headers[key] + "\n");
          }
        }
      }

      appender("\n");

      // pretty print body
      internal.startCaptureMode();
      print(JSON.parse(response.body));
      output = internal.stopCaptureMode();
      appender(output);
      appender("\n");
    };
  };

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                  public functions
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoShell
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief log function
////////////////////////////////////////////////////////////////////////////////

  internal.log = function (level, msg) {
    internal.output(level, ": ", msg, "\n");
  };

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

}());

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint"
// End:
<|endoftext|>


<commit_before>import {polygon as turfPolygon} from '@turf/helpers'
import GeometryType from '../geom/GeometryType.js';
import booleanOverlap from '@turf/boolean-overlap'
import Draw from './Draw.js';
import {DrawEvent} from './Draw.js';
import {DrawEventType} from './Draw.js';
import Circle from '../geom/Circle.js';
import Feature from '../Feature.js';
import Polygon from '../geom/Polygon.js'
import MapBrowserEventType from '../MapBrowserEventType.js';
import EventType from '../events/EventType.js';
import {shiftKeyOnly} from '../events/condition.js';
import {fromCircle} from '../geom/Polygon.js';
import {union} from '../geom/flat/union.js';
import {createEditingStyle} from '../style/Style.js';

class PolygonBrush extends Draw {

  constructor(options) {

    super(options);
    this.circleRadius_ = 10000  //TODO better value
    this.mode_ = null;
    this.overlay_.setStyle(options.style ? options.style : getDefaultStyleFunction());
  }

  handleEvent(event) {
    const type = event.type;
    let pass = true;
    if (shiftKeyOnly(event) && (type === EventType.WHEEL || type === EventType.MOUSEWHEEL)) {
      this.updateSketchPointRadius_(event);
    }

    if (event.type === MapBrowserEventType.POINTERDRAG && this.handlingDownUpSequence) {
      pass = false;
    }

    return super.handleEvent(event) && pass;
  }

  /**
   * @inheritDoc
   */
  handleDownEvent(event) {
    if (!this.handlingDownUpSequence) {
      this.startDrawing_(event);
      return true;
    }

    return false;
  }

  /**
   * @inheritDoc
   */
  handleUpEvent(event) {
    if (this.handlingDownUpSequence) {
      this.finishDrawing();

      return true;
    }

    return false;
  }

  /**
   * @param {import("../MapBrowserEvent.js").default} event Event.
   * @private
   */
  createOrUpdateSketchPoint_(event) {
    const coordinates = event.coordinate.slice();
    if (!this.sketchPoint_) {
      this.sketchPoint_ = new Feature(new Circle(coordinates,this.circleRadius_));
      this.updateSketchFeatures_();
    } else {
      const sketchPointGeom = this.sketchPoint_.getGeometry();
      sketchPointGeom.setCenter(coordinates);
    }
  }

  updateSketchPointRadius_(event) {
    if (this.sketchPoint_) {
      const sketchPointGeom = this.sketchPoint_.getGeometry();
      if (event.originalEvent.deltaY > 0) {
        this.circleRadius_ = sketchPointGeom.getRadius() + 1000;  //TODO better value
      }
      if (event.originalEvent.deltaY < 0) {
        this.circleRadius_ = sketchPointGeom.getRadius() - 1000;  //TODO better value
      }
      sketchPointGeom.setRadius(this.circleRadius_);
    }
  }

  startDrawing_(event) {
    const start = event.coordinate;
    this.finishCoordinate_ = start;

    this.sketchFeature_ = new Feature(fromCircle(this.sketchPoint_.getGeometry()));
    this.updateSketchFeatures_();
    this.dispatchEvent(new DrawEvent(DrawEventType.DRAWSTART, this.sketchFeature_));
  }

  /**
   * Stop drawing and add the sketch feature to the target layer.
   * The {@link module:ol/interaction/Draw~DrawEventType.DRAWEND} event is
   * dispatched before inserting the feature.
   * @api
   */
  handlePointerMove_(event) {
    this.createOrUpdateSketchPoint_(event);

    if (this.sketchFeature_) {
      const sketchFeature = this.sketchFeature_;
      const geometry = fromCircle(this.sketchPoint_.getGeometry());
      var sketchPointPolygon = turfPolygon(geometry.getCoordinates())

      var sketchFeaturePolygon = turfPolygon(sketchFeature.getGeometry().getCoordinates());
      if (booleanOverlap(sketchPointPolygon, sketchFeaturePolygon)) {
          var coords = union(sketchPointPolygon, sketchFeaturePolygon);
          sketchFeature.getGeometry().setCoordinates(coords);
      }
    }
  }

  finishDrawing() {
    const sketchFeature = this.abortDrawing_();
    if (!sketchFeature) {
      return;
    }

    this.dispatchEvent(new DrawEvent(DrawEventType.DRAWEND, sketchFeature));
    if (this.features_) {
      this.features_.push(sketchFeature);
    }
    if (this.source_) {
      this.source_.addFeature(sketchFeature);
    }
  }
}

function getDefaultStyleFunction() {
  let styles = createEditingStyle();
  styles[GeometryType.POLYGON] =
      styles[GeometryType.POLYGON].concat(
        styles[GeometryType.LINE_STRING]
      );
  return function(feature, resolution) {
    return styles[feature.getGeometry().getType()];
  };
}

export default PolygonBrush;
<commit_msg>Fix stopping of event when sketch point radius is changed<commit_after>import {polygon as turfPolygon} from '@turf/helpers'
import GeometryType from '../geom/GeometryType.js';
import booleanOverlap from '@turf/boolean-overlap'
import Draw from './Draw.js';
import {DrawEvent} from './Draw.js';
import {DrawEventType} from './Draw.js';
import Circle from '../geom/Circle.js';
import Feature from '../Feature.js';
import Polygon from '../geom/Polygon.js'
import MapBrowserEventType from '../MapBrowserEventType.js';
import EventType from '../events/EventType.js';
import {shiftKeyOnly} from '../events/condition.js';
import {fromCircle} from '../geom/Polygon.js';
import {union} from '../geom/flat/union.js';
import {createEditingStyle} from '../style/Style.js';

class PolygonBrush extends Draw {

  constructor(options) {

    super(options);
    this.circleRadius_ = 10000  //TODO better value
    this.mode_ = null;
    this.overlay_.setStyle(options.style ? options.style : getDefaultStyleFunction());
  }

  handleEvent(event) {
    const type = event.type;
    let pass = true;
    if (shiftKeyOnly(event) && (type === EventType.WHEEL || type === EventType.MOUSEWHEEL)) {
      this.updateSketchPointRadius_(event);
      pass = false;
    }

    if (event.type === MapBrowserEventType.POINTERDRAG && this.handlingDownUpSequence) {
      pass = false;
    }

    return super.handleEvent(event) && pass;
  }

  /**
   * @inheritDoc
   */
  handleDownEvent(event) {
    if (!this.handlingDownUpSequence) {
      this.startDrawing_(event);
      return true;
    }

    return false;
  }

  /**
   * @inheritDoc
   */
  handleUpEvent(event) {
    if (this.handlingDownUpSequence) {
      this.finishDrawing();

      return true;
    }

    return false;
  }

  /**
   * @param {import("../MapBrowserEvent.js").default} event Event.
   * @private
   */
  createOrUpdateSketchPoint_(event) {
    const coordinates = event.coordinate.slice();
    if (!this.sketchPoint_) {
      this.sketchPoint_ = new Feature(new Circle(coordinates,this.circleRadius_));
      this.updateSketchFeatures_();
    } else {
      const sketchPointGeom = this.sketchPoint_.getGeometry();
      sketchPointGeom.setCenter(coordinates);
    }
  }

  updateSketchPointRadius_(event) {
    if (this.sketchPoint_) {
      const sketchPointGeom = this.sketchPoint_.getGeometry();
      if (event.originalEvent.deltaY > 0) {
        this.circleRadius_ = sketchPointGeom.getRadius() + 1000;  //TODO better value
      }
      if (event.originalEvent.deltaY < 0) {
        this.circleRadius_ = sketchPointGeom.getRadius() - 1000;  //TODO better value
      }
      sketchPointGeom.setRadius(this.circleRadius_);
    }
  }

  startDrawing_(event) {
    const start = event.coordinate;
    this.finishCoordinate_ = start;

    this.sketchFeature_ = new Feature(fromCircle(this.sketchPoint_.getGeometry()));
    this.updateSketchFeatures_();
    this.dispatchEvent(new DrawEvent(DrawEventType.DRAWSTART, this.sketchFeature_));
  }

  /**
   * Stop drawing and add the sketch feature to the target layer.
   * The {@link module:ol/interaction/Draw~DrawEventType.DRAWEND} event is
   * dispatched before inserting the feature.
   * @api
   */
  handlePointerMove_(event) {
    this.createOrUpdateSketchPoint_(event);

    if (this.sketchFeature_) {
      const sketchFeature = this.sketchFeature_;
      const geometry = fromCircle(this.sketchPoint_.getGeometry());
      var sketchPointPolygon = turfPolygon(geometry.getCoordinates())

      var sketchFeaturePolygon = turfPolygon(sketchFeature.getGeometry().getCoordinates());
      if (booleanOverlap(sketchPointPolygon, sketchFeaturePolygon)) {
          var coords = union(sketchPointPolygon, sketchFeaturePolygon);
          sketchFeature.getGeometry().setCoordinates(coords);
      }
    }
  }

  finishDrawing() {
    const sketchFeature = this.abortDrawing_();
    if (!sketchFeature) {
      return;
    }

    this.dispatchEvent(new DrawEvent(DrawEventType.DRAWEND, sketchFeature));
    if (this.features_) {
      this.features_.push(sketchFeature);
    }
    if (this.source_) {
      this.source_.addFeature(sketchFeature);
    }
  }
}

function getDefaultStyleFunction() {
  let styles = createEditingStyle();
  styles[GeometryType.POLYGON] =
      styles[GeometryType.POLYGON].concat(
        styles[GeometryType.LINE_STRING]
      );
  return function(feature, resolution) {
    return styles[feature.getGeometry().getType()];
  };
}

export default PolygonBrush;
<|endoftext|>


<commit_before>var participants = [];		//people currently running an instance of the hangout
var queue = [];				//list of participant ids waiting to speak. 0 is the current speaker
var timeOut = -1;				//unix time of when the current speaker's turn will end
var currentSpeakerId;		//id of the current speaker; on updates if it doesn't match queue, manager sets new time

var greenDot = gapi.hangout.av.effects.createImageResource('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90BDwMNIxL4LdEAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAuNJREFUeNrtmy2M2mAYx3/tTsxchliWnDi1kAxBhsE0aTBkbkPg0Ljhlp1CYnF3Dj03wbBnSJOaMywTXLKcOkGyICBnJrhsog9Lj7Xlo3y078s/qSx9/z+e9/N5XoMdy3Z5BpwBOaAgTw44B14CM2AC3ANDYCDPEBg5Fo+7bJ+xI9MvgBJQB97H/Lke0AH6jsU0sQBsFwMoAs0tmI6C0QJuHIs/iQAgxsvAFwnpfWgM1IDruCCMmObfAl+B1xxGd0DVsfi+VwC2y3MJxU8kQ22g6Vj83jkA2+UN8AM4IVmaAXnH4nadl8w1zX+Q6Slp5pE2DaWN2wdgu3wEuiRfXWnr9gDYLp+BS9KjS2lz/DFAaKbJvF8Nx+JqYwDSn7qkWxXH4tvaAGS0H6KGcmGzgxExzz8kdLTfdIo8DVonhA2CLYXMz6fI1koRIMvbAWqqsLhsNgI2Nj8PuLbfx94h699ALXaBssLmEW/lwAiQf//XHre0h9IYeDWPAn8EFDUwj3gsBnWBJvqo+aQLyBneBL2UcSym8wgooZ9K/i5Q1xBAHcCQc/sZeurExEta6KozEy9Lo6tyJl6qSlcVjgCOXcDL0uqqcxPIaAwgY6K5TA33AH5NTLzKDF11b6LO0fcmGpqoewC6igZHAMcuACONAYxMqcPraWi+51g8zhdCHQ0BdOYLIYC+hgD6/wBIBWZPs/Cf+iMAQrKniqrl3wvMdYOXNlJdY/H6FIDkymoaAKhFZYev8VLIqupOPBIIQMhUFQZQXSyu/u9ARCoo2gqabwcVVYedCDVRK1s0IyT7HQhAqqnyCgHIh1WSh54JSl1dRQHzlagK8shDUamwbKTYfCOqSnQpAIFwBVyk0PzFsjphWOPCRMqKphurmF8LgEBIQ/F0ZVnYbwxAIOh7ZcY3O5wmbLHUxiuGvl33Re2vzcXKDcqHs8C7PW+lx/LNbBzzsSNgIRr0vDobAkO/y9MRMBJ9ff4vhV3btM/DqFkAAAAASUVORK5CYII=');
var greenDotOverlay = greenDot.createOverlay(
	{'scale':
		{'magnitude': 0.15, 'reference': gapi.hangout.av.effects.ScaleReference.WIDTH}});

var yellowDot = gapi.hangout.av.effects.createImageResource('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90BDwMXCA5pLkoAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAuFJREFUeNrtmyts21AUhj97BiPVCiZLBUVzpAVUKykuqca2gLDgsoVNKwoMDWtZ8NhAFloSXJJpIJXmooJIVkCjkoFbbcAnk5vZzsN52Pfml8yS+P5fzn2ecy3WrMB3XgAHQBk4lqcMHAKvAQU8APfAAOjLMwCGrqee1tk+a02mXwGnwDnwIePPdYE20HM9Nc4tgMB3LOAEaKzAdBqMJnDjeupPLgCI8TPgq4T0JjQCasB1VhBWRvPvgG/AG7ajO6DqeurHRgEEvvNSQvEz+VALaLie+r12AIHvvAV+Ag75kgKOXE/dLvIle0HzH2V6ypt5pE0DaePqAQS+8wnokH91pK2rAxD4zhfgkuLoUtqcfQwQmkUyH1Xd9dTV0gCkP3Uotiqup74vDEBG+wF6qJw0O1gp8/xjTkf7ZafIvbh1QtIg2NTI/GSKbM4VAbK87aOnjqeXzVbMxubXFtf2m9g7lKIbqOkucKaxecTbWWwEyL8fbHBLuy2NAHcSBdEIODHAPOLxJK4LNDBHjWddQM7wHjBL+66nxpMIOMU8nUa7wLmBAM4BLDm3V5gpxyZMWpiqA5swS2OqyjZhqspUHe8A7LpAmKU1VYc2sG8wgH0bw2UbuAeI6sEmrMwwVfc2+hx9L6OBjb4HoPOovwOw6wIwNBjA0JY6vK6B5ruup54mC6G2gQDak4UQQM9AAL1/AKQCs2tY+I+jEQAJ2VNN1YzuBSa6IUwb6a6ReH0OQHJlNQMA1NKyw9eEKWRddSceiQUgZKoaA6hOF1f/dyAiFRQtDc234oqqd0VScZ+WDx5p9O8fJVWSJ54JSl1dRQPzlbQK8tRDUamwrBfYfD2tSnQmAIFwBVwU0PzFrDrhxEEwYWAsUtF0fR7zCwEQCEUonq7MCvulAQgEc6/MRGaHvZwtlloyz98u+kXjr81lyg3Ki0vA+w1vpUfyzlIW85kjYCoazLw6mwDDvMvTKTByfX3+L4KL/xorzXR/AAAAAElFTkSuQmCC');
	var yellowDotOverlay = yellowDot.createOverlay(
	{'scale':
		{'magnitude': 0.15, 'reference': gapi.hangout.av.effects.ScaleReference.WIDTH}});

var buttonDisabled = false;	//true when button is clicked to prevent joining the queue several times

gapi.hangout.onApiReady.add(function(eventObj){
	if (eventObj.isApiReady) {
		buttonDisabled = false;
		participants = gapi.hangout.getEnabledParticipants();
		printParticipants();

		gapi.hangout.onParticipantsChanged.add(onParticipantsChange);
		gapi.hangout.data.onStateChanged.add(onDataChange);

		setInterval(updateTimeOutText, 200);
	}
});

function onParticipantsChange(eventObj) {
	participants = eventObj.participants;

	onServerUpdate();
};

function onDataChange (eventObj){
	var state = gapi.hangout.data.getState();
	queue = JSON.parse(state.queue);
	try{
		timeOut = JSON.parse((state.timeOut) ? state.timeOut : -1);
	}
	catch (e){
		console.log(e);
		timeOut = -1;
	}

	onServerUpdate();
}

function onServerUpdate(){
	console.log("onServerUpdate called");
	buttonDisabled = false;
	printParticipants();
	clearOverlay();
	var queuePosition = queue.indexOf(gapi.hangout.getParticipantId());
	if (queuePosition == 0){
		placeGreenDot();
		document.getElementById('queueButton').innerHTML = "End Early";
	}
	else if (queuePosition > 0){
		placeYellowDot();
		document.getElementById('queueButton').innerHTML = "Leave Queue";
	}
	else{
		document.getElementById('queueButton').innerHTML = "Raise Hand";
	}

	//lowest order participant manages time updates
	//and checks for disconnected queue memembers
	if (isManager()){
		console.log("managing update...");
		var validSpeaker = false;
		var updateRequired = false;
		while (queue.length > 0 && !validSpeaker){

			var speakerInHangout = false;
			for (var i = 0; i < participants.length; i++){
				if (participants[i].id == queue[0]){
					if (!participants[i].hasAppEnabled){
						console.log("speaker doesn't have app on");
						queue.shift();
						updateRequired = true;
						speakerInHangout = true;
					}
					else{
						console.log("speaker running app");
						validSpeaker = true;
						speakerInHangout = true;
					}
				}
			}
			if (!speakerInHangout){
				console.log("speaker not in hangout");
				queue.shift();
				updateRequire = true;
			}
		}
		if (timeOut == -1 || new Date().getTime() > timeOut){
			console.log('new timeout value required');
			updateRequired = true;
		}
		if (updateRequired){
			console.log("sending new update");
			timeOut = new Date().getTime() + 1000*60;
			gapi.hangout.data.submitDelta({'queue':JSON.stringify(queue), 'timeOut': JSON.stringify(timeOut)});
		}
		//set time
	}
}

function printParticipants(){
	var members = "";
	if (queue.length > 0){
		document.getElementById('speakerName').innerHTML = getParticipantNameById(queue[0]);
		document.getElementById('speakerDisplay').style.visibility = 'visible';
	}
	else {
		document.getElementById('speakerDisplay').style.visibility = 'hidden';
	}
	for (var i = 1; i < queue.length; i++){
		members = members + getParticipantNameById(queue[i]) + '
';
	}
	for (var i = 0; i < participants.length; i++){
		if (queue.indexOf(participants[i].id) == -1){
			members = members + participants[i].person.displayName + '
';
		}
	}
	document.getElementById('otherParticipants').innerHTML = members;
}

function getParticipantNameById(id){
	for (var i = 0; i < participants.length; i++){
		if (participants[i].id == id){
			return participants[i].person.displayName;
		}
	}
	return '';
}

function buttonClick(){
	if (!buttonDisabled){
		buttonDisabled = true;
		var queuePosition = queue.indexOf(gapi.hangout.getParticipantId());
		if (queuePosition == 0){
			queue.shift();
			gapi.hangout.data.submitDelta({'queue':JSON.stringify(queue)});
		}
		else if (queuePosition == -1){
			queue.push(gapi.hangout.getParticipantId());
			gapi.hangout.data.submitDelta({'queue':JSON.stringify(queue), 'timeOut':JSON.stringify(new Date().getTime() + 1000*60)});
		}
	}
}

function placeGreenDot(){
	greenDotOverlay.setPosition(.4, -.35);
	greenDotOverlay.setVisible(true);
}

function placeYellowDot(){
	yellowDotOverlay.setPosition(.4, -.35);
	yellowDotOverlay.setVisible(true);
}

function clearOverlay(){
	greenDotOverlay.setVisible(false);
	yellowDotOverlay.setVisible(false);
}

function isManager(){
	return (participants[0].id == gapi.hangout.getParticipantId());
}

//what happens if manager is alt tabbed?
function updateTimeOutText(){
	if (timeOut != -1 && queue.length > 0){
		var timeDif = timeOut - new Date().getTime();
		document.getElementById('timeLeft').innerHTML = '  - ' + Math.max(0, Math.round(timeDif/1000)) + ' secounds';
		if (isManager && timeDif < 0 || timeDif < 2000){
			console.log("Time up!");
			//force update iff queue is empty
			if (queue.length > 1){
				queue.shift();
			}
			timeOut = new Date().getTime() + 1000*60;
			gapi.hangout.data.submitDelta({'queue':JSON.stringify(queue), 'timeOut': JSON.stringify(timeOut)});
		}
	}
	else{
		document.getElementById('timeLeft').innerHTML = '';
	}
}<commit_msg>none instead of hidden<commit_after>var participants = [];		//people currently running an instance of the hangout
var queue = [];				//list of participant ids waiting to speak. 0 is the current speaker
var timeOut = -1;				//unix time of when the current speaker's turn will end
var currentSpeakerId;		//id of the current speaker; on updates if it doesn't match queue, manager sets new time

var greenDot = gapi.hangout.av.effects.createImageResource('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90BDwMNIxL4LdEAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAuNJREFUeNrtmy2M2mAYx3/tTsxchliWnDi1kAxBhsE0aTBkbkPg0Ljhlp1CYnF3Dj03wbBnSJOaMywTXLKcOkGyICBnJrhsog9Lj7Xlo3y078s/qSx9/z+e9/N5XoMdy3Z5BpwBOaAgTw44B14CM2AC3ANDYCDPEBg5Fo+7bJ+xI9MvgBJQB97H/Lke0AH6jsU0sQBsFwMoAs0tmI6C0QJuHIs/iQAgxsvAFwnpfWgM1IDruCCMmObfAl+B1xxGd0DVsfi+VwC2y3MJxU8kQ22g6Vj83jkA2+UN8AM4IVmaAXnH4nadl8w1zX+Q6Slp5pE2DaWN2wdgu3wEuiRfXWnr9gDYLp+BS9KjS2lz/DFAaKbJvF8Nx+JqYwDSn7qkWxXH4tvaAGS0H6KGcmGzgxExzz8kdLTfdIo8DVonhA2CLYXMz6fI1koRIMvbAWqqsLhsNgI2Nj8PuLbfx94h699ALXaBssLmEW/lwAiQf//XHre0h9IYeDWPAn8EFDUwj3gsBnWBJvqo+aQLyBneBL2UcSym8wgooZ9K/i5Q1xBAHcCQc/sZeurExEta6KozEy9Lo6tyJl6qSlcVjgCOXcDL0uqqcxPIaAwgY6K5TA33AH5NTLzKDF11b6LO0fcmGpqoewC6igZHAMcuACONAYxMqcPraWi+51g8zhdCHQ0BdOYLIYC+hgD6/wBIBWZPs/Cf+iMAQrKniqrl3wvMdYOXNlJdY/H6FIDkymoaAKhFZYev8VLIqupOPBIIQMhUFQZQXSyu/u9ARCoo2gqabwcVVYedCDVRK1s0IyT7HQhAqqnyCgHIh1WSh54JSl1dRQHzlagK8shDUamwbKTYfCOqSnQpAIFwBVyk0PzFsjphWOPCRMqKphurmF8LgEBIQ/F0ZVnYbwxAIOh7ZcY3O5wmbLHUxiuGvl33Re2vzcXKDcqHs8C7PW+lx/LNbBzzsSNgIRr0vDobAkO/y9MRMBJ9ff4vhV3btM/DqFkAAAAASUVORK5CYII=');
var greenDotOverlay = greenDot.createOverlay(
	{'scale':
		{'magnitude': 0.15, 'reference': gapi.hangout.av.effects.ScaleReference.WIDTH}});

var yellowDot = gapi.hangout.av.effects.createImageResource('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90BDwMXCA5pLkoAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAuFJREFUeNrtmyts21AUhj97BiPVCiZLBUVzpAVUKykuqca2gLDgsoVNKwoMDWtZ8NhAFloSXJJpIJXmooJIVkCjkoFbbcAnk5vZzsN52Pfml8yS+P5fzn2ecy3WrMB3XgAHQBk4lqcMHAKvAQU8APfAAOjLMwCGrqee1tk+a02mXwGnwDnwIePPdYE20HM9Nc4tgMB3LOAEaKzAdBqMJnDjeupPLgCI8TPgq4T0JjQCasB1VhBWRvPvgG/AG7ajO6DqeurHRgEEvvNSQvEz+VALaLie+r12AIHvvAV+Ag75kgKOXE/dLvIle0HzH2V6ypt5pE0DaePqAQS+8wnokH91pK2rAxD4zhfgkuLoUtqcfQwQmkUyH1Xd9dTV0gCkP3Uotiqup74vDEBG+wF6qJw0O1gp8/xjTkf7ZafIvbh1QtIg2NTI/GSKbM4VAbK87aOnjqeXzVbMxubXFtf2m9g7lKIbqOkucKaxecTbWWwEyL8fbHBLuy2NAHcSBdEIODHAPOLxJK4LNDBHjWddQM7wHjBL+66nxpMIOMU8nUa7wLmBAM4BLDm3V5gpxyZMWpiqA5swS2OqyjZhqspUHe8A7LpAmKU1VYc2sG8wgH0bw2UbuAeI6sEmrMwwVfc2+hx9L6OBjb4HoPOovwOw6wIwNBjA0JY6vK6B5ruup54mC6G2gQDak4UQQM9AAL1/AKQCs2tY+I+jEQAJ2VNN1YzuBSa6IUwb6a6ReH0OQHJlNQMA1NKyw9eEKWRddSceiQUgZKoaA6hOF1f/dyAiFRQtDc234oqqd0VScZ+WDx5p9O8fJVWSJ54JSl1dRQPzlbQK8tRDUamwrBfYfD2tSnQmAIFwBVwU0PzFrDrhxEEwYWAsUtF0fR7zCwEQCEUonq7MCvulAQgEc6/MRGaHvZwtlloyz98u+kXjr81lyg3Ki0vA+w1vpUfyzlIW85kjYCoazLw6mwDDvMvTKTByfX3+L4KL/xorzXR/AAAAAElFTkSuQmCC');
	var yellowDotOverlay = yellowDot.createOverlay(
	{'scale':
		{'magnitude': 0.15, 'reference': gapi.hangout.av.effects.ScaleReference.WIDTH}});

var buttonDisabled = false;	//true when button is clicked to prevent joining the queue several times

gapi.hangout.onApiReady.add(function(eventObj){
	if (eventObj.isApiReady) {
		buttonDisabled = false;
		participants = gapi.hangout.getEnabledParticipants();
		printParticipants();

		gapi.hangout.onParticipantsChanged.add(onParticipantsChange);
		gapi.hangout.data.onStateChanged.add(onDataChange);

		setInterval(updateTimeOutText, 200);
	}
});

function onParticipantsChange(eventObj) {
	participants = eventObj.participants;

	onServerUpdate();
};

function onDataChange (eventObj){
	var state = gapi.hangout.data.getState();
	queue = JSON.parse(state.queue);
	try{
		timeOut = JSON.parse((state.timeOut) ? state.timeOut : -1);
	}
	catch (e){
		console.log(e);
		timeOut = -1;
	}

	onServerUpdate();
}

function onServerUpdate(){
	console.log("onServerUpdate called");
	buttonDisabled = false;
	printParticipants();
	clearOverlay();
	var queuePosition = queue.indexOf(gapi.hangout.getParticipantId());
	if (queuePosition == 0){
		placeGreenDot();
		document.getElementById('queueButton').innerHTML = "End Early";
	}
	else if (queuePosition > 0){
		placeYellowDot();
		document.getElementById('queueButton').innerHTML = "Leave Queue";
	}
	else{
		document.getElementById('queueButton').innerHTML = "Raise Hand";
	}

	//lowest order participant manages time updates
	//and checks for disconnected queue memembers
	if (isManager()){
		console.log("managing update...");
		var validSpeaker = false;
		var updateRequired = false;
		while (queue.length > 0 && !validSpeaker){

			var speakerInHangout = false;
			for (var i = 0; i < participants.length; i++){
				if (participants[i].id == queue[0]){
					if (!participants[i].hasAppEnabled){
						console.log("speaker doesn't have app on");
						queue.shift();
						updateRequired = true;
						speakerInHangout = true;
					}
					else{
						console.log("speaker running app");
						validSpeaker = true;
						speakerInHangout = true;
					}
				}
			}
			if (!speakerInHangout){
				console.log("speaker not in hangout");
				queue.shift();
				updateRequire = true;
			}
		}
		if (timeOut == -1 || new Date().getTime() > timeOut){
			console.log('new timeout value required');
			updateRequired = true;
		}
		if (updateRequired){
			console.log("sending new update");
			timeOut = new Date().getTime() + 1000*60;
			gapi.hangout.data.submitDelta({'queue':JSON.stringify(queue), 'timeOut': JSON.stringify(timeOut)});
		}
		//set time
	}
}

function printParticipants(){
	var members = "";
	if (queue.length > 0){
		document.getElementById('speakerName').innerHTML = getParticipantNameById(queue[0]);
		document.getElementById('speakerDisplay').style.visibility = 'visible';
	}
	else {
		document.getElementById('speakerDisplay').style.visibility = 'none';
	}
	for (var i = 1; i < queue.length; i++){
		members = members + getParticipantNameById(queue[i]) + '
';
	}
	for (var i = 0; i < participants.length; i++){
		if (queue.indexOf(participants[i].id) == -1){
			members = members + participants[i].person.displayName + '
';
		}
	}
	document.getElementById('otherParticipants').innerHTML = members;
}

function getParticipantNameById(id){
	for (var i = 0; i < participants.length; i++){
		if (participants[i].id == id){
			return participants[i].person.displayName;
		}
	}
	return '';
}

function buttonClick(){
	if (!buttonDisabled){
		buttonDisabled = true;
		var queuePosition = queue.indexOf(gapi.hangout.getParticipantId());
		if (queuePosition == 0){
			queue.shift();
			gapi.hangout.data.submitDelta({'queue':JSON.stringify(queue)});
		}
		else if (queuePosition == -1){
			queue.push(gapi.hangout.getParticipantId());
			gapi.hangout.data.submitDelta({'queue':JSON.stringify(queue), 'timeOut':JSON.stringify(new Date().getTime() + 1000*60)});
		}
	}
}

function placeGreenDot(){
	greenDotOverlay.setPosition(.4, -.35);
	greenDotOverlay.setVisible(true);
}

function placeYellowDot(){
	yellowDotOverlay.setPosition(.4, -.35);
	yellowDotOverlay.setVisible(true);
}

function clearOverlay(){
	greenDotOverlay.setVisible(false);
	yellowDotOverlay.setVisible(false);
}

function isManager(){
	return (participants[0].id == gapi.hangout.getParticipantId());
}

//what happens if manager is alt tabbed?
function updateTimeOutText(){
	if (timeOut != -1 && queue.length > 0){
		var timeDif = timeOut - new Date().getTime();
		document.getElementById('timeLeft').innerHTML = '  - ' + Math.max(0, Math.round(timeDif/1000)) + ' secounds';
		if (isManager && timeDif < 0 || timeDif < 2000){
			console.log("Time up!");
			//force update iff queue is empty
			if (queue.length > 1){
				queue.shift();
			}
			timeOut = new Date().getTime() + 1000*60;
			gapi.hangout.data.submitDelta({'queue':JSON.stringify(queue), 'timeOut': JSON.stringify(timeOut)});
		}
	}
	else{
		document.getElementById('timeLeft').innerHTML = '';
	}
}<|endoftext|>


<commit_before>'use strict';
const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
const fs = require('fs');

module.exports = Generator.extend({
    initializing() {
        this.log(yosay(
            'Welcome to the prime ' + chalk.red('generator-neptun react component') + ' generator!'
        ));
    },

    default() {
        this.fs.copy(
            this.templatePath('./root/**'),
            this.destinationPath('.'),
            {
                globOptions: {
                    dot: true
                }
            }
        );

        this.fs.copy(
            this.templatePath('./package.template.json'),
            this.destinationPath('./package.json')
        );

        this.fs.copy(
            this.templatePath('./gitignore.template'),
            this.destinationPath('./.gitignore')
        );

        this.composeWith(require.resolve('generator-node/generators/app'), {
            babel: false,
            boilerplate: false,
            projectRoot: './',
            skipInstall: true,
            gulp: false,
            travis: false,
            git: true,
            githubAccount: 'neptunjs',
            eslint: false,
            editorconfig: false
        });
    },

    install () {

        this.yarnInstall([
            'babel-cli',
            'babel-core',
            'babel-loader',
            'babel-preset-env',
            'babel-preset-react',
            'eslint',
            'eslint-config-cheminfo',
            'eslint-config-neptun-react',
            'eslint-plugin-no-only-tests',
            'eslint-plugin-react',
            'jest-cli',
            'npm-run-all',
            'react',
            'react-dom',
            'react-test-renderer',
            'webpack',
            'webpack-dev-server'
        ], {dev: true});

        this.yarnInstall([
            'react',
            'react-dom'
        ], {peer: true});
    },

    end() {
        // remove generator-node's eslint config and dependencies
        const pkgPath = this.destinationPath('.', 'package.json');
        const pkg = JSON.parse(fs.readFileSync(pkgPath));
        delete pkg.eslintConfig;
        delete pkg.devDependencies['eslint-config-xo-space'];
        fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, '    '));

        // remove useless files
        fs.unlinkSync(this.destinationPath('.gitattributes'));
        fs.unlinkSync(this.destinationPath('.editorconfig'));
    }
});
<commit_msg>try to fix gitignore generation<commit_after>'use strict';
const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
const fs = require('fs');

module.exports = Generator.extend({
    initializing() {
        this.log(yosay(
            'Welcome to the prime ' + chalk.red('generator-neptun react component') + ' generator!'
        ));
    },

    default() {
        this.fs.copy(
            this.templatePath('./root/**'),
            this.destinationPath('.'),
            {
                globOptions: {
                    dot: true
                }
            }
        );

        this.fs.copy(
            this.templatePath('./package.template.json'),
            this.destinationPath('./package.json')
        );

        this.composeWith(require.resolve('generator-node/generators/app'), {
            babel: false,
            boilerplate: false,
            projectRoot: './',
            skipInstall: true,
            gulp: false,
            travis: false,
            git: true,
            githubAccount: 'neptunjs',
            eslint: false,
            editorconfig: false
        });

        this.fs.copy(
            this.templatePath('./gitignore.template'),
            this.destinationPath('./.gitignore')
        );
    },

    install () {

        this.yarnInstall([
            'babel-cli',
            'babel-core',
            'babel-loader',
            'babel-preset-env',
            'babel-preset-react',
            'eslint',
            'eslint-config-cheminfo',
            'eslint-config-neptun-react',
            'eslint-plugin-no-only-tests',
            'eslint-plugin-react',
            'jest-cli',
            'npm-run-all',
            'react',
            'react-dom',
            'react-test-renderer',
            'webpack',
            'webpack-dev-server'
        ], {dev: true});

        this.yarnInstall([
            'react',
            'react-dom'
        ], {peer: true});
    },

    end() {
        // remove generator-node's eslint config and dependencies
        const pkgPath = this.destinationPath('.', 'package.json');
        const pkg = JSON.parse(fs.readFileSync(pkgPath));
        delete pkg.eslintConfig;
        delete pkg.devDependencies['eslint-config-xo-space'];
        fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, '    '));

        // remove useless files
        fs.unlinkSync(this.destinationPath('.gitattributes'));
        fs.unlinkSync(this.destinationPath('.editorconfig'));
    }
});
<|endoftext|>


<commit_before>var _ = require('lodash'),
	acorn = require('acorn'),
	async = require('async'),
	chalk = require('chalk'),
	constants = require('./constants'),
	fs = require('fs-extra'),
	path = require('path'),
	readline = require('readline'),
	request = require('request'),
	server = require('./server'),
	spinner = require('char-spinner'),
	tiappXml = require('tiapp.xml'),
	titanium = require('./titanium'),
	util = require('./util');

var DEFAULTS = {
	PROJECT: '_tmp',
	ID: 'triple.tmpapp'
};

var error = chalk.bold.red,
	warn = chalk.bold.yellow.
	requireRE = /\brequire\s*\(['"](([\w\.\/-]+\/)?([\w\.\/-]*))/,
	simpleExpressionRE = /(([a-zA-Z_$](?:\w|\$)*)\.)*([a-zA-Z_$](?:\w|\$)*)\.?$/,
	tabCompletionNS = {};

module.exports = function(opts, callback) {
	var buffer = [];

	callback = arguments[arguments.length-1];
	if (!opts || _.isFunction(opts)) {
		opts = {};
	}

	if (opts.verbose) {
		titanium.verbose = true;
	}

	var rl = readline.createInterface({
		input: process.stdin,
		output: process.stdout,
		completer: tabCompletion(rl)
	});

	async.series([

		// make sure we're logged in
		function(cb) {
			titanium.loggedIn(function(err, loggedIn) {
				if (err) {
					return cb('error checking status: ' + err);
				} else if (!loggedIn) {
					return cb('You must be logged in to use triple. Use `titanium login`.');
				}
				return cb();
			});
		},

		// setup titanium completion database
		function (cb) {
			titanium.sdk(function(err,sdk, version, info){
				var cacheFile = path.join(sdk.path,'triple.cache');
				if (fs.existsSync(cacheFile)) {
					return fs.readFile(cacheFile, function(err,contents){
						contents && (tabCompletionSetup(JSON.parse(contents.toString())));
						cb(err);
					});
				}
				var interval = spinner();
				fs.readFile(path.join(sdk.path,'api.jsca'), function(err,buf){
					if (err) {
						clearInterval(interval);
						console.warn(warn('warn: could not find api.jsca file, auto-complete disabled'));
						return cb();
					}
					var tabCompletionDB = [];
					JSON.parse(buf.toString()).types.forEach(function(entry){
						tabCompletionDB.push(entry.name);
						entry.properties && entry.properties.forEach(function(prop){
							tabCompletionDB.push(entry.name+'.'+prop.name);
						});
						entry.functions && entry.functions.forEach(function(fn){
							tabCompletionDB.push(entry.name+'.'+fn.name);
						});
					});
					fs.writeFile(cacheFile, JSON.stringify(tabCompletionDB), function(err){
						clearInterval(interval);
						tabCompletionSetup(tabCompletionDB);
						cb(err);
					});
				});
			});
		},

		// create the repl project
		function(cb) {
			if (!fs.existsSync(DEFAULTS.PROJECT)) {
				console.log('[creating app]');
				var interval = spinner();
				var createOpts = _.defaults(opts.create || {}, {
					name: DEFAULTS.PROJECT,
					id: DEFAULTS.ID,
					logLevel: 'error'
				});
				titanium.create(createOpts, function(err, results) {
					clearInterval(interval);
					cb(err, results);
				});
			} else {
				cb();
			}
		},

		// prep app
		function(cb) {
			var resources = path.join(DEFAULTS.PROJECT, 'Resources'),
				app = path.join(__dirname, '..', 'app');

			// copy in all app files
			fs.readdirSync(app).forEach(function(file) {
				copy(path.join(app, file), path.join(resources, file));
			});

			// copy in shared constants file
			copy(path.join(__dirname, 'constants.js'), path.join(resources, 'constants.js'));

			cb();
		},

		// update tiapp.xml
		function(cb) {

			var tiapp = tiappXml.load(path.resolve(DEFAULTS.PROJECT, 'tiapp.xml'));

			// load native modules
			if(opts.module) {
				opts.module.forEach(function(id) {
					console.log('[Injecting module: %s]', id);
					tiapp.setModule(id);
				});
			}

			// write changes
			tiapp.write();

			cb();
		},

		// // start up repl server
		function(cb) {
			server.on('end', function(data) {
				return cb(data);
			});
			server.listen(constants.PORT, cb);
		},

		// build the repl project
		function(cb) {
			console.log('[launching app]');
			var interval = spinner();
			var buildOpts = _.defaults(opts.build || {}, {
				projectDir: DEFAULTS.PROJECT,
				platform: 'ios',
				iosVersion: '7.1',
				noSimFocus: true,
				server: server
			});
			titanium.build(buildOpts);
			server.on('ready', function() {
				clearInterval(interval);
				cb();
			});
		},

		// prompt
		function(cb) {

			// clear spinner and prompt
			process.stdout.write('\r \r');
			rl.setPrompt(constants.PROMPT);
			rl.prompt();

			// handle each line of input
			rl.on('line', function(line) {
				var match;

				// skip empty lines
				if (!line) {
					rl.prompt();
					return;

				// handle triple commands
				} else if (match = line.match(/^\s*(\.\w*)(?:\s|$)/)) {
					var args = match.input.trim().split(/\s+/).slice(1);

					// don't put triple commands on history
					rl.history.shift();

					// execute the command
					switch(match[1].substring(1)) {
						case 'add':

							// usage: .add file1 file2 file3 ...
							for (var i = 0; i < args.length; i++) {
								util.addToApp(args[i]);
							}
							break;
						case 'break':
							buffer = [];
							rl.setPrompt(constants.PROMPT);
							break;
						case 'clear':
							server.emit('message', constants.CLEAR_MESSAGE);
							break;
						case 'load':
							load(args, rl);
							break;
						case 'exit':
							return cb();
						case 'save':
							var file = args[0];
							if (!file) {
								console.error(error('must specify path for save'));
							} else {
								fs.ensureDir(path.dirname(file));
								fs.writeFileSync(file, rl.history.slice(0).reverse().join('\n'));
							}
							break;
						default:
							console.error(error('invalid command "' + match[1] + '"'));
							break;
					}
					rl.prompt();

				// process code
				} else {
					try {

						// handle requires
						var requireRE = /(\brequire\s*\(\s*['"])([^'"]+)(['"]\s*\))/;

						// if it contains a require(), but isn't a native require
						if ((match = line.match(requireRE)) && !_.contains(opts.module, match[1])) {
							var moduleId = match[2],
								modulePath;

							// get absolute path
							if (moduleId.indexOf('/') === 0) {
								modulePath = moduleId;
							} else {
								modulePath = path.join(process.cwd(), moduleId);
							}

							// .add it
							var addPath = modulePath + (!/\.js$/.test(modulePath) ? '.js' : '');
							util.addToApp(addPath);

							// modify the line before sending it to the app
							line = line.substring(0, match.index) + match[1] + '__modules' + modulePath +
								match[3] + line.substring(match.index + match[0].length);

						}

						// assemble code from buffer
						buffer.push(line);
						var code = buffer.join('\n');

						// validate the buffered code
						acorn.parse(code);

						// send code to server
						server.emit('message', code);

						// reset buffer and prompt
						buffer = [];
						rl.setPrompt(constants.PROMPT);
					} catch (e) {
						console.error('sdsdfsdfdsf');
						console.error(e.stack);

						// prompt for multi-line statement
						rl.setPrompt(constants.CONTINUE_PROMPT);
						rl.prompt();
					}
				}

			});

			// handle CTRL+C
			rl.on('SIGINT', function() {

				// If we're in a multi-line statement, break out of it
				if (buffer.length) {
					buffer = [];
					console.log('\n(^C again to quit)');
					rl.setPrompt(constants.PROMPT);
					rl.prompt();

				// quit
				} else {
					cb();
				}
			});

			// do we have a file to load?
			if (opts.args && opts.args.length) {
				load(opts.args, rl);
			}

		}

	], callback);
};

function copy(src, dst) {
	fs.writeFileSync(dst, fs.readFileSync(src));
}

function sendLoadCommand(rl, location, content, delay) {
	try {
		acorn.parse(content);
	} catch (err) {
		console.error(error('error parsing "' + location + '"'));
		console.error(err);
		return rl.prompt();
	}

	var tasks = [];
	content.split('\n').forEach(function(line){
		line = line.trim();
		if (line) {
			tasks.push(function(next){
				setTimeout(function(){
					rl.write(line + '\n');
					next();
				}, delay || 25);
			});
		}
	});
	return async.series(tasks);
}

function load(tokens, rl) {
	var location = tokens[0],
		delay = tokens[1] || 0;

	// looks like a url, fetch it
	if (/^https?:\/\//.test(location)) {
		var interval = spinner();
		return request(location, function(err,content) {
			clearInterval(interval);
			if (err) {
				console.error(error('error loading "' + location + '"'));
				console.error(error(err));
				rl.prompt();
				return;
			}
			sendLoadCommand(rl, location, content.body, delay);
		});

	// probably a file
	} else {
		if (fs.existsSync(location)) {
			return sendLoadCommand(rl, location, fs.readFileSync(location).toString(), delay);
		}
	}

	console.error(error('not sure how to load "' + location + '". does it exist?'));
	rl.prompt();
}

function tabCompletionSetup(tabCompletionDB) {
	if (tabCompletionDB && tabCompletionDB.length) {
		tabCompletionDB.forEach(function(name){
			var tokens = name.split('.'),
				obj = tabCompletionNS;
			for (var c=0;c<tokens.length;c++){
				var cname = tokens[c];
				var entry = obj[cname];
				if (!entry) {
					obj[cname] = entry = {};
				}
				obj = entry;
			}
		});
		tabCompletionDB = null;
		tabCompletionNS.Ti = tabCompletionNS.Titanium;
	}
}

function tabCompletion(rl) {
	return function(line) {

		var match = line.match(simpleExpressionRE);
		line = match[0];

		var tokens = line.split('.'),
			obj = tabCompletionNS,
			hits = [];

		for (var c=0;c<tokens.length;c++) {
			var token = tokens[c];
			if (token) {
				var entry = obj[token];
				if (!entry) {
					hits = Object.keys(obj).filter(function(e){
						return e.indexOf(token)===0;
					});
					obj = null;
					line = token;
					break;
				}
				obj = entry;
			}
		}

		if (obj) {
			hits = Object.keys(obj);
		}

		return [!hits.length && !line ? Object.keys(tabCompletionNS) : hits, line];
	};
}
<commit_msg>cleanup<commit_after>var _ = require('lodash'),
	acorn = require('acorn'),
	async = require('async'),
	chalk = require('chalk'),
	constants = require('./constants'),
	fs = require('fs-extra'),
	path = require('path'),
	readline = require('readline'),
	request = require('request'),
	server = require('./server'),
	spinner = require('char-spinner'),
	tiappXml = require('tiapp.xml'),
	titanium = require('./titanium'),
	util = require('./util');

var DEFAULTS = {
	PROJECT: '_tmp',
	ID: 'triple.tmpapp'
};

var error = chalk.bold.red,
	warn = chalk.bold.yellow.
	requireRE = /\brequire\s*\(['"](([\w\.\/-]+\/)?([\w\.\/-]*))/,
	simpleExpressionRE = /(([a-zA-Z_$](?:\w|\$)*)\.)*([a-zA-Z_$](?:\w|\$)*)\.?$/,
	tabCompletionNS = {};

module.exports = function(opts, callback) {
	var buffer = [];

	callback = arguments[arguments.length-1];
	if (!opts || _.isFunction(opts)) {
		opts = {};
	}

	if (opts.verbose) {
		titanium.verbose = true;
	}

	var rl = readline.createInterface({
		input: process.stdin,
		output: process.stdout,
		completer: tabCompletion(rl)
	});

	async.series([

		// make sure we're logged in
		function(cb) {
			titanium.loggedIn(function(err, loggedIn) {
				if (err) {
					return cb('error checking status: ' + err);
				} else if (!loggedIn) {
					return cb('You must be logged in to use triple. Use `titanium login`.');
				}
				return cb();
			});
		},

		// setup titanium completion database
		function (cb) {
			titanium.sdk(function(err,sdk, version, info){
				var cacheFile = path.join(sdk.path,'triple.cache');
				if (fs.existsSync(cacheFile)) {
					return fs.readFile(cacheFile, function(err,contents){
						contents && (tabCompletionSetup(JSON.parse(contents.toString())));
						cb(err);
					});
				}
				var interval = spinner();
				fs.readFile(path.join(sdk.path,'api.jsca'), function(err,buf){
					if (err) {
						clearInterval(interval);
						console.warn(warn('warn: could not find api.jsca file, auto-complete disabled'));
						return cb();
					}
					var tabCompletionDB = [];
					JSON.parse(buf.toString()).types.forEach(function(entry){
						tabCompletionDB.push(entry.name);
						entry.properties && entry.properties.forEach(function(prop){
							tabCompletionDB.push(entry.name+'.'+prop.name);
						});
						entry.functions && entry.functions.forEach(function(fn){
							tabCompletionDB.push(entry.name+'.'+fn.name);
						});
					});
					fs.writeFile(cacheFile, JSON.stringify(tabCompletionDB), function(err){
						clearInterval(interval);
						tabCompletionSetup(tabCompletionDB);
						cb(err);
					});
				});
			});
		},

		// create the repl project
		function(cb) {
			if (!fs.existsSync(DEFAULTS.PROJECT)) {
				console.log('[creating app]');
				var interval = spinner();
				var createOpts = _.defaults(opts.create || {}, {
					name: DEFAULTS.PROJECT,
					id: DEFAULTS.ID,
					logLevel: 'error'
				});
				titanium.create(createOpts, function(err, results) {
					clearInterval(interval);
					cb(err, results);
				});
			} else {
				cb();
			}
		},

		// prep app
		function(cb) {
			var resources = path.join(DEFAULTS.PROJECT, 'Resources'),
				app = path.join(__dirname, '..', 'app');

			// copy in all app files
			fs.readdirSync(app).forEach(function(file) {
				copy(path.join(app, file), path.join(resources, file));
			});

			// copy in shared constants file
			copy(path.join(__dirname, 'constants.js'), path.join(resources, 'constants.js'));

			cb();
		},

		// update tiapp.xml
		function(cb) {

			var tiapp = tiappXml.load(path.resolve(DEFAULTS.PROJECT, 'tiapp.xml'));

			// load native modules
			if(opts.module) {
				opts.module.forEach(function(id) {
					console.log('[Injecting module: %s]', id);
					tiapp.setModule(id);
				});
			}

			// write changes
			tiapp.write();

			cb();
		},

		// // start up repl server
		function(cb) {
			server.on('end', function(data) {
				return cb(data);
			});
			server.listen(constants.PORT, cb);
		},

		// build the repl project
		function(cb) {
			console.log('[launching app]');
			var interval = spinner();
			var buildOpts = _.defaults(opts.build || {}, {
				projectDir: DEFAULTS.PROJECT,
				platform: 'ios',
				iosVersion: '7.1',
				noSimFocus: true,
				server: server
			});
			titanium.build(buildOpts);
			server.on('ready', function() {
				clearInterval(interval);
				cb();
			});
		},

		// prompt
		function(cb) {

			// clear spinner and prompt
			process.stdout.write('\r \r');
			rl.setPrompt(constants.PROMPT);
			rl.prompt();

			// handle each line of input
			rl.on('line', function(line) {
				var match;

				// skip empty lines
				if (!line) {
					rl.prompt();
					return;

				// handle triple commands
				} else if (match = line.match(/^\s*(\.\w*)(?:\s|$)/)) {
					var args = match.input.trim().split(/\s+/).slice(1);

					// don't put triple commands on history
					rl.history.shift();

					// execute the command
					switch(match[1].substring(1)) {
						case 'add':
							for (var i = 0; i < args.length; i++) {
								util.addToApp(args[i]);
							}
							break;
						case 'break':
							buffer = [];
							rl.setPrompt(constants.PROMPT);
							break;
						case 'clear':
							server.emit('message', constants.CLEAR_MESSAGE);
							break;
						case 'load':
							load(args, rl);
							break;
						case 'exit':
							return cb();
						case 'save':
							var file = args[0];
							if (!file) {
								console.error(error('must specify path for save'));
							} else {
								fs.ensureDir(path.dirname(file));
								fs.writeFileSync(file, rl.history.slice(0).reverse().join('\n'));
							}
							break;
						default:
							console.error(error('invalid command "' + match[1] + '"'));
							break;
					}
					rl.prompt();

				// process code
				} else {
					try {

						// handle requires
						var requireRE = /(\brequire\s*\(\s*['"])([^'"]+)(['"]\s*\))/;

						// if it contains a require(), but isn't a native require
						if ((match = line.match(requireRE)) && !_.contains(opts.module, match[1])) {
							var moduleId = match[2],
								modulePath;

							// get absolute path
							if (moduleId.indexOf('/') === 0) {
								modulePath = moduleId;
							} else {
								modulePath = path.join(process.cwd(), moduleId);
							}

							// .add it
							var addPath = modulePath + (!/\.js$/.test(modulePath) ? '.js' : '');
							util.addToApp(addPath);

							// modify the line before sending it to the app
							line = line.substring(0, match.index) + match[1] + '__modules' + modulePath +
								match[3] + line.substring(match.index + match[0].length);

						}

						// assemble code from buffer
						buffer.push(line);
						var code = buffer.join('\n');

						// validate the buffered code
						acorn.parse(code);

						// send code to server
						server.emit('message', code);

						// reset buffer and prompt
						buffer = [];
						rl.setPrompt(constants.PROMPT);
					} catch (e) {
						console.error('sdsdfsdfdsf');
						console.error(e.stack);

						// prompt for multi-line statement
						rl.setPrompt(constants.CONTINUE_PROMPT);
						rl.prompt();
					}
				}

			});

			// handle CTRL+C
			rl.on('SIGINT', function() {

				// If we're in a multi-line statement, break out of it
				if (buffer.length) {
					buffer = [];
					console.log('\n(^C again to quit)');
					rl.setPrompt(constants.PROMPT);
					rl.prompt();

				// quit
				} else {
					cb();
				}
			});

			// do we have a file to load?
			if (opts.args && opts.args.length) {
				load(opts.args, rl);
			}

		}

	], callback);
};

function copy(src, dst) {
	fs.writeFileSync(dst, fs.readFileSync(src));
}

function sendLoadCommand(rl, location, content, delay) {
	try {
		acorn.parse(content);
	} catch (err) {
		console.error(error('error parsing "' + location + '"'));
		console.error(err);
		return rl.prompt();
	}

	var tasks = [];
	content.split('\n').forEach(function(line){
		line = line.trim();
		if (line) {
			tasks.push(function(next){
				setTimeout(function(){
					rl.write(line + '\n');
					next();
				}, delay || 25);
			});
		}
	});
	return async.series(tasks);
}

function load(tokens, rl) {
	var location = tokens[0],
		delay = tokens[1] || 0;

	// looks like a url, fetch it
	if (/^https?:\/\//.test(location)) {
		var interval = spinner();
		return request(location, function(err,content) {
			clearInterval(interval);
			if (err) {
				console.error(error('error loading "' + location + '"'));
				console.error(error(err));
				rl.prompt();
				return;
			}
			sendLoadCommand(rl, location, content.body, delay);
		});

	// probably a file
	} else {
		if (fs.existsSync(location)) {
			return sendLoadCommand(rl, location, fs.readFileSync(location).toString(), delay);
		}
	}

	console.error(error('not sure how to load "' + location + '". does it exist?'));
	rl.prompt();
}

function tabCompletionSetup(tabCompletionDB) {
	if (tabCompletionDB && tabCompletionDB.length) {
		tabCompletionDB.forEach(function(name){
			var tokens = name.split('.'),
				obj = tabCompletionNS;
			for (var c=0;c<tokens.length;c++){
				var cname = tokens[c];
				var entry = obj[cname];
				if (!entry) {
					obj[cname] = entry = {};
				}
				obj = entry;
			}
		});
		tabCompletionDB = null;
		tabCompletionNS.Ti = tabCompletionNS.Titanium;
	}
}

function tabCompletion(rl) {
	return function(line) {

		var match = line.match(simpleExpressionRE);
		line = match[0];

		var tokens = line.split('.'),
			obj = tabCompletionNS,
			hits = [];

		for (var c=0;c<tokens.length;c++) {
			var token = tokens[c];
			if (token) {
				var entry = obj[token];
				if (!entry) {
					hits = Object.keys(obj).filter(function(e){
						return e.indexOf(token)===0;
					});
					obj = null;
					line = token;
					break;
				}
				obj = entry;
			}
		}

		if (obj) {
			hits = Object.keys(obj);
		}

		return [!hits.length && !line ? Object.keys(tabCompletionNS) : hits, line];
	};
}
<|endoftext|>