<commit_before>$(function(){

	var height, width;

	window.options = {
		renderer: {
			name: "canvas"
		},
		layout: {
			name: "grid"
		},
		style: cytoscape.stylesheet()
			.selector("node")
				.css({
					"content": "data(id)",
					"shape": "data(shape)"
				})
			.selector("edge")
				.css({
					"width": "mapData(weight, 0, 100, 1, 5)",
					"target-arrow-shape": "triangle",
					"source-arrow-shape": "circle"
				})
			.selector(":selected")
				.css({
					"background-color": "#000",
					"line-color": "#000",
					"source-arrow-color": "#000",
					"target-arrow-color": "#000"
				})
			.selector(".ui-cytoscape-edgehandles-source")
				.css({
					"border-color": "#5CC2ED",
					"border-width": 3
				})
			.selector(".ui-cytoscape-edgehandles-target, node.ui-cytoscape-edgehandles-preview")
				.css({
					"background-color": "#5CC2ED"
				})
			.selector("edge.ui-cytoscape-edgehandles-preview")
				.css({
					"line-color": "#5CC2ED"
				})
			.selector("node.ui-cytoscape-edgehandles-preview, node.intermediate")
				.css({
					"shape": "rectangle",
					"width": 15,
					"height": 15
				})

		,
		elements: {
			nodes: [
			],

			edges: [
			]
		},
		ready: function(){
			console.log('cy ready');

			window.cy = this;
			window.$$ = cytoscape;
		}
	};

	var cliques = 2;
	var numNodes = 16;
	var numEdges = 32;

	function randNodeId( clique ){
		var min = numNodes * clique / cliques;
		var max = numNodes * (clique + 1) / cliques - (cliques == 1 ? 0 : 1);
		var rand = Math.floor( Math.random() * (max - min) + min );
		var id = "n" + rand;

		return id;
	}

	for(var i = 0; i < numNodes; i++){
		options.elements.nodes.push({
			data: {
				id: "n" + i,
				weight: Math.round( Math.random() * 100 )
			}
		});
	}

	var j = 0;
	for(var clique = 0; clique < cliques; clique++){
		for(var i = 0; i < numEdges/cliques; i++){
			var srcId = randNodeId( clique );
			var tgtId = randNodeId( clique );

			options.elements.edges.push({
				data: {
					id: "e" + (j++),
					source: srcId,
					target: tgtId,
					weight: Math.round( Math.random() * 100 )
				}
			});
		}
	}

	var $container = $("#cytoscape");
	var $container2 = $("#cytoscape2");

	$container.cy(options).cy(function(){

		height = $container.height();
		width = $container.width();

		$container.cytoscapePanzoom();

		$container.cytoscapeEdgehandles({
			lineType: "straight",
			preview: true,
			handleSize: 12,
			handleColor: "#5CC2ED",
			edgeType: function(){
				return $("#add-edge-type-select").val();
			},
			nodeParams: function(){
				return {
					classes: "intermediate"
				};
			},
			start: function( sourceNode ){
//				console.log("start(%o)", sourceNode);
			},
			complete: function( sourceNode, targetNodes, added ){
//				console.log("complete(%o, %o, %o)", sourceNode, targetNodes, added);
			},
			stop: function( sourceNode ){
//				console.log("stop(%o)", sourceNode);
			}
		});

		function number(group){
			var input = $("#" + group + "-number");
			var val = parseInt( input.val() );

			if( isNaN(val) ){
				return 0;
			}

			return val;
		}

		function time(callback){
			var start = new Date();
			callback();
			var end = new Date();

			$("#add-remove-time").html( (end - start) + " ms" );
		}

		$("#add-elements-button").click(function(){
			var n = number("nodes");
			var e = number("edges");

			var nodes = [];
			for(var i = 0; i < n; i++){
				nodes.push({
					group: "nodes",
					data: { id: "n" + (i + numNodes), weight: Math.round( Math.random() * 100 ) },
					position: { x: Math.random() * width, y: Math.random() * height }
				});
			}
			numNodes += n;

			cy.add(nodes);

			var nodesCollection = cy.nodes();
			function nodeId(){
				var index = Math.round((nodesCollection.size() - 1) * Math.random());
				return nodesCollection.eq(index).data("id");
			}

			var edges = [];
			for(var i = 0; i < e; i++){
				edges.push({
					group: "edges",
					data: {
						id: "e" + (i + numEdges),
						weight: Math.round( Math.random() * 100 ),
						source: nodeId(),
						target: nodeId()
					}
				});
			}
			numEdges += e;

			time(function(){
				cy.add(edges);
			});
		});

		$container2.cy({
			elements: {
				nodes: [ { data: { id: 'n0' } }, { data: { id: 'n1' } } ],
				edges: [ { data: { id: 'n0n1', source: 'n0', target: 'n1' } } ]
			},

			ready: function(){
				window.cy2 = this;
			}
		});

		$("#remove-elements-button").click(function(){
			var n = number("nodes");
			var e = number("edges");

			time(function(){
				cy.nodes().slice(0, n).remove();
				cy.edges().slice(0, e).remove();
			});

		});

		$("#remove-selected-button").click(function(){
			cy.elements(":selected").remove();
		});
	});

});<commit_msg>disable edgehandles for now<commit_after>$(function(){

	var height, width;

	window.options = {
		renderer: {
			name: "canvas"
		},
		layout: {
			name: "grid"
		},
		style: cytoscape.stylesheet()
			.selector("node")
				.css({
					"content": "data(id)",
					"shape": "data(shape)"
				})
			.selector("edge")
				.css({
					"width": "mapData(weight, 0, 100, 1, 5)",
					"target-arrow-shape": "triangle",
					"source-arrow-shape": "circle"
				})
			.selector(":selected")
				.css({
					"background-color": "#000",
					"line-color": "#000",
					"source-arrow-color": "#000",
					"target-arrow-color": "#000"
				})
			.selector(".ui-cytoscape-edgehandles-source")
				.css({
					"border-color": "#5CC2ED",
					"border-width": 3
				})
			.selector(".ui-cytoscape-edgehandles-target, node.ui-cytoscape-edgehandles-preview")
				.css({
					"background-color": "#5CC2ED"
				})
			.selector("edge.ui-cytoscape-edgehandles-preview")
				.css({
					"line-color": "#5CC2ED"
				})
			.selector("node.ui-cytoscape-edgehandles-preview, node.intermediate")
				.css({
					"shape": "rectangle",
					"width": 15,
					"height": 15
				})

		,
		elements: {
			nodes: [
			],

			edges: [
			]
		},
		ready: function(){
			console.log('cy ready');

			window.cy = this;
			window.$$ = cytoscape;
		}
	};

	var cliques = 2;
	var numNodes = 16;
	var numEdges = 32;

	function randNodeId( clique ){
		var min = numNodes * clique / cliques;
		var max = numNodes * (clique + 1) / cliques - (cliques == 1 ? 0 : 1);
		var rand = Math.floor( Math.random() * (max - min) + min );
		var id = "n" + rand;

		return id;
	}

	for(var i = 0; i < numNodes; i++){
		options.elements.nodes.push({
			data: {
				id: "n" + i,
				weight: Math.round( Math.random() * 100 )
			}
		});
	}

	var j = 0;
	for(var clique = 0; clique < cliques; clique++){
		for(var i = 0; i < numEdges/cliques; i++){
			var srcId = randNodeId( clique );
			var tgtId = randNodeId( clique );

			options.elements.edges.push({
				data: {
					id: "e" + (j++),
					source: srcId,
					target: tgtId,
					weight: Math.round( Math.random() * 100 )
				}
			});
		}
	}

	var $container = $("#cytoscape");
	var $container2 = $("#cytoscape2");

	$container.cy(options).cy(function(){

		height = $container.height();
		width = $container.width();

		$container.cytoscapePanzoom();

// 		$container.cytoscapeEdgehandles({
// 			lineType: "straight",
// 			preview: true,
// 			handleSize: 12,
// 			handleColor: "#5CC2ED",
// 			edgeType: function(){
// 				return $("#add-edge-type-select").val();
// 			},
// 			nodeParams: function(){
// 				return {
// 					classes: "intermediate"
// 				};
// 			},
// 			start: function( sourceNode ){
// //				console.log("start(%o)", sourceNode);
// 			},
// 			complete: function( sourceNode, targetNodes, added ){
// //				console.log("complete(%o, %o, %o)", sourceNode, targetNodes, added);
// 			},
// 			stop: function( sourceNode ){
// //				console.log("stop(%o)", sourceNode);
// 			}
// 		});

		function number(group){
			var input = $("#" + group + "-number");
			var val = parseInt( input.val() );

			if( isNaN(val) ){
				return 0;
			}

			return val;
		}

		function time(callback){
			var start = new Date();
			callback();
			var end = new Date();

			$("#add-remove-time").html( (end - start) + " ms" );
		}

		$("#add-elements-button").click(function(){
			var n = number("nodes");
			var e = number("edges");

			var nodes = [];
			for(var i = 0; i < n; i++){
				nodes.push({
					group: "nodes",
					data: { id: "n" + (i + numNodes), weight: Math.round( Math.random() * 100 ) },
					position: { x: Math.random() * width, y: Math.random() * height }
				});
			}
			numNodes += n;

			cy.add(nodes);

			var nodesCollection = cy.nodes();
			function nodeId(){
				var index = Math.round((nodesCollection.size() - 1) * Math.random());
				return nodesCollection.eq(index).data("id");
			}

			var edges = [];
			for(var i = 0; i < e; i++){
				edges.push({
					group: "edges",
					data: {
						id: "e" + (i + numEdges),
						weight: Math.round( Math.random() * 100 ),
						source: nodeId(),
						target: nodeId()
					}
				});
			}
			numEdges += e;

			time(function(){
				cy.add(edges);
			});
		});

		$container2.cy({
			elements: {
				nodes: [ { data: { id: 'n0' } }, { data: { id: 'n1' } } ],
				edges: [ { data: { id: 'n0n1', source: 'n0', target: 'n1' } } ]
			},

			ready: function(){
				window.cy2 = this;
			}
		});

		$("#remove-elements-button").click(function(){
			var n = number("nodes");
			var e = number("edges");

			time(function(){
				cy.nodes().slice(0, n).remove();
				cy.edges().slice(0, e).remove();
			});

		});

		$("#remove-selected-button").click(function(){
			cy.elements(":selected").remove();
		});
	});

});<|endoftext|>


<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2013 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License along with this program.  If not, see http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc directive
     * @name openlmis.administration.disableDrag
     *
     * @description
     * Disable drag action on html elements i.e. inputs.
     *
     */
    angular.module('admin-template').directive('disableDrag', disableDrag);

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

        function link(scope, element) {
            element.on('focus', function(event) {
                var draggableElements = angular.element("[dnd-draggable]");
                angular.forEach(draggableElements, function(el) {
                    angular.element(el).attr("draggable", false);
                });
            });
            element.on('blur', function(event) {
                var draggableElements = angular.element("[dnd-draggable]");
                angular.forEach(draggableElements, function(el) {
                    angular.element(el).attr("draggable", true);
                });
            });
        }
    }

})();
<commit_msg>OLMIS-1469: Fixed JSDocs in disable-drag.directive.js<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2013 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License along with this program.  If not, see http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc directive
     * @name admin-template.disableDrag
     *
     * @description
     * Disable drag action on html elements i.e. inputs.
     *
     */
    angular.module('admin-template').directive('disableDrag', disableDrag);

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

        function link(scope, element) {
            element.on('focus', function(event) {
                var draggableElements = angular.element("[dnd-draggable]");
                angular.forEach(draggableElements, function(el) {
                    angular.element(el).attr("draggable", false);
                });
            });
            element.on('blur', function(event) {
                var draggableElements = angular.element("[dnd-draggable]");
                angular.forEach(draggableElements, function(el) {
                    angular.element(el).attr("draggable", true);
                });
            });
        }
    }

})();
<|endoftext|>


<commit_before>var http = require('http')
  , url = require('url')

var memento = require('memento-client')
  , request = require('hyperquest')

var timeNear = require('./lib/time-near')

var WAYBACK_HOST = 'web.archive.org'
  , isAsset = /\/web\/\d{14}/

module.exports = peabody

function peabody(timestamp, fuzz) {
  return http.createServer(handler)

  function handler(req, res) {
    var assetUrl

    if(!isAsset.test(req.url)) {
      return memento(req.url, timestamp, checkSites)
    }

    assetUrl = url.format({
        host: WAYBACK_HOST
      , pathname: url.parse(req.url).path
      , protocol: 'http'
    })

    request.get(assetUrl, assetRespond)

    function checkSites(err, sites) {
      var noSites = sites.length < 2

      if(err || noSites || !timeNear(sites[1].datetime, timestamp, fuzz)) {
        return notFound(res)
      }

      request.get(sites[1].href, respond)
    }

    function respond(err, response) {
      if(err) {
        return notFound(res)
      }

      response.pipe(res)
      res.writeHead(response.statusCode, response.headers)
    }

    function assetRespond(err, response) {
      if(err) {
        return notFound(res)
      }

      var assetUrl

      if(response.statusCode === 302) {
        assetUrl = url.format({
            host: WAYBACK_HOST
          , pathname: response.headers.location
          , protocol: 'http'
        })

        return request.get(assetUrl, assetRespond)
      }

      res.writeHead(response.statusCode, response.headers)

      if(response.statusCode < 200 || response.statusCode > 299) {
        res.end()
      }

      response.pipe(res)
    }
  }
}

function notFound(res) {
  res.writeHead(404, {'content-type': 'text/plain'})

  res.end('Site not available')
}
<commit_msg>fix minor bug<commit_after>var http = require('http')
  , url = require('url')

var memento = require('memento-client')
  , request = require('hyperquest')

var timeNear = require('./lib/time-near')

var WAYBACK_HOST = 'web.archive.org'
  , isAsset = /\/web\/\d{14}/

module.exports = peabody

function peabody(timestamp, fuzz) {
  return http.createServer(handler)

  function handler(req, res) {
    var assetUrl

    if(!isAsset.test(req.url)) {
      return memento(req.url, timestamp, checkSites)
    }

    assetUrl = url.format({
        host: WAYBACK_HOST
      , pathname: url.parse(req.url).path
      , protocol: 'http'
    })

    request.get(assetUrl, assetRespond)

    function checkSites(err, sites) {
      var noSites = sites.length < 2

      if(err || noSites || !timeNear(sites[1].datetime, timestamp, fuzz)) {
        return notFound(res)
      }

      request.get(sites[1].href, respond)
    }

    function respond(err, response) {
      if(err) {
        return notFound(res)
      }

      response.pipe(res)
      res.writeHead(response.statusCode, response.headers)
    }

    function assetRespond(err, response) {
      if(err) {
        return notFound(res)
      }

      var assetUrl

      if(response.statusCode === 302) {
        assetUrl = url.format({
            host: WAYBACK_HOST
          , pathname: response.headers.location
          , protocol: 'http'
        })

        return request.get(assetUrl, assetRespond)
      }

      res.writeHead(response.statusCode, response.headers)

      if(response.statusCode < 200 || response.statusCode > 299) {
        return res.end()
      }

      response.pipe(res)
    }
  }
}

function notFound(res) {
  res.writeHead(404, {'content-type': 'text/plain'})

  res.end('Site not available')
}
<|endoftext|>


<commit_before>var rbush = typeof require !== 'undefined' ? require('../rbush.js') : rbush;

var data = [],
    x, y;

var N = 1000000,
    bbox = [49,72,51,74];

for (var i = 0; i < N; i++) {
    x = Math.random() * 99;
    y = Math.random() * 99;
    data[i] = [x, y, x + 1, y + 1];
}

console.log('number: ' + N);

console.time('load');
var tree = rbush().load(data);
console.timeEnd('load');

console.time('search');
var result = tree.search(bbox);
console.timeEnd('search');

// console.time('naive search');
// var result = [];
// for (var i = 0; i < N; i++) {
//  if (tree._contains(bbox, data[i])) {
//      result.push(data[i]);
//  }
// }
// console.timeEnd('naive search');

RTree

var RTree = typeof require !== 'undefined' ? require('rtree') : RTree;

var tree2 = new RTree();

var data2 = [];
for (var i = 0; i < N; i++) {
    data2.push({x: data[i][0], y: data[i][1], w: 0, h: 0});
}

console.time('load 2');
for (var i = 0; i < N; i++) {
    tree2.insert(data2[i]);
}
console.timeEnd('load 2');

console.time('search 2');
var result = tree2.search({x: bbox[0], y: bbox[1], w: bbox[2] - bbox[0], h: bbox[3] - bbox[1]});
console.timeEnd('search 2');
<commit_msg>add a second bbox for perf tests<commit_after>var rbush = typeof require !== 'undefined' ? require('../rbush.js') : rbush;

var data = [],
    x, y;

var N = 1000000,
    bbox = [49,72,51,74],
    bbox2 = [23.5, 43.5, 23.6, 43.6];

for (var i = 0; i < N; i++) {
    x = Math.random() * 99;
    y = Math.random() * 99;
    data[i] = [x, y, x + 1, y + 1];
}

console.log('number: ' + N);

console.time('load');
var tree = rbush().load(data);
console.timeEnd('load');

console.time('search 2x2 of 100x100');
var result = tree.search(bbox);
console.timeEnd('search 2x2 of 100x100');

console.time('search 0.1x0.1 of 100x100');
var result = tree.search(bbox2);
console.timeEnd('search 0.1x0.1 of 100x100');

console.time('naive search');
var result = [];
for (var i = 0; i < N; i++) {
 if (tree._contains(bbox, data[i])) {
     result.push(data[i]);
 }
}
console.timeEnd('naive search');

// var RTree = typeof require !== 'undefined' ? require('rtree') : RTree;

// var tree2 = new RTree();

// var data2 = [];
// for (var i = 0; i < N; i++) {
//     data2.push({x: data[i][0], y: data[i][1], w: 0, h: 0});
// }

// console.time('load 2');
// for (var i = 0; i < N; i++) {
//     tree2.insert(data2[i]);
// }
// console.timeEnd('load 2');

// console.time('search 2');
// var result = tree2.search({x: bbox[0], y: bbox[1], w: bbox[2] - bbox[0], h: bbox[3] - bbox[1]});
// console.timeEnd('search 2');
<|endoftext|>


<commit_before>/*! http://mths.be/array-from v0.1.0 by @mathias */
if (!Array.from) {
	(function () {
		'use strict';
		var defineProperty = (function () {
			// IE 8 only supports `Object.defineProperty` on DOM elements
			try {
				var object = {};
				var $defineProperty = Object.defineProperty;
				var result = $defineProperty(object, object, object) && $defineProperty;
			} catch(error) {}
			return result;
		}());
		var toStr = Object.prototype.toString;
		var isCallable = function (fn) {
			return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
		};
		var toInteger = function (value) {
			var number = Number(value);
			if (isNaN(number)) { return 0; }
			if (number === 0 || !isFinite(number)) { return number; }
			return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
		};
		var maxSafeInteger = Math.pow(2, 53) - 1;
		var toLength = function (value) {
			var len = toInteger(value);
			return Math.min(Math.max(len, 0), maxSafeInteger);
		};
		var isConstructor = function (Constructor) {
			try {
				new Constructor();
				return true;
			} catch(_) {
				return false;
			}
		};
		var from = function (arrayLike) {
			var Me = this;
			if (arrayLike == null) {
				throw TypeError("Array.from requires an array-like object - not null or undefined");
			}
			var items = Object(arrayLike);
			var mapping = arguments.length > 1;

			var mapFn, T;
			if (arguments.length > 1) {
				mapFn = arguments[1];
				if (!isCallable(mapFn)) {
					throw new TypeError('Array.from: when provided, the second argument must be a function');
				}
				if (arguments.length > 2) {
					T = arguments[2];
				}
			}

			var len = toLength(items.length);
			var A = isConstructor(Me) ? Object(new Me(len)) : new Array(len);
			var k = 0;
			var kValue;
			var mappedValue;
			while (k < len) {
				if (k in items) { // note: `HasProperty` (not `HasOwnProperty`)
					kValue = items[k];
					mappedValue = mapping ? mapFn.call(T, kValue, k) : kValue;
					A[k] = mappedValue;
				}
				++k;
			}
			A.length = len;
			return A;
		};
		if (defineProperty) {
			defineProperty(Array, 'from', {
				'value': from,
				'configurable': true,
				'writable': true
			});
		} else {
			Array.from = from;
		}
	}());
}

<commit_msg>Don't use Function#call if the thisArg is not provided.<commit_after>/*! http://mths.be/array-from v0.1.0 by @mathias */
if (!Array.from) {
	(function () {
		'use strict';
		var defineProperty = (function () {
			// IE 8 only supports `Object.defineProperty` on DOM elements
			try {
				var object = {};
				var $defineProperty = Object.defineProperty;
				var result = $defineProperty(object, object, object) && $defineProperty;
			} catch(error) {}
			return result;
		}());
		var toStr = Object.prototype.toString;
		var isCallable = function (fn) {
			return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
		};
		var toInteger = function (value) {
			var number = Number(value);
			if (isNaN(number)) { return 0; }
			if (number === 0 || !isFinite(number)) { return number; }
			return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
		};
		var maxSafeInteger = Math.pow(2, 53) - 1;
		var toLength = function (value) {
			var len = toInteger(value);
			return Math.min(Math.max(len, 0), maxSafeInteger);
		};
		var isConstructor = function (Constructor) {
			try {
				new Constructor();
				return true;
			} catch(_) {
				return false;
			}
		};
		var from = function (arrayLike) {
			var Me = this;
			if (arrayLike == null) {
				throw TypeError("Array.from requires an array-like object - not null or undefined");
			}
			var items = Object(arrayLike);
			var mapping = arguments.length > 1;

			var mapFn, T;
			if (arguments.length > 1) {
				mapFn = arguments[1];
				if (!isCallable(mapFn)) {
					throw new TypeError('Array.from: when provided, the second argument must be a function');
				}
				if (arguments.length > 2) {
					T = arguments[2];
				}
			}

			var len = toLength(items.length);
			var A = isConstructor(Me) ? Object(new Me(len)) : new Array(len);
			var k = 0;
			var kValue;
			while (k < len) {
				if (k in items) { // note: `HasProperty` (not `HasOwnProperty`)
					kValue = items[k];
					if (mapFn) {
						A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
					} else {
						A[k] = kValue;
					}
				}
				++k;
			}
			A.length = len;
			return A;
		};
		if (defineProperty) {
			defineProperty(Array, 'from', {
				'value': from,
				'configurable': true,
				'writable': true
			});
		} else {
			Array.from = from;
		}
	}());
}

<|endoftext|>


<commit_before>const updater = require('electron-simple-updater'),
      {dialog, BrowserWindow, ipcMain} = require('electron'),
      logger = require('electron-log'),
      url = require('url'),
      path = require('path'),
      isDev = require('electron-is-dev')

let versionAvailable,
    versionDownloaded,
    mainWin,
    updaterWin,
    checkingUpdates = false

logger.transports.file.level = 'info'

// Auto-update
updater.init({logger, autoDownload: false, checkUpdateOnStart: false})

const
  onUpdateDownloaded = ()=>{
    logger.info("Update downloaded.")
    versionDownloaded = versionAvailable
    promptRestart()
  },

  onUpdateAvailable = meta =>{
    logger.info("Update available.")
    if(meta.version == versionAvailable)return
    versionAvailable = meta.version
    updater.downloadUpdate()
  },

  promptRestart = ()=> {
    openMainUpdater()
  },

  openMainUpdater = ()=> {
    updaterWin = new BrowserWindow({
      width: 500,
      height: 500,
      parent: mainWin,
      center: true,
      title: "EnvKey Auto-Update",
      backgroundColor: "#222",
      modal: true,
      show: false,
      webPreferences: {
        preload: path.join(__dirname, "..", 'preload.js')
      }
    })

    updaterWin.params = {versionDownloaded}

    updaterWin.on('page-title-updated', e => e.preventDefault())

    updaterWin.loadURL(url.format({
      pathname: path.join(__dirname, "..", (isDev ? 'main_updater.dev.html' : 'main_updater.production.html')),
      protocol: 'file:',
      slashes: true,
    }))

    if (isDev){
      // Open the DevTools.
      updaterWin.webContents.openDevTools()
    }

    updaterWin.webContents.on('did-finish-load', ()=> {
      updaterWin.webContents.send('version-downloaded', versionAvailable)
    })

    ipcMain.on("main-updater-version-received", ()=>{
      updaterWin.show()
    })

    ipcMain.on('main-updater-closed', ()=> {
      updaterWin.hide()
    })

    ipcMain.on('main-updater-restart', ()=> {
      updaterWin.close()
      updater.quitAndInstall()
    })

    updaterWin.on('hide', ()=> {
      updaterWin = null
    })

    updaterWin.on('close', ()=> {
      updaterWin = null
    })

    mainWin.on('closed', () => {
      mainWin = null
      udpaterWin = null
    })
  }

module.exports = {

  listenUpdater: (win)=>{
    mainWin = win

    if(checkingUpdates)return

    updater.on('update-available', onUpdateAvailable)
    updater.on('update-downloaded', onUpdateDownloaded)
    updater.on('error', err => logger.error(err))

    // Check for updates every 10 minutes
    setInterval(()=> updater.checkForUpdates(), 1000 * 60 * 10)

    updater.checkForUpdates()

    checkingUpdates = true
  }
}

<commit_msg>updates typo fix<commit_after>const updater = require('electron-simple-updater'),
      {dialog, BrowserWindow, ipcMain} = require('electron'),
      logger = require('electron-log'),
      url = require('url'),
      path = require('path'),
      isDev = require('electron-is-dev')

let versionAvailable,
    versionDownloaded,
    mainWin,
    updaterWin,
    checkingUpdates = false

logger.transports.file.level = 'info'

// Auto-update
updater.init({logger, autoDownload: false, checkUpdateOnStart: false})

const
  onUpdateDownloaded = ()=>{
    logger.info("Update downloaded.")
    versionDownloaded = versionAvailable
    promptRestart()
  },

  onUpdateAvailable = meta =>{
    logger.info("Update available.")
    if(meta.version == versionAvailable)return
    versionAvailable = meta.version
    updater.downloadUpdate()
  },

  promptRestart = ()=> {
    openMainUpdater()
  },

  openMainUpdater = ()=> {
    updaterWin = new BrowserWindow({
      width: 500,
      height: 500,
      parent: mainWin,
      center: true,
      title: "EnvKey Auto-Update",
      backgroundColor: "#222",
      modal: true,
      show: false,
      webPreferences: {
        preload: path.join(__dirname, "..", 'preload.js')
      }
    })

    updaterWin.params = {versionDownloaded}

    updaterWin.on('page-title-updated', e => e.preventDefault())

    updaterWin.loadURL(url.format({
      pathname: path.join(__dirname, "..", (isDev ? 'main_updater.dev.html' : 'main_updater.production.html')),
      protocol: 'file:',
      slashes: true,
    }))

    if (isDev){
      // Open the DevTools.
      updaterWin.webContents.openDevTools()
    }

    updaterWin.webContents.on('did-finish-load', ()=> {
      updaterWin.webContents.send('version-downloaded', versionAvailable)
    })

    ipcMain.on("main-updater-version-received", ()=>{
      updaterWin.show()
    })

    ipcMain.on('main-updater-closed', ()=> {
      updaterWin.hide()
    })

    ipcMain.on('main-updater-restart', ()=> {
      updaterWin.close()
      updater.quitAndInstall()
    })

    updaterWin.on('hide', ()=> {
      updaterWin = null
    })

    updaterWin.on('close', ()=> {
      updaterWin = null
    })

    mainWin.on('closed', () => {
      mainWin = null
      updaterWin = null
    })
  }

module.exports = {

  listenUpdater: (win)=>{
    mainWin = win

    if(checkingUpdates)return

    updater.on('update-available', onUpdateAvailable)
    updater.on('update-downloaded', onUpdateDownloaded)
    updater.on('error', err => logger.error(err))

    // Check for updates every 10 minutes
    setInterval(()=> updater.checkForUpdates(), 1000 * 60 * 10)

    updater.checkForUpdates()

    checkingUpdates = true
  }
}

<|endoftext|>


<commit_before>var InputState = (function () {
	'use strict';
	var inputState = {
		keyCodes: {
			BACKSPACE: 8,
			TAB: 9,
			ENTER: 13,
			SHIFT: 16,
			CTRL: 17,
			ALT: 18,
			PAUSE_BREAK: 19,
			CAPS_LOCK: 20,
			ESCAPE: 27,
			SPACE: 32,
			PAGE_UP: 33,
			PAGE_DOWN: 34,
			END: 35,
			HOME: 36,
			LEFT_ARROW: 37,
			UP_ARROW: 38,
			RIGHT_ARROW: 39,
			DOWN_ARROW: 40,
			INSERT: 45,
			DELETE: 46,

			ZERO: 48,
			ONE: 49,
			TWO: 50,
			THREE: 51,
			FOUR: 52,
			FIVE: 53,
			SIX: 54,
			SEVEN: 55,
			EIGHT: 56,
			NINE: 57,

			A: 65,
			B: 66,
			C: 67,
			D: 68,
			E: 69,
			F: 70,
			G: 71,
			H: 72,
			I: 73,
			J: 74,
			K: 75,
			L: 76,
			M: 77,
			N: 78,
			O: 79,
			P: 80,
			Q: 81,
			R: 82,
			S: 83,
			T: 84,
			U: 85,
			V: 86,
			W: 87,
			X: 88,
			Y: 89,
			Z: 90,

			LEFT_WINDOW: 91,
			RIGHT_WINDOW: 92,
			SELECT: 93,

			NUMPAD_0: 96,
			NUMPAD_1: 97,
			NUMPAD_2: 98,
			NUMPAD_3: 99,
			NUMPAD_4: 100,
			NUMPAD_5: 101,
			NUMPAD_6: 102,
			NUMPAD_7: 103,
			NUMPAD_8: 104,
			NUMPAD_9: 105,

			MULTIPLY: 106,
			ADD: 107,
			SUBTRACT: 109,
			DECIMAL: 110,
			DIVIDE: 111,

			F1: 112,
			F2: 113,
			F3: 114,
			F4: 115,
			F5: 116,
			F6: 117,
			F7: 118,
			F8: 119,
			F9: 120,
			F10: 121,
			F11: 122,
			F12: 123,

			NUM_LOCK: 144,
			SCROLL_LOCK: 145,
			SEMI_COLON: 186,
			EQUAL_SIGN: 187,
			COMMA: 188,
			HYPHEN: 189,
			PERIOD: 190,
			FORWARD_SLASH: 191,
			GRAVE_ACCENT: 192,
			OPEN_BRACKET: 219,
			BACK_SLASH: 220,
			CLOSE_BRACKET: 221,
			SINGLE_QUOTE: 222
		},
		keyboard: new Array(128),
		mouse: {
			left: false,
			middle: false,
			right: false,
			x: 0,
			y: 0
		}
	};

	var onKeyDown = function (event) {
			inputState.keyboard[event.keyCode] = true;
		},
		onKeyUp = function (event) {
			inputState.keyboard[event.keyCode] = false;
		},
		onMouseMove = function (event) {
			inputState.mouse.x = event.clientX;
			inputState.mouse.y = event.clientY;
		},
		onMouseDown = function (event) {
			inputState.mouse[event.button] = true;
		},
		onMouseUp = function (event) {
			inputState.mouse[event.button] = false;
		},
		/*onMouseClick = function (event) {

		};*/

	window.onload = function () {
		document.addEventListener('keydown', onKeyDown, true);
		document.addEventListener('keyup', onKeyUp, true);
		document.addEventListener('mousemove', onMouseMove, true);
		document.addEventListener('mousedown', onMouseDown, true);
		document.addEventListener('mouseup', onMouseUp, true);
		//document.addEventListener('mouseclick', onMouseClick, true);
	};

	return inputState;
})();
<commit_msg>Adds missing semicolon<commit_after>var InputState = (function () {
	'use strict';
	var inputState = {
		keyCodes: {
			BACKSPACE: 8,
			TAB: 9,
			ENTER: 13,
			SHIFT: 16,
			CTRL: 17,
			ALT: 18,
			PAUSE_BREAK: 19,
			CAPS_LOCK: 20,
			ESCAPE: 27,
			SPACE: 32,
			PAGE_UP: 33,
			PAGE_DOWN: 34,
			END: 35,
			HOME: 36,
			LEFT_ARROW: 37,
			UP_ARROW: 38,
			RIGHT_ARROW: 39,
			DOWN_ARROW: 40,
			INSERT: 45,
			DELETE: 46,

			ZERO: 48,
			ONE: 49,
			TWO: 50,
			THREE: 51,
			FOUR: 52,
			FIVE: 53,
			SIX: 54,
			SEVEN: 55,
			EIGHT: 56,
			NINE: 57,

			A: 65,
			B: 66,
			C: 67,
			D: 68,
			E: 69,
			F: 70,
			G: 71,
			H: 72,
			I: 73,
			J: 74,
			K: 75,
			L: 76,
			M: 77,
			N: 78,
			O: 79,
			P: 80,
			Q: 81,
			R: 82,
			S: 83,
			T: 84,
			U: 85,
			V: 86,
			W: 87,
			X: 88,
			Y: 89,
			Z: 90,

			LEFT_WINDOW: 91,
			RIGHT_WINDOW: 92,
			SELECT: 93,

			NUMPAD_0: 96,
			NUMPAD_1: 97,
			NUMPAD_2: 98,
			NUMPAD_3: 99,
			NUMPAD_4: 100,
			NUMPAD_5: 101,
			NUMPAD_6: 102,
			NUMPAD_7: 103,
			NUMPAD_8: 104,
			NUMPAD_9: 105,

			MULTIPLY: 106,
			ADD: 107,
			SUBTRACT: 109,
			DECIMAL: 110,
			DIVIDE: 111,

			F1: 112,
			F2: 113,
			F3: 114,
			F4: 115,
			F5: 116,
			F6: 117,
			F7: 118,
			F8: 119,
			F9: 120,
			F10: 121,
			F11: 122,
			F12: 123,

			NUM_LOCK: 144,
			SCROLL_LOCK: 145,
			SEMI_COLON: 186,
			EQUAL_SIGN: 187,
			COMMA: 188,
			HYPHEN: 189,
			PERIOD: 190,
			FORWARD_SLASH: 191,
			GRAVE_ACCENT: 192,
			OPEN_BRACKET: 219,
			BACK_SLASH: 220,
			CLOSE_BRACKET: 221,
			SINGLE_QUOTE: 222
		},
		keyboard: new Array(128),
		mouse: {
			left: false,
			middle: false,
			right: false,
			x: 0,
			y: 0
		}
	};

	var onKeyDown = function (event) {
			inputState.keyboard[event.keyCode] = true;
		},
		onKeyUp = function (event) {
			inputState.keyboard[event.keyCode] = false;
		},
		onMouseMove = function (event) {
			inputState.mouse.x = event.clientX;
			inputState.mouse.y = event.clientY;
		},
		onMouseDown = function (event) {
			inputState.mouse[event.button] = true;
		},
		onMouseUp = function (event) {
			inputState.mouse[event.button] = false;
		};

	window.onload = function () {
		document.addEventListener('keydown', onKeyDown, true);
		document.addEventListener('keyup', onKeyUp, true);
		document.addEventListener('mousemove', onMouseMove, true);
		document.addEventListener('mousedown', onMouseDown, true);
		document.addEventListener('mouseup', onMouseUp, true);
	};

	return inputState;
})();
<|endoftext|>


<commit_before>(function ($) {
  var ident = 0;

  $.fn.swiftype = function (options) {
    var options = $.extend({}, $.fn.swiftype.defaults, options);

    return this.each(function () {
      var $this = $(this);
      var config = $.meta ? $.extend({}, options, $this.data()) : options;
      $this.attr('autocomplete', 'off');
      $this.data('swiftype-config', config);
      $this.submitted = false;
      $this.cache = new LRUCache(10);
      $this.emptyQueries = [];

      $this.isEmpty = function(query) {
	   return $.inArray(normalize(query), this.emptyQueries) >= 0
      };

      $this.addEmpty = function(query) {
        $this.emptyQueries.unshift(normalize(query));
      };

      var $attachEl = config.attachTo ? $(config.attachTo) : $this;
      var offset = $attachEl.offset();
      var styles = {
        'position': 'absolute',
        'z-index': 999,
        'top': offset.top + $attachEl.outerHeight() + 1,
        'left': offset.left
      };
      if (config.setWidth) {
        styles['width'] = $attachEl.outerWidth() - 2;
      }

      var $list = $('<' + config.suggestionListType + ' />').addClass(config.suggestionListClass).appendTo('body').hide().css(styles);
      $this.data('swiftype-list', $list);

      $this.abortCurrent = function() {
        if ($this.currentRequest) {
          $this.currentRequest.abort();
        }
      };

      $this.hideList = function() {
        setTimeout(function() { $list.hide(); }, 10);
      };

      $this.focused = function() {
        return $this.is(':focus');
      };

      $this.submitting = function() {
        $this.submitted = true;
      };

      $this.listResults = function() {
        return $(config.resultListSelector, $list);
      };

      $this.registerResult = function($element, data) {
        $element.data('swiftype-item', data);
        $element.click(function () {
          config.onComplete(data);
        }).mouseover(function () {
          $this.listResults().removeClass(config.activeItemClass);
          $element.addClass(config.activeItemClass);
        });
      };

      $this.getContext = function() {
        return {
          config: config,
          list: $list,
          registerResult: $this.registerResult
        };
      };

      var typingDelayPointer;
      var suppressKey = false;
      $this.lastValue = '';
      $this.keyup(function (event) {
        if (suppressKey) {
          suppressKey = false;
          return;
        }

        // ignore arrow keys, shift
        if (((event.which > 36) && (event.which < 41)) || (event.which == 16)) return;

        if (config.typingDelay > 0) {
          clearTimeout(typingDelayPointer);
          typingDelayPointer = setTimeout(function () {
            processInput($this);
          }, config.typingDelay);
        } else {
          processInput($this);
        }
      });

      $this.keydown(function (event) {
        // enter = 13; up = 38; down = 40; esc = 27
        var $active = $list.children('li.' + config.activeItemClass);
        switch (event.which) {
        case 13:
          if (($active.length !== 0) && ($list.is(':visible'))) {
            event.preventDefault();
            var prefix = $this.val();
            config.onComplete($active.data('swiftype-item'), prefix);
          } else if ($this.currentRequest) {
            $this.submitting();
          }
          $this.hideList();
          suppressKey = true;
          break;
        case 38:
          event.preventDefault();
          if ($active.length === 0) {
            $list.children('li:last-child').addClass(config.activeItemClass);
          } else {
            $active.prev().addClass(config.activeItemClass);
            $active.removeClass(config.activeItemClass);
          }
          break;
        case 40:
          event.preventDefault();
          if ($active.length === 0) {
            $list.children('li:first-child').addClass(config.activeItemClass);
          } else if ($active.is(':not(:last-child)')) {
            $active.next().addClass(config.activeItemClass);
            $active.removeClass(config.activeItemClass);
          }
          break;
        case 27:
          $this.hideList();
          suppressKey = true;
          break;
        default:
          $this.submitted = false;
          break;
        }
      });

      // opera wants keypress rather than keydown to prevent the form submit
      $this.keypress(function (event) {
        var $active = $list.children('li.' + config.activeItemClass);

        if ((event.which == 13) && ($list.children('li.' + config.activeItemClass).length > 0)) {
          event.preventDefault();
        }
      });

      // stupid hack to get around loss of focus on mousedown
      var mouseDown = false;
      var blurWait = false;
      $(document).bind('mousedown.swiftype' + ++ident, function () {
        mouseDown = true;
      });
      $(document).bind('mouseup.swiftype' + ident, function () {
        mouseDown = false;
        if (blurWait) {
          blurWait = false;
          $this.hideList();
        }
      });
      $this.blur(function () {
        if (mouseDown) {
          blurWait = true;
        } else {
          $this.hideList();
        }
      });
      $this.focus(function () {
        setTimeout(function() { $this.select() }, 10);
        if ($list.children(':not(.' + config.noResultsClass + ')').length > 0) {
          $list.show();
        }
      });
    });
  };

  var normalize = function(str) {
    return $.trim(str).toLowerCase();
  };

  var callRemote = function ($this, term) {
    $this.abortCurrent();

    var params = {},
      config = $this.data('swiftype-config');

    params['q'] = term;
    params['engine_key'] = config.engineKey;

    if(config.searchFields !== undefined) {
      params['search_fields'] = config.searchFields;
    }
    if(config.fetchFields !== undefined) {
      params['fetch_fields'] = config.fetchFields;
    }
    if(config.filters !== undefined) {
      params['filters'] = config.filters;
    }
    if(config.documentTypes !== undefined) {
      params['document_types'] = config.documentTypes;
    }
    if(config.functionalBoosts !== undefined) {
      params['functional_boosts'] = config.functionalBoosts;
    }

    var endpoint = 'http://api.swiftype.com/api/v1/public/engines/suggest.json';
    $this.currentRequest = $.ajax({
      type: 'GET',
      dataType: 'jsonp',
      url: endpoint,
      data: params
    }).success(function(data) {
      var norm = normalize(term);
      if (data.record_count > 0) {
        $this.cache.put(norm, data.records);
      } else {
        $this.addEmpty(norm);
        $this.data('swiftype-list').empty().hide();
        return;
      }
      processData($this, data.records, term);
    });
  };

  var getResults = function($this, term) {
    var norm = normalize(term);
    if ($this.isEmpty(norm)) {
      $this.data('swiftype-list').empty().hide();
      return;
    }
    var cached = $this.cache.get(norm);
    if (cached) {
      processData($this, cached, term);
    } else {
      callRemote($this, term);
    }
  };

  // private helpers
  var processInput = function ($this) {
      var term = $this.val();
      if (term === $this.lastValue) {
        return;
      }
      $this.lastValue = term;
      if ($.trim(term) === '') {
        $this.data('swiftype-list').empty().hide();
        return;
      }
      if (typeof $this.data('swiftype-config').engineKey !== 'undefined') {
        getResults($this, term);
      }
    };

  var processData = function ($this, data, term) {
      var $list = $this.data('swiftype-list'),
        config = $this.data('swiftype-config');

      $list.empty().hide();
      config.resultRenderFunction($this.getContext(), data);

      var totalItems = $this.listResults().length;
      if ((totalItems > 0 && $this.focused()) || (config.noResultsMessage !== undefined)) {
        if ($this.submitted) {
          $this.submitted = false;
        } else {
          $list.show();
        }
      }
    };

  var defaultResultRenderFunction = function(ctx, results) {
    var $list = ctx.list,
      config = ctx.config;

    $.each(results, function(document_type, items) {
      $.each(items, function(idx, item) {
        ctx.registerResult($('
' + config.renderFunction(document_type, item) + '
').appendTo($list), item);
      });
    });
  };

  var defaultRenderFunction = function(document_type, item) {
    return '
' + item['title'] + '
';
  };

  var defaultOnComplete = function(item, prefix) {
    window.location = item['url'];
  };

	// simple client-side LRU Cache, based on https://github.com/rsms/js-lru

	function LRUCache(limit) {
	  this.size = 0;
	  this.limit = limit;
	  this._keymap = {};
	}

  LRUCache.prototype.put = function (key, value) {
    var entry = {
      key: key,
      value: value
    };
    this._keymap[key] = entry;
    if (this.tail) {
      this.tail.newer = entry;
      entry.older = this.tail;
    } else {
      this.head = entry;
    }
    this.tail = entry;
    if (this.size === this.limit) {
      return this.shift();
    } else {
      this.size++;
    }
  };

  LRUCache.prototype.shift = function () {
    var entry = this.head;
    if (entry) {
      if (this.head.newer) {
        this.head = this.head.newer;
        this.head.older = undefined;
      } else {
        this.head = undefined;
      }
      entry.newer = entry.older = undefined;
      delete this._keymap[entry.key];
    }
    return entry;
  };

  LRUCache.prototype.get = function (key, returnEntry) {
    var entry = this._keymap[key];
    if (entry === undefined) return;
    if (entry === this.tail) {
      return entry.value;
    }
    if (entry.newer) {
      if (entry === this.head) this.head = entry.newer;
      entry.newer.older = entry.older;
    }
    if (entry.older) entry.older.newer = entry.newer;
    entry.newer = undefined;
    entry.older = this.tail;
    if (this.tail) this.tail.newer = entry;
    this.tail = entry;
    return returnEntry ? entry : entry.value;
  };

  LRUCache.prototype.remove = function (key) {
    var entry = this._keymap[key];
    if (!entry) return;
    delete this._keymap[entry.key];
    if (entry.newer && entry.older) {
      entry.older.newer = entry.newer;
      entry.newer.older = entry.older;
    } else if (entry.newer) {
      entry.newer.older = undefined;
      this.head = entry.newer;
    } else if (entry.older) {
      entry.older.newer = undefined;
      this.tail = entry.older;
    } else {
      this.head = this.tail = undefined;
    }

    this.size--;
    return entry.value;
  };

  LRUCache.prototype.clear = function () {
    this.head = this.tail = undefined;
    this.size = 0;
    this._keymap = {};
  };

  if (typeof Object.keys === 'function') {
    LRUCache.prototype.keys = function () {
      return Object.keys(this._keymap);
    };
  } else {
    LRUCache.prototype.keys = function () {
      var keys = [];
      for (var k in this._keymap) keys.push(k);
      return keys;
    };
  }

  $.fn.swiftype.defaults = {
    activeItemClass: 'active',
    attachTo: undefined,
    documentTypes: undefined,
    filters: undefined,
    engineKey: undefined,
    searchFields: undefined,
    functionalBoosts: undefined,
    fetchFields: undefined,
    noResultsClass: 'noResults',
    noResultsMessage: undefined,
    onComplete: defaultOnComplete,
    resultRenderFunction: defaultResultRenderFunction,
    renderFunction: defaultRenderFunction,
    resultLimit: 10,
    suggestionListType: 'ul',
    suggestionListClass: 'st-autocomplete',
    resultListSelector: 'li',
    setWidth: true,
    typingDelay: 80
  };

})(jQuery);
<commit_msg>use result selector option for arrow controls<commit_after>(function ($) {
  var ident = 0;

  $.fn.swiftype = function (options) {
    var options = $.extend({}, $.fn.swiftype.defaults, options);

    return this.each(function () {
      var $this = $(this);
      var config = $.meta ? $.extend({}, options, $this.data()) : options;
      $this.attr('autocomplete', 'off');
      $this.data('swiftype-config', config);
      $this.submitted = false;
      $this.cache = new LRUCache(10);
      $this.emptyQueries = [];

      $this.isEmpty = function(query) {
	   return $.inArray(normalize(query), this.emptyQueries) >= 0
      };

      $this.addEmpty = function(query) {
        $this.emptyQueries.unshift(normalize(query));
      };

      var $attachEl = config.attachTo ? $(config.attachTo) : $this;
      var offset = $attachEl.offset();
      var styles = {
        'position': 'absolute',
        'z-index': 999,
        'top': offset.top + $attachEl.outerHeight() + 1,
        'left': offset.left
      };
      if (config.setWidth) {
        styles['width'] = $attachEl.outerWidth() - 2;
      }

      var $list = $('<' + config.suggestionListType + ' />').addClass(config.suggestionListClass).appendTo('body').hide().css(styles);
      $this.data('swiftype-list', $list);

      $this.abortCurrent = function() {
        if ($this.currentRequest) {
          $this.currentRequest.abort();
        }
      };

      $this.hideList = function() {
        setTimeout(function() { $list.hide(); }, 10);
      };

      $this.focused = function() {
        return $this.is(':focus');
      };

      $this.submitting = function() {
        $this.submitted = true;
      };

      $this.listResults = function() {
        return $(config.resultListSelector, $list);
      };

      $this.activeResult = function() {
        return $this.listResults().filter('.' + config.activeItemClass);
      };

      $this.registerResult = function($element, data) {
        $element.data('swiftype-item', data);
        $element.click(function () {
          config.onComplete(data);
        }).mouseover(function () {
          $this.listResults().removeClass(config.activeItemClass);
          $element.addClass(config.activeItemClass);
        });
      };

      $this.getContext = function() {
        return {
          config: config,
          list: $list,
          registerResult: $this.registerResult
        };
      };

      var typingDelayPointer;
      var suppressKey = false;
      $this.lastValue = '';
      $this.keyup(function (event) {
        if (suppressKey) {
          suppressKey = false;
          return;
        }

        // ignore arrow keys, shift
        if (((event.which > 36) && (event.which < 41)) || (event.which == 16)) return;

        if (config.typingDelay > 0) {
          clearTimeout(typingDelayPointer);
          typingDelayPointer = setTimeout(function () {
            processInput($this);
          }, config.typingDelay);
        } else {
          processInput($this);
        }
      });

      $this.keydown(function (event) {
        // enter = 13; up = 38; down = 40; esc = 27
        var $active = $this.activeResult();
        switch (event.which) {
        case 13:
          if (($active.length !== 0) && ($list.is(':visible'))) {
            event.preventDefault();
            var prefix = $this.val();
            config.onComplete($active.data('swiftype-item'), prefix);
          } else if ($this.currentRequest) {
            $this.submitting();
          }
          $this.hideList();
          suppressKey = true;
          break;
        case 38:
          event.preventDefault();
          if ($active.length === 0) {
            $this.listResults().last().addClass(config.activeItemClass);
          } else {
            $active.prev().addClass(config.activeItemClass);
            $active.removeClass(config.activeItemClass);
          }
          break;
        case 40:
          event.preventDefault();
          if ($active.length === 0) {
            $this.listResults().first().addClass(config.activeItemClass);
          } else if ($active != $this.listResults().last()) {
            $active.next().addClass(config.activeItemClass);
            $active.removeClass(config.activeItemClass);
          }
          break;
        case 27:
          $this.hideList();
          suppressKey = true;
          break;
        default:
          $this.submitted = false;
          break;
        }
      });

      // opera wants keypress rather than keydown to prevent the form submit
      $this.keypress(function (event) {
        if ((event.which == 13) && ($this.activeResult().length > 0)) {
          event.preventDefault();
        }
      });

      // stupid hack to get around loss of focus on mousedown
      var mouseDown = false;
      var blurWait = false;
      $(document).bind('mousedown.swiftype' + ++ident, function () {
        mouseDown = true;
      });
      $(document).bind('mouseup.swiftype' + ident, function () {
        mouseDown = false;
        if (blurWait) {
          blurWait = false;
          $this.hideList();
        }
      });
      $this.blur(function () {
        if (mouseDown) {
          blurWait = true;
        } else {
          $this.hideList();
        }
      });
      $this.focus(function () {
        setTimeout(function() { $this.select() }, 10);
        if ($this.listResults().filter(':not(.' + config.noResultsClass + ')').length > 0) {
          $list.show();
        }
      });
    });
  };

  var normalize = function(str) {
    return $.trim(str).toLowerCase();
  };

  var callRemote = function ($this, term) {
    $this.abortCurrent();

    var params = {},
      config = $this.data('swiftype-config');

    params['q'] = term;
    params['engine_key'] = config.engineKey;

    if(config.searchFields !== undefined) {
      params['search_fields'] = config.searchFields;
    }
    if(config.fetchFields !== undefined) {
      params['fetch_fields'] = config.fetchFields;
    }
    if(config.filters !== undefined) {
      params['filters'] = config.filters;
    }
    if(config.documentTypes !== undefined) {
      params['document_types'] = config.documentTypes;
    }
    if(config.functionalBoosts !== undefined) {
      params['functional_boosts'] = config.functionalBoosts;
    }

    var endpoint = 'http://api.swiftype.com/api/v1/public/engines/suggest.json';
    $this.currentRequest = $.ajax({
      type: 'GET',
      dataType: 'jsonp',
      url: endpoint,
      data: params
    }).success(function(data) {
      var norm = normalize(term);
      if (data.record_count > 0) {
        $this.cache.put(norm, data.records);
      } else {
        $this.addEmpty(norm);
        $this.data('swiftype-list').empty().hide();
        return;
      }
      processData($this, data.records, term);
    });
  };

  var getResults = function($this, term) {
    var norm = normalize(term);
    if ($this.isEmpty(norm)) {
      $this.data('swiftype-list').empty().hide();
      return;
    }
    var cached = $this.cache.get(norm);
    if (cached) {
      processData($this, cached, term);
    } else {
      callRemote($this, term);
    }
  };

  // private helpers
  var processInput = function ($this) {
      var term = $this.val();
      if (term === $this.lastValue) {
        return;
      }
      $this.lastValue = term;
      if ($.trim(term) === '') {
        $this.data('swiftype-list').empty().hide();
        return;
      }
      if (typeof $this.data('swiftype-config').engineKey !== 'undefined') {
        getResults($this, term);
      }
    };

  var processData = function ($this, data, term) {
      var $list = $this.data('swiftype-list'),
        config = $this.data('swiftype-config');

      $list.empty().hide();
      config.resultRenderFunction($this.getContext(), data);

      var totalItems = $this.listResults().length;
      if ((totalItems > 0 && $this.focused()) || (config.noResultsMessage !== undefined)) {
        if ($this.submitted) {
          $this.submitted = false;
        } else {
          $list.show();
        }
      }
    };

  var defaultResultRenderFunction = function(ctx, results) {
    var $list = ctx.list,
      config = ctx.config;

    $.each(results, function(document_type, items) {
      $.each(items, function(idx, item) {
        ctx.registerResult($('
' + config.renderFunction(document_type, item) + '
').appendTo($list), item);
      });
    });
  };

  var defaultRenderFunction = function(document_type, item) {
    return '
' + item['title'] + '
';
  };

  var defaultOnComplete = function(item, prefix) {
    window.location = item['url'];
  };

	// simple client-side LRU Cache, based on https://github.com/rsms/js-lru

	function LRUCache(limit) {
	  this.size = 0;
	  this.limit = limit;
	  this._keymap = {};
	}

  LRUCache.prototype.put = function (key, value) {
    var entry = {
      key: key,
      value: value
    };
    this._keymap[key] = entry;
    if (this.tail) {
      this.tail.newer = entry;
      entry.older = this.tail;
    } else {
      this.head = entry;
    }
    this.tail = entry;
    if (this.size === this.limit) {
      return this.shift();
    } else {
      this.size++;
    }
  };

  LRUCache.prototype.shift = function () {
    var entry = this.head;
    if (entry) {
      if (this.head.newer) {
        this.head = this.head.newer;
        this.head.older = undefined;
      } else {
        this.head = undefined;
      }
      entry.newer = entry.older = undefined;
      delete this._keymap[entry.key];
    }
    return entry;
  };

  LRUCache.prototype.get = function (key, returnEntry) {
    var entry = this._keymap[key];
    if (entry === undefined) return;
    if (entry === this.tail) {
      return entry.value;
    }
    if (entry.newer) {
      if (entry === this.head) this.head = entry.newer;
      entry.newer.older = entry.older;
    }
    if (entry.older) entry.older.newer = entry.newer;
    entry.newer = undefined;
    entry.older = this.tail;
    if (this.tail) this.tail.newer = entry;
    this.tail = entry;
    return returnEntry ? entry : entry.value;
  };

  LRUCache.prototype.remove = function (key) {
    var entry = this._keymap[key];
    if (!entry) return;
    delete this._keymap[entry.key];
    if (entry.newer && entry.older) {
      entry.older.newer = entry.newer;
      entry.newer.older = entry.older;
    } else if (entry.newer) {
      entry.newer.older = undefined;
      this.head = entry.newer;
    } else if (entry.older) {
      entry.older.newer = undefined;
      this.tail = entry.older;
    } else {
      this.head = this.tail = undefined;
    }

    this.size--;
    return entry.value;
  };

  LRUCache.prototype.clear = function () {
    this.head = this.tail = undefined;
    this.size = 0;
    this._keymap = {};
  };

  if (typeof Object.keys === 'function') {
    LRUCache.prototype.keys = function () {
      return Object.keys(this._keymap);
    };
  } else {
    LRUCache.prototype.keys = function () {
      var keys = [];
      for (var k in this._keymap) keys.push(k);
      return keys;
    };
  }

  $.fn.swiftype.defaults = {
    activeItemClass: 'active',
    attachTo: undefined,
    documentTypes: undefined,
    filters: undefined,
    engineKey: undefined,
    searchFields: undefined,
    functionalBoosts: undefined,
    fetchFields: undefined,
    noResultsClass: 'noResults',
    noResultsMessage: undefined,
    onComplete: defaultOnComplete,
    resultRenderFunction: defaultResultRenderFunction,
    renderFunction: defaultRenderFunction,
    resultLimit: 10,
    suggestionListType: 'ul',
    suggestionListClass: 'st-autocomplete',
    resultListSelector: 'li',
    setWidth: true,
    typingDelay: 80
  };

})(jQuery);
<|endoftext|>


<commit_before>'use strict'
const Web3 = require('web3')

module.exports = {
  loadWeb3: function (url) {
    if (!url) url = 'http://localhost:8545'
    const web3 = new Web3()
    web3.setProvider(new web3.providers.HttpProvider(url))
    this.extend(web3)
    return web3
  },

  extendWeb3: function (web3) {
    this.extend(web3)
  },

  setProvider: function (web3, url) {
    web3.setProvider(new web3.providers.HttpProvider(url))
  },

  web3DebugNode: function (network) {
    if (web3DebugNodes[network]) {
      return this.loadWeb3(web3DebugNodes[network])
    }
    return null
  },

  extend: function (web3) {
    if (!web3.extend) {
      return
    }
    // DEBUG
    const methods = []
    if (!(web3.debug && web3.debug.preimage)) {
      methods.push(new web3.extend.Method({
        name: 'preimage',
        call: 'debug_preimage',
        inputFormatter: [null],
        params: 1
      }))
    }

    if (!(web3.debug && web3.debug.traceTransaction)) {
      methods.push(new web3.extend.Method({
        name: 'traceTransaction',
        call: 'debug_traceTransaction',
        inputFormatter: [null, null],
        params: 2
      }))
    }

    if (!(web3.debug && web3.debug.storageRangeAt)) {
      methods.push(new web3.extend.Method({
        name: 'storageRangeAt',
        call: 'debug_storageRangeAt',
        inputFormatter: [null, null, null, null, null],
        params: 5
      }))
    }
    if (methods.length > 0) {
      web3.extend({
        property: 'debug',
        methods: methods,
        properties: []
      })
    }
  }
}

const web3DebugNodes = {
  'Main': 'https://mainnet.infura.io/remix',
  'Rinkeby': 'https://remix-rinkeby.ethdevops.io',
  'Ropsten': 'https://remix-ropsten.ethdevops.io',
  'Goerli': 'https://remix-goerli.ethdevops.io',
  'Kovan': 'https://remix-kovan.ethdevops.io'
}
<commit_msg>change mainnet debug endpoint<commit_after>'use strict'
const Web3 = require('web3')

module.exports = {
  loadWeb3: function (url) {
    if (!url) url = 'http://localhost:8545'
    const web3 = new Web3()
    web3.setProvider(new web3.providers.HttpProvider(url))
    this.extend(web3)
    return web3
  },

  extendWeb3: function (web3) {
    this.extend(web3)
  },

  setProvider: function (web3, url) {
    web3.setProvider(new web3.providers.HttpProvider(url))
  },

  web3DebugNode: function (network) {
    if (web3DebugNodes[network]) {
      return this.loadWeb3(web3DebugNodes[network])
    }
    return null
  },

  extend: function (web3) {
    if (!web3.extend) {
      return
    }
    // DEBUG
    const methods = []
    if (!(web3.debug && web3.debug.preimage)) {
      methods.push(new web3.extend.Method({
        name: 'preimage',
        call: 'debug_preimage',
        inputFormatter: [null],
        params: 1
      }))
    }

    if (!(web3.debug && web3.debug.traceTransaction)) {
      methods.push(new web3.extend.Method({
        name: 'traceTransaction',
        call: 'debug_traceTransaction',
        inputFormatter: [null, null],
        params: 2
      }))
    }

    if (!(web3.debug && web3.debug.storageRangeAt)) {
      methods.push(new web3.extend.Method({
        name: 'storageRangeAt',
        call: 'debug_storageRangeAt',
        inputFormatter: [null, null, null, null, null],
        params: 5
      }))
    }
    if (methods.length > 0) {
      web3.extend({
        property: 'debug',
        methods: methods,
        properties: []
      })
    }
  }
}

const web3DebugNodes = {
  'Main': 'https://gethmainnet.komputing.org',
  'Rinkeby': 'https://remix-rinkeby.ethdevops.io',
  'Ropsten': 'https://remix-ropsten.ethdevops.io',
  'Goerli': 'https://remix-goerli.ethdevops.io',
  'Kovan': 'https://remix-kovan.ethdevops.io'
}
<|endoftext|>


<commit_before>import SPELLS from 'common/SPELLS';

import CoreAbilities from 'parser/core/modules/Abilities';

class Abilities extends CoreAbilities {
  spellbook() {
    const combatant = this.selectedCombatant;
    return [
      // Rotational Spells
      {
        spell: SPELLS.RENEWING_MIST,
        category: Abilities.SPELL_CATEGORIES.ROTATIONAL,
        cooldown: 9,
        charges: 2,
        gcd: {
          base: 1500,
        },
        castEfficiency: {
          suggestion: true,
        },
        timelineSortIndex: 1,
      },
      {
        spell: SPELLS.SOOTHING_MIST,
        category: Abilities.SPELL_CATEGORIES.ROTATIONAL,
        gcd: {
          base: 1000,
        },
        timelineSortIndex: 100,
      },

      // Cooldowns
      {
        spell: SPELLS.THUNDER_FOCUS_TEA,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 30,
        castEfficiency: {
          suggestion: true,
        },
        timelineSortIndex: 17,
      },
      {
        spell: SPELLS.MANA_TEA_TALENT,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 90,
        enabled: combatant.hasTalent(SPELLS.MANA_TEA_TALENT.id),
        castEfficiency: {
          suggestion: true,
        },
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 15,
      },
      {
        spell: SPELLS.CHI_BURST_TALENT,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 30,
        enabled: combatant.hasTalent(SPELLS.CHI_BURST_TALENT.id),
        castEfficiency: {
          suggestion: true,
        },
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 10,
      },
      {
        spell: SPELLS.CHI_WAVE_TALENT,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 15,
        enabled: combatant.hasTalent(SPELLS.CHI_WAVE_TALENT.id),
        castEfficiency: {
          suggestion: true,
        },
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 10,
      },
      {
        spell: SPELLS.LIFE_COCOON,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 120,
        timelineSortIndex: 17,
      },
      {
        spell: SPELLS.REVIVAL,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 180,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 18,
      },
      {
        spell: SPELLS.INVOKE_YULON_THE_JADE_SERPENT,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        enabled: !combatant.hasTalent(SPELLS.INVOKE_CHIJI_THE_RED_CRANE_TALENT.id),
        cooldown: 180,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 20,
      },

      // Other Spell Casting Metrics

      {
        spell: SPELLS.ENVELOPING_MIST,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 19,
      },
      {
        spell: SPELLS.VIVIFY,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 4,
      },
      {
        spell: SPELLS.ESSENCE_FONT,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        gcd: {
          base: 1500,
        },
        cooldown: 12,
        timelineSortIndex: 2,
      },

      {
        spell: SPELLS.REFRESHING_JADE_WIND_TALENT,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        enabled: combatant.hasTalent(SPELLS.REFRESHING_JADE_WIND_TALENT.id),
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 3,
      },
      {
        spell: SPELLS.SUMMON_JADE_SERPENT_STATUE_TALENT,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        enabled: combatant.hasTalent(SPELLS.SUMMON_JADE_SERPENT_STATUE_TALENT.id),
        gcd: {
          base: 1500,
        },
        cooldown: 10,
        timelineSortIndex: 15,
      },
      {
        spell: SPELLS.EXPEL_HARM,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        gcd: {
          base: 1000,
        },
      },

      // Utility Spells
      {
        spell: SPELLS.DIFFUSE_MAGIC_TALENT,
        buffSpellId: SPELLS.DIFFUSE_MAGIC_TALENT.id,
        category: Abilities.SPELL_CATEGORIES.DEFENSIVE,
        cooldown: 90,
        enabled: combatant.hasTalent(SPELLS.DIFFUSE_MAGIC_TALENT.id),
      },
      {
        spell: SPELLS.DAMPEN_HARM_TALENT,
        buffSpellId: SPELLS.DAMPEN_HARM_TALENT.id,
        category: Abilities.SPELL_CATEGORIES.DEFENSIVE,
        cooldown: 120,
        enabled: combatant.hasTalent(SPELLS.DAMPEN_HARM_TALENT.id),
      },
      {
        spell: SPELLS.FORTIFYING_BREW,
        buffSpellId: SPELLS.FORTIFYING_BREW.id,
        category: Abilities.SPELL_CATEGORIES.DEFENSIVE,
        cooldown: 90,
      },
      {
        spell: SPELLS.HEALING_ELIXIR_TALENT,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        charges: 2,
        cooldown: 30,
        enabled: combatant.hasTalent(SPELLS.HEALING_ELIXIR_TALENT.id),
      },
      {
        spell: SPELLS.DETOX,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 8,
        gcd: {
          base: 1500,
        },
      },
      {
        spell: SPELLS.PARALYSIS,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 45,
        gcd: {
          base: 1500,
        },
      },
      {
        spell: SPELLS.RING_OF_PEACE_TALENT,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 45,
        enabled: combatant.hasTalent(SPELLS.RING_OF_PEACE_TALENT.id),
        gcd: {
          base: 1500,
        },
      },

      {
        spell:SPELLS.LEG_SWEEP,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: combatant.hasTalent(SPELLS.TIGER_TAIL_SWEEP_TALENT.id) ? 50 : 60,
        gcd: {
          base: 1500,
        },
      },

      {
        spell: SPELLS.ROLL,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        charges: combatant.hasTalent(SPELLS.CELERITY_TALENT.id) ? 3 : 2,
        cooldown: combatant.hasTalent(SPELLS.CELERITY_TALENT.id) ? 15 : 20,
        enabled: !combatant.hasTalent(SPELLS.CHI_TORPEDO_TALENT.id),
      },
      {
        spell: SPELLS.CHI_TORPEDO_TALENT,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        charges: 2,
        cooldown: 20,
        enabled: combatant.hasTalent(SPELLS.CHI_TORPEDO_TALENT.id),
      },
      {
        spell: SPELLS.TIGERS_LUST_TALENT,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 30,
        gcd: {
          static: 1500,
        },
        enabled: combatant.hasTalent(SPELLS.TIGERS_LUST_TALENT.id),
      },
      {
        spell: SPELLS.TRANSCENDENCE,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 10,
        gcd: {
          base: 1500,
        },
      },
      {
        spell: SPELLS.TRANSCENDENCE_TRANSFER,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 25,
        gcd: {
          base: 1500,
        },
      },

      // Damage Spells
      {
        spell: SPELLS.TIGER_PALM,
        category: Abilities.SPELL_CATEGORIES.HEALER_DAMAGING_SPELL,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 31,
      },
      {
        spell: SPELLS.BLACKOUT_KICK,
        category: Abilities.SPELL_CATEGORIES.HEALER_DAMAGING_SPELL,
        cooldown: haste => 3 / (1 + haste),
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 32,
      },
      {
        spell: SPELLS.RISING_SUN_KICK,
        category: Abilities.SPELL_CATEGORIES.HEALER_DAMAGING_SPELL,
        cooldown: haste => 12 / (1 + haste),
        gcd: {
          base: 1500,
        },
        castEfficiency: {
          suggestion: combatant.hasTalent(SPELLS.RISING_MIST_TALENT.id),
        },
        timelineSortIndex: 100,
      },
      {
        spell: SPELLS.SPINNING_CRANE_KICK,
        category: Abilities.SPELL_CATEGORIES.HEALER_DAMAGING_SPELL,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 100,
      },
      {
        spell: SPELLS.CRACKLING_JADE_LIGHTNING,
        category: Abilities.SPELL_CATEGORIES.HEALER_DAMAGING_SPELL,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 100,
      },

    ];
  }
}

export default Abilities;
<commit_msg>Add ChiJi to abilities<commit_after>import SPELLS from 'common/SPELLS';

import CoreAbilities from 'parser/core/modules/Abilities';

class Abilities extends CoreAbilities {
  spellbook() {
    const combatant = this.selectedCombatant;
    return [
      // Rotational Spells
      {
        spell: SPELLS.RENEWING_MIST,
        category: Abilities.SPELL_CATEGORIES.ROTATIONAL,
        cooldown: 9,
        charges: 2,
        gcd: {
          base: 1500,
        },
        castEfficiency: {
          suggestion: true,
        },
        timelineSortIndex: 1,
      },
      {
        spell: SPELLS.SOOTHING_MIST,
        category: Abilities.SPELL_CATEGORIES.ROTATIONAL,
        gcd: {
          base: 1000,
        },
        timelineSortIndex: 100,
      },

      // Cooldowns
      {
        spell: SPELLS.THUNDER_FOCUS_TEA,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 30,
        castEfficiency: {
          suggestion: true,
        },
        timelineSortIndex: 17,
      },
      {
        spell: SPELLS.MANA_TEA_TALENT,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 90,
        enabled: combatant.hasTalent(SPELLS.MANA_TEA_TALENT.id),
        castEfficiency: {
          suggestion: true,
        },
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 15,
      },
      {
        spell: SPELLS.CHI_BURST_TALENT,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 30,
        enabled: combatant.hasTalent(SPELLS.CHI_BURST_TALENT.id),
        castEfficiency: {
          suggestion: true,
        },
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 10,
      },
      {
        spell: SPELLS.CHI_WAVE_TALENT,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 15,
        enabled: combatant.hasTalent(SPELLS.CHI_WAVE_TALENT.id),
        castEfficiency: {
          suggestion: true,
        },
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 10,
      },
      {
        spell: SPELLS.LIFE_COCOON,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 120,
        timelineSortIndex: 17,
      },
      {
        spell: SPELLS.REVIVAL,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 180,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 18,
      },
      {
        spell: SPELLS.INVOKE_YULON_THE_JADE_SERPENT,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        enabled: !combatant.hasTalent(SPELLS.INVOKE_CHIJI_THE_RED_CRANE_TALENT.id),
        cooldown: 180,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 20,
      },
      {
        spell: SPELLS.INVOKE_CHIJI_THE_RED_CRANE_TALENT,
        category: Abilities.SPELL_CATEGORIES.COOLDOWNS,
        cooldown: 180,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 20,
      },

      // Other Spell Casting Metrics
      {
        spell: SPELLS.ENVELOPING_MIST,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 19,
      },
      {
        spell: SPELLS.VIVIFY,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 4,
      },
      {
        spell: SPELLS.ESSENCE_FONT,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        gcd: {
          base: 1500,
        },
        cooldown: 12,
        timelineSortIndex: 2,
      },

      {
        spell: SPELLS.REFRESHING_JADE_WIND_TALENT,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        enabled: combatant.hasTalent(SPELLS.REFRESHING_JADE_WIND_TALENT.id),
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 3,
      },
      {
        spell: SPELLS.SUMMON_JADE_SERPENT_STATUE_TALENT,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        enabled: combatant.hasTalent(SPELLS.SUMMON_JADE_SERPENT_STATUE_TALENT.id),
        gcd: {
          base: 1500,
        },
        cooldown: 10,
        timelineSortIndex: 15,
      },
      {
        spell: SPELLS.EXPEL_HARM,
        category: Abilities.SPELL_CATEGORIES.OTHERS,
        gcd: {
          base: 1000,
        },
      },

      // Utility Spells
      {
        spell: SPELLS.DIFFUSE_MAGIC_TALENT,
        buffSpellId: SPELLS.DIFFUSE_MAGIC_TALENT.id,
        category: Abilities.SPELL_CATEGORIES.DEFENSIVE,
        cooldown: 90,
        enabled: combatant.hasTalent(SPELLS.DIFFUSE_MAGIC_TALENT.id),
      },
      {
        spell: SPELLS.DAMPEN_HARM_TALENT,
        buffSpellId: SPELLS.DAMPEN_HARM_TALENT.id,
        category: Abilities.SPELL_CATEGORIES.DEFENSIVE,
        cooldown: 120,
        enabled: combatant.hasTalent(SPELLS.DAMPEN_HARM_TALENT.id),
      },
      {
        spell: SPELLS.FORTIFYING_BREW,
        buffSpellId: SPELLS.FORTIFYING_BREW.id,
        category: Abilities.SPELL_CATEGORIES.DEFENSIVE,
        cooldown: 90,
      },
      {
        spell: SPELLS.HEALING_ELIXIR_TALENT,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        charges: 2,
        cooldown: 30,
        enabled: combatant.hasTalent(SPELLS.HEALING_ELIXIR_TALENT.id),
      },
      {
        spell: SPELLS.DETOX,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 8,
        gcd: {
          base: 1500,
        },
      },
      {
        spell: SPELLS.PARALYSIS,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 45,
        gcd: {
          base: 1500,
        },
      },
      {
        spell: SPELLS.RING_OF_PEACE_TALENT,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 45,
        enabled: combatant.hasTalent(SPELLS.RING_OF_PEACE_TALENT.id),
        gcd: {
          base: 1500,
        },
      },

      {
        spell:SPELLS.LEG_SWEEP,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: combatant.hasTalent(SPELLS.TIGER_TAIL_SWEEP_TALENT.id) ? 50 : 60,
        gcd: {
          base: 1500,
        },
      },

      {
        spell: SPELLS.ROLL,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        charges: combatant.hasTalent(SPELLS.CELERITY_TALENT.id) ? 3 : 2,
        cooldown: combatant.hasTalent(SPELLS.CELERITY_TALENT.id) ? 15 : 20,
        enabled: !combatant.hasTalent(SPELLS.CHI_TORPEDO_TALENT.id),
      },
      {
        spell: SPELLS.CHI_TORPEDO_TALENT,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        charges: 2,
        cooldown: 20,
        enabled: combatant.hasTalent(SPELLS.CHI_TORPEDO_TALENT.id),
      },
      {
        spell: SPELLS.TIGERS_LUST_TALENT,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 30,
        gcd: {
          static: 1500,
        },
        enabled: combatant.hasTalent(SPELLS.TIGERS_LUST_TALENT.id),
      },
      {
        spell: SPELLS.TRANSCENDENCE,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 10,
        gcd: {
          base: 1500,
        },
      },
      {
        spell: SPELLS.TRANSCENDENCE_TRANSFER,
        category: Abilities.SPELL_CATEGORIES.UTILITY,
        cooldown: 25,
        gcd: {
          base: 1500,
        },
      },

      // Damage Spells
      {
        spell: SPELLS.TIGER_PALM,
        category: Abilities.SPELL_CATEGORIES.HEALER_DAMAGING_SPELL,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 31,
      },
      {
        spell: SPELLS.BLACKOUT_KICK,
        category: Abilities.SPELL_CATEGORIES.HEALER_DAMAGING_SPELL,
        cooldown: haste => 3 / (1 + haste),
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 32,
      },
      {
        spell: SPELLS.RISING_SUN_KICK,
        category: Abilities.SPELL_CATEGORIES.HEALER_DAMAGING_SPELL,
        cooldown: haste => 12 / (1 + haste),
        gcd: {
          base: 1500,
        },
        castEfficiency: {
          suggestion: combatant.hasTalent(SPELLS.RISING_MIST_TALENT.id),
        },
        timelineSortIndex: 100,
      },
      {
        spell: SPELLS.SPINNING_CRANE_KICK,
        category: Abilities.SPELL_CATEGORIES.HEALER_DAMAGING_SPELL,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 100,
      },
      {
        spell: SPELLS.CRACKLING_JADE_LIGHTNING,
        category: Abilities.SPELL_CATEGORIES.HEALER_DAMAGING_SPELL,
        gcd: {
          base: 1500,
        },
        timelineSortIndex: 100,
      },

    ];
  }
}

export default Abilities;
<|endoftext|>