<commit_before>/*!
 * ${copyright}
 */

// Provides control sap.tnt.NavigationList
sap.ui.define(['jquery.sap.global', './library', 'sap/ui/core/Control', 'sap/m/Popover', 'sap/ui/core/delegate/ItemNavigation'],
	function(jQuery, library, Control, Popover, ItemNavigation) {
		"use strict";

		/**
		 * Constructor for a new NavigationList.
		 *
		 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
		 * @param {object} [mSettings] Initial settings for the new control
		 *
		 * @class
		 * The NavigationList control is an interactive control, which provides a choice of
		 * different items, ordered as a list.
		 * @extends sap.ui.core.Control
		 *
		 * @author SAP SE
		 * @version ${version}
		 *
		 * @constructor
		 * @public
		 * @since 1.34
		 * @alias sap.tnt.NavigationList
		 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
		 */
		var NavigationList = Control.extend("sap.tnt.NavigationList", /** @lends sap.tnt.NavigationList.prototype */ {
			metadata: {
				library: "sap.tnt",
				properties: {
					/**
					 * Specifies the width of the control.
					 */
					width: {type: "sap.ui.core.CSSSize", group: "Dimension"},
					/**
					 * Specifies if the control is in expanded or collapsed mode.
					 */
					expanded: {type: "boolean", group: "Misc", defaultValue: true}
				},
				defaultAggregation: "items",
				aggregations: {

					/**
					 * The items displayed in the list.
					 */
					items: {type: "sap.tnt.NavigationListItem", multiple: true, singularName: "item"}
				},
				associations : {
					/**
					 * Association to controls / IDs, which describe this control (see WAI-ARIA attribute aria-describedby).
					 */
					ariaDescribedBy : { type: "sap.ui.core.Control", multiple: true, singularName: "ariaDescribedBy" },

					/**
					 * Association to controls / IDs, which label this control (see WAI-ARIA attribute aria-labelledby).
					 */
					ariaLabelledBy : { type: "sap.ui.core.Control", multiple: true, singularName: "ariaLabelledBy" }
				},
				events: {
					/**
					 * Fired when an item is selected.
					 */
					itemSelect: {
						parameters: {
							/**
							 * The selected item.
							 */
							item: {type: "sap.ui.core.Item"}
						}
					}
				}
			}
		});

		/**
		 * Initializes the control.
		 * @private
		 * @override
		 */
		NavigationList.prototype.init = function () {
			this._itemNavigation = new ItemNavigation();
			this._itemNavigation.setCycling(false);
			this.addEventDelegate(this._itemNavigation);

			this._itemNavigation.setPageSize(10);

			this._resourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.ui.core");
		};

		/**
		 * Sets a listbox accessibility role to the control.
		 * @private
		 */
		NavigationList.prototype.setHasListBoxRole = function (hasListBoxRole) {
			this._hasListBoxRole = hasListBoxRole;
		};

		/**
		 * Gets if the control has listbox accessibility role.
		 * @private
		 */
		NavigationList.prototype.getHasListBoxRole = function () {
			return this._hasListBoxRole;
		};

		/**
		 * Called after the control is rendered.
		 */
		NavigationList.prototype.onAfterRendering = function() {
			this._itemNavigation.setRootDomRef(this.getDomRef());
			this._itemNavigation.setItemDomRefs(this._getDomRefs());

			if (this._selectedItem) {
				this._selectedItem._select();
			}
		};

		NavigationList.prototype._updateNavItems = function() {
			this._itemNavigation.setItemDomRefs(this._getDomRefs());
		};

		/**
		 * Gets DOM references of the navigation items.
		 * @private
		 */
		NavigationList.prototype._getDomRefs = function() {
			var domRefs = [];

			var items = this.getItems();

			for (var i = 0; i < items.length; i++) {
				jQuery.merge(domRefs, items[i]._getDomRefs());
			}

			return domRefs;
		};

		/**
		 * Adapts popover position.
		 * @private
		 */
		NavigationList.prototype._adaptPopoverPositionParams = function () {
			if (this.getShowArrow()) {
				this._marginLeft = 10;
				this._marginRight = 10;
				this._marginBottom = 10;

				this._arrowOffset = 18;
				this._offsets = ["0 -18", "18 0", "0 18", "-18 0"];

				this._myPositions = ["center bottom", "begin top", "center top", "end top"];
				this._atPositions = ["center top", "end top", "center bottom", "begin top"];
			} else {
				this._marginTop = 0;
				this._marginLeft = 0;
				this._marginRight = 0;
				this._marginBottom = 0;

				this._arrowOffset = 0;
				this._offsets = ["0 0", "0 0", "0 0", "0 0"];

				this._myPositions = ["begin bottom", "begin top", "begin top", "end top"];
				this._atPositions = ["begin top", "end top", "begin bottom", "begin top"];
			}
		};

		/**
		 * Clears the control dependencies.
		 * @private
		 */
		NavigationList.prototype.exit = function () {
			if (this._itemNavigation) {
				this._itemNavigation.destroy();
			}
		};

		/**
		 * Selects an item.
		 * @private
		 */
		NavigationList.prototype._selectItem = function (params) {
			this.fireItemSelect(params);

			var item = params.item;

			if (this._selectedItem) {
				this._selectedItem._unselect();
			}

			item._select();

			this._selectedItem = item;
		};

		/**
		 * Gets the currently selected item.
		 */
		NavigationList.prototype.getSelectedItem = function() {
			return this._selectedItem;
		};

		/**
		 * Sets the currently selected item. Set null to deselect.
		 */
		NavigationList.prototype.setSelectedItem = function(item) {

			if (this._selectedItem) {
				this._selectedItem._unselect();
			}

			if (item) {
				item._select();
			}

			this._selectedItem = item;
		};

		/**
		 * Opens a popover.
		 * @private
		 */
		NavigationList.prototype._openPopover = function (source, list) {

			var selectedItem = list.getSelectedItem();
			if (selectedItem && list.isGroupSelected) {
				selectedItem = null;
			}

			var popover = new Popover({
				showHeader: false,
				horizontalScrolling: false,
				verticalScrolling: true,
				initialFocus: selectedItem,
				content: list
			});

			popover._adaptPositionParams = this._adaptPopoverPositionParams;

			popover.openBy(source);
		};

		return NavigationList;

	}, /* bExport= */ true);
<commit_msg>[INTERNAL] sap.tnt: Belize theme improvements<commit_after>/*!
 * ${copyright}
 */

// Provides control sap.tnt.NavigationList
sap.ui.define(['jquery.sap.global', './library', 'sap/ui/core/Control', 'sap/m/Popover', 'sap/ui/core/delegate/ItemNavigation'],
	function(jQuery, library, Control, Popover, ItemNavigation) {
		"use strict";

		/**
		 * Constructor for a new NavigationList.
		 *
		 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
		 * @param {object} [mSettings] Initial settings for the new control
		 *
		 * @class
		 * The NavigationList control is an interactive control, which provides a choice of
		 * different items, ordered as a list.
		 * @extends sap.ui.core.Control
		 *
		 * @author SAP SE
		 * @version ${version}
		 *
		 * @constructor
		 * @public
		 * @since 1.34
		 * @alias sap.tnt.NavigationList
		 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
		 */
		var NavigationList = Control.extend("sap.tnt.NavigationList", /** @lends sap.tnt.NavigationList.prototype */ {
			metadata: {
				library: "sap.tnt",
				properties: {
					/**
					 * Specifies the width of the control.
					 */
					width: {type: "sap.ui.core.CSSSize", group: "Dimension"},
					/**
					 * Specifies if the control is in expanded or collapsed mode.
					 */
					expanded: {type: "boolean", group: "Misc", defaultValue: true}
				},
				defaultAggregation: "items",
				aggregations: {

					/**
					 * The items displayed in the list.
					 */
					items: {type: "sap.tnt.NavigationListItem", multiple: true, singularName: "item"}
				},
				associations : {
					/**
					 * Association to controls / IDs, which describe this control (see WAI-ARIA attribute aria-describedby).
					 */
					ariaDescribedBy : { type: "sap.ui.core.Control", multiple: true, singularName: "ariaDescribedBy" },

					/**
					 * Association to controls / IDs, which label this control (see WAI-ARIA attribute aria-labelledby).
					 */
					ariaLabelledBy : { type: "sap.ui.core.Control", multiple: true, singularName: "ariaLabelledBy" }
				},
				events: {
					/**
					 * Fired when an item is selected.
					 */
					itemSelect: {
						parameters: {
							/**
							 * The selected item.
							 */
							item: {type: "sap.ui.core.Item"}
						}
					}
				}
			}
		});

		/**
		 * Initializes the control.
		 * @private
		 * @override
		 */
		NavigationList.prototype.init = function () {
			this._itemNavigation = new ItemNavigation();
			this._itemNavigation.setCycling(false);
			this.addEventDelegate(this._itemNavigation);

			this._itemNavigation.setPageSize(10);

			this._resourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.ui.core");
		};

		/**
		 * Sets a listbox accessibility role to the control.
		 * @private
		 */
		NavigationList.prototype.setHasListBoxRole = function (hasListBoxRole) {
			this._hasListBoxRole = hasListBoxRole;
		};

		/**
		 * Gets if the control has listbox accessibility role.
		 * @private
		 */
		NavigationList.prototype.getHasListBoxRole = function () {
			return this._hasListBoxRole;
		};

		/**
		 * Called after the control is rendered.
		 */
		NavigationList.prototype.onAfterRendering = function() {
			this._itemNavigation.setRootDomRef(this.getDomRef());
			this._itemNavigation.setItemDomRefs(this._getDomRefs());

			if (this._selectedItem) {
				this._selectedItem._select();
			}
		};

		NavigationList.prototype._updateNavItems = function() {
			this._itemNavigation.setItemDomRefs(this._getDomRefs());
		};

		/**
		 * Gets DOM references of the navigation items.
		 * @private
		 */
		NavigationList.prototype._getDomRefs = function() {
			var domRefs = [];

			var items = this.getItems();

			for (var i = 0; i < items.length; i++) {
				jQuery.merge(domRefs, items[i]._getDomRefs());
			}

			return domRefs;
		};

		/**
		 * Adapts popover position.
		 * @private
		 */
		NavigationList.prototype._adaptPopoverPositionParams = function () {
			if (this.getShowArrow()) {
				this._marginLeft = 10;
				this._marginRight = 10;
				this._marginBottom = 10;

				this._arrowOffset = 18;
				this._offsets = ["0 -18", "18 0", "0 18", "-18 0"];

				this._myPositions = ["center bottom", "begin top", "center top", "end top"];
				this._atPositions = ["center top", "end top", "center bottom", "begin top"];
			} else {
				this._marginTop = 0;
				this._marginLeft = 0;
				this._marginRight = 0;
				this._marginBottom = 0;

				this._arrowOffset = 0;
				this._offsets = ["0 0", "0 0", "0 0", "0 0"];

				this._myPositions = ["begin bottom", "begin top", "begin top", "end top"];
				this._atPositions = ["begin top", "end top", "begin bottom", "begin top"];
			}
		};

		/**
		 * Clears the control dependencies.
		 * @private
		 */
		NavigationList.prototype.exit = function () {
			if (this._itemNavigation) {
				this._itemNavigation.destroy();
			}
		};

		/**
		 * Selects an item.
		 * @private
		 */
		NavigationList.prototype._selectItem = function (params) {
			this.fireItemSelect(params);

			var item = params.item;

			if (this._selectedItem) {
				this._selectedItem._unselect();
			}

			item._select();

			this._selectedItem = item;
		};

		/**
		 * Gets the currently selected item.
		 */
		NavigationList.prototype.getSelectedItem = function() {
			return this._selectedItem;
		};

		/**
		 * Sets the currently selected item. Set null to deselect.
		 */
		NavigationList.prototype.setSelectedItem = function(item) {

			if (this._selectedItem) {
				this._selectedItem._unselect();
			}

			if (item) {
				item._select();
			}

			this._selectedItem = item;
		};

		/**
		 * Opens a popover.
		 * @private
		 */
		NavigationList.prototype._openPopover = function (source, list) {

			var selectedItem = list.getSelectedItem();
			if (selectedItem && list.isGroupSelected) {
				selectedItem = null;
			}

			var popover = new Popover({
				showHeader: false,
				horizontalScrolling: false,
				verticalScrolling: true,
				initialFocus: selectedItem,
				content: list
			}).addStyleClass('sapContrastPlus');

			popover._adaptPositionParams = this._adaptPopoverPositionParams;

			popover.openBy(source);
		};

		return NavigationList;

	}, /* bExport= */ true);
<|endoftext|>


<commit_before>import 'core-js/fn/array/from';
import 'core-js/fn/object/assign';

import { discover, config, deserialize } from 'opensearch-browser';
import { DOMParser } from 'xmldom';
import BluebirdPromise from 'bluebird';

import { convertFilters, prepareRecords } from './common';

BluebirdPromise.config({
  cancellation: true,
});
config({
  useXHR: true,
});

self.Promise = BluebirdPromise;
self.DOMParser = DOMParser;

self.services = {};
self.promises = {};

function getService(url, description) {
  if (!self.services[url]) {
    if (description) {
      self.services[url] = BluebirdPromise.resolve(deserialize(description));
    } else {
      self.services[url] = discover(url, { useXHR: true, PromiseClass: BluebirdPromise });
    }
  }
  return self.services[url];
}

function searchAll(url, method, filterParams, mapParams, options, format, description, maxUrlLength, dropEmptyParameters, parseOptions) {
  const maxCount = options.maxCount;
  const totalResults = options.totalResults;
  const itemsPerPage = options.itemsPerPage;

  return getService(url, description)
    .then((service) => {
      const parameters = convertFilters(filterParams, mapParams, options, format, service);
      const paginator = service.getPaginator(parameters, {
        type: format,
        method,
        baseOffset: options.startIndex,
        maxUrlLength,
        dropEmptyParameters,
        parseOptions,
        totalResults,
        serverItemsPerPage: itemsPerPage,
      });
      return paginator.searchFirstRecords(maxCount);
    });
}

function cancel() {
  if (self.search) {
    self.search.cancel();
    self.search = null;
  }
  if (self.emitter) {
    self.emitter.emit('cancel');
    self.emitter = null;
  }
}

self.onmessage = function onMessage({ data }) {
  const [operation, params] = data;
  switch (operation) {
    case 'searchAll': {
      const {
        url, method, filterParams, mapParams, options, format, description,
        maxUrlLength, dropEmptyParameters, parseOptions, switchMultiPolygonCoordinates
      } = params;
      self.search = searchAll(
        url, method, filterParams, mapParams, options, format, description,
        maxUrlLength, dropEmptyParameters, parseOptions
      );
      self.search
        .then((emitter) => {
          self.emitter = emitter;
          emitter
            .on('page', page => self.postMessage(['progress', Object.assign(page, { records: prepareRecords(page.records, switchMultiPolygonCoordinates) })]))
            .on('success', result => self.postMessage(['success', Object.assign(result, { records: prepareRecords(result.records, switchMultiPolygonCoordinates) })]))
            .on('error', error => self.postMessage(['error', error.toString()]));
        }, error => self.postMessage(['error', error.toString()]));
      break;
    }
    case 'cancel':
      cancel();
      break;
    case 'terminate':
      cancel();
      self.close();
      break;
    default:
      break;
  }
};
<commit_msg>opensearch success event does not need to check coordinates, as page event already do that<commit_after>import 'core-js/fn/array/from';
import 'core-js/fn/object/assign';

import { discover, config, deserialize } from 'opensearch-browser';
import { DOMParser } from 'xmldom';
import BluebirdPromise from 'bluebird';

import { convertFilters, prepareRecords } from './common';

BluebirdPromise.config({
  cancellation: true,
});
config({
  useXHR: true,
});

self.Promise = BluebirdPromise;
self.DOMParser = DOMParser;

self.services = {};
self.promises = {};

function getService(url, description) {
  if (!self.services[url]) {
    if (description) {
      self.services[url] = BluebirdPromise.resolve(deserialize(description));
    } else {
      self.services[url] = discover(url, { useXHR: true, PromiseClass: BluebirdPromise });
    }
  }
  return self.services[url];
}

function searchAll(url, method, filterParams, mapParams, options, format, description, maxUrlLength, dropEmptyParameters, parseOptions) {
  const maxCount = options.maxCount;
  const totalResults = options.totalResults;
  const itemsPerPage = options.itemsPerPage;

  return getService(url, description)
    .then((service) => {
      const parameters = convertFilters(filterParams, mapParams, options, format, service);
      const paginator = service.getPaginator(parameters, {
        type: format,
        method,
        baseOffset: options.startIndex,
        maxUrlLength,
        dropEmptyParameters,
        parseOptions,
        totalResults,
        serverItemsPerPage: itemsPerPage,
      });
      return paginator.searchFirstRecords(maxCount);
    });
}

function cancel() {
  if (self.search) {
    self.search.cancel();
    self.search = null;
  }
  if (self.emitter) {
    self.emitter.emit('cancel');
    self.emitter = null;
  }
}

self.onmessage = function onMessage({ data }) {
  const [operation, params] = data;
  switch (operation) {
    case 'searchAll': {
      const {
        url, method, filterParams, mapParams, options, format, description,
        maxUrlLength, dropEmptyParameters, parseOptions, switchMultiPolygonCoordinates
      } = params;
      self.search = searchAll(
        url, method, filterParams, mapParams, options, format, description,
        maxUrlLength, dropEmptyParameters, parseOptions
      );
      self.search
        .then((emitter) => {
          self.emitter = emitter;
          emitter
            .on('page', page => self.postMessage(['progress', Object.assign(page, { records: prepareRecords(page.records, switchMultiPolygonCoordinates) })]))
            // success does not need to save records, page callback does that
            .on('success', result => self.postMessage(['success', result]))
            .on('error', error => self.postMessage(['error', error.toString()]));
        }, error => self.postMessage(['error', error.toString()]));
      break;
    }
    case 'cancel':
      cancel();
      break;
    case 'terminate':
      cancel();
      self.close();
      break;
    default:
      break;
  }
};
<|endoftext|>


<commit_before>'use strict'

module.exports = function * (next) {
  try { yield next } catch (err) {
    this.status = err.status || 500
    if (this.status === 500) {
      this.opbeat.captureError(err, {
        user: {username: this.state.username},
        request: this.req
      })
    }
    this.body = {error: err.message}
    this.app.emit('error', err, this)
  }
}
<commit_msg>hide errors in production (#56)<commit_after>'use strict'

const config = require('../config')

module.exports = function * (next) {
  try { yield next } catch (err) {
    this.status = err.status || 500
    if (this.status === 500) {
      this.opbeat.captureError(err, {
        user: {username: this.state.username},
        request: this.req
      })
    }
    if (config.production) this.body = {error: 'server error'}
    else this.body = {error: err.message}
    this.app.emit('error', err, this)
  }
}
<|endoftext|>


<commit_before>const { authenticate } = require('@feathersjs/authentication');
// const { BadRequest, Forbidden } = require('@feathersjs/errors');
const { iff, isProvider, disallow } = require('feathers-hooks-common');
// const logger = require('../../../logger');
const {
	modelServices: { prepareInternalParams },
} = require('../../../utils');
const { userModel } = require('../model');
const { hasEditPermissionForUser, hasReadPermissionForUser } = require('../hooks/index.hooks');

const {
	mapPaginationQuery,
	resolveToIds,
	restrictToCurrentSchool,
	permitGroupOperation,
	denyIfNotCurrentSchool,
	denyIfStudentTeamCreationNotAllowed,
	computeProperty,
	addCollation,
	blockDisposableEmail,
} = require('../../../hooks');
const {
	mapRoleFilterQuery,
	checkUnique,
	checkUniqueEmail,
	checkJwt,
	checkUniqueAccount,
	updateAccountUsername,
	removeStudentFromClasses,
	removeStudentFromCourses,
	sanitizeData,
	pinIsVerified,
	securePatching,
	decorateUser,
	decorateAvatar,
	decorateUsers,
	handleClassId,
	pushRemoveEvent,
	enforceRoleHierarchyOnDelete,
	enforceRoleHierarchyOnCreate,
	filterResult,
	generateRegistrationLink,
	sendRegistrationLink,
	includeOnlySchoolRoles,
} = require('../hooks/userService');

// const USER_RABBIT_EXCHANGE = 'user';
class UserService {
	constructor(options) {
		this.options = options || {};
	}

	find(params) {
		return this.app.service('usersModel').find(prepareInternalParams(params));
	}

	get(id, params) {
		return this.app.service('usersModel').get(id, prepareInternalParams(params));
	}

	create(data, params) {
		return this.app.service('usersModel').create(data, prepareInternalParams(params));
	}

	update(id, data, params) {
		return this.app.service('usersModel').update(id, data, prepareInternalParams(params));
	}

	patch(id, data, params) {
		return this.app.service('usersModel').patch(id, data, prepareInternalParams(params));
	}

	remove(id, params) {
		return this.app.service('usersModel').remove(id, prepareInternalParams(params));
	}

	async setup(app) {
		this.app = app;
	}
}

const userService = new UserService({
	paginate: {
		default: 1000,
		max: 5000,
	},
});

const userHooks = {
	before: {
		all: [],
		find: [
			mapPaginationQuery,
			// resolve ids for role strings (e.g. 'TEACHER')
			resolveToIds('/roles', 'params.query.roles', 'name'),
			authenticate('jwt'),
			iff(isProvider('external'), restrictToCurrentSchool),
			mapRoleFilterQuery,
			addCollation,
			iff(isProvider('external'), includeOnlySchoolRoles),
		],
		get: [authenticate('jwt')],
		create: [
			checkJwt(),
			pinIsVerified,
			iff(isProvider('external'), restrictToCurrentSchool),
			iff(isProvider('external'), enforceRoleHierarchyOnCreate),
			sanitizeData,
			checkUniqueEmail,
			checkUnique,
			checkUniqueAccount,
			blockDisposableEmail('email'),
			generateRegistrationLink,
			sendRegistrationLink,
			resolveToIds('/roles', 'data.roles', 'name'),
		],
		update: [
			iff(isProvider('external'), disallow()),
			authenticate('jwt'),
			sanitizeData,
			checkUniqueEmail,
			resolveToIds('/roles', 'data.$set.roles', 'name'),
		],
		patch: [
			authenticate('jwt'),
			iff(isProvider('external'), securePatching),
			permitGroupOperation,
			sanitizeData,
			checkUniqueEmail,
			iff(isProvider('external'), hasEditPermissionForUser),
			iff(isProvider('external'), restrictToCurrentSchool),
			resolveToIds('/roles', 'data.roles', 'name'),
			updateAccountUsername,
		],
		remove: [authenticate('jwt'), iff(isProvider('external'), [restrictToCurrentSchool, enforceRoleHierarchyOnDelete])],
	},
	after: {
		all: [],
		find: [
			decorateAvatar,
			decorateUsers,
			iff(isProvider('external'), [
				filterResult,
				denyIfStudentTeamCreationNotAllowed({
					errorMessage: 'The current user is not allowed to list other users!',
				}),
			]),
		],
		get: [
			decorateAvatar,
			decorateUser,
			computeProperty(userModel, 'getPermissions', 'permissions'),
			iff(isProvider('external'), [
				hasReadPermissionForUser,
				denyIfNotCurrentSchool({
					errorMessage: 'Der angefragte Nutzer gehört nicht zur eigenen Schule!',
				}),
			]),
			iff(isProvider('external'), filterResult),
		],
		create: [handleClassId],
		update: [iff(isProvider('external'), filterResult)],
		patch: [iff(isProvider('external'), filterResult)],
		remove: [
			pushRemoveEvent,
			removeStudentFromClasses,
			removeStudentFromCourses,
			iff(isProvider('external'), filterResult),
		],
	},
};

module.exports = {
	userHooks,
	userService,
};
<commit_msg>Unique check is already included within creation<commit_after>const { authenticate } = require('@feathersjs/authentication');
// const { BadRequest, Forbidden } = require('@feathersjs/errors');
const { iff, isProvider, disallow } = require('feathers-hooks-common');
// const logger = require('../../../logger');
const {
	modelServices: { prepareInternalParams },
} = require('../../../utils');
const { userModel } = require('../model');
const { hasEditPermissionForUser, hasReadPermissionForUser } = require('../hooks/index.hooks');

const {
	mapPaginationQuery,
	resolveToIds,
	restrictToCurrentSchool,
	permitGroupOperation,
	denyIfNotCurrentSchool,
	denyIfStudentTeamCreationNotAllowed,
	computeProperty,
	addCollation,
	blockDisposableEmail,
} = require('../../../hooks');
const {
	mapRoleFilterQuery,
	checkUnique,
	checkUniqueEmail,
	checkJwt,
	checkUniqueAccount,
	updateAccountUsername,
	removeStudentFromClasses,
	removeStudentFromCourses,
	sanitizeData,
	pinIsVerified,
	securePatching,
	decorateUser,
	decorateAvatar,
	decorateUsers,
	handleClassId,
	pushRemoveEvent,
	enforceRoleHierarchyOnDelete,
	enforceRoleHierarchyOnCreate,
	filterResult,
	generateRegistrationLink,
	sendRegistrationLink,
	includeOnlySchoolRoles,
} = require('../hooks/userService');

// const USER_RABBIT_EXCHANGE = 'user';
class UserService {
	constructor(options) {
		this.options = options || {};
	}

	find(params) {
		return this.app.service('usersModel').find(prepareInternalParams(params));
	}

	get(id, params) {
		return this.app.service('usersModel').get(id, prepareInternalParams(params));
	}

	create(data, params) {
		return this.app.service('usersModel').create(data, prepareInternalParams(params));
	}

	update(id, data, params) {
		return this.app.service('usersModel').update(id, data, prepareInternalParams(params));
	}

	patch(id, data, params) {
		return this.app.service('usersModel').patch(id, data, prepareInternalParams(params));
	}

	remove(id, params) {
		return this.app.service('usersModel').remove(id, prepareInternalParams(params));
	}

	async setup(app) {
		this.app = app;
	}
}

const userService = new UserService({
	paginate: {
		default: 1000,
		max: 5000,
	},
});

const userHooks = {
	before: {
		all: [],
		find: [
			mapPaginationQuery,
			// resolve ids for role strings (e.g. 'TEACHER')
			resolveToIds('/roles', 'params.query.roles', 'name'),
			authenticate('jwt'),
			iff(isProvider('external'), restrictToCurrentSchool),
			mapRoleFilterQuery,
			addCollation,
			iff(isProvider('external'), includeOnlySchoolRoles),
		],
		get: [authenticate('jwt')],
		create: [
			checkJwt(),
			pinIsVerified,
			iff(isProvider('external'), restrictToCurrentSchool),
			iff(isProvider('external'), enforceRoleHierarchyOnCreate),
			sanitizeData,
			checkUnique,
			checkUniqueAccount,
			blockDisposableEmail('email'),
			generateRegistrationLink,
			sendRegistrationLink,
			resolveToIds('/roles', 'data.roles', 'name'),
		],
		update: [
			iff(isProvider('external'), disallow()),
			authenticate('jwt'),
			sanitizeData,
			checkUniqueEmail,
			resolveToIds('/roles', 'data.$set.roles', 'name'),
		],
		patch: [
			authenticate('jwt'),
			iff(isProvider('external'), securePatching),
			permitGroupOperation,
			sanitizeData,
			checkUniqueEmail,
			iff(isProvider('external'), hasEditPermissionForUser),
			iff(isProvider('external'), restrictToCurrentSchool),
			resolveToIds('/roles', 'data.roles', 'name'),
			updateAccountUsername,
		],
		remove: [authenticate('jwt'), iff(isProvider('external'), [restrictToCurrentSchool, enforceRoleHierarchyOnDelete])],
	},
	after: {
		all: [],
		find: [
			decorateAvatar,
			decorateUsers,
			iff(isProvider('external'), [
				filterResult,
				denyIfStudentTeamCreationNotAllowed({
					errorMessage: 'The current user is not allowed to list other users!',
				}),
			]),
		],
		get: [
			decorateAvatar,
			decorateUser,
			computeProperty(userModel, 'getPermissions', 'permissions'),
			iff(isProvider('external'), [
				hasReadPermissionForUser,
				denyIfNotCurrentSchool({
					errorMessage: 'Der angefragte Nutzer gehört nicht zur eigenen Schule!',
				}),
			]),
			iff(isProvider('external'), filterResult),
		],
		create: [handleClassId],
		update: [iff(isProvider('external'), filterResult)],
		patch: [iff(isProvider('external'), filterResult)],
		remove: [
			pushRemoveEvent,
			removeStudentFromClasses,
			removeStudentFromCourses,
			iff(isProvider('external'), filterResult),
		],
	},
};

module.exports = {
	userHooks,
	userService,
};
<|endoftext|>


<commit_before>import styled from 'styled-components'
import { Box } from '../../components/Primitives'

// this component basically exists as a giant stylesheet that inherits from the theme
// it's for markdown content (hence the name)
// it's kind of a b
const MarkdownContent = styled(Box)`
  /* Vertical Rhythm */
  & > * {
    /* reset all margins */
    margin-top: 0;
    margin-bottom: 0;

    /* margin top to all child elements */
    & + * {
      margin-top: ${({ theme }) => theme.space[3]};
    }

    /* bigger margin top on headers */
    & + h1,
    & + h2 {
      margin-top: ${({ theme }) => theme.space[5]};
    }

    & + h3,
    & + h4 {
      margin-top: ${({ theme }) => theme.space[4]};
    }
  }

  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    line-height: ${({ theme }) => theme.lineHeights.title};
  }

  p,
  ul,
  ol,
  address {
    max-width: 33em;
  }

  /* Headers */
  h1 {
    font-size: ${({ theme }) => theme.fontSizes[3]};
    font-weight: 600;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[4]};
    }
  }

  h2 {
    font-size: ${({ theme }) => theme.fontSizes[2]};
    font-weight: 600;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[3]};
    }
  }

  h3 {
    font-size: ${({ theme }) => theme.fontSizes[1]};
    font-weight: 600;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[2]};
    }
  }

  h4,
  h5,
  h6 {
    font-size: ${({ theme }) => theme.fontSizes[1]};
    font-weight: 500;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[2]};
    }
  }

  h1 code,
  h2 code,
  h3 code,
  h4 code,
  h5 code,
  h6 code {
    background-color: transparent;
    color: inherit;
  }

  /* Type Elements */

  hr {
    width: 100%;
    max-width: 4rem;
    margin-left: 0;
    margin-right: 0;
    border: ${({ theme }) => theme.borders[1]}
      ${({ theme }) => theme.colors.orange};
    margin: ${({ theme }) => theme.space[4]} 0;
  }

  ul,
  ol {
    padding-left: ${({ theme }) => theme.space[4]};
  }

  ul ul,
  ol ol,
  ul ol,
  ol ul {
    margin-top: 0;
    margin-bottom: 0;
  }

  b,
  strong,
  em,
  small,
  code {
    line-height: 1;
  }

  sup,
  sub {
    vertical-align: baseline;
    position: relative;
    top: -0.4em;
  }

  sub {
    top: 0.4em;
  }

  a {
    color: ${({ theme }) => theme.colors.darkGrey};
    text-decoration: underline;
    text-decoration-color: ${({ theme }) => theme.colors.orange};

    &:hover {
      color: ${({ theme }) => theme.colors.orange};
    }

    @media print {
      &:after {
        content: ' (' attr(href) ')';
        font-size: 0.875em;
      }
      &[href^='/']:after {
        content: ' (https://lowmess.com' attr(href) ')';
      }
      &[href^='#'] {
        text-decoration: none;

        &:after {
          content: '';
        }
      }
    }
  }

  blockquote,
  details {
    margin-top: ${({ theme }) => theme.space[4]};
    margin-right: 0;
    margin-bottom: ${({ theme }) => theme.space[4]};
    margin-left: 0;
    border-left: ${({ theme }) => theme.borders[3]}
      ${({ theme }) => theme.colors.orange};
    border-radius: ${({ theme }) => theme.radii[1]};
    padding: ${({ theme }) => theme.space[3]};
    background-color: ${({ theme }) => theme.colors.nearWhite};

    p {
      max-width: 30em;
    }

    > :first-child {
      margin-top: 0;
    }
    > :last-child {
      margin-bottom: 0;
    }
  }

  code {
    font-family: ${({ theme }) => theme.fonts.monospace};
  }

  p code,
  li code {
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: ${({ theme }) => theme.radii[1]};
    padding-left: ${({ theme }) => theme.space[1]};
    padding-right: ${({ theme }) => theme.space[1]};
    background-color: ${({ theme }) => theme.colors.nearWhite};
    color: ${({ theme }) => theme.colors.darkGrey};
    font-size: ${({ theme }) => theme.fontSizes[0]};
    white-space: nowrap;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[1]};
    }
  }

  pre {
    width: 100%;
    overflow-x: scroll;
    margin-top: ${({ theme }) => theme.space[4]};
    margin-bottom: ${({ theme }) => theme.space[4]};
    border-left: ${({ theme }) => theme.borders[3]}
      ${({ theme }) => theme.colors.orange};
    border-radius: ${({ theme }) => theme.radii[1]};
    padding: ${({ theme }) => theme.space[3]};
    background-color: ${({ theme }) => theme.colors.nearBlack};
    color: ${({ theme }) => theme.colors.nearWhite};
    font-size: ${({ theme }) => theme.fontSizes[0]};
    font-family: ${({ theme }) => theme.fonts.monospace};
    white-space: pre;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[1]};
    }

    @media print {
      background-color: transparent;
      color: ${({ theme }) => theme.colors.darkGrey};
    }
  }

  img {
    display: block;
    width: 100%;
    max-width: 48rem;
    margin-top: ${({ theme }) => theme.space[4]};
    margin-bottom: ${({ theme }) => theme.space[4]};
    border-radius: ${({ theme }) => theme.radii[1]};
  }

  iframe {
    margin-top: ${({ theme }) => theme.space[4]};
    margin-bottom: ${({ theme }) => theme.space[4]};
    border: 1px solid ${({ theme }) => theme.colors.grey};
  }
`

export default MarkdownContent
<commit_msg>:lipstick: handle dls in markdown content<commit_after>import styled from 'styled-components'
import { Box } from '../../components/Primitives'

// this component basically exists as a giant stylesheet that inherits from the theme
// it's for markdown content (hence the name)
// it's kind of a b
const MarkdownContent = styled(Box)`
  /* Vertical Rhythm */
  & > * {
    /* reset all margins */
    margin-top: 0;
    margin-bottom: 0;

    /* margin top to all child elements */
    & + * {
      margin-top: ${({ theme }) => theme.space[3]};
    }

    /* bigger margin top on headers */
    & + h1,
    & + h2 {
      margin-top: ${({ theme }) => theme.space[5]};
    }

    & + h3,
    & + h4 {
      margin-top: ${({ theme }) => theme.space[4]};
    }
  }

  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    line-height: ${({ theme }) => theme.lineHeights.title};
  }

  p,
  ul,
  ol,
  dl,
  address {
    max-width: 33em;
  }

  /* Headers */
  h1 {
    font-size: ${({ theme }) => theme.fontSizes[3]};
    font-weight: 600;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[4]};
    }
  }

  h2 {
    font-size: ${({ theme }) => theme.fontSizes[2]};
    font-weight: 600;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[3]};
    }
  }

  h3 {
    font-size: ${({ theme }) => theme.fontSizes[1]};
    font-weight: 600;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[2]};
    }
  }

  h4,
  h5,
  h6 {
    font-size: ${({ theme }) => theme.fontSizes[1]};
    font-weight: 500;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[2]};
    }
  }

  h1 code,
  h2 code,
  h3 code,
  h4 code,
  h5 code,
  h6 code {
    background-color: transparent;
    color: inherit;
  }

  /* Type Elements */

  hr {
    width: 100%;
    max-width: 4rem;
    margin-left: 0;
    margin-right: 0;
    border: ${({ theme }) => theme.borders[1]}
      ${({ theme }) => theme.colors.orange};
    margin: ${({ theme }) => theme.space[4]} 0;
  }

  ul,
  ol,
  dl {
    padding-left: ${({ theme }) => theme.space[4]};
  }

  ul ul,
  ol ol,
  ul ol,
  ol ul {
    margin-top: 0;
    margin-bottom: 0;
  }

  b,
  strong,
  em,
  small,
  code {
    line-height: 1;
  }

  sup,
  sub {
    vertical-align: baseline;
    position: relative;
    top: -0.4em;
  }

  sub {
    top: 0.4em;
  }

  a {
    color: ${({ theme }) => theme.colors.darkGrey};
    text-decoration: underline;
    text-decoration-color: ${({ theme }) => theme.colors.orange};

    &:hover {
      color: ${({ theme }) => theme.colors.orange};
    }

    @media print {
      &:after {
        content: ' (' attr(href) ')';
        font-size: 0.875em;
      }
      &[href^='/']:after {
        content: ' (https://lowmess.com' attr(href) ')';
      }
      &[href^='#'] {
        text-decoration: none;

        &:after {
          content: '';
        }
      }
    }
  }

  blockquote,
  details {
    margin-top: ${({ theme }) => theme.space[4]};
    margin-right: 0;
    margin-bottom: ${({ theme }) => theme.space[4]};
    margin-left: 0;
    border-left: ${({ theme }) => theme.borders[3]}
      ${({ theme }) => theme.colors.orange};
    border-radius: ${({ theme }) => theme.radii[1]};
    padding: ${({ theme }) => theme.space[3]};
    background-color: ${({ theme }) => theme.colors.nearWhite};

    p {
      max-width: 30em;
    }

    > :first-child {
      margin-top: 0;
    }
    > :last-child {
      margin-bottom: 0;
    }
  }

  code {
    font-family: ${({ theme }) => theme.fonts.monospace};
  }

  p code,
  li code {
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: ${({ theme }) => theme.radii[1]};
    padding-left: ${({ theme }) => theme.space[1]};
    padding-right: ${({ theme }) => theme.space[1]};
    background-color: ${({ theme }) => theme.colors.nearWhite};
    color: ${({ theme }) => theme.colors.darkGrey};
    font-size: ${({ theme }) => theme.fontSizes[0]};
    white-space: nowrap;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[1]};
    }
  }

  pre {
    width: 100%;
    overflow-x: scroll;
    margin-top: ${({ theme }) => theme.space[4]};
    margin-bottom: ${({ theme }) => theme.space[4]};
    border-left: ${({ theme }) => theme.borders[3]}
      ${({ theme }) => theme.colors.orange};
    border-radius: ${({ theme }) => theme.radii[1]};
    padding: ${({ theme }) => theme.space[3]};
    background-color: ${({ theme }) => theme.colors.nearBlack};
    color: ${({ theme }) => theme.colors.nearWhite};
    font-size: ${({ theme }) => theme.fontSizes[0]};
    font-family: ${({ theme }) => theme.fonts.monospace};
    white-space: pre;

    @media (min-width: ${({ theme }) => theme.breakpoints[0]}) {
      font-size: ${({ theme }) => theme.fontSizes[1]};
    }

    @media print {
      background-color: transparent;
      color: ${({ theme }) => theme.colors.darkGrey};
    }
  }

  img {
    display: block;
    width: 100%;
    max-width: 48rem;
    margin-top: ${({ theme }) => theme.space[4]};
    margin-bottom: ${({ theme }) => theme.space[4]};
    border-radius: ${({ theme }) => theme.radii[1]};
  }

  iframe {
    margin-top: ${({ theme }) => theme.space[4]};
    margin-bottom: ${({ theme }) => theme.space[4]};
    border: 1px solid ${({ theme }) => theme.colors.grey};
  }
`

export default MarkdownContent
<|endoftext|>


<commit_before>var keyMirror = require('keymirror');
var api = require('../lib/api');

var Types = keyMirror({
    SET_SCHEDULE: null,
    SET_SCHEDULE_FETCHING: null,
    SET_SCHEDULE_ERROR: null
});

module.exports.scheduleReducer = function (state, action) {
    if (typeof state === 'undefined') {
        state = {
            timeSlots: [],
            day: ''
        };
    }
    switch (action.type) {
    case Types.SET_SCHEDULE:
        return action.schedule;
    case Types.SET_SCHEDULE_FETCHING:
        return state;
    case Types.SET_SCHEDULE_ERROR:
        return state;
    default:
        return state;
    }
};

module.exports.setSchedule = function (schedule) {
    return {
        type: Types.SET_SCHEDULE,
        schedule: schedule
    };
};

module.exports.setScheduleFetching = function () {
    return {
        type: Types.SET_SCHEDULE_FETCHING,
        fetching: true
    };
};

module.exports.setScheduleError = function (error) {
    return {
        type: Types.SET_SCHEDULE_ERROR,
        error: error
    };
};

module.exports.startGetSchedule = function (day) {
    return function (dispatch) {
        dispatch(module.exports.setScheduleFetching());
        dispatch(module.exports.getDaySchedule(day));
    };
};

// group periods of time by start time
module.exports.sortTimeSlots = function (timeSlot1, timeSlot2) {
    var timeSlot1Am = (timeSlot1.time.substr(timeSlot1.time.length - 1, timeSlot1.time.length) === 'a') ? true : false;
    var timeSlot2Am = (timeSlot2.time.substr(timeSlot2.time.length - 1, timeSlot2.time.length) === 'a') ? true : false;
    var timeSlot1Time = parseInt(timeSlot1.time.substr(0, timeSlot1.time.length - 1));
    var timeSlot2Time = parseInt(timeSlot2.time.substr(0, timeSlot2.time.length - 1));

    // convert to 24-hour for sorting
    if (timeSlot1Time !== 12 && !timeSlot1Am) {
        timeSlot1Time = timeSlot1Time + 12;
    }
    if (timeSlot2Time !== 12 && !timeSlot2Am) {
        timeSlot2Time = timeSlot2Time + 12;
    }

    if (timeSlot1Time < timeSlot2Time) {
        return -1;
    } else {
        return 1;
    }
};

/**
 * Gets the schedule for the given day from the api
 * @param  {String} day  Day of the conference (Thursday, Friday or Satrurday)
 *
 *  @return {Object}     Schedule for the day, broken into chunks
 */
module.exports.getDaySchedule = function (day) {
    return function (dispatch) {
        api({
            uri: '/conference/schedule/' + day
        }, function (err, body) {
            if (err) {
                dispatch(module.exports.setScheduleError(err));
                return;
            }

            if (typeof body !== 'undefined') {
                var columns = body.columns;
                var rows = body.rows || [];
                // Group events by the time period in which they occur (for presentation)
                var scheduleByTimeSlot = rows.reduce(function (prev, cur) {
                    var cleanedRow = {};
                    for (var i = 0; i < columns.length; i++) {
                        if (cur[i].length > 0) {
                            cleanedRow[columns[i]] = cur[i];
                        }
                    }
                    cleanedRow['uri'] = '/conference/' + cleanedRow.rowid + '/details';
                    var timeSlot = cleanedRow.Chunk + cleanedRow.Start;
                    if (typeof prev.timeSlots[timeSlot] === 'undefined') {
                        prev.timeSlots[timeSlot] = [cleanedRow];
                        prev.info.push({
                            name: cleanedRow.Chunk,
                            time: cleanedRow.Start
                        });
                    } else {
                        prev.timeSlots[timeSlot].push(cleanedRow);
                    }
                    return prev;
                }, {timeSlots: [], info: []});

                scheduleByTimeSlot.info.sort(module.exports.sortTimeSlots);
                var schedule = scheduleByTimeSlot.info.map(function (timeSlot) {
                    return {
                        info: timeSlot,
                        items: scheduleByTimeSlot.timeSlots[timeSlot.name + timeSlot.time]
                    };
                });
                dispatch(module.exports.setSchedule({
                    timeSlots: schedule,
                    day: day
                }));
                return;
            } else {
                dispatch(module.exports.setScheduleError('An unexpected error occurred'));
                return;
            }
        });
    };
};
<commit_msg>Update details uri to have 2016 path<commit_after>var keyMirror = require('keymirror');
var api = require('../lib/api');

var Types = keyMirror({
    SET_SCHEDULE: null,
    SET_SCHEDULE_FETCHING: null,
    SET_SCHEDULE_ERROR: null
});

module.exports.scheduleReducer = function (state, action) {
    if (typeof state === 'undefined') {
        state = {
            timeSlots: [],
            day: ''
        };
    }
    switch (action.type) {
    case Types.SET_SCHEDULE:
        return action.schedule;
    case Types.SET_SCHEDULE_FETCHING:
        return state;
    case Types.SET_SCHEDULE_ERROR:
        return state;
    default:
        return state;
    }
};

module.exports.setSchedule = function (schedule) {
    return {
        type: Types.SET_SCHEDULE,
        schedule: schedule
    };
};

module.exports.setScheduleFetching = function () {
    return {
        type: Types.SET_SCHEDULE_FETCHING,
        fetching: true
    };
};

module.exports.setScheduleError = function (error) {
    return {
        type: Types.SET_SCHEDULE_ERROR,
        error: error
    };
};

module.exports.startGetSchedule = function (day) {
    return function (dispatch) {
        dispatch(module.exports.setScheduleFetching());
        dispatch(module.exports.getDaySchedule(day));
    };
};

// group periods of time by start time
module.exports.sortTimeSlots = function (timeSlot1, timeSlot2) {
    var timeSlot1Am = (timeSlot1.time.substr(timeSlot1.time.length - 1, timeSlot1.time.length) === 'a') ? true : false;
    var timeSlot2Am = (timeSlot2.time.substr(timeSlot2.time.length - 1, timeSlot2.time.length) === 'a') ? true : false;
    var timeSlot1Time = parseInt(timeSlot1.time.substr(0, timeSlot1.time.length - 1));
    var timeSlot2Time = parseInt(timeSlot2.time.substr(0, timeSlot2.time.length - 1));

    // convert to 24-hour for sorting
    if (timeSlot1Time !== 12 && !timeSlot1Am) {
        timeSlot1Time = timeSlot1Time + 12;
    }
    if (timeSlot2Time !== 12 && !timeSlot2Am) {
        timeSlot2Time = timeSlot2Time + 12;
    }

    if (timeSlot1Time < timeSlot2Time) {
        return -1;
    } else {
        return 1;
    }
};

/**
 * Gets the schedule for the given day from the api
 * @param  {String} day  Day of the conference (Thursday, Friday or Satrurday)
 *
 *  @return {Object}     Schedule for the day, broken into chunks
 */
module.exports.getDaySchedule = function (day) {
    return function (dispatch) {
        api({
            uri: '/conference/schedule/' + day
        }, function (err, body) {
            if (err) {
                dispatch(module.exports.setScheduleError(err));
                return;
            }

            if (typeof body !== 'undefined') {
                var columns = body.columns;
                var rows = body.rows || [];
                // Group events by the time period in which they occur (for presentation)
                var scheduleByTimeSlot = rows.reduce(function (prev, cur) {
                    var cleanedRow = {};
                    for (var i = 0; i < columns.length; i++) {
                        if (cur[i].length > 0) {
                            cleanedRow[columns[i]] = cur[i];
                        }
                    }
                    cleanedRow['uri'] = '/conference/2016/' + cleanedRow.rowid + '/details';
                    var timeSlot = cleanedRow.Chunk + cleanedRow.Start;
                    if (typeof prev.timeSlots[timeSlot] === 'undefined') {
                        prev.timeSlots[timeSlot] = [cleanedRow];
                        prev.info.push({
                            name: cleanedRow.Chunk,
                            time: cleanedRow.Start
                        });
                    } else {
                        prev.timeSlots[timeSlot].push(cleanedRow);
                    }
                    return prev;
                }, {timeSlots: [], info: []});

                scheduleByTimeSlot.info.sort(module.exports.sortTimeSlots);
                var schedule = scheduleByTimeSlot.info.map(function (timeSlot) {
                    return {
                        info: timeSlot,
                        items: scheduleByTimeSlot.timeSlots[timeSlot.name + timeSlot.time]
                    };
                });
                dispatch(module.exports.setSchedule({
                    timeSlots: schedule,
                    day: day
                }));
                return;
            } else {
                dispatch(module.exports.setScheduleError('An unexpected error occurred'));
                return;
            }
        });
    };
};
<|endoftext|>


<commit_before>var version = "0.4.5";

function sendRequest(requestDataType)
{
	// set default
	if(requestDataType === undefined)
	{
		requestDataType = "json";
	}

	// in case of HTML
	if(requestDataType == "html")
	{
		$('form.cpage').submit();
	}

	if(requestDataType === "json")
	{
		// define data type
		var request = $.ajax($('form.cpage').attr('action'), {
			dataType: requestDataType,
			data: $('form.cpage input, form.cpage select, form.cpage textarea').serialize(),
			cache: false,
			timeout: 30000,
			method: "post",
			headers: {
				'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
			},
			beforeSend: function () {
				// set end time
				$('form.cpage input[name="ccusr_nd"]').val(Date.now());
			},
			success: function (response) {
				// check for redirection request by server
				if(response.redirect === undefined)
				{
					// update comproso items
					$('form.cpage input[name="ccfg_tmlt"]').val(response.time_limit);
					$('form.cpage input[name="ccfg_tvl"]').val(response.interval);
					$('form.cpage input[name="ccusr_rnd"]').val(response.round);
					$('form.cpage input[name="ccusr_ctns"]').val(JSON.stringify([]));

					// update items
					$.each(response.results, function (name, result) {
						if(result.results.accessors !== undefined)
						{
							// define element
							element = $('body#comproso form.cpage *[name="' + result.name + '"]');

							// replace attributes
							$.each(result.results.accessors, function (index, accessor) {

								// store history
								if(element.attr("data-" + accessor) !== undefined)
								{
									arr = element.data(accessor);
									arr.push(result.results[accessor]);
									element.data(accessor, arr);
								}

								element.attr(accessor, result.results[accessor]);
							});

							element.triggerHandler("updated");
						}
					});

					$(document).triggerHandler('jsonResponse');

				}
				else
				{
					// reset data
					if(typeof tInt !== 'undefined')
					{
						clearTimeout(tInt);
					}

					sendRequest("html");
				}

				$(document).triggerHandler('ajaxProceeded');
			},
			complete: function () {
				// disable
				$('form.cpage .cnav input[type="button"]').prop('disabled', false);

				// set start time
				$('form.cpage input[name="ccusr_tstrt"]').val(Date.now());
			},
			done: function () {
				// update transaction time
				$('form.cpage input[name="ccusr_rt"]').val((Date.now() - $('form.cpage input[name="ccusr_nd"]').val()));
			},
			error: function (xhr, status, errorThrown) {
				console.log( "Error: " + errorThrown );
				console.log( "Status: " + status );
				console.dir( xhr );
				document.write(xhr.responseText);
			}
		});
	}
}

// store process data
function storeProcessData(element) {
	if((element === undefined) && (!$(this).attr('name')))
		return;

	actions = JSON.parse($('form.cpage input[name="ccusr_ctns"]').val());

	// store new actions
	newactions = {};

	if(element === undefined)
	{
		newactions.item = $(this).attr('name');
		newactions.value = $(this).attr('value');
	}
	else
	{
		newactions.item = "reset";
		newactions.value = true;
	}

	newactions.tstmp = Date.now();

	actions.push(newactions);

	$('form.cpage input[name="ccusr_ctns"]').val(JSON.stringify(actions));
}

$(document).on("jsonResponse", function () {
	// auto send mode
	if($('form.cpage .cnav').length === 0)
	{
		// prt
		if($('form.cpage input[name="ccfg_tvl"]').val() > 0)
		{
			var tvlId = setTimeout(sendRequest, ($('form.cpage input[name="ccfg_tvl"]').val() * 1000));
		}
	}
});

$(document).on("ready", function () {
	// set beginning time
	$('form.cpage input[name="ccusr_tsrt"]').val(Date.now());

	// reset data
	if(typeof tInt !== 'undefined')
	{
		clearTimeout(tInt);
	}

	// pseudorealtime
	if(($('form.cpage .cnav').length === 0) && ($('form.cpage input[name="ccfg_tvl"]').val() > 0))
	{
		// timeout
		if($('form.cpage input[name="ccfg_tvl"]').val() > 5)
		{
			// count down
			var tInt = setTimeout(sendRequest, ($('form.cpage input[name="ccfg_tvl"]').val() * 1000));
		}
		else
		{
			var tInt = setTimeout(sendRequest, 5000);
		}
	}

	// navigation
	$('form.cpage .cnav input[type="button"]:not(.inactive)').click(function () {

		// check if reset
		if($(this).hasClass('rst'))
		{
			$('form.cpage').trigger('reset');
		}
		else
		{
			// disable
			$('form.cpage .cnav input[type="button"]').prop('disabled', true);

			// check request
			if((typeof request === 'undefined') || (request.readyState === 0) || (request.readyState > 4))
			{
				// set direction
				if($(this).hasClass('bwd'))
				{
					$('form.cpage input[name="cctrl_prvs"]').val(1);
				}
				else
				{
					$('form.cpage input[name="cctrl_prvs"]').val(0);

				}

				// set end time
				$('form.cpage input[name="ccusr_nd"]').val(Date.now());

				// send form
				sendRequest();
			}
		}
	});

	// record process data on form fields
	$('form.cpage *:not(.notrace) input[name^="item"]:not(.notrace)').change(storeProcessData());
});<commit_msg>bugfix form submitting<commit_after>var version = "0.4.5";

function sendRequest(requestDataType)
{
	// set default
	if(requestDataType === undefined)
	{
		requestDataType = "json";
	}

	// in case of HTML
	if(requestDataType == "html")
	{
		$('form.cpage').submit();
	}

	if(requestDataType === "json")
	{
		// define data type
		var request = $.ajax($('form.cpage').attr('action'), {
			dataType: requestDataType,
			data: $('form.cpage input, form.cpage select, form.cpage textarea').serialize(),
			cache: false,
			timeout: 30000,
			method: "post",
			headers: {
				'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
			},
			beforeSend: function () {
				// set end time
				$('form.cpage input[name="ccusr_nd"]').val(Date.now());
			},
			success: function (response) {
				// check for redirection request by server
				if(response.redirect === undefined)
				{
					// update comproso items
					$('form.cpage input[name="ccfg_tmlt"]').val(response.time_limit);
					$('form.cpage input[name="ccfg_tvl"]').val(response.interval);
					$('form.cpage input[name="ccusr_rnd"]').val(response.round);
					$('form.cpage input[name="ccusr_ctns"]').val(JSON.stringify([]));

					// update items
					$.each(response.results, function (name, result) {
						if(result.results.accessors !== undefined)
						{
							// define element
							element = $('body#comproso form.cpage *[name="' + result.name + '"]');

							// replace attributes
							$.each(result.results.accessors, function (index, accessor) {

								// store history
								if(element.attr("data-" + accessor) !== undefined)
								{
									arr = element.data(accessor);
									arr.push(result.results[accessor]);
									element.data(accessor, arr);
								}

								element.attr(accessor, result.results[accessor]);
							});

							element.triggerHandler("updated");
						}
					});

					$(document).triggerHandler('jsonResponse');

				}
				else
				{
					// reset data
					if(typeof tInt !== 'undefined')
					{
						clearTimeout(tInt);
					}

					sendRequest("html");
				}

				$(document).triggerHandler('ajaxProceeded');
			},
			complete: function () {
				// disable
				$('.cnav .button').prop('disabled', false).removeClass('disabled');

				// set start time
				$('form.cpage input[name="ccusr_tstrt"]').val(Date.now());
			},
			done: function () {
				// update transaction time
				$('form.cpage input[name="ccusr_rt"]').val((Date.now() - $('form.cpage input[name="ccusr_nd"]').val()));
			},
			error: function (xhr, status, errorThrown) {
				console.log( "Error: " + errorThrown );
				console.log( "Status: " + status );
				console.dir( xhr );
				document.write(xhr.responseText);
			}
		});
	}
}

// store process data
function storeProcessData(element) {
	if((element === undefined) && (!$(this).attr('name')))
		return;

	actions = JSON.parse($('form.cpage input[name="ccusr_ctns"]').val());

	// store new actions
	newactions = {};

	if(element === undefined)
	{
		newactions.item = $(this).attr('name');
		newactions.value = $(this).attr('value');
	}
	else
	{
		newactions.item = "reset";
		newactions.value = true;
	}

	newactions.tstmp = Date.now();

	actions.push(newactions);

	$('form.cpage input[name="ccusr_ctns"]').val(JSON.stringify(actions));
}

$(document).on("jsonResponse", function () {
	// auto send mode
	if($('form.cpage .cnav').length === 0)
	{
		// prt
		if($('form.cpage input[name="ccfg_tvl"]').val() > 0)
		{
			var tvlId = setTimeout(sendRequest, ($('form.cpage input[name="ccfg_tvl"]').val() * 1000));
		}
	}
});

$(document).on("ready", function () {
	// set beginning time
	$('form.cpage input[name="ccusr_tsrt"]').val(Date.now());

	// reset data
	if(typeof tInt !== 'undefined')
	{
		clearTimeout(tInt);
	}

	// pseudorealtime
	if(($('form.cpage .cnav').length === 0) && ($('form.cpage input[name="ccfg_tvl"]').val() > 0))
	{
		// timeout
		if($('form.cpage input[name="ccfg_tvl"]').val() > 5)
		{
			// count down
			var tInt = setTimeout(sendRequest, ($('form.cpage input[name="ccfg_tvl"]').val() * 1000));
		}
		else
		{
			var tInt = setTimeout(sendRequest, 5000);
		}
	}

	// navigation
	$('.cnav .button:not(.inactive):not(.disabled)').click(function () {

		// check if reset
		if($(this).hasClass('rst'))
		{
			$('form.cpage').trigger('reset');
		}
		else
		{
			// disable
			$('.cnav .button').prop('disabled', true).addClass('disabled');

			// check request
			if((typeof request === 'undefined') || (request.readyState === 0) || (request.readyState > 4))
			{
				// set direction
				if($(this).hasClass('bwd'))
				{
					$('form.cpage input[name="cctrl_prvs"]').val(1);
				}
				else
				{
					$('form.cpage input[name="cctrl_prvs"]').val(0);

				}

				// set end time
				$('form.cpage input[name="ccusr_nd"]').val(Date.now());

				// send form
				sendRequest();
			}
		}
	});

	// record process data on form fields
	$('form.cpage *:not(.notrace) input[name^="item"]:not(.notrace)').change(storeProcessData());
});<|endoftext|>


<commit_before>export {
  fetchInstances, INSTANCES_REQUEST, INSTANCES_SUCCESS, INSTANCES_FAILURE,
  updateInstance, INSTANCE_UPDATE_REQUEST, INSTANCE_UPDATE_SUCCESS, INSTANCE_UPDATE_FAILURE,
  deleteInstance, INSTANCE_DELETE_REQUEST, INSTANCE_DELETE_SUCCESS, INSTANCE_DELETE_FAILURE,
  createInstance, CREATE_INSTANCE_REQUEST, CREATE_INSTANCE_SUCCESS, CREATE_INSTANCE_FAILURE,
} from './instances'

export {
  fetchClusters, CLUSTERS_REQUEST, CLUSTERS_SUCCESS, CLUSTERS_FAILURE,
  updateCluster, CLUSTER_UPDATE_REQUEST, CLUSTER_UPDATE_SUCCESS, CLUSTER_UPDATE_FAILURE,
  deleteCluster, CLUSTER_DELETE_REQUEST, CLUSTER_DELETE_SUCCESS, CLUSTER_DELETE_FAILURE,
  createCluster, CREATE_CLUSTER_REQUEST, CREATE_CLUSTER_SUCCESS, CREATE_CLUSTER_FAILURE,
} from './clusters'

export {
  ADD_INSTANCE, UNADD_INSTANCE, ADD_CLUSTER, UNADD_CLUSTER, SELECT_INSTANCE,
} from './container'

export {
  getKey, GET_KEY_REQUEST, GET_KEY_SUCCESS, GET_KEY_FAILURE,
  setKey, SET_KEY_REQUEST, SET_KEY_SUCCESS, SET_KEY_FAILURE,
} from './kdb'

export {
  configureInstance, CONFIGURE_INSTANCE_REQUEST, CONFIGURE_INSTANCE_SUCCESS, CONFIGURE_INSTANCE_FAILURE,
  configureCluster, CONFIGURE_CLUSTER_REQUEST, CONFIGURE_CLUSTER_SUCCESS, CONFIGURE_CLUSTER_FAILURE,
  returnToMain, RETURN_TO_MAIN,
} from './router'
<commit_msg>export container action creators<commit_after>export {
  fetchInstances, INSTANCES_REQUEST, INSTANCES_SUCCESS, INSTANCES_FAILURE,
  updateInstance, INSTANCE_UPDATE_REQUEST, INSTANCE_UPDATE_SUCCESS, INSTANCE_UPDATE_FAILURE,
  deleteInstance, INSTANCE_DELETE_REQUEST, INSTANCE_DELETE_SUCCESS, INSTANCE_DELETE_FAILURE,
  createInstance, CREATE_INSTANCE_REQUEST, CREATE_INSTANCE_SUCCESS, CREATE_INSTANCE_FAILURE,
} from './instances'

export {
  fetchClusters, CLUSTERS_REQUEST, CLUSTERS_SUCCESS, CLUSTERS_FAILURE,
  updateCluster, CLUSTER_UPDATE_REQUEST, CLUSTER_UPDATE_SUCCESS, CLUSTER_UPDATE_FAILURE,
  deleteCluster, CLUSTER_DELETE_REQUEST, CLUSTER_DELETE_SUCCESS, CLUSTER_DELETE_FAILURE,
  createCluster, CREATE_CLUSTER_REQUEST, CREATE_CLUSTER_SUCCESS, CREATE_CLUSTER_FAILURE,
} from './clusters'

export {
  addInstance, unaddInstance, ADD_INSTANCE, UNADD_INSTANCE,
  addCluster, unaddCluster, ADD_CLUSTER, UNADD_CLUSTER,
  selectInstance, SELECT_INSTANCE,
} from './container'

export {
  getKey, GET_KEY_REQUEST, GET_KEY_SUCCESS, GET_KEY_FAILURE,
  setKey, SET_KEY_REQUEST, SET_KEY_SUCCESS, SET_KEY_FAILURE,
} from './kdb'

export {
  configureInstance, CONFIGURE_INSTANCE_REQUEST, CONFIGURE_INSTANCE_SUCCESS, CONFIGURE_INSTANCE_FAILURE,
  configureCluster, CONFIGURE_CLUSTER_REQUEST, CONFIGURE_CLUSTER_SUCCESS, CONFIGURE_CLUSTER_FAILURE,
  returnToMain, RETURN_TO_MAIN,
} from './router'
<|endoftext|>


<commit_before>// Find the element where the commit timeline should be drawn
var commits = d3.select("#commits");

var orgName = commits.attr("orgName") || "JavaPosseRoundup";
var startDate = commits.attr("startDate") || "";
var width = commits.attr("width") || 1200;
var height = commits.attr("height") || 600;
var leftMargin = commits.attr("leftMargin") || 180;
var rightMargin = commits.attr("rightMargin") || 0;
var topMargin = commits.attr("topMargin") || 20;
var bottomMargin = commits.attr("bottomMargin") || 50;

var w = width - leftMargin - rightMargin,
    h = height - topMargin - bottomMargin;

// Scales. Note the inverted domain for the y-scale: bigger is up!
var x = d3.time.scale().rangeRound([0, w]),
    y = d3.scale.ordinal().rangePoints([0, h], .5),
    colors = d3.scale.category20();

// Axes.
var xAxis = d3.svg.axis().scale(x).tickSubdivide(true);
var yAxis = d3.svg.axis().scale(y).tickSize(0).tickPadding(5).orient("left");

// Add an SVG element with the desired dimensions and margin.
var svg = commits.append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + leftMargin + "," + topMargin + ")");

// Add the clip path.
svg.append("clipPath")
    .attr("id", "clip")
  .append("rect")
    .attr("width", w)
    .attr("height", h + 20);

// Need something in the background absorb the mouse events!
svg.append("rect")
    .attr("width", w)
    .attr("height", h)
    .style("fill-opacity", ".0");

$.getJSON("https://api.github.com/orgs/" + orgName + "/repos?callback=?", function(response) {
  var allCommits = [];
  var timelines = [];
  response.data.forEach(function(repo, i, array) {
    function gitSource(repo) {
      return repo.url + "/commits?callback=?";
    }
    $.getJSON(gitSource(repo), function(response) {
      var commits = response.data.map(function(r) {
        return {
          repo: repo.name,
          message: r.commit.message,
          authorDate: d3.time.format.iso.parse(r.commit.author.date),
          committerEmail: r.commit.committer.email,
          committerName: r.commit.committer.name,
          commitDate: d3.time.format.iso.parse(r.commit.committer.date),
          sha: r.sha
        }
      });
      var timeline = {
        repo: repo.name,
        earliest: commits[commits.length - 1].commitDate,
        latest: commits[0].commitDate
      };
      allCommits.push.apply(allCommits, commits);
      timelines.push(timeline);
      if (timelines.length == array.length) drawChart(allCommits, timelines);
    });
  });
});

function drawChart(allCommits, timelines) {

  var tickHeight = height / (timelines.length * 4 + 1);

  var earliestCommitDate = d3.min(timelines, function(d) { return d.earliest; });

  var start = d3.time.format("%Y-%m-%d").parse(startDate) || earliestCommitDate;

  x.domain([d3.time.day.floor(start), d3.time.day.ceil(new Date())]);

  y.domain(timelines.map(function(t) { return t.repo; }));

  // Add the x-axis.
  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + (h + topMargin + tickHeight) + ")")
    .call(xAxis);

  // Add the y-axis.
  svg.append("g")
    .attr("class", "y axis")
    .call(yAxis);

  svg.selectAll(".commit")
      .data(allCommits)
    .enter().append("line")
      .attr("class", "commit")
      .attr("clip-path", "url(#clip)")
      .attr("x1", function(d) { return x(d.commitDate); })
      .attr("y1", function(d) { return Math.floor(y(d.repo)) - tickHeight; })
      .attr("x2", function(d) { return x(d.commitDate); })
      .attr("y2", function(d) { return Math.floor(y(d.repo)) + tickHeight; })
      .style("stroke", function(d) { return colors(d.committerEmail); })
      .on("mouseover", showCommitInfo);

  svg.selectAll(".timeline")
      .data(timelines)
    .enter().append("line")
      .attr("class", "timeline")
      .attr("clip-path", "url(#clip)")
      .attr("x1", function(d) { return x(d.earliest); })
      .attr("y1", function(d) { return Math.floor(y(d.repo)); })
      .attr("x2", function(d) { return x(d.latest); })
      .attr("y2", function(d) { return Math.floor(y(d.repo)); });

  svg.call(d3.behavior.zoom().x(x).on("zoom", zoom));

  function zoom() {
    svg.select(".x.axis").call(xAxis);
    svg.selectAll(".commit")
      .data(allCommits)
      .attr("x1", function(d) { return x(d.commitDate); })
      .attr("x2", function(d) { return x(d.commitDate); });
    svg.selectAll(".timeline")
      .data(timelines)
      .attr("x1", function(d) { return x(d.earliest); })
      .attr("x2", function(d) { return x(d.latest); });
    svg.selectAll(".committer, .message")
      .attr("x", function(d) { return x(d.commitDate); });
  }

  function showCommitInfo(d, i) {

    var committer = svg.selectAll(".committer")
      .data([d], function(d) { return d.sha; });

    committer.enter().append("text")
      .attr("class", "committer")
      .attr("x", x(d.commitDate))
      .attr("y", y(d.repo))
      .attr("dx", -2)
      .attr("dy", 2 * tickHeight + 5)
      .attr("text-anchor", "end")
      .style("fill", colors(d.committerEmail))
      .text(d.committerName);

    committer.exit().remove();

    var message = svg.selectAll(".message")
      .data([d], function(d) { return d.sha; });

    message.enter().append("text")
      .attr("class", "message")
      .attr("x", x(d.commitDate))
      .attr("y", y(d.repo))
      .attr("dx", 2)
      .attr("dy", 2 * tickHeight + 5)
      .text(d.message);

    message.exit().remove();
  }

}
<commit_msg>Rename margin attributes<commit_after>// Find the element where the commit timeline should be drawn
var commits = d3.select("#commits");

var orgName = commits.attr("orgName") || "JavaPosseRoundup";
var startDate = commits.attr("startDate") || "";
var width = commits.attr("width") || 1200;
var height = commits.attr("height") || 600;
var leftMargin = commits.attr("left-margin") || 180;
var rightMargin = commits.attr("right-margin") || 0;
var topMargin = commits.attr("top-margin") || 20;
var bottomMargin = commits.attr("bottom-margin") || 60;

var w = width - leftMargin - rightMargin,
    h = height - topMargin - bottomMargin;

// Scales. Note the inverted domain for the y-scale: bigger is up!
var x = d3.time.scale().rangeRound([0, w]),
    y = d3.scale.ordinal().rangePoints([0, h], .5),
    colors = d3.scale.category20();

// Axes.
var xAxis = d3.svg.axis().scale(x).tickSubdivide(true);
var yAxis = d3.svg.axis().scale(y).tickSize(0).tickPadding(5).orient("left");

// Add an SVG element with the desired dimensions and margin.
var svg = commits.append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + leftMargin + "," + topMargin + ")");

// Add the clip path.
svg.append("clipPath")
    .attr("id", "clip")
  .append("rect")
    .attr("width", w)
    .attr("height", h + 20);

// Need something in the background absorb the mouse events!
svg.append("rect")
    .attr("width", w)
    .attr("height", h)
    .style("fill-opacity", ".0");

$.getJSON("https://api.github.com/orgs/" + orgName + "/repos?callback=?", function(response) {
  var allCommits = [];
  var timelines = [];
  response.data.forEach(function(repo, i, array) {
    function gitSource(repo) {
      return repo.url + "/commits?callback=?";
    }
    $.getJSON(gitSource(repo), function(response) {
      var commits = response.data.map(function(r) {
        return {
          repo: repo.name,
          message: r.commit.message,
          authorDate: d3.time.format.iso.parse(r.commit.author.date),
          committerEmail: r.commit.committer.email,
          committerName: r.commit.committer.name,
          commitDate: d3.time.format.iso.parse(r.commit.committer.date),
          sha: r.sha
        }
      });
      var timeline = {
        repo: repo.name,
        earliest: commits[commits.length - 1].commitDate,
        latest: commits[0].commitDate
      };
      allCommits.push.apply(allCommits, commits);
      timelines.push(timeline);
      if (timelines.length == array.length) drawChart(allCommits, timelines);
    });
  });
});

function drawChart(allCommits, timelines) {

  var tickHeight = height / (timelines.length * 4 + 1);

  var earliestCommitDate = d3.min(timelines, function(d) { return d.earliest; });

  var start = d3.time.format("%Y-%m-%d").parse(startDate) || earliestCommitDate;

  x.domain([d3.time.day.floor(start), d3.time.day.ceil(new Date())]);

  y.domain(timelines.map(function(t) { return t.repo; }));

  // Add the x-axis.
  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + (h + topMargin + tickHeight) + ")")
    .call(xAxis);

  // Add the y-axis.
  svg.append("g")
    .attr("class", "y axis")
    .call(yAxis);

  svg.selectAll(".commit")
      .data(allCommits)
    .enter().append("line")
      .attr("class", "commit")
      .attr("clip-path", "url(#clip)")
      .attr("x1", function(d) { return x(d.commitDate); })
      .attr("y1", function(d) { return Math.floor(y(d.repo)) - tickHeight; })
      .attr("x2", function(d) { return x(d.commitDate); })
      .attr("y2", function(d) { return Math.floor(y(d.repo)) + tickHeight; })
      .style("stroke", function(d) { return colors(d.committerEmail); })
      .on("mouseover", showCommitInfo);

  svg.selectAll(".timeline")
      .data(timelines)
    .enter().append("line")
      .attr("class", "timeline")
      .attr("clip-path", "url(#clip)")
      .attr("x1", function(d) { return x(d.earliest); })
      .attr("y1", function(d) { return Math.floor(y(d.repo)); })
      .attr("x2", function(d) { return x(d.latest); })
      .attr("y2", function(d) { return Math.floor(y(d.repo)); });

  svg.call(d3.behavior.zoom().x(x).on("zoom", zoom));

  function zoom() {
    svg.select(".x.axis").call(xAxis);
    svg.selectAll(".commit")
      .data(allCommits)
      .attr("x1", function(d) { return x(d.commitDate); })
      .attr("x2", function(d) { return x(d.commitDate); });
    svg.selectAll(".timeline")
      .data(timelines)
      .attr("x1", function(d) { return x(d.earliest); })
      .attr("x2", function(d) { return x(d.latest); });
    svg.selectAll(".committer, .message")
      .attr("x", function(d) { return x(d.commitDate); });
  }

  function showCommitInfo(d, i) {

    var committer = svg.selectAll(".committer")
      .data([d], function(d) { return d.sha; });

    committer.enter().append("text")
      .attr("class", "committer")
      .attr("x", x(d.commitDate))
      .attr("y", y(d.repo))
      .attr("dx", -2)
      .attr("dy", 2 * tickHeight + 5)
      .attr("text-anchor", "end")
      .style("fill", colors(d.committerEmail))
      .text(d.committerName);

    committer.exit().remove();

    var message = svg.selectAll(".message")
      .data([d], function(d) { return d.sha; });

    message.enter().append("text")
      .attr("class", "message")
      .attr("x", x(d.commitDate))
      .attr("y", y(d.repo))
      .attr("dx", 2)
      .attr("dy", 2 * tickHeight + 5)
      .text(d.message);

    message.exit().remove();
  }

}
<|endoftext|>


<commit_before>var VirtualTextSearch = function()
{
  const
  DEFAULT_STYLE = "background-color:#ff0; color:#000;",
  HIGHLIGHT_STYLE = "background-color:#0f0; color:#000;",
  DEFAULT_SCROLL_MARGIN = 50,
  SEARCH_DELAY = 50;

  var
  self = this,
  search_therm = '',
  search_results = [], // collection of span elements
  cursor = -1,
  container = null,
  source_container = null,
  source_container_parentNode = null,
  timeouts = new Timeouts(),
  __script = null,
  __offset = 0,
  __length = 0,
  __hit = null,
  //matches = null,

  search_node = function(node)
  {
    var cur_node = node.firstChild, pos = 0, hit = null, span = null, length = 0;
    while( cur_node && __offset )
    {
      switch(cur_node.nodeType)
      {
        case 1:
        {
          search_node(cur_node);
          break;
        }
        case 3:
        {
          if( cur_node.nodeValue.length > __offset )
          {
            pos = __offset;
            hit = cur_node.splitText(pos);
            if( ( length = hit.nodeValue.length ) >= __length )
            {
              length = __length;
              __offset = 0;
            }
            else
            {
              __length = __offset = __length - length;
            }
            cur_node = hit.splitText(length);
            span = node.insertBefore(node.ownerDocument.createElement('span'), hit);
            span.style.cssText = HIGHLIGHT_STYLE;
            span.appendChild(node.removeChild(hit));
            if( !__hit )
            {
              __hit = span;
            }
          }
          else
          {
            __offset -= cur_node.nodeValue.length;
          }
          break;
        };
      }
      cur_node = cur_node.nextSibling;
    }
  };

  this.clearHit = function()
  {
    __hit.parentNode.replaceChild(__hit.firstChild, __hit);
    __hit = null;
  }

  this.search = function(new_search_therm)
  {
    var
    pos = -1,
    source = '',
    line_arr = null,
    line_arr_length = 0,
    line_cur = 0;

    if( new_search_therm && new_search_therm != search_therm )
    {
      if(new_search_therm.length > 2)
      {
        search_therm = new_search_therm;
        if(__hit)
        {
          self.clearHit();
        }
        if( __script )
        {
          var line_matches = __script.line_matches = [];
          var line_offsets = __script.line_offsets = [];
          __script.match_cursor = 0;
          __script.match_length = search_therm.length
          source = __script.source;
          line_arr = __script.line_arr;
          line_arr_length = line_arr.length
          while( ( pos = source.indexOf(search_therm, pos + 1) ) != -1 )
          {
            while( line_cur < line_arr_length && line_arr[line_cur] < pos && ++line_cur );
            line_matches[line_matches.length] = line_cur;
            line_offsets[line_offsets.length] = pos - line_arr[line_cur - 1];
          }
          self.highlight();
          topCell.statusbar.updateInfo('matches for "' + search_therm + '": ' +line_matches.length );
        }
      }
      else
      {
        if(__hit)
        {
          self.clearHit();
        }
        topCell.statusbar.updateInfo('');
        search_therm = '';
      }
    }

  }

  this.searchDelayed = function(new_search_therm)
  {
    timeouts.set(this.search, SEARCH_DELAY, new_search_therm);
  }

  this.update = function()
  {
    var new_search_therm = search_therm;
    if( search_therm.length > 2 )
    {
      search_therm = '';
      this.search(new_search_therm);
    }
  }

  this.highlight = function()
  {
    if(__script && __script.line_matches && __script.line_matches.length )
    {
      var line = __script.line_matches[__script.match_cursor];
      if( views.js_source.showLine(__script.id, line - 7 ) )
      {
        var top_line = views.js_source.getTopLine();
        if( !source_container )
        {
          source_container_parentNode = container.getElementsByTagName('div')[0];
          source_container = container.getElementsByTagName('div')[1];
        }
        var div = source_container.getElementsByTagName('div')[line - top_line];
        __offset = __script.line_offsets[__script.match_cursor];
        __length = __script.match_length;
        __hit = null;
        search_node(div);
        source_container.parentNode.scrollLeft = 0;
        if( __hit
           && __hit.offsetLeft > source_container_parentNode.scrollLeft + source_container_parentNode.offsetWidth )
        {
          source_container.parentNode.scrollLeft = __hit.offsetLeft - 50;
        }
        topCell.statusbar.updateInfo('matches for "' +
          search_therm + '": ' + __script.line_matches.length +', match ' + __script.match_cursor );
        if( ++__script.match_cursor >= __script.line_matches.length )
        {
          __script.match_cursor = 0;
        }
      }
    }
  }

  this.setContainer = function(_container)
  {
    if( container != _container )
    {
      container = _container;
    }
  }

  this.setScript = function(script)
  {
    __script = script;
  }

  this.cleanup = function()
  {
    search_therm = '';
    search_results = [];
    cursor = -1;
    container = null;
    source_container = null;
    source_container_parentNode = null;
    __offset = 0;
    __hit = null;
  }

};<commit_msg>all context must be cleared on new script<commit_after>var VirtualTextSearch = function()
{
  const
  DEFAULT_STYLE = "background-color:#ff0; color:#000;",
  HIGHLIGHT_STYLE = "background-color:#0f0; color:#000;",
  DEFAULT_SCROLL_MARGIN = 50,
  SEARCH_DELAY = 50;

  var
  self = this,
  search_therm = '',
  search_results = [], // collection of span elements
  cursor = -1,
  container = null,
  source_container = null,
  source_container_parentNode = null,
  timeouts = new Timeouts(),
  __script = null,
  __offset = 0,
  __length = 0,
  __hit = null,
  //matches = null,

  search_node = function(node)
  {
    var cur_node = node.firstChild, pos = 0, hit = null, span = null, length = 0;
    while( cur_node && __offset )
    {
      switch(cur_node.nodeType)
      {
        case 1:
        {
          search_node(cur_node);
          break;
        }
        case 3:
        {
          if( cur_node.nodeValue.length > __offset )
          {
            pos = __offset;
            hit = cur_node.splitText(pos);
            if( ( length = hit.nodeValue.length ) >= __length )
            {
              length = __length;
              __offset = 0;
            }
            else
            {
              __length = __offset = __length - length;
            }
            cur_node = hit.splitText(length);
            span = node.insertBefore(node.ownerDocument.createElement('span'), hit);
            span.style.cssText = HIGHLIGHT_STYLE;
            span.appendChild(node.removeChild(hit));
            if( !__hit )
            {
              __hit = span;
            }
          }
          else
          {
            __offset -= cur_node.nodeValue.length;
          }
          break;
        };
      }
      cur_node = cur_node.nextSibling;
    }
  };

  this.clearHit = function()
  {
    __hit.parentNode.replaceChild(__hit.firstChild, __hit);
    __hit = null;
  }

  this.search = function(new_search_therm)
  {
    var
    pos = -1,
    source = '',
    line_arr = null,
    line_arr_length = 0,
    line_cur = 0;

    if( new_search_therm && new_search_therm != search_therm )
    {
      if(new_search_therm.length > 2)
      {
        search_therm = new_search_therm;
        if(__hit)
        {
          self.clearHit();
        }
        if( __script )
        {
          var line_matches = __script.line_matches = [];
          var line_offsets = __script.line_offsets = [];
          __script.match_cursor = 0;
          __script.match_length = search_therm.length
          source = __script.source;
          line_arr = __script.line_arr;
          line_arr_length = line_arr.length
          while( ( pos = source.indexOf(search_therm, pos + 1) ) != -1 )
          {
            while( line_cur < line_arr_length && line_arr[line_cur] < pos && ++line_cur );
            line_matches[line_matches.length] = line_cur;
            line_offsets[line_offsets.length] = pos - line_arr[line_cur - 1];
          }
          self.highlight();
          topCell.statusbar.updateInfo('matches for "' + search_therm + '": ' +line_matches.length );
        }
      }
      else
      {
        if(__hit)
        {
          self.clearHit();
        }
        topCell.statusbar.updateInfo('');
        search_therm = '';
      }
    }

  }

  this.searchDelayed = function(new_search_therm)
  {
    timeouts.set(this.search, SEARCH_DELAY, new_search_therm);
  }

  this.update = function()
  {
    var new_search_therm = search_therm;
    if( search_therm.length > 2 )
    {
      search_therm = '';
      this.search(new_search_therm);
    }
  }

  this.highlight = function()
  {
    if(__script && __script.line_matches && __script.line_matches.length )
    {
      var line = __script.line_matches[__script.match_cursor];
      if( views.js_source.showLine(__script.id, line - 7 ) )
      {
        var top_line = views.js_source.getTopLine();
        if( !source_container )
        {
          source_container_parentNode = container.getElementsByTagName('div')[0];
          source_container = container.getElementsByTagName('div')[1];
        }
        var div = source_container.getElementsByTagName('div')[line - top_line];
        __offset = __script.line_offsets[__script.match_cursor];
        __length = __script.match_length;
        __hit = null;
        search_node(div);
        source_container.parentNode.scrollLeft = 0;
        if( __hit
           && __hit.offsetLeft > source_container_parentNode.scrollLeft + source_container_parentNode.offsetWidth )
        {
          source_container.parentNode.scrollLeft = __hit.offsetLeft - 50;
        }
        topCell.statusbar.updateInfo('matches for "' +
          search_therm + '": ' + __script.line_matches.length +', match ' + __script.match_cursor );
        if( ++__script.match_cursor >= __script.line_matches.length )
        {
          __script.match_cursor = 0;
        }
      }
    }
  }

  this.setContainer = function(_container)
  {
    if( container != _container )
    {
      container = _container;
      source_container = null;
      source_container_parentNode = null;
    }
  }

  this.setScript = function(script)
  {
    __script = script;
    source_container = null;
    source_container_parentNode = null;
  }

  this.cleanup = function()
  {
    search_therm = '';
    search_results = [];
    cursor = -1;
    container = null;
    source_container = null;
    source_container_parentNode = null;
    __offset = 0;
    __hit = null;
  }

};<|endoftext|>


<commit_before>module.exports = function (grunt) {
  var exec = require('child_process').exec;
  var command = "webtizen";

  /**
   * grunt sdb:* task
   * Wrappers for sdb commands for the whole development lifecycle,
   * including pushing wgt files to a device and
   * wrapping the wrt-installer and wrt-launcher commands;
   * also makes it easy to set up remote debugging for an app.
   *
   * Caveats: it will probably fail miserably if you try to have
   * multiple Tizen devices attached at the same time.
   *
   * DEPENDENCIES: grunt, lodash, xml2js, async
   * (install with npm)
   *
   * The actions available are:
   *
   *   push
   *   install
   *   uninstall
   *   start (see launch())
   *   stop (see launch())
   *   debug (see launch())
   *
   * To be able to use these actions, you should first set up a
   * push action to send the tizen-app.sh script to the device.
   * Configure in grunt.initConfig() like this (the example creates
   * a grunt sdb:prepare task which pushes the tizen-app.sh control
   * script to /opt/home/developer):
   *
   *   sdb: {
   *     prepare: {
   *       action: 'push',
   *       localFiles: './tools/grunt-tasks/tizen-app.sh',
   *       remoteDestDir: '/opt/home/developer/',
   *       chmod: '+x',
   *       overwrite: true
   *     },
   *     ...
   *   }
   *
   * Then call with grunt like this:
   *
   *   grunt sdb:prepare
   *
   * Once the tizen-app.sh script is in place, you can configure the
   * other tasks to make use of it, e.g.
   *
   * sdb: {
   *   prepare: { ... see above ... },
   *
   *   pushwgt: {
   *     action: 'push',
   *     localFiles: {
   *       pattern: 'build/*.wgt',
   *       filter: 'latest'
   *     },
   *     remoteDestDir: '/opt/home/developer/'
   *   },
   *
   *   install: {
   *     action: 'install',
   *     remoteFiles: {
   *       pattern: '/opt/home/developer/*.wgt',
   *       filter: 'latest'
   *     },
   *     remoteScript: '/opt/home/developer/tizen-app.sh'
   *   }
   * }
   *
   * See the documentation for push(), install(), uninstall()
   * and launch() for the valid configuration options for each task.
   *
   * Note that the wrt-launcher commands use the <widget> element's
   * id attribute to determine the ID of the app, by default derived from
   * the config.xml file in the root of the project.
   */
  grunt.registerMultiTask('webtizen', 'use Tizen webtizen', function () {
    var commandline=[ command, this.data.args ].join(" ");
    exec(commandline, { cwd: this.data.cwd }, function (err, stdout, stderr) {
      if (err) {
        grunt.log.error(commandline+":failed");
      }
      else {
        grunt.log.ok('successfully signed');
      }
    });
  });
};
<commit_msg>fixed comment<commit_after>module.exports = function (grunt) {
  var exec = require('child_process').exec;
  var command = "webtizen";

  /**
   * grunt webtizen:* task
   * Wrappers for webtizen command.
   *
   * Caveats: it will probably fail miserably if you try to have
   * multiple Tizen devices attached at the same time.
   *
   * DEPENDENCIES: grunt
   * (install with npm)
   *
   * PROPERTIES:
   * cwd: the directory in which to run the webtizen command
   *      (it is important for some commands, eg signing)
   * args: the arguments to the webtizen command
   *
   * To be able to use this task, you should first set up a
   * task and target in your Gruntfile.js.
   * Configure in grunt.initConfig() like this (the example creates
   * a grunt sdb:prepare task which pushes the tizen-app.sh control
   * script to /opt/home/developer):
   *
   *   webtizen: {
   *     sign: {
   *       cwd: 'build/wgt',
   *       args: 'signing --nocheck -p '+process.env.TIZENSDKPROFILE
   *     },
   *     ...
   *   }
   *
   * You have to then set the TIZENSDKPROFILE environment variable to
   * point to where your profile is located.
   *
   * Then call with grunt like this:
   *
   *   grunt webtizen:sign
   *
   */
  grunt.registerMultiTask('webtizen', 'use Tizen webtizen', function () {
    var commandline=[ command, this.data.args ].join(" ");
    exec(commandline, { cwd: this.data.cwd }, function (err, stdout, stderr) {
      if (err) {
        grunt.log.error(commandline+":failed");
      }
      else {
        grunt.log.ok('successfully signed');
      }
    });
  });
};
<|endoftext|>


<commit_before>/*
 * Levels
 * ============================================================================
 *
 * A simple level selection screen, with unlockable buttons.
 */

const levelButtonFaces = {
  '1': 'button-lvl-1',
  '2': 'button-lvl-2',
  '3': 'button-lvl-3',
  '4': 'button-lvl-4',
  '5': 'button-lvl-5',
};

class Levels extends Phaser.State {

  create () {
    const levelButtonPositions = [
      { x: 144, y: 432, level: 1 },
      { x: 240, y: 432, level: 2 },
      { x: 336, y: 432, level: 3 },
      { x: 192, y: 528, level: 4 },
      { x: 288, y: 528, level: 5 }
    ];

    this.stage.backgroundColor = '#333';

    this.add.tween(this.add.image(118, 96, 'levels', 'label'))
      .from({ y: -150 }, 2000, Phaser.Easing.Elastic.Out)
      .start();

    for (let { x, y, level } of levelButtonPositions)
      this.add.existing(this.makeLevelButton(x, y, level));

    this.add.existing(this.makeBackButton(48, 48));
  }

  // --------------------------------------------------------------------------

  makeButton (x, y, key, face, callback = null) {
    let button = this.make.button(
      x, y, key, callback, this, face, face);

    button.anchor.set(0.5);
    button.input.useHandCursor = true;

    return button;
  }

  makeBackButton (x, y) {
    return this.makeButton(x, y, 'buttons', 'button-back', this.showMenu);
  }

  makeLevelButton (x, y, level) {
    let button = this.makeButton(
      x, y, 'levels', this.getLevelButtonFace(level), this.goToLevel);

    button.levelNumber = level;

    return button;
  }

  getLevelUnlocked (level) {
    return level <= this.game.settings.lastLevel;
  }

  getLevelButtonFace (level) {
    if (this.getLevelUnlocked(level))
      return levelButtonFaces[level];

    return 'button-lvl-no';
  }

  goToLevel ({ levelNumber }) {
    if (this.getLevelUnlocked(levelNumber))
      this.state.start('Game', true, false, levelNumber);
  }

  showMenu () {
    this.state.start('Menu');
  }

}

export default Levels;
<commit_msg>Do that using a template string instead.<commit_after>/*
 * Levels
 * ============================================================================
 *
 * A simple level selection screen, with unlockable buttons.
 */

class Levels extends Phaser.State {

  create () {
    const levelButtonPositions = [
      { x: 144, y: 432, level: 1 },
      { x: 240, y: 432, level: 2 },
      { x: 336, y: 432, level: 3 },
      { x: 192, y: 528, level: 4 },
      { x: 288, y: 528, level: 5 }
    ];

    this.stage.backgroundColor = '#333';

    this.add.tween(this.add.image(118, 96, 'levels', 'label'))
      .from({ y: -150 }, 2000, Phaser.Easing.Elastic.Out)
      .start();

    for (let { x, y, level } of levelButtonPositions)
      this.add.existing(this.makeLevelButton(x, y, level));

    this.add.existing(this.makeBackButton(48, 48));
  }

  // --------------------------------------------------------------------------

  makeButton (x, y, key, face, callback = null) {
    let button = this.make.button(
      x, y, key, callback, this, face, face);

    button.anchor.set(0.5);
    button.input.useHandCursor = true;

    return button;
  }

  makeBackButton (x, y) {
    return this.makeButton(x, y, 'buttons', 'button-back', this.showMenu);
  }

  makeLevelButton (x, y, level) {
    let button = this.makeButton(
      x, y, 'levels', this.getLevelButtonFace(level), this.goToLevel);

    button.levelNumber = level;

    return button;
  }

  getLevelUnlocked (level) {
    return level <= this.game.settings.lastLevel;
  }

  getLevelButtonFace (level) {
    if (this.getLevelUnlocked(level))
      return `button-lvl-${level}`;

    return 'button-lvl-no';
  }

  goToLevel ({ levelNumber }) {
    if (this.getLevelUnlocked(levelNumber))
      this.state.start('Game', true, false, levelNumber);
  }

  showMenu () {
    this.state.start('Menu');
  }

}

export default Levels;
<|endoftext|>