<commit_before>AUI.add('dialog', function(A) {

var L = A.Lang,
	isBoolean = L.isBoolean,
	isNumber = L.isNumber,
	isString = L.isString,
	isArray = L.isArray,
	isObject = L.isObject,

	ADD_CLASS = 'addClass',
	ANCHOR = 'a',
	BLANK = '',
	BODY_CONTENT = 'bodyContent',
	BOUNDING_BOX = 'boundingBox',
	BUTTON = 'button',
	BUTTONS = 'buttons',
	CLOSE = 'close',
	CONSTRAIN_TO_VIEWPORT = 'constrain2view',
	CONTAINER = 'container',
	CONTENT_BOX = 'contentBox',
	DD = 'dd',
	DEFAULT = 'default',
	DIALOG = 'dialog',
	DOT = '.',
	DRAGGABLE = 'draggable',
	DRAG_INSTANCE = 'dragInstance',
	FOOTER_CONTENT = 'footerContent',
	GROUP = 'group',
	HD = 'hd',
	HEADER = 'header',
	HEADER_CONTENT = 'headerContent',
	HOVER = 'hover',
	ICON = 'icon',
	INNER_HTML = 'innerHTML',
	IO = 'io',
	LOADING = 'loading',
	POST = 'POST',
	REMOVE_CLASS = 'removeClass',
	STACK = 'stack',
	STATE = 'state',
	TITLE = 'title',
	TOOL = 'tool',
	WIDGET = 'widget',

	getCN = A.ClassNameManager.getClassName,

	CSS_DIALOG_BUTTON = getCN(DIALOG, BUTTON),
	CSS_DIALOG_BUTTON_CONTAINER = getCN(DIALOG, BUTTON, CONTAINER),
	CSS_DIALOG_BUTTON_DEFAULT = getCN(DIALOG, BUTTON, DEFAULT),
	CSS_DIALOG_CLOSE = getCN(DIALOG, CLOSE),
	CSS_DIALOG_TITLE = getCN(DIALOG, TITLE),
	CSS_ICON = getCN(ICON),
	CSS_ICON_CLOSE = getCN(ICON, CLOSE),
	CSS_ICON_LOADING = getCN(ICON, LOADING),
	CSS_PREFIX = getCN(DD),
	CSS_STATE_DEFAULT = getCN(STATE, DEFAULT),
	CSS_STATE_HOVER = getCN(STATE, HOVER),
	CSS_TOOL = getCN(TOOL),
	CSS_WIDGET_HD = getCN(WIDGET, HD),

	TPL_LOADING = '

';

function Dialog(config) {
	Dialog.superclass.constructor.apply(this, arguments);
}

A.mix(Dialog, {
	NAME: DIALOG,

	ATTRS: {
		buttons: {
			value: [],
			validator: isArray
		},

		constrain2view: {
			value: true,
			validator: isBoolean
		},

		draggable: {
			lazyAdd: true,
			value: false,
			setter: function(v) {
				return this._setDraggable(v);
			}
		},

		dragInstance: {
			value: null
		},

		group: {
			value: DEFAULT,
			validator: isString
		},

		headerContent: {
			writeOnce: true,
			getter: function() {
				return this.titleContainter;
			}
		},

		io: {
			lazyAdd: true,
			value: null,
			setter: function(v) {
				return this._setIO(v);
			}
		},

		ioCfg: {
			value: null
		},

		stack: {
			lazyAdd: true,
			value: false,
			setter: function(v) {
				return this._setStack(v);
			},
			validator: isBoolean
		},

		title: {
			value: BLANK,
			validator: isString
		}
	}
});

A.extend(Dialog, A.Overlay, {
	/*
	* Lifecycle
	*/
	renderUI: function () {
		var instance = this;

		instance._renderElements();
	},

	bindUI: function () {
		var instance = this;

		instance._bindElements();
	},

	renderer: function() {
		var instance = this;

		Dialog.superclass.renderer.apply(instance, arguments);

		instance._afterRenderer();
	},

	destructor: function() {
		var instance = this;

		if (instance.OverlayManager) {
			instance.OverlayManager.destroy();
		}

		instance.get(BOUNDING_BOX).remove();
	},

	/*
	* Methods
	*/
	_bindElements: function () {
		var instance = this;
		var boundingBox = instance.get(BOUNDING_BOX);
		var closeIconContainter = instance.closeIconContainter;

		var closeFn = function(event) {
			var method = { mouseover: ADD_CLASS, mouseout: REMOVE_CLASS }[event.type];
			event.currentTarget[method](CSS_STATE_HOVER);
		};

		closeIconContainter.on('mouseover', closeFn);
		closeIconContainter.on('mouseout', closeFn);

		closeIconContainter.on('click', function(event) {
			instance.hide();
			instance.fire('close');
		});

		boundingBox.on('mousedown', function() {
			if (instance.OverlayManager) {
				instance.OverlayManager.bringToTop();
			}

			instance.fire('focus');
		});

		instance.after('titleChange', this._afterSetTitle);
	},

	_renderElements: function() {
		var instance = this;

		instance.titleContainter = A.Node.create('

');
		instance.closeIconContainter = A.Node.create('');
		instance.closeIcon = A.Node.create('');

		var closeIcon = instance.closeIcon;
		var closeIconContainter = instance.closeIconContainter;
		var title = instance.get(TITLE);
		var titleContainter = instance.titleContainter;

		closeIcon.addClass(CSS_ICON);
		closeIcon.addClass(CSS_ICON_CLOSE);
		closeIconContainter.addClass(CSS_DIALOG_CLOSE);
		closeIconContainter.addClass(CSS_STATE_DEFAULT);
		closeIconContainter.addClass(CSS_TOOL);
		titleContainter.addClass(CSS_DIALOG_TITLE);

		instance.titleContainter.html(title);
	},

	_afterRenderer: function() {
		var instance = this;
		var headerNode = instance.headerNode;
		var stack = instance.get(STACK);
		var closeIconContainter = instance.closeIconContainter;

		headerNode.addClass(CSS_STATE_DEFAULT);

		headerNode.append(instance.titleContainter);
		headerNode.append(closeIconContainter);
		closeIconContainter.append(instance.closeIcon);

		instance._initButtons();

		// forcing lazyAdd:true attrs call the setter
		instance.get(DRAGGABLE);
		instance.get(IO);
	},

	_initButtons: function() {
		var instance = this;
		var buttons = instance.get(BUTTONS);
		var container = A.Node.create('

');
		var nodeModel = A.Node.create('<button></button>');

		container.addClass(CSS_DIALOG_BUTTON_CONTAINER);
		nodeModel.addClass(CSS_DIALOG_BUTTON);

		A.each(buttons, function(button, i) {
			var node = nodeModel.cloneNode();

			if (button.isDefault) {
				node.addClass(CSS_DIALOG_BUTTON_DEFAULT);
			}

			if (button.handler) {
				node.on('click', A.bind(button.handler, instance));
			}

			node.html(button.text || BLANK);

			container.append(node);
		});

		if (buttons.length) {
			instance.set(FOOTER_CONTENT, container);
		}
	},

	_setDraggable: function(value) {
		var instance = this;
		var boundingBox = instance.get(BOUNDING_BOX);

		var destroyDraggable = function() {
			var dragInstance = instance.get(DRAG_INSTANCE);

			if (dragInstance) {
				// TODO - YUI3 has a bug when destroy and recreates
				dragInstance.destroy();
				dragInstance.unplug(A.Plugin.DDConstrained);
			}
		};

		A.DD.DDM.CSS_PREFIX = CSS_PREFIX;

		if (value) {
			var defaults = {
				node: boundingBox,
				handles: [ DOT + CSS_WIDGET_HD ]
			};
			var dragOptions = A.merge(defaults, instance.get(DRAGGABLE) || {});

			// change the drag scope callback to execute using the dialog scope
			if (dragOptions.on) {
				A.each(dragOptions.on, function(fn, eventName) {
					dragOptions.on[eventName] = A.bind(fn, instance);
				});
			}

			destroyDraggable();

			var dragInstance = new A.DD.Drag(dragOptions);

			dragInstance.plug(A.Plugin.DDConstrained, {
				constrain2view: instance.get(CONSTRAIN_TO_VIEWPORT)
			});

			instance.set(DRAG_INSTANCE, dragInstance);
		}
		else {
			destroyDraggable();
		}

		return value;
	},

	_setIO: function(value) {
		var instance = this;

		if (value && !instance.get(BODY_CONTENT)) {
			instance.set(BODY_CONTENT, TPL_LOADING);
		}

		if (value) {
			instance.unplug(A.Plugin.StdModIOPlugin);

			value.uri = value.uri || value.url;

			value.cfg = A.merge({
				method: POST
			},
			value.cfg);

			var data = value.cfg.data;

			if (isObject(data)) {
				value.cfg.data = A.toQueryString(data);
			}

			instance.plug(A.Plugin.StdModIOPlugin, value);

			if (instance.io) {
				instance.io.refresh();
			}
		}
		else {
			instance.unplug(A.Plugin.StdModIOPlugin);
		}

		return value;
	},

	_setStack: function(value) {
		var instance = this;

		if (value) {
			instance.unplug(A.Plugin.OverlayManager);

			instance.plug(A.Plugin.OverlayManager, {
				group: instance.get(GROUP)
			});
		}
		else {
			instance.unplug(A.Plugin.OverlayManager);
		}

		return value;
	},

	/*
	* Attribute Listeners
	*/
	_afterSetTitle: function(event) {
		var instance = this;

		instance.titleContainter.html(event.newVal);
	}
});

A.Dialog = Dialog;

}, '@VERSION', { requires: [ 'aui-base', 'overlay', 'dd-constrain', 'overlay-manager', 'io-stdmod', 'dialog-css' ] });<commit_msg>Dialog set stack and default to true<commit_after>AUI.add('dialog', function(A) {

var L = A.Lang,
	isBoolean = L.isBoolean,
	isNumber = L.isNumber,
	isString = L.isString,
	isArray = L.isArray,
	isObject = L.isObject,

	ADD_CLASS = 'addClass',
	ANCHOR = 'a',
	BLANK = '',
	BODY_CONTENT = 'bodyContent',
	BOUNDING_BOX = 'boundingBox',
	BUTTON = 'button',
	BUTTONS = 'buttons',
	CLOSE = 'close',
	CONSTRAIN_TO_VIEWPORT = 'constrain2view',
	CONTAINER = 'container',
	CONTENT_BOX = 'contentBox',
	DD = 'dd',
	DEFAULT = 'default',
	DIALOG = 'dialog',
	DOT = '.',
	DRAGGABLE = 'draggable',
	DRAG_INSTANCE = 'dragInstance',
	FOOTER_CONTENT = 'footerContent',
	GROUP = 'group',
	HD = 'hd',
	HEADER = 'header',
	HEADER_CONTENT = 'headerContent',
	HOVER = 'hover',
	ICON = 'icon',
	INNER_HTML = 'innerHTML',
	IO = 'io',
	LOADING = 'loading',
	POST = 'POST',
	REMOVE_CLASS = 'removeClass',
	STACK = 'stack',
	STATE = 'state',
	TITLE = 'title',
	TOOL = 'tool',
	WIDGET = 'widget',

	getCN = A.ClassNameManager.getClassName,

	CSS_DIALOG_BUTTON = getCN(DIALOG, BUTTON),
	CSS_DIALOG_BUTTON_CONTAINER = getCN(DIALOG, BUTTON, CONTAINER),
	CSS_DIALOG_BUTTON_DEFAULT = getCN(DIALOG, BUTTON, DEFAULT),
	CSS_DIALOG_CLOSE = getCN(DIALOG, CLOSE),
	CSS_DIALOG_TITLE = getCN(DIALOG, TITLE),
	CSS_ICON = getCN(ICON),
	CSS_ICON_CLOSE = getCN(ICON, CLOSE),
	CSS_ICON_LOADING = getCN(ICON, LOADING),
	CSS_PREFIX = getCN(DD),
	CSS_STATE_DEFAULT = getCN(STATE, DEFAULT),
	CSS_STATE_HOVER = getCN(STATE, HOVER),
	CSS_TOOL = getCN(TOOL),
	CSS_WIDGET_HD = getCN(WIDGET, HD),

	TPL_LOADING = '

';

function Dialog(config) {
	Dialog.superclass.constructor.apply(this, arguments);
}

A.mix(Dialog, {
	NAME: DIALOG,

	ATTRS: {
		buttons: {
			value: [],
			validator: isArray
		},

		constrain2view: {
			value: true,
			validator: isBoolean
		},

		draggable: {
			lazyAdd: true,
			value: true,
			setter: function(v) {
				return this._setDraggable(v);
			}
		},

		dragInstance: {
			value: null
		},

		group: {
			value: DEFAULT,
			validator: isString
		},

		headerContent: {
			writeOnce: true,
			getter: function() {
				return this.titleContainter;
			}
		},

		io: {
			lazyAdd: true,
			value: null,
			setter: function(v) {
				return this._setIO(v);
			}
		},

		ioCfg: {
			value: null
		},

		stack: {
			lazyAdd: true,
			value: true,
			setter: function(v) {
				return this._setStack(v);
			},
			validator: isBoolean
		},

		title: {
			value: BLANK,
			validator: isString
		}
	}
});

A.extend(Dialog, A.Overlay, {
	/*
	* Lifecycle
	*/
	renderUI: function () {
		var instance = this;

		instance._renderElements();
	},

	bindUI: function () {
		var instance = this;

		instance._bindElements();
	},

	renderer: function() {
		var instance = this;

		Dialog.superclass.renderer.apply(instance, arguments);

		instance._afterRenderer();
	},

	destructor: function() {
		var instance = this;

		if (instance.OverlayManager) {
			instance.OverlayManager.destroy();
		}

		instance.get(BOUNDING_BOX).remove();
	},

	/*
	* Methods
	*/
	_bindElements: function () {
		var instance = this;
		var boundingBox = instance.get(BOUNDING_BOX);
		var closeIconContainter = instance.closeIconContainter;

		var closeFn = function(event) {
			var method = { mouseover: ADD_CLASS, mouseout: REMOVE_CLASS }[event.type];
			event.currentTarget[method](CSS_STATE_HOVER);
		};

		closeIconContainter.on('mouseover', closeFn);
		closeIconContainter.on('mouseout', closeFn);

		closeIconContainter.on('click', function(event) {
			instance.hide();
			instance.fire('close');
		});

		boundingBox.on('mousedown', function() {
			if (instance.OverlayManager) {
				instance.OverlayManager.bringToTop();
			}

			instance.fire('focus');
		});

		instance.after('titleChange', this._afterSetTitle);
	},

	_renderElements: function() {
		var instance = this;

		instance.titleContainter = A.Node.create('

');
		instance.closeIconContainter = A.Node.create('');
		instance.closeIcon = A.Node.create('');

		var closeIcon = instance.closeIcon;
		var closeIconContainter = instance.closeIconContainter;
		var title = instance.get(TITLE);
		var titleContainter = instance.titleContainter;

		closeIcon.addClass(CSS_ICON);
		closeIcon.addClass(CSS_ICON_CLOSE);
		closeIconContainter.addClass(CSS_DIALOG_CLOSE);
		closeIconContainter.addClass(CSS_STATE_DEFAULT);
		closeIconContainter.addClass(CSS_TOOL);
		titleContainter.addClass(CSS_DIALOG_TITLE);

		instance.titleContainter.html(title);
	},

	_afterRenderer: function() {
		var instance = this;
		var headerNode = instance.headerNode;
		var stack = instance.get(STACK);
		var closeIconContainter = instance.closeIconContainter;

		headerNode.addClass(CSS_STATE_DEFAULT);

		headerNode.append(instance.titleContainter);
		headerNode.append(closeIconContainter);
		closeIconContainter.append(instance.closeIcon);

		instance._initButtons();

		// forcing lazyAdd:true attrs call the setter
		instance.get(DRAGGABLE);
		instance.get(IO);
	},

	_initButtons: function() {
		var instance = this;
		var buttons = instance.get(BUTTONS);
		var container = A.Node.create('

');
		var nodeModel = A.Node.create('<button></button>');

		container.addClass(CSS_DIALOG_BUTTON_CONTAINER);
		nodeModel.addClass(CSS_DIALOG_BUTTON);

		A.each(buttons, function(button, i) {
			var node = nodeModel.cloneNode();

			if (button.isDefault) {
				node.addClass(CSS_DIALOG_BUTTON_DEFAULT);
			}

			if (button.handler) {
				node.on('click', A.bind(button.handler, instance));
			}

			node.html(button.text || BLANK);

			container.append(node);
		});

		if (buttons.length) {
			instance.set(FOOTER_CONTENT, container);
		}
	},

	_setDraggable: function(value) {
		var instance = this;
		var boundingBox = instance.get(BOUNDING_BOX);

		var destroyDraggable = function() {
			var dragInstance = instance.get(DRAG_INSTANCE);

			if (dragInstance) {
				// TODO - YUI3 has a bug when destroy and recreates
				dragInstance.destroy();
				dragInstance.unplug(A.Plugin.DDConstrained);
			}
		};

		A.DD.DDM.CSS_PREFIX = CSS_PREFIX;

		if (value) {
			var defaults = {
				node: boundingBox,
				handles: [ DOT + CSS_WIDGET_HD ]
			};
			var dragOptions = A.merge(defaults, instance.get(DRAGGABLE) || {});

			// change the drag scope callback to execute using the dialog scope
			if (dragOptions.on) {
				A.each(dragOptions.on, function(fn, eventName) {
					dragOptions.on[eventName] = A.bind(fn, instance);
				});
			}

			destroyDraggable();

			var dragInstance = new A.DD.Drag(dragOptions);

			dragInstance.plug(A.Plugin.DDConstrained, {
				constrain2view: instance.get(CONSTRAIN_TO_VIEWPORT)
			});

			instance.set(DRAG_INSTANCE, dragInstance);
		}
		else {
			destroyDraggable();
		}

		return value;
	},

	_setIO: function(value) {
		var instance = this;

		if (value && !instance.get(BODY_CONTENT)) {
			instance.set(BODY_CONTENT, TPL_LOADING);
		}

		if (value) {
			instance.unplug(A.Plugin.StdModIOPlugin);

			value.uri = value.uri || value.url;

			value.cfg = A.merge({
				method: POST
			},
			value.cfg);

			var data = value.cfg.data;

			if (isObject(data)) {
				value.cfg.data = A.toQueryString(data);
			}

			instance.plug(A.Plugin.StdModIOPlugin, value);

			if (instance.io) {
				instance.io.refresh();
			}
		}
		else {
			instance.unplug(A.Plugin.StdModIOPlugin);
		}

		return value;
	},

	_setStack: function(value) {
		var instance = this;

		if (value) {
			instance.unplug(A.Plugin.OverlayManager);

			instance.plug(A.Plugin.OverlayManager, {
				group: instance.get(GROUP)
			});
		}
		else {
			instance.unplug(A.Plugin.OverlayManager);
		}

		return value;
	},

	/*
	* Attribute Listeners
	*/
	_afterSetTitle: function(event) {
		var instance = this;

		instance.titleContainter.html(event.newVal);
	}
});

A.Dialog = Dialog;

}, '@VERSION', { requires: [ 'aui-base', 'overlay-manager', 'dd-constrain', 'io-stdmod', 'dialog-css' ] });<|endoftext|>


<commit_before>// ==UserScript==
// @id             iitc-plugin-scoreboard@vita10gy
// @name           iitc: show a localized scoreboard.
// @version        0.1.1
// @namespace      https://github.com/breunigs/ingress-intel-total-conversion
// @updateURL      https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scoreboard.user.js
// @downloadURL    https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scoreboard.user.js
// @description    A localized scoreboard.
// @include        https://www.ingress.com/intel*
// @match          https://www.ingress.com/intel*
// ==/UserScript==

function wrapper() {
// ensure plugin framework is there, even if iitc is not yet loaded
if(typeof window.plugin !== 'function') window.plugin = function() {};

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
window.plugin.scoreboard = function() {};

window.plugin.scoreboard.scores = {};
window.plugin.scoreboard.playerGuids = new Array();

window.plugin.scoreboard.resetTeam = function(team) {
  var scores = window.plugin.scoreboard.scores['team'];
  scores[team] = {};
  scores[team]['mu'] = 0;
  scores[team]['count_fields'] = 0;
  scores[team]['count_links'] = 0;
  scores[team]['count_portals'] = 0;
  scores[team]['count_resonators'] = 0;
  scores[team]['largest'] = {};
};

window.plugin.scoreboard.initPlayer = function(player, team) {
  var scores = window.plugin.scoreboard.scores['player'];
  if(scores[player] === undefined) {
    scores[player] = {};
    scores[player]['team'] = team;
    scores[player]['mu'] = 0;
    scores[player]['count_fields'] = 0;
    scores[player]['count_links'] = 0;
    scores[player]['count_portals'] = 0;
    scores[player]['count_resonators'] = 0;
    //  scores[player]['count_shields'] = 0;
    scores[player]['largest'] = {};
    window.plugin.scoreboard.playerGuids.push(player);
  }
}

window.plugin.scoreboard.compileStats = function() {
  var somethingInView = false;
  window.plugin.scoreboard.playerGuids = new Array();
  window.plugin.scoreboard.scores = {'team': {}, 'player': {}};
  var scores = window.plugin.scoreboard.scores;
  window.plugin.scoreboard.resetTeam(TEAM_RES);
  window.plugin.scoreboard.resetTeam(TEAM_ENL);

  $.each(window.fields, function(qk, val) {
    var team = getTeam(val.options.data);
    var player = val.options.data.creator.creatorGuid;

    window.plugin.scoreboard.initPlayer(player,team);

    // Google sends fields long since dead in the data. This makes sure it's still actually up.
    if(window.portals[val.options.vertices.vertexA.guid] !== undefined ||
       window.portals[val.options.vertices.vertexB.guid] !== undefined ||
       window.portals[val.options.vertices.vertexC.guid] !== undefined ) {

      somethingInView = true;
      scores['team'][team]['mu'] += parseInt(val.options.data.entityScore.entityScore);
      scores['player'][player]['mu'] += parseInt(val.options.data.entityScore.entityScore);
      scores['team'][team]['count_fields']++;
      scores['player'][player]['count_fields']++;

      //var largestMu = scores['team'][team]['largest']['mu'];
      //if(largestMu === undefined || parseInt(largestMu.options.data.entityScore.entityScore) < parseInt(val.options.data.entityScore.entityScore)) {
      //  largestMu = val;
      //}
      //scores['team'][team]['largest']['mu'] = largestMu;
      //
      //var largestMu = scores['player'][player]['largest']['mu'];
      //if(largestMu === undefined || parseInt(largestMu.options.data.entityScore.entityScore) < parseInt(val.options.data.entityScore.entityScore)) {
      //  largestMu = val;
      //}
      //scores['player'][player]['largest']['mu'] = largestMu;
    }
  });
  $.each(window.links, function(qk, link) {
    somethingInView = true;
    var team = getTeam(link.options.data);
    var player = link.options.data.creator.creatorGuid;
    window.plugin.scoreboard.initPlayer(player, team);
    scores['team'][team]['count_links']++;
    scores['player'][player]['count_links']++;
  });
  $.each(window.portals, function(qk, portal) {
    somethingInView = true;
    var team = getTeam(portal.options.details);
    var player = portal.options.details.captured.capturingPlayerId;
    window.plugin.scoreboard.initPlayer(player, team);
    scores['team'][team]['count_portals']++;
    scores['player'][player]['count_portals']++;

    //$.each(portal.options.details.portalV2.linkedModArray, function(ind, mod) {
    //  if(mod !== null) {
    //    somethingInView = true;
    //    scores['team'][team]['count_shields']++;
    //    scores['player'][mod.installingUser]['count_shields']++;
    //  }
    //});

    $.each(portal.options.details.resonatorArray.resonators, function(ind, reso) {
      if(reso !== null) {
        somethingInView = true;
        window.plugin.scoreboard.initPlayer(reso.ownerGuid, team);
        scores['team'][team]['count_resonators']++;
        scores['player'][reso.ownerGuid]['count_resonators']++;
      }
    });
  });
  return somethingInView;
};

window.plugin.scoreboard.percentSpan = function(percent, cssClass) {
   var retVal = '';
   if(percent > 0) {
      retVal += '' + percent;
      if(percent >= 7) { // anything less than this and the text doesnt fit in the span.
        retVal += '%';
      }
      retVal += '';
   }
   return retVal;
};

window.plugin.scoreboard.teamTableRow = function(field,title) {
  var scores = window.plugin.scoreboard.scores['team'];
  var retVal = '
'
   + title
   + '	'
   + scores[TEAM_RES][field]
   + '	'
   + scores[TEAM_ENL][field]
   + '	'
   + (scores[TEAM_RES][field] + scores[TEAM_ENL][field])
   + '
';
  return retVal;
};

window.plugin.scoreboard.playerTableRow = function(playerGuid) {
  var scores = window.plugin.scoreboard.scores['player'];
  var retVal = '
'
    + window.getPlayerName(playerGuid);
    + '	';

  $.each(['mu','count_fields','count_links','count_portals','count_resonators'], function(i, field) {
    retVal += ''
      + scores[playerGuid][field]
      + '	';
  });
  retVal += '
';
  return retVal;
};

window.plugin.scoreboard.playerTable = function(sortBy) {

  // Sort the playerGuid array by sortBy
  window.plugin.scoreboard.playerGuids.sort(function(a, b) {
    var playerA = window.plugin.scoreboard.scores['player'][a];
    var playerB = window.plugin.scoreboard.scores['player'][b];
    var retVal = 0;
    if(sortBy === 'names') {
      retVal = window.getPlayerName(a).toLowerCase() < window.getPlayerName(b).toLowerCase() ? -1 : 1;
    } else {
      retVal = playerB[sortBy] - playerA[sortBy];
    }
    return retVal;
  });

  var sort = window.plugin.scoreboard.playerTableSort;
  var scoreHtml = '
'
                + '
Player	'
                + 'Mu	'
                + 'Fields	'
                + 'Links	'
                + 'Portals	'
                + 'Resonators
';
  $.each(window.plugin.scoreboard.playerGuids, function(index, guid) {
    scoreHtml += window.plugin.scoreboard.playerTableRow(guid);
  });
  scoreHtml += '
';

  return scoreHtml;
}

// A little helper functon so the above isn't so messy
window.plugin.scoreboard.playerTableSort = function(name, by) {
  var retVal = 'sort="' + name + '"';
  if(name === by) {
    retVal += ' class="sorted"';
  }
  return retVal;
};

window.plugin.scoreboard.display = function() {

  var somethingInView = window.plugin.scoreboard.compileStats();

  var resMu = window.plugin.scoreboard.scores['team'][TEAM_RES]['mu'];
  var enlMu = window.plugin.scoreboard.scores['team'][TEAM_ENL]['mu'];

  var scoreHtml = '';
  if(somethingInView) {

    if(resMu + enlMu > 0) {
      var resMuPercent = Math.round((resMu / (resMu + enlMu)) * 100);
      scoreHtml += '
'
        + window.plugin.scoreboard.percentSpan(resMuPercent, 'res')
        + window.plugin.scoreboard.percentSpan(100-resMuPercent, 'enl')
        + '
';
    }

    scoreHtml += '
'
              + '
	Resistance	Enlightened	Total
';
    scoreHtml += window.plugin.scoreboard.teamTableRow('mu','Mu');
    scoreHtml += window.plugin.scoreboard.teamTableRow('count_fields','Fields');
    scoreHtml += window.plugin.scoreboard.teamTableRow('count_links','Links');
    scoreHtml += window.plugin.scoreboard.teamTableRow('count_portals','Portals');
    scoreHtml += window.plugin.scoreboard.teamTableRow('count_resonators','Resonators');
    scoreHtml += '
';

    scoreHtml += '
';
    scoreHtml += window.plugin.scoreboard.playerTable('mu');
    scoreHtml += '
';

    scoreHtml += '
Score is subject to portals available based on zoom level. If names are unresolved try again. For best results wait until updates are fully loaded.
';
  } else {
    scoreHtml += 'You need something in view.';
  }

  alert('
' + scoreHtml + '
');
  $(".ui-dialog").addClass('ui-dialog-scoreboard');

  // Setup sorting
  $(document).on('click', '#players table th', function() {
    $('#players').html(window.plugin.scoreboard.playerTable($(this).attr('sort')));
  });
}

var setup =  function() {
  $('body').append('

');
  $('#toolbox').append('scoreboard');
  $('head').append('');
}

// PLUGIN END //////////////////////////////////////////////////////////

if(window.iitcLoaded && typeof setup === 'function') {
  setup();
} else {
  if(window.bootPlugins)
    window.bootPlugins.push(setup);
  else
    window.bootPlugins = [setup];
}
} // wrapper end
// inject code into site context
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ wrapper +')();'));
(document.body || document.head || document.documentElement).appendChild(script);
<commit_msg>Style changes - Use Largest field info<commit_after>// ==UserScript==
// @id             iitc-plugin-scoreboard@vita10gy
// @name           iitc: show a localized scoreboard.
// @version        0.1.1
// @namespace      https://github.com/breunigs/ingress-intel-total-conversion
// @updateURL      https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scoreboard.user.js
// @downloadURL    https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/scoreboard.user.js
// @description    A localized scoreboard.
// @include        https://www.ingress.com/intel*
// @match          https://www.ingress.com/intel*
// ==/UserScript==

function wrapper() {
// ensure plugin framework is there, even if iitc is not yet loaded
if(typeof window.plugin !== 'function') window.plugin = function() {};

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
window.plugin.scoreboard = function() {};

window.plugin.scoreboard.scores = {};
window.plugin.scoreboard.playerGuids = new Array();

window.plugin.scoreboard.resetTeam = function(team) {
  var scores = window.plugin.scoreboard.scores['team'];
  scores[team] = {};
  scores[team]['mu'] = 0;
  scores[team]['count_fields'] = 0;
  scores[team]['count_links'] = 0;
  scores[team]['count_portals'] = 0;
  scores[team]['count_resonators'] = 0;
  scores[team]['largest'] = {};
};

window.plugin.scoreboard.initPlayer = function(player, team) {
  var scores = window.plugin.scoreboard.scores['player'];
  if(scores[player] === undefined) {
    scores[player] = {};
    scores[player]['team'] = team;
    scores[player]['mu'] = 0;
    scores[player]['count_fields'] = 0;
    scores[player]['count_links'] = 0;
    scores[player]['count_portals'] = 0;
    scores[player]['count_resonators'] = 0;
    //  scores[player]['count_shields'] = 0;
    scores[player]['largest'] = {};
    window.plugin.scoreboard.playerGuids.push(player);
  }
}

window.plugin.scoreboard.compileStats = function() {
  var somethingInView = false;
  window.plugin.scoreboard.playerGuids = new Array();
  window.plugin.scoreboard.scores = {'team': {}, 'player': {}};
  var scores = window.plugin.scoreboard.scores;
  window.plugin.scoreboard.resetTeam(TEAM_RES);
  window.plugin.scoreboard.resetTeam(TEAM_ENL);

  $.each(window.fields, function(qk, val) {
    var team = getTeam(val.options.data);
    var player = val.options.data.creator.creatorGuid;

    window.plugin.scoreboard.initPlayer(player,team);

    // Google sends fields long since dead in the data. This makes sure it's still actually up.
    if(window.portals[val.options.vertices.vertexA.guid] !== undefined ||
       window.portals[val.options.vertices.vertexB.guid] !== undefined ||
       window.portals[val.options.vertices.vertexC.guid] !== undefined ) {

      somethingInView = true;
      scores['team'][team]['mu'] += parseInt(val.options.data.entityScore.entityScore);
      scores['player'][player]['mu'] += parseInt(val.options.data.entityScore.entityScore);
      scores['team'][team]['count_fields']++;
      scores['player'][player]['count_fields']++;

      var largestMu = scores['team'][team]['largest']['mu'];
      if(largestMu === undefined || parseInt(largestMu.options.data.entityScore.entityScore) < parseInt(val.options.data.entityScore.entityScore)) {
        largestMu = val;
      }
      scores['team'][team]['largest']['mu'] = largestMu;

      var largestMu = scores['player'][player]['largest']['mu'];
      if(largestMu === undefined || parseInt(largestMu.options.data.entityScore.entityScore) < parseInt(val.options.data.entityScore.entityScore)) {
        largestMu = val;
      }
      scores['player'][player]['largest']['mu'] = largestMu;
    }
  });
  $.each(window.links, function(qk, link) {
    somethingInView = true;
    var team = getTeam(link.options.data);
    var player = link.options.data.creator.creatorGuid;
    window.plugin.scoreboard.initPlayer(player, team);
    scores['team'][team]['count_links']++;
    scores['player'][player]['count_links']++;
  });
  $.each(window.portals, function(qk, portal) {
    somethingInView = true;
    var team = getTeam(portal.options.details);
    var player = portal.options.details.captured.capturingPlayerId;
    window.plugin.scoreboard.initPlayer(player, team);
    scores['team'][team]['count_portals']++;
    scores['player'][player]['count_portals']++;

    //$.each(portal.options.details.portalV2.linkedModArray, function(ind, mod) {
    //  if(mod !== null) {
    //    somethingInView = true;
    //    scores['team'][team]['count_shields']++;
    //    scores['player'][mod.installingUser]['count_shields']++;
    //  }
    //});

    $.each(portal.options.details.resonatorArray.resonators, function(ind, reso) {
      if(reso !== null) {
        somethingInView = true;
        window.plugin.scoreboard.initPlayer(reso.ownerGuid, team);
        scores['team'][team]['count_resonators']++;
        scores['player'][reso.ownerGuid]['count_resonators']++;
      }
    });
  });
  return somethingInView;
};

window.plugin.scoreboard.percentSpan = function(percent, cssClass) {
   var retVal = '';
   if(percent > 0) {
      retVal += '' + percent;
      if(percent >= 7) { // anything less than this and the text doesnt fit in the span.
        retVal += '%';
      }
      retVal += '';
   }
   return retVal;
};

window.plugin.scoreboard.teamTableRow = function(field,title) {
  var scores = window.plugin.scoreboard.scores['team'];
  var retVal = '
'
   + title
   + '	'
   + window.digits(scores[TEAM_RES][field])
   + '	'
   + window.digits(scores[TEAM_ENL][field])
   + '	'
   + window.digits(scores[TEAM_RES][field] + scores[TEAM_ENL][field])
   + '
';
  return retVal;
};

window.plugin.scoreboard.fieldInfo = function(field) {
  var title = '';
  var retVal = '';

  if(field !== undefined) {
    var portal = window.portals[field.options.vertices.vertexA.guid];
    if(portal !== undefined) {
      title = ' @' + portal.options.details.portalV2.descriptiveText.TITLE;
    }

    retVal = '
'
      + field.options.data.entityScore.entityScore
      + ' - ' + window.getPlayerName(field.options.data.creator.creatorGuid)
      + '
';
  }  else {
    retVal = 'N/A';
  }
  return retVal;
};

window.plugin.scoreboard.playerTableRow = function(playerGuid) {
  var scores = window.plugin.scoreboard.scores['player'];
  var retVal = '
'
    + window.getPlayerName(playerGuid);
    + '	';

  $.each(['mu','count_fields','count_links','count_portals','count_resonators'], function(i, field) {
    retVal += ''
      + window.digits(scores[playerGuid][field])
      + '	';
  });
  retVal += '
';
  return retVal;
};

window.plugin.scoreboard.playerTable = function(sortBy) {

  // Sort the playerGuid array by sortBy
  window.plugin.scoreboard.playerGuids.sort(function(a, b) {
    var playerA = window.plugin.scoreboard.scores['player'][a];
    var playerB = window.plugin.scoreboard.scores['player'][b];
    var retVal = 0;
    if(sortBy === 'names') {
      retVal = window.getPlayerName(a).toLowerCase() < window.getPlayerName(b).toLowerCase() ? -1 : 1;
    } else {
      retVal = playerB[sortBy] - playerA[sortBy];
    }
    return retVal;
  });

  var sort = window.plugin.scoreboard.playerTableSort;
  var scoreHtml = '
'
    + '
Player	'
    + 'Mu	'
    + 'Fields	'
    + 'Links	'
    + 'Portals	'
    + 'Resonators
';
  $.each(window.plugin.scoreboard.playerGuids, function(index, guid) {
    scoreHtml += window.plugin.scoreboard.playerTableRow(guid);
  });
  scoreHtml += '
';

  return scoreHtml;
}

// A little helper functon so the above isn't so messy
window.plugin.scoreboard.playerTableSort = function(name, by) {
  var retVal = 'sort="' + name + '"';
  if(name === by) {
    retVal += ' class="sorted"';
  }
  return retVal;
};

window.plugin.scoreboard.display = function() {

  var somethingInView = window.plugin.scoreboard.compileStats();
  var scores = window.plugin.scoreboard.scores;
  var resMu = scores['team'][TEAM_RES]['mu'];
  var enlMu = scores['team'][TEAM_ENL]['mu'];
  var scoreHtml = '';

  if(somethingInView) {

    if(resMu + enlMu > 0) {
      var resMuPercent = Math.round((resMu / (resMu + enlMu)) * 100);
      scoreHtml += '
'
        + window.plugin.scoreboard.percentSpan(resMuPercent, 'res')
        + window.plugin.scoreboard.percentSpan(100-resMuPercent, 'enl')
        + '
';
    }

    scoreHtml += '
'
      + '
	Resistance	Enlightened	Total
'
      + window.plugin.scoreboard.teamTableRow('mu','Mu')
      + window.plugin.scoreboard.teamTableRow('count_fields','Fields')
      + window.plugin.scoreboard.teamTableRow('count_links','Links')
      + window.plugin.scoreboard.teamTableRow('count_portals','Portals')
      + window.plugin.scoreboard.teamTableRow('count_resonators','Resonators')
      + '
';

    scoreHtml += '
'
      + '
	Resistance	Enlightened
'
      + '
Largest Field	'
      + window.plugin.scoreboard.fieldInfo(scores['team'][TEAM_RES]['largest']['mu'])
      + '	'
      + window.plugin.scoreboard.fieldInfo(scores['team'][TEAM_ENL]['largest']['mu'])
      + '
'
      + '
';

    scoreHtml += '
'
      + window.plugin.scoreboard.playerTable('mu')
      + '
';

    scoreHtml += '
Click on player table headers to sort by that column. '
      + 'Score is subject to portals available based on zoom level. '
      + 'If names are unresolved try again. For best results wait until updates are fully loaded.
';
  } else {
    scoreHtml += 'You need something in view.';
  }

  alert('
' + scoreHtml + '
');
  $(".ui-dialog").addClass('ui-dialog-scoreboard');

  // Setup sorting
  $(document).on('click', '#players table th', function() {
    $('#players').html(window.plugin.scoreboard.playerTable($(this).attr('sort')));
  });
}

var setup =  function() {
  $('body').append('

');
  $('#toolbox').append('scoreboard');
  $('head').append('');
}

// PLUGIN END //////////////////////////////////////////////////////////

if(window.iitcLoaded && typeof setup === 'function') {
  setup();
} else {
  if(window.bootPlugins)
    window.bootPlugins.push(setup);
  else
    window.bootPlugins = [setup];
}
} // wrapper end
// inject code into site context
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ wrapper +')();'));
(document.body || document.head || document.documentElement).appendChild(script);
<|endoftext|>


<commit_before>(function() {
  'use strict';

  angular.module('civic.search')
    .directive('queryBuilder', queryBuilder)
    .controller('QueryBuilderController', QueryBuilderController);

  // @ngInject
  function queryBuilder() {
    var directive = {
      restrict: 'E',
      replace: true,
      scope: {
        entity: '=',
        fields: '='
      },
      controller: 'QueryBuilderController',
      templateUrl: 'app/views/search/directives/queryBuilder.tpl.html'
    };

    return directive;
  }

  // @ngInject
  function QueryBuilderController($scope, $state, $stateParams, $log, _, Search) {
    var vm = $scope.vm = {};
    var entity = vm.entity = $scope.entity;

    // function assignment
    vm.onSubmit = onSubmit;
    vm.options = {};
    vm.searchResults = [];
    vm.showGrid = false;

    init();

    // function definition
    function onSubmit() {
      $log.debug(JSON.stringify(vm.model));
      //vm.searchResults = Search.post(vm.model);
      //vm.showEvidenceGrid = true;
      vm.model.entity = entity;
      vm.model.save = true;
      Search.post(vm.model)
        .then(function(response) {
          vm.searchResults = response.results;
          vm.showGrid = true;
          if(_.has(response, 'token') && !_.isNull(response.token)) {
            var state = entity === 'evidence_items' ? 'search.evidence' : 'search.' + entity;
            $state.transitionTo(state, { token: response.token }, {notify: false});
          }
        });
    }

    vm.buttonLabel = 'Search';

    function init() {
      if (_.has($stateParams, 'token') && !_.isEmpty($stateParams.token)) {
        Search.get({entity: entity, token: $stateParams.token})
          .then(function (response) {
            vm.model.operator = response.params.operator;
            vm.model.queries = response.params.queries;
            vm.searchResults = response.results;
            vm.showGrid = true;
          });
      } else {
        Search.reset();
        vm.model = {
          operator: 'AND',
          queries: [
            {
              field: '',
              condition: {
                name: undefined,
                parameters: []
              }
            }
          ]
        };
      }
    }
    vm.operatorField = [
      {
        key: 'operator',
        type: 'queryBuilderSelect',
        data: {
          defaultValue: 'AND'
        },
        templateOptions: {
          label: '',
          options: [
            { value: 'AND', name: 'all' },
            { value: 'OR', name: 'any' }
          ]
        }
      }
    ];

    vm.fields = $scope.fields;
  }
})();
<commit_msg>decided to show the grids on the initial advanced search pages - fills out the page a big before the results are shown<commit_after>(function() {
  'use strict';

  angular.module('civic.search')
    .directive('queryBuilder', queryBuilder)
    .controller('QueryBuilderController', QueryBuilderController);

  // @ngInject
  function queryBuilder() {
    var directive = {
      restrict: 'E',
      replace: true,
      scope: {
        entity: '=',
        fields: '='
      },
      controller: 'QueryBuilderController',
      templateUrl: 'app/views/search/directives/queryBuilder.tpl.html'
    };

    return directive;
  }

  // @ngInject
  function QueryBuilderController($scope, $state, $stateParams, $log, _, Search) {
    var vm = $scope.vm = {};
    var entity = vm.entity = $scope.entity;

    // function assignment
    vm.onSubmit = onSubmit;
    vm.options = {};
    vm.searchResults = [];
    vm.showGrid = true;

    init();

    // function definition
    function onSubmit() {
      $log.debug(JSON.stringify(vm.model));
      //vm.searchResults = Search.post(vm.model);
      //vm.showEvidenceGrid = true;
      vm.model.entity = entity;
      vm.model.save = true;
      Search.post(vm.model)
        .then(function(response) {
          vm.searchResults = response.results;
          vm.showGrid = true;
          if(_.has(response, 'token') && !_.isNull(response.token)) {
            var state = entity === 'evidence_items' ? 'search.evidence' : 'search.' + entity;
            $state.transitionTo(state, { token: response.token }, {notify: false});
          }
        });
    }

    vm.buttonLabel = 'Search';

    function init() {
      if (_.has($stateParams, 'token') && !_.isEmpty($stateParams.token)) {
        Search.get({entity: entity, token: $stateParams.token})
          .then(function (response) {
            vm.model.operator = response.params.operator;
            vm.model.queries = response.params.queries;
            vm.searchResults = response.results;
            vm.showGrid = true;
          });
      } else {
        Search.reset();
        vm.model = {
          operator: 'AND',
          queries: [
            {
              field: '',
              condition: {
                name: undefined,
                parameters: []
              }
            }
          ]
        };
      }
    }
    vm.operatorField = [
      {
        key: 'operator',
        type: 'queryBuilderSelect',
        data: {
          defaultValue: 'AND'
        },
        templateOptions: {
          label: '',
          options: [
            { value: 'AND', name: 'all' },
            { value: 'OR', name: 'any' }
          ]
        }
      }
    ];

    vm.fields = $scope.fields;
  }
})();
<|endoftext|>


<commit_before>'use strict';

define(['ol',
        'sidebar',
        'toolbar',
        'layermanager',
        'query',
        'search',
        'print',
        'permalink',
        'measure',
        'bootstrap',
        'geolocation',
        'api',
        'draw',
        'drag',
        'compositions'
    ],
    function(ol, toolbar) {
        var module = angular.module('hs', [
            'hs.toolbar',
            'hs.layermanager',
            'hs.query',
            'hs.search',
            'hs.print',
            'hs.permalink',
            'hs.geolocation',
            'hs.api',
            'hs.sidebar',
            'hs.draw',
            'hs.drag',
            'hs.compositions'
        ]);

        module.directive(
            'hs', [
                'hs.map.service', 'Core',
                function(OlMap, Core) {
                    return {
                        templateUrl: hsl_path + 'hslayers.html',
                        link: function(scope, element) {
                            Core.fullScreenMap(element);
                        }
                    };
                }
            ]);

        module.value('config', {
            default_layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM(),
                    title: "Base layer",
                    base: true
                })
            ],
            default_view: new ol.View({
                center: ol.proj.transform([6.1319, 49.6116], 'EPSG:4326', 'EPSG:3857'), //Latitude longitude    to Spherical Mercator
                zoom: 13,
                units: "m"
            })
        });

        module.controller('Main', ['$scope', 'Core', '$compile', 'hs.map.service', 'hs.compositions.service_parser', '$timeout',
            function($scope, Core, $compile, hsmap, composition_parser, $timeout) {
                $scope.hsl_path = hsl_path; //Get this from hslayers.js file
                $scope.Core = Core;

                $scope.split_moved = function(x, y) {
                    $scope.split_x = x;
                    $scope.split_y = y;
                    hsmap.map.render();
                }
                $scope.$on("scope_loaded", function(event, args) {
                    if (args == 'Map') {

                        $scope.split_x = hsmap.map.getSize()[0] / 2;
                        $scope.split_y = hsmap.map.getSize()[1] / 2;

                        var slider_button = angular.element('');

                        angular.element('#map').append(slider_button);
                        $compile(slider_button)($scope);
                    }
                });
                $scope.$on('layermanager.updated', function(data, layer) {
                    if (layer.get('base') != true && layer.get('always_visible') != true) {
                        if (layer.get('title') == 'Intenzita dopravy v Plzni - normální stav - podzim') {
                            layer.set('split_group', 2);
                            layer.setVisible(true);
                        } else if (layer.get('title').indexOf('Intenzita') > -1) {
                            layer.set('split_group', 1);
                            layer.set('exclusive', true);
                        }
                        layer.on('precompose', function(evt) {
                            var ctx = evt.context;
                            ctx.save();
                            ctx.beginPath();
                            //Set clip rectangle and draw red outline for splitter
                            if (evt.currentTarget.get('split_group') == 1) {
                                ctx.rect(0, 0, $scope.split_x, $scope.split_y);

                            } else {
                                ctx.moveTo($scope.split_x, 0);
                                ctx.lineTo(ctx.canvas.width, 0);
                                ctx.lineTo(ctx.canvas.width, ctx.canvas.height);
                                ctx.lineTo(0, ctx.canvas.height);
                                ctx.lineTo(0, $scope.split_y);
                                ctx.lineTo($scope.split_x, $scope.split_y);
                                ctx.closePath();
                            }
                            ctx.strokeStyle = 'red';
                            ctx.stroke();
                            ctx.clip();
                        });
                        layer.on('postcompose', function(evt) {
                            evt.context.restore();
                        })
                    }
                    if (layer.get('base') == true) {
                        //Grayscale map
                        layer.on('postcompose', function(event) {
                            var context = event.context;
                            var canvas = context.canvas;
                            var image = context.getImageData(0, 0, canvas.width, canvas.height);
                            var data = image.data;
                            for (var i = 0, ii = data.length; i < ii; i += 4) {
                                data[i] = data[i + 1] = data[i + 2] = (3 * data[i] + 4 * data[i + 1] + data[i + 2]) / 8;
                            }
                            context.putImageData(image, 0, 0);
                        });
                    }
                });
                $scope.$on('layermanager.layer_time_changed', function(evt, layer, d) {
                    angular.forEach(hsmap.map.getLayers(), function(other_layer) {
                        if (other_layer.getSource().updateParams)
                            other_layer.getSource().updateParams({
                                'TIME': d
                            });
                    })
                })

                composition_parser.load('http://opentransportnet.eu/wwwlibs/statusmanager2/index.php?request=load&id=b8b5a347-4637-44d0-ae67-da17c5b047d3', undefined, undefined, function(response) {
                    angular.forEach(response.data.layers, function(layer) {
                        if (layer.title == 'Intenzita dopravy v Plzni - normální stav - podzim') {
                            layer.path = 'Bez dopravních omezení (base)';
                        } else if (layer.title.indexOf('Intenzita') > -1) {
                            layer.path = 'S dopravním omezením (other)';
                        }
                    })
                    return response;
                });
                Core.panelEnabled('compositions', true);

                $scope.$on('infopanel.updated', function(event) {});
            }
        ]);

        return module;
    });
<commit_msg>draw on canvas which layers are split<commit_after>'use strict';

define(['ol',
        'sidebar',
        'toolbar',
        'layermanager',
        'query',
        'search',
        'print',
        'permalink',
        'measure',
        'bootstrap',
        'geolocation',
        'api',
        'draw',
        'drag',
        'compositions'
    ],
    function(ol, toolbar) {
        var module = angular.module('hs', [
            'hs.toolbar',
            'hs.layermanager',
            'hs.query',
            'hs.search',
            'hs.print',
            'hs.permalink',
            'hs.geolocation',
            'hs.api',
            'hs.sidebar',
            'hs.draw',
            'hs.drag',
            'hs.compositions'
        ]);

        module.directive(
            'hs', [
                'hs.map.service', 'Core',
                function(OlMap, Core) {
                    return {
                        templateUrl: hsl_path + 'hslayers.html',
                        link: function(scope, element) {
                            Core.fullScreenMap(element);
                        }
                    };
                }
            ]);

        module.value('config', {
            default_layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM(),
                    title: "Base layer",
                    base: true
                })
            ],
            default_view: new ol.View({
                center: ol.proj.transform([6.1319, 49.6116], 'EPSG:4326', 'EPSG:3857'), //Latitude longitude    to Spherical Mercator
                zoom: 13,
                units: "m"
            })
        });

        module.controller('Main', ['$scope', 'Core', '$compile', 'hs.map.service', 'hs.compositions.service_parser', '$timeout',
            function($scope, Core, $compile, hsmap, composition_parser, $timeout) {
                $scope.hsl_path = hsl_path; //Get this from hslayers.js file
                $scope.Core = Core;

                $scope.split_moved = function(x, y) {
                    $scope.split_x = x;
                    $scope.split_y = y;
                    hsmap.map.render();
                }
                $scope.$on("scope_loaded", function(event, args) {
                    if (args == 'Map') {

                        $scope.split_x = hsmap.map.getSize()[0] / 2;
                        $scope.split_y = hsmap.map.getSize()[1] / 2;

                        var slider_button = angular.element('');

                        angular.element('#map').append(slider_button);
                        $compile(slider_button)($scope);
                    }
                });
                $scope.$on('layermanager.updated', function(data, layer) {
                    if (layer.get('base') != true && layer.get('always_visible') != true) {
                        if (layer.get('title') == 'Intenzita dopravy v Plzni - normální stav - podzim') {
                            layer.set('split_group', 2);
                            layer.setVisible(true);
                        } else if (layer.get('title').indexOf('Intenzita') > -1) {
                            layer.set('split_group', 1);
                            layer.set('exclusive', true);
                        }
                        layer.on('precompose', function(evt) {
                            var ctx = evt.context;
                            ctx.save();
                            ctx.beginPath();
                            var title = evt.currentTarget.get('title');
                            //Set clip rectangle and draw red outline for splitter
                            if (evt.currentTarget.get('split_group') == 1) {
                                ctx.rect(0, 0, $scope.split_x, $scope.split_y);
                                ctx.font = '14pt Calibri';
                                ctx.fillText(title, $scope.split_x - ctx.measureText(title).width-5, 15);
                            } else {
                                ctx.moveTo($scope.split_x, 0);
                                ctx.lineTo(ctx.canvas.width, 0);
                                ctx.lineTo(ctx.canvas.width, ctx.canvas.height);
                                ctx.lineTo(0, ctx.canvas.height);
                                ctx.lineTo(0, $scope.split_y);
                                ctx.lineTo($scope.split_x, $scope.split_y);
                                ctx.closePath();
                                ctx.font = '14pt Calibri';
                                ctx.fillText(title, $scope.split_x+5, 15);
                            }
                            ctx.strokeStyle = 'red';
                            ctx.stroke();
                            ctx.clip();
                        });
                        layer.on('postcompose', function(evt) {
                            evt.context.restore();
                        })
                    }
                    if (layer.get('base') == true) {
                        //Grayscale map
                        layer.on('postcompose', function(event) {
                            var context = event.context;
                            var canvas = context.canvas;
                            var image = context.getImageData(0, 0, canvas.width, canvas.height);
                            var data = image.data;
                            for (var i = 0, ii = data.length; i < ii; i += 4) {
                                data[i] = data[i + 1] = data[i + 2] = (3 * data[i] + 4 * data[i + 1] + data[i + 2]) / 8;
                            }
                            context.putImageData(image, 0, 0);
                        });
                    }
                });
                $scope.$on('layermanager.layer_time_changed', function(evt, layer, d) {
                    angular.forEach(hsmap.map.getLayers(), function(other_layer) {
                        if (other_layer.getSource().updateParams)
                            other_layer.getSource().updateParams({
                                'TIME': d
                            });
                    })
                })

                composition_parser.load('http://opentransportnet.eu/wwwlibs/statusmanager2/index.php?request=load&id=b8b5a347-4637-44d0-ae67-da17c5b047d3', undefined, undefined, function(response) {
                    angular.forEach(response.data.layers, function(layer) {
                        if (layer.title == 'Intenzita dopravy v Plzni - normální stav - podzim') {
                            layer.path = 'Bez dopravních omezení (base)';
                        } else if (layer.title.indexOf('Intenzita') > -1) {
                            layer.path = 'S dopravním omezením (other)';
                        }
                    })
                    return response;
                });
                Core.panelEnabled('compositions', true);

                $scope.$on('infopanel.updated', function(event) {});
            }
        ]);

        return module;
    });
<|endoftext|>


<commit_before>import Posts from 'meteor/nova:posts';
import Users from 'meteor/nova:users';
import Comments from 'meteor/nova:comments';
import Categories from 'meteor/nova:categories';

const postSchema = `
  type Post {
    _id: String
    createdAt: String
    postedAt: String
    url: String
    title: String
    slug: String
    body: String
    htmlBody: String
    excerpt: String
    sticky: Boolean
    viewCount: Int
    lastCommentedAt: String
    clickCount: Int
    status: Int
    isFuture: Boolean
    user: User
    commentCount: Int
    commenters: [User]
    comments: [Comment]
    categories: [Category]
    scheduledAt: String
    dummySlug: String
    isDummy: String
    upvotes: Int
    upvoters: [User]
    downvotes: Int
    downvoters: [User]
    baseScore: Int
    score: Float
    clickCount: Int
    viewCount: Int
    thumbnailUrl: String
    userIP: String
    userAgent: String
    referrer: String
  }
`;

const userSchema = `
  type User {
    _id: String
    username: String
    createdAt: String
    isAdmin: Boolean
    telescope: UserTelescope
  }

  type UserTelescope {
    bio: String
    commentCount: Float
    displayName: String
    downvotedComments: [Vote]
    downvotedPosts: [Vote]
    email: String
    emailHash: String
    htmlBio: String
    karma: Float
    postCount: Int
    slug: String
    twitterUsername: String
    upvotedComments: [Vote]
    upvotedPosts: [Vote]
    website: String
    groups: [String]
    notifications_users: Boolean
    notifications_posts: Boolean
    newsletter_subscribeToNewsletter: Boolean
    isDummy: Boolean
  }

  type Vote {
    itemId: String
    power: Float
    votedAt: String
  }
`;

const commentSchema = `
  type Comment {
    _id: String
    parentComment: Comment
    topLevelComment: Comment
    createdAt: String
    postedAt: String
    body: String
    htmlBody: String
    author: String
    inactive: Boolean
    post: Post
    user: User
    isDeleted: Boolean
    isDummy: Boolean
    upvotes: Int
    upvoters: [User]
    downvotes: Int
    downvoters: [User]
    baseScore: Int
    score: Float
  }
`

const categorySchema = `
  type Category {
    _id: String
    name: String
    description: String
    order: Int
    slug: String
    image: String
    parent: Category
  }
`;

export default schema = [`
${postSchema}
${userSchema}
${commentSchema}
${categorySchema}
input Terms {
  view: String
  userId: String
  cat: String
  date: String
  after: String
  before: String
  enableCache: Boolean
  listId: String
}
type Query {
  posts(terms: Terms, offset: Int, limit: Int): [Post]
  postsViewTotal(terms: Terms): Int
  post(_id: String): Post
  users: [User]
  user(_id: String): User
  comments: [Comment]
  comment(_id: String): Comment
  categories: [Category]
  category(_id: String): Category
}
`];
<commit_msg>re-enable search: add search query to Terms schema<commit_after>import Posts from 'meteor/nova:posts';
import Users from 'meteor/nova:users';
import Comments from 'meteor/nova:comments';
import Categories from 'meteor/nova:categories';

const postSchema = `
  type Post {
    _id: String
    createdAt: String
    postedAt: String
    url: String
    title: String
    slug: String
    body: String
    htmlBody: String
    excerpt: String
    sticky: Boolean
    viewCount: Int
    lastCommentedAt: String
    clickCount: Int
    status: Int
    isFuture: Boolean
    user: User
    commentCount: Int
    commenters: [User]
    comments: [Comment]
    categories: [Category]
    scheduledAt: String
    dummySlug: String
    isDummy: String
    upvotes: Int
    upvoters: [User]
    downvotes: Int
    downvoters: [User]
    baseScore: Int
    score: Float
    clickCount: Int
    viewCount: Int
    thumbnailUrl: String
    userIP: String
    userAgent: String
    referrer: String
  }
`;

const userSchema = `
  type User {
    _id: String
    username: String
    createdAt: String
    isAdmin: Boolean
    telescope: UserTelescope
  }

  type UserTelescope {
    bio: String
    commentCount: Float
    displayName: String
    downvotedComments: [Vote]
    downvotedPosts: [Vote]
    email: String
    emailHash: String
    htmlBio: String
    karma: Float
    postCount: Int
    slug: String
    twitterUsername: String
    upvotedComments: [Vote]
    upvotedPosts: [Vote]
    website: String
    groups: [String]
    notifications_users: Boolean
    notifications_posts: Boolean
    newsletter_subscribeToNewsletter: Boolean
    isDummy: Boolean
  }

  type Vote {
    itemId: String
    power: Float
    votedAt: String
  }
`;

const commentSchema = `
  type Comment {
    _id: String
    parentComment: Comment
    topLevelComment: Comment
    createdAt: String
    postedAt: String
    body: String
    htmlBody: String
    author: String
    inactive: Boolean
    post: Post
    user: User
    isDeleted: Boolean
    isDummy: Boolean
    upvotes: Int
    upvoters: [User]
    downvotes: Int
    downvoters: [User]
    baseScore: Int
    score: Float
  }
`

const categorySchema = `
  type Category {
    _id: String
    name: String
    description: String
    order: Int
    slug: String
    image: String
    parent: Category
  }
`;

export default schema = [`
${postSchema}
${userSchema}
${commentSchema}
${categorySchema}
input Terms {
  view: String
  userId: String
  cat: String
  date: String
  after: String
  before: String
  enableCache: Boolean
  listId: String
  query: String # search query
}
type Query {
  posts(terms: Terms, offset: Int, limit: Int): [Post]
  postsViewTotal(terms: Terms): Int
  post(_id: String): Post
  users: [User]
  user(_id: String): User
  comments: [Comment]
  comment(_id: String): Comment
  categories: [Category]
  category(_id: String): Category
}
`];
<|endoftext|>


<commit_before>import React, { useCallback, useEffect, useRef } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { ensureState } from 'redux-optimistic-ui'
import QueueItem from '../QueueItem'
import { formatSeconds } from 'lib/dateTime'
import { CSSTransition, TransitionGroup } from 'react-transition-group'

import { moveItem } from '../../modules/queue'

import getPlayerHistory from '../../selectors/getPlayerHistory'
import getRoundRobinQueue from '../../selectors/getRoundRobinQueue'
import getWaits from '../../selectors/getWaits'

import styles from './QueueList.css'
const QUEUE_ITEM_HEIGHT = 92

const QueueList = props => {
  const containerRef = useRef()

  const artists = useSelector(state => state.artists)
  const { errorMessage, isAtQueueEnd, isErrored, position, queueId } = useSelector(state => state.status)

  const playerHistory = useSelector(getPlayerHistory)
  const queue = useSelector(getRoundRobinQueue)
  const songs = useSelector(state => state.songs)
  const starredSongs = useSelector(state => ensureState(state.userStars).starredSongs)
  const user = useSelector(state => state.user)
  const waits = useSelector(getWaits)

  // ensure current song is visible
  useEffect(() => {
    if (containerRef.current) {
      const i = queue.result.indexOf(queueId)
      containerRef.current.parentNode.scrollTop = QUEUE_ITEM_HEIGHT * i
    }
  }, [queue.result, queueId])

  // actions
  const dispatch = useDispatch()
  const handleMoveClick = useCallback(qId => dispatch(moveItem(qId, queueId)), [dispatch, queueId])

  // build children array
  const items = queue.result.map(qId => {
    const item = queue.entities[qId]

    if (item.isOptimistic ||
        !songs.entities[item.songId] ||
        !artists.entities[songs.entities[item.songId].artistId]) return null

    const duration = songs.entities[item.songId].duration
    const isCurrent = (qId === queueId) && !isAtQueueEnd
    const isUpcoming = qId !== queueId && !playerHistory.includes(qId)
    const isOwner = item.userId === user.userId

    return (
      <CSSTransition
        key={qId}
        timeout={800}
        unmountOnExit={false}
        classNames={{
          appear: '',
          appearActive: '',
          enter: styles.fadeEnter,
          enterActive: styles.fadeEnterActive,
          exit: styles.itemExit,
          exitActive: styles.itemExitActive,
        }}
      >
        <QueueItem {...item}
          artist={artists.entities[songs.entities[item.songId].artistId].name}
          errorMessage={isCurrent && errorMessage ? errorMessage : ''}
          isCurrent={isCurrent}
          isErrored={isCurrent && isErrored}
          isInfoable={user.isAdmin}
          isMovable={isUpcoming && (isOwner || user.isAdmin)}
          isOwner={isOwner}
          isPlayed={!isUpcoming && !isCurrent}
          isRemovable={isUpcoming && (isOwner || user.isAdmin)}
          isSkippable={isCurrent && (isOwner || user.isAdmin)}
          isStarred={starredSongs.includes(item.songId)}
          isUpcoming={isUpcoming}
          pctPlayed={isCurrent ? position / duration * 100 : 0}
          title={songs.entities[item.songId].title}
          wait={formatSeconds(waits[qId], true)} // fuzzy
          // actions
          onMoveClick={handleMoveClick}
        />
      </CSSTransition>
    )
  })

  return (

      <TransitionGroup component={null}>
        {items}
      </TransitionGroup>

  )
}

export default QueueList
<commit_msg>Fix potential cyclical list when moving a QueueItem<commit_after>import React, { useCallback, useEffect, useRef } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { ensureState } from 'redux-optimistic-ui'
import QueueItem from '../QueueItem'
import { formatSeconds } from 'lib/dateTime'
import { CSSTransition, TransitionGroup } from 'react-transition-group'

import { moveItem } from '../../modules/queue'

import getPlayerHistory from '../../selectors/getPlayerHistory'
import getRoundRobinQueue from '../../selectors/getRoundRobinQueue'
import getWaits from '../../selectors/getWaits'

import styles from './QueueList.css'
const QUEUE_ITEM_HEIGHT = 92

const QueueList = props => {
  const containerRef = useRef()

  const artists = useSelector(state => state.artists)
  const { errorMessage, isAtQueueEnd, isErrored, position, queueId } = useSelector(state => state.status)

  const playerHistory = useSelector(getPlayerHistory)
  const queue = useSelector(getRoundRobinQueue)
  const songs = useSelector(state => state.songs)
  const starredSongs = useSelector(state => ensureState(state.userStars).starredSongs)
  const user = useSelector(state => state.user)
  const waits = useSelector(getWaits)

  // ensure current song is visible
  useEffect(() => {
    if (containerRef.current) {
      const i = queue.result.indexOf(queueId)
      containerRef.current.parentNode.scrollTop = QUEUE_ITEM_HEIGHT * i
    }
  }, [queue.result, queueId])

  // actions
  const dispatch = useDispatch()
  const handleMoveClick = useCallback(qId => {
    // reference user's last-played item as the new prevQueueId
    const userId = queue.entities[qId].userId
    let lastPlayed = queueId // default in case user has no played items

    for (let i = queue.result.indexOf(queueId); i >= 0; i--) {
      if (queue.entities[queue.result[i]].userId === userId) {
        lastPlayed = queue.result[i]
        break
      }
    }

    dispatch(moveItem(qId, lastPlayed))
  }, [dispatch, queueId, queue.entities, queue.result])

  // build children array
  const items = queue.result.map(qId => {
    const item = queue.entities[qId]

    if (item.isOptimistic ||
        !songs.entities[item.songId] ||
        !artists.entities[songs.entities[item.songId].artistId]) return null

    const duration = songs.entities[item.songId].duration
    const isCurrent = (qId === queueId) && !isAtQueueEnd
    const isUpcoming = qId !== queueId && !playerHistory.includes(qId)
    const isOwner = item.userId === user.userId

    return (
      <CSSTransition
        key={qId}
        timeout={800}
        unmountOnExit={false}
        classNames={{
          appear: '',
          appearActive: '',
          enter: styles.fadeEnter,
          enterActive: styles.fadeEnterActive,
          exit: styles.itemExit,
          exitActive: styles.itemExitActive,
        }}
      >
        <QueueItem {...item}
          artist={artists.entities[songs.entities[item.songId].artistId].name}
          errorMessage={isCurrent && errorMessage ? errorMessage : ''}
          isCurrent={isCurrent}
          isErrored={isCurrent && isErrored}
          isInfoable={user.isAdmin}
          isMovable={isUpcoming && (isOwner || user.isAdmin)}
          isOwner={isOwner}
          isPlayed={!isUpcoming && !isCurrent}
          isRemovable={isUpcoming && (isOwner || user.isAdmin)}
          isSkippable={isCurrent && (isOwner || user.isAdmin)}
          isStarred={starredSongs.includes(item.songId)}
          isUpcoming={isUpcoming}
          pctPlayed={isCurrent ? position / duration * 100 : 0}
          title={songs.entities[item.songId].title}
          wait={formatSeconds(waits[qId], true)} // fuzzy
          // actions
          onMoveClick={handleMoveClick}
        />
      </CSSTransition>
    )
  })

  return (

      <TransitionGroup component={null}>
        {items}
      </TransitionGroup>

  )
}

export default QueueList
<|endoftext|>