<commit_before>import React from 'react';
import { Subjects } from '../subject/Subjects';
import { Tag } from '../widgets/Tag';
import { MetricSummaryCard } from '../dashboard/MetricSummaryCard';
import { CardDashboard } from '../dashboard/CardDashboard';
import { ReportTitle } from './ReportTitle'

function ReportDashboard(props) {
    const subject_cards = Object.entries(props.report.summary_by_subject).map(([subject_uuid, summary]) =>
        <MetricSummaryCard
            key={subject_uuid} header={props.report.subjects[subject_uuid].name}
            onClick={(event) => props.onClick(event, subject_uuid)} {...summary} />);
    const tag_cards = Object.entries(props.report.summary_by_tag).map(([tag, summary]) =>
        <MetricSummaryCard key={tag} header={<Tag tag={tag} />} {...summary} />);
    return (
        <CardDashboard big_cards={subject_cards} small_cards={tag_cards} />
    )
}

export function Report(props) {
    function navigate_to_subject(event, subject_uuid) {
        event.preventDefault();
        document.getElementById(subject_uuid).scrollIntoView();
        window.scrollBy(0, -65);  // Correct for menu bar
    }
    return (
        <>
            <ReportTitle
                go_home={props.go_home}
                report={props.report}
                readOnly={props.readOnly}
                reload={props.reload}
            />
            <ReportDashboard report={props.report} onClick={(e, s) => navigate_to_subject(e, s)} />
            <Subjects
                datamodel={props.datamodel}
                nr_new_measurements={props.nr_new_measurements}
                readOnly={props.readOnly}
                reload={props.reload}
                report={props.report}
                report_date={props.report_date}
                search_string={props.search_string}
            />
        </>
    )
}
<commit_msg>Show error message when report doesn't exist (anymore). (#356)<commit_after>import React from 'react';
import { Message } from 'semantic-ui-react';
import { Subjects } from '../subject/Subjects';
import { Tag } from '../widgets/Tag';
import { MetricSummaryCard } from '../dashboard/MetricSummaryCard';
import { CardDashboard } from '../dashboard/CardDashboard';
import { ReportTitle } from './ReportTitle'

function ReportDashboard(props) {
    const subject_cards = Object.entries(props.report.summary_by_subject).map(([subject_uuid, summary]) =>
        <MetricSummaryCard
            key={subject_uuid} header={props.report.subjects[subject_uuid].name}
            onClick={(event) => props.onClick(event, subject_uuid)} {...summary} />);
    const tag_cards = Object.entries(props.report.summary_by_tag).map(([tag, summary]) =>
        <MetricSummaryCard key={tag} header={<Tag tag={tag} />} {...summary} />);
    return (
        <CardDashboard big_cards={subject_cards} small_cards={tag_cards} />
    )
}

export function Report(props) {
    function navigate_to_subject(event, subject_uuid) {
        event.preventDefault();
        document.getElementById(subject_uuid).scrollIntoView();
        window.scrollBy(0, -65);  // Correct for menu bar
    }
    if (!props.report) {
        return props.report_date ?
            <Message warning size='huge'>
                <Message.Header>{`Sorry, this report didn't exist at ${props.report_date}`}</Message.Header>
            </Message>
            :
            <Message negative size='huge'>
                <Message.Header>Sorry, this report doesn't exist</Message.Header>
            </Message>
    }
    return (
        <>
            <ReportTitle
                go_home={props.go_home}
                report={props.report}
                readOnly={props.readOnly}
                reload={props.reload}
            />
            <ReportDashboard report={props.report} onClick={(e, s) => navigate_to_subject(e, s)} />
            <Subjects
                datamodel={props.datamodel}
                nr_new_measurements={props.nr_new_measurements}
                readOnly={props.readOnly}
                reload={props.reload}
                report={props.report}
                report_date={props.report_date}
                search_string={props.search_string}
            />
        </>
    )
}
<|endoftext|>


<commit_before>/**
 * Polyfill for HTML5 CanvasRenderingContext2D.currentTransform[Inverse].
 * Matt <pseudobananamatty@yahoo.com.au, 2012-2013.
 * Please remove the yellow, tasty fruit from my email address in order to contact me.
 *
 * I, the author of this code, grant any entity the right to use this work for any purpose,
 * without any conditions, unless such conditions are required by law.
 * There are no warranties as to the operation or failure to operate of this code,
 * nor of its fitness for any particular purpose.
 *
 * Patches, bugfixes, enhancements, use stories etc are welcome - please email me.
 */
(function() {
	var vendorPrefixes = ['moz', 'webkit', 'khtml', 'o', 'ms'],
		i,
		identityMatrix = [1, 0, 0, 1, 0, 0],
		canvas,
		context,
		canvasProto,
		contextProto,
		originalGetContext, originalSave, originalRestore, originalRotate,
		originalScale, originalTranslate, originalTransform,
		originalSetTransform, originalResetTransform,
		getPrototypeOf, defineProperty;
	/*
	debug('Object.getPrototypeOf: ', Object.getPrototypeOf);
	debug('Object.defineProperty: ', Object.defineProperty);
	debug('__defineGetter__: ', __defineGetter__);
	debug('__defineSetter__: ', __defineSetter__);
	*/
	canvas = document.createElement('canvas');
	if (canvas && canvas.getContext) {
		context = canvas.getContext("2d");
	} else {
		context = undefined;
	}
	if (!context) {
		return; // Silently do nothing if <canvas> 2D context unavailable
	}
	// This would be a polyfill for Object.getPrototypeOf,
	// except that extending Object.prototype is Evil.
	if (Object.getPrototypeOf) {
		getPrototypeOf = Object.getPrototypeOf;
	} else {
		getPrototypeOf = function() {
			return this.__proto__ || this.constructor.prototype;
		};
	}
	// Another would-be polyfill, for Object.defineProperty.
	// This only handles the 'accessor descriptor' case, not the 'data descriptor' case.
	if (Object.defineProperty) {
		// NOTE: IE8 has this method, but it only works on DOM objects attached to the DOM tree.
		// But IE8 doesn't support <canvas>, so we're stuffed anyway and should have bailed earlier.
		defineProperty = Object.defineProperty;
	} else if (Object.__defineGetter__ && Object.__defineSetter__) {
		// Old Mozilla property API
		defineProperty = function(name, descriptor) {
			if (descriptor.get) {
				this.__defineGetter__(name, descriptor.get);
			}
			if (descriptor.set) {
				this.__defineSetter__(name, descriptor.set);
			}
		};
	} else {
		// NOTE: IE6-7 have an 'onpropertychange' event, but they also don't support <canvas>,
		// so it's useless for our purposes, and again we should have bailed earlier.
		defineProperty = undefined;
	}
	canvasProto = getPrototypeOf(canvas) || HTMLCanvasElement;
	contextProto = getPrototypeOf(context) || CanvasRenderingContext2D;
	// Separate polyfills for potentially missing Canvas context methods
	if (!('resetTransform' in contextProto)) {
		contextProto.resetTransform = function() {
			this.setTransform.apply(this, identityMatrix);
		};
	}
	if ('currentTransform' in contextProto && 'currentTransformInverse' in contextProto) {
		return; // Already have the two properties; no polyfill required
	}
	// If we have defineProperty, and if the browser has prefixed <foo>CurrentTransform[Inverse] properties,
	// add renamed non-prefixed properties mirroring them.
	for (i = 0; i < vendorPrefixes.length; i++) {
		if (defineProperty && !('currentTransform' in contextProto) && ((vendorPrefixes[i] + 'CurrentTransform') in contextProto)) {
			defineProperty(contextProto, 'currentTransform', {
				get: function() {
					return this[vendorPrefixes[i] + 'CurrentTransform'];
				},
				set: function(newMatrix) {
					this.setTransform.apply(this, newMatrix);
				},
				configurable: false,
				enumerable: false
			});
			defineProperty(contextProto, 'currentTransformInverse', {
				get: function() {
					return this[vendorPrefixes[i] + 'CurrentTransformInverse'];
				},
				// No setter for inverse matrix
				configurable: false,
				enumerable: false
			});
			return; // We're done at this point.
		}
	}
	// If we get here, we still don't have currentTransform[Inverse] properties
	// (not even prefixed ones), so we need to track the CTM ourselves.
	/*
	debug('currentTransform in contextProto: ', ('currentTransform' in contextProto));
	debug('currentTransformInverse in contextProto: ', ('currentTransformInverse' in contextProto));
	*/
	if (!('currentTransform' in contextProto) || !('currentTransformInverse' in contextProto)) {
		// Saved values of over-ridden Canvas methods
		originalGetContext = canvasProto.getContext;
		// Saved values of over-ridden Context methods
		originalSave      = contextProto.save;
		originalRestore   = contextProto.restore;
		originalRotate    = contextProto.rotate;
		originalScale     = contextProto.scale;
		originalTranslate = contextProto.translate;
		originalTransform = contextProto.transform;
		originalSetTransform = context.setTransform;
		originalResetTransform = contextProto.resetTransform;
		// Over-ride the Canvas factory method that creates Contexts to create decorated ones
		canvasProto.getContext = function() {
			// Workaround: older browsers do not accept 'arguments' as second parameter of Function.apply
			var context = originalGetContext.apply(this, Array.prototype.slice.call(arguments, 0));
			if (Object.defineProperty) {
				// Using Object.defineProperty rather than simple assignment in order to hide these 'private' data
				Object.defineProperty(context, '_transformMatrix', {
					configurable: false,
					enumerable: false,
					value: identityMatrix,
					writable: true
				});
				Object.defineProperty(context, '_transformStack', {
					configurable: false,
					enumerable: false,
					value: [],
					writable: true
				});
			} else {
				// Object.defineProperty unavailable; fall back to simple assignment.
				// TODO: Could avoid littering the context by storing these in a private (closed-over)
				// hash keyed by context. However JS gives no easy way to associate a unique ID with each context.
				context._transformMatrix = identityMatrix;
				context._transformStack = [];
			}
			return context;
		};
		// Over-ride each Context method that modifies the transform matrix
		contextProto.save = function() {
			this._transformStack.push(this._transformMatrix.concat()); // shallow copy
			return originalSave.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.restore = function() {
			var mtx = this._transformStack.pop();
			if (mtx) {
				this._transformMatrix = mtx;
			}
			return originalRestore.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.translate = function(x, y) {
			this._transformMatrix[4] += this._transformMatrix[0] * x + this._transformMatrix[2] * y;
			this._transformMatrix[5] += this._transformMatrix[1] * x + this._transformMatrix[3] * y;
			return originalTranslate.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.scale = function(x, y) {
			this._transformMatrix[0] *= x;
			this._transformMatrix[1] *= x;
			this._transformMatrix[2] *= y;
			this._transformMatrix[3] *= y;
			return originalScale.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.rotate = function(angle) {
			var c = Math.cos(angle), s = Math.sin(angle);
			this._transformMatrix = [
				this._transformMatrix[0] *  c + this._transformMatrix[2] * s,
				this._transformMatrix[1] *  c + this._transformMatrix[3] * s,
				this._transformMatrix[0] * -s + this._transformMatrix[2] * c,
				this._transformMatrix[1] * -s + this._transformMatrix[3] * c,
				this._transformMatrix[4],
				this._transformMatrix[5]
			];
			return originalRotate.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.transform = function(a, b, c, d, e, f) {
			this._transformMatrix = [
				this._transformMatrix[0] * a + this._transformMatrix[2] * b,
				this._transformMatrix[1] * a + this._transformMatrix[3] * b,
				this._transformMatrix[0] * c + this._transformMatrix[2] * d,
				this._transformMatrix[1] * c + this._transformMatrix[3] * d,
				this._transformMatrix[0] * e + this._transformMatrix[2] * f + this._transformMatrix[4],
				this._transformMatrix[1] * e + this._transformMatrix[3] * f + this._transformMatrix[5]
			];
			return originalTransform.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.setTransform = function(a, b, c, d, e, f) {
			this._transformMatrix = [ a, b, c, d, e, f];
			return originalSetTransform.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.resetTransform = function() {
			this._transformMatrix = identityMatrix;
			return originalResetTransform.apply(this, Array.prototype.slice.call(arguments, 0));
		};
	}
	if (defineProperty && !('currentTransform' in contextProto)) {
		defineProperty(contextProto, 'currentTransform', {
			get: function() {
				return this._transformMatrix;
			},
			set: function(newMatrix) {
				this.setTransform.apply(this, newMatrix);
			},
			configurable: false,
			enumerable: true
		});
	}
	if (defineProperty && !('currentTransformInverse' in contextProto)) {
		defineProperty(contextProto, 'currentTransformInverse', {
			get: function() {
				var a = this._transformMatrix[0], b = this._transformMatrix[1],
					c = this._transformMatrix[2], d = this._transformMatrix[3],
					e = this._transformMatrix[4], f = this._transformMatrix[5],
					ad_minus_bc = a * d - b * c,
					bc_minus_ad = b * c - a * d;
				return [
					d / ad_minus_bc, b / bc_minus_ad,
					c / bc_minus_ad, a / ad_minus_bc,
					(d * e - c * f) / bc_minus_ad, (b * e - a * f) / ad_minus_bc
				];
			},
			configurable: false,
			enumerable: true
		});
	}
})();
<commit_msg>Update copyright header.<commit_after>/**
 * Polyfill for HTML5 CanvasRenderingContext2D.currentTransform[Inverse].
 * Matt <mabananatty@supermattycom>, 2012-2013.
 * Please remove the yellow, tasty fruit from my email address in order to contact me.
 *
 * I, the author of this code, grant any entity the right to use this work
 * for any purpose and in any way, without any conditions or restrictions of any kind,
 * unless such conditions or restrictions are required by law.
 *
 * Notwithstanding the above, I would greatly appreciate it if you were to:
 * - Notify me of your use of this code, if any; and/or
 * - Contribute any changes which you may make back to me.
 *
 * There are no warranties as to the operation or failure to operate of this code,
 * nor of its fitness for any particular purpose.
 *
 * Patches, bugfixes, enhancements, use stories etc are welcome - please email me.
 */
(function() {
	var vendorPrefixes = ['moz', 'webkit', 'khtml', 'o', 'ms'],
		i,
		identityMatrix = [1, 0, 0, 1, 0, 0],
		canvas,
		context,
		canvasProto,
		contextProto,
		originalGetContext, originalSave, originalRestore, originalRotate,
		originalScale, originalTranslate, originalTransform,
		originalSetTransform, originalResetTransform,
		getPrototypeOf, defineProperty;
	/*
	debug('Object.getPrototypeOf: ', Object.getPrototypeOf);
	debug('Object.defineProperty: ', Object.defineProperty);
	debug('__defineGetter__: ', __defineGetter__);
	debug('__defineSetter__: ', __defineSetter__);
	*/
	canvas = document.createElement('canvas');
	if (canvas && canvas.getContext) {
		context = canvas.getContext("2d");
	} else {
		context = undefined;
	}
	if (!context) {
		return; // Silently do nothing if <canvas> 2D context unavailable
	}
	// This would be a polyfill for Object.getPrototypeOf,
	// except that extending Object.prototype is Evil.
	if (Object.getPrototypeOf) {
		getPrototypeOf = Object.getPrototypeOf;
	} else {
		getPrototypeOf = function() {
			return this.__proto__ || this.constructor.prototype;
		};
	}
	// Another would-be polyfill, for Object.defineProperty.
	// This only handles the 'accessor descriptor' case, not the 'data descriptor' case.
	if (Object.defineProperty) {
		// NOTE: IE8 has this method, but it only works on DOM objects attached to the DOM tree.
		// But IE8 doesn't support <canvas>, so we're stuffed anyway and should have bailed earlier.
		defineProperty = Object.defineProperty;
	} else if (Object.__defineGetter__ && Object.__defineSetter__) {
		// Old Mozilla property API
		defineProperty = function(name, descriptor) {
			if (descriptor.get) {
				this.__defineGetter__(name, descriptor.get);
			}
			if (descriptor.set) {
				this.__defineSetter__(name, descriptor.set);
			}
		};
	} else {
		// NOTE: IE6-7 have an 'onpropertychange' event, but they also don't support <canvas>,
		// so it's useless for our purposes, and again we should have bailed earlier.
		defineProperty = undefined;
	}
	canvasProto = getPrototypeOf(canvas) || HTMLCanvasElement;
	contextProto = getPrototypeOf(context) || CanvasRenderingContext2D;
	// Separate polyfills for potentially missing Canvas context methods
	if (!('resetTransform' in contextProto)) {
		contextProto.resetTransform = function() {
			this.setTransform.apply(this, identityMatrix);
		};
	}
	if ('currentTransform' in contextProto && 'currentTransformInverse' in contextProto) {
		return; // Already have the two properties; no polyfill required
	}
	// If we have defineProperty, and if the browser has prefixed <foo>CurrentTransform[Inverse] properties,
	// add renamed non-prefixed properties mirroring them.
	for (i = 0; i < vendorPrefixes.length; i++) {
		if (defineProperty && !('currentTransform' in contextProto) && ((vendorPrefixes[i] + 'CurrentTransform') in contextProto)) {
			defineProperty(contextProto, 'currentTransform', {
				get: function() {
					return this[vendorPrefixes[i] + 'CurrentTransform'];
				},
				set: function(newMatrix) {
					this.setTransform.apply(this, newMatrix);
				},
				configurable: false,
				enumerable: false
			});
			defineProperty(contextProto, 'currentTransformInverse', {
				get: function() {
					return this[vendorPrefixes[i] + 'CurrentTransformInverse'];
				},
				// No setter for inverse matrix
				configurable: false,
				enumerable: false
			});
			return; // We're done at this point.
		}
	}
	// If we get here, we still don't have currentTransform[Inverse] properties
	// (not even prefixed ones), so we need to track the CTM ourselves.
	/*
	debug('currentTransform in contextProto: ', ('currentTransform' in contextProto));
	debug('currentTransformInverse in contextProto: ', ('currentTransformInverse' in contextProto));
	*/
	if (!('currentTransform' in contextProto) || !('currentTransformInverse' in contextProto)) {
		// Saved values of over-ridden Canvas methods
		originalGetContext = canvasProto.getContext;
		// Saved values of over-ridden Context methods
		originalSave      = contextProto.save;
		originalRestore   = contextProto.restore;
		originalRotate    = contextProto.rotate;
		originalScale     = contextProto.scale;
		originalTranslate = contextProto.translate;
		originalTransform = contextProto.transform;
		originalSetTransform = context.setTransform;
		originalResetTransform = contextProto.resetTransform;
		// Over-ride the Canvas factory method that creates Contexts to create decorated ones
		canvasProto.getContext = function() {
			// Workaround: older browsers do not accept 'arguments' as second parameter of Function.apply
			var context = originalGetContext.apply(this, Array.prototype.slice.call(arguments, 0));
			if (Object.defineProperty) {
				// Using Object.defineProperty rather than simple assignment in order to hide these 'private' data
				Object.defineProperty(context, '_transformMatrix', {
					configurable: false,
					enumerable: false,
					value: identityMatrix,
					writable: true
				});
				Object.defineProperty(context, '_transformStack', {
					configurable: false,
					enumerable: false,
					value: [],
					writable: true
				});
			} else {
				// Object.defineProperty unavailable; fall back to simple assignment.
				// TODO: Could avoid littering the context by storing these in a private (closed-over)
				// hash keyed by context. However JS gives no easy way to associate a unique ID with each context.
				context._transformMatrix = identityMatrix;
				context._transformStack = [];
			}
			return context;
		};
		// Over-ride each Context method that modifies the transform matrix
		contextProto.save = function() {
			this._transformStack.push(this._transformMatrix.concat()); // shallow copy
			return originalSave.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.restore = function() {
			var mtx = this._transformStack.pop();
			if (mtx) {
				this._transformMatrix = mtx;
			}
			return originalRestore.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.translate = function(x, y) {
			this._transformMatrix[4] += this._transformMatrix[0] * x + this._transformMatrix[2] * y;
			this._transformMatrix[5] += this._transformMatrix[1] * x + this._transformMatrix[3] * y;
			return originalTranslate.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.scale = function(x, y) {
			this._transformMatrix[0] *= x;
			this._transformMatrix[1] *= x;
			this._transformMatrix[2] *= y;
			this._transformMatrix[3] *= y;
			return originalScale.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.rotate = function(angle) {
			var c = Math.cos(angle), s = Math.sin(angle);
			this._transformMatrix = [
				this._transformMatrix[0] *  c + this._transformMatrix[2] * s,
				this._transformMatrix[1] *  c + this._transformMatrix[3] * s,
				this._transformMatrix[0] * -s + this._transformMatrix[2] * c,
				this._transformMatrix[1] * -s + this._transformMatrix[3] * c,
				this._transformMatrix[4],
				this._transformMatrix[5]
			];
			return originalRotate.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.transform = function(a, b, c, d, e, f) {
			this._transformMatrix = [
				this._transformMatrix[0] * a + this._transformMatrix[2] * b,
				this._transformMatrix[1] * a + this._transformMatrix[3] * b,
				this._transformMatrix[0] * c + this._transformMatrix[2] * d,
				this._transformMatrix[1] * c + this._transformMatrix[3] * d,
				this._transformMatrix[0] * e + this._transformMatrix[2] * f + this._transformMatrix[4],
				this._transformMatrix[1] * e + this._transformMatrix[3] * f + this._transformMatrix[5]
			];
			return originalTransform.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.setTransform = function(a, b, c, d, e, f) {
			this._transformMatrix = [ a, b, c, d, e, f];
			return originalSetTransform.apply(this, Array.prototype.slice.call(arguments, 0));
		};
		contextProto.resetTransform = function() {
			this._transformMatrix = identityMatrix;
			return originalResetTransform.apply(this, Array.prototype.slice.call(arguments, 0));
		};
	}
	if (defineProperty && !('currentTransform' in contextProto)) {
		defineProperty(contextProto, 'currentTransform', {
			get: function() {
				return this._transformMatrix;
			},
			set: function(newMatrix) {
				this.setTransform.apply(this, newMatrix);
			},
			configurable: false,
			enumerable: true
		});
	}
	if (defineProperty && !('currentTransformInverse' in contextProto)) {
		defineProperty(contextProto, 'currentTransformInverse', {
			get: function() {
				var a = this._transformMatrix[0], b = this._transformMatrix[1],
					c = this._transformMatrix[2], d = this._transformMatrix[3],
					e = this._transformMatrix[4], f = this._transformMatrix[5],
					ad_minus_bc = a * d - b * c,
					bc_minus_ad = b * c - a * d;
				return [
					d / ad_minus_bc, b / bc_minus_ad,
					c / bc_minus_ad, a / ad_minus_bc,
					(d * e - c * f) / bc_minus_ad, (b * e - a * f) / ad_minus_bc
				];
			},
			configurable: false,
			enumerable: true
		});
	}
})();
<|endoftext|>


<commit_before>const assert = require('assert');
const mocha = require('mocha');
const Try = require('../dist');

mocha.describe('Success', () => {

    mocha.describe('.filter()', () => {

        mocha.it('should return success when filter predicate matches', () => {
            let success = Try.success(100)
                .filter(value => value > 50);
            assert(success.isSuccess());
        });

        mocha.it('should return failure when predicate does not match', () => {
            let success = Try.success(100)
                .filter(value => value > 500);
            assert(success.isFailure());
        });

        mocha.it('should throw error when function argument is not present', () => {
            let success = Try.success(100);
            assert.throws(() => success.filter());
        });

        mocha.it('should throw error when function argument is not a function', () => {
            let success = Try.success(100);
            assert.throws(() => success.filter({}), Error);
        });

    });

    mocha.describe('.flapMap()', () => {

        mocha.it('should flat map success try value', () => {
            let success = Try.success(100)
                .flatMap(value => Try.success(value + 10));
            assert(success.isSuccess());
            assert.equal(success.value, 110);
        });

        mocha.it('should not flat map failure try value', () => {
            let failure = Try.success(100)
                .flatMap(value => Try.failure('Something went wrong'));
            assert(failure.isFailure());
            assert.equal(failure.err, 'Something went wrong');
        });

        mocha.it('should throw error when function argument is not present', () => {
            let success = Try.success(100);
            assert.throws(() => success.flatMap());
        });

        mocha.it('should throw error when function argument is not a function', () => {
            let success = Try.success(100);
            assert.throws(() => success.flatMap({}));
        });

    });
});<commit_msg>Use var instead of let.<commit_after>const assert = require('assert');
const mocha = require('mocha');
const Try = require('../dist');

mocha.describe('Success', () => {

    mocha.describe('.filter()', () => {

        mocha.it('should return success when filter predicate matches', () => {
            var success = Try.success(100)
                .filter(value => value > 50);
            assert(success.isSuccess());
        });

        mocha.it('should return failure when predicate does not match', () => {
            var success = Try.success(100)
                .filter(value => value > 500);
            assert(success.isFailure());
        });

        mocha.it('should throw error when function argument is not present', () => {
            var success = Try.success(100);
            assert.throws(() => success.filter());
        });

        mocha.it('should throw error when function argument is not a function', () => {
            var success = Try.success(100);
            assert.throws(() => success.filter({}), Error);
        });

    });

    mocha.describe('.flapMap()', () => {

        mocha.it('should flat map success try value', () => {
            var success = Try.success(100)
                .flatMap(value => Try.success(value + 10));
            assert(success.isSuccess());
            assert.equal(success.value, 110);
        });

        mocha.it('should not flat map failure try value', () => {
            var failure = Try.success(100)
                .flatMap(value => Try.failure('Something went wrong'));
            assert(failure.isFailure());
            assert.equal(failure.err, 'Something went wrong');
        });

        mocha.it('should throw error when function argument is not present', () => {
            var success = Try.success(100);
            assert.throws(() => success.flatMap());
        });

        mocha.it('should throw error when function argument is not a function', () => {
            var success = Try.success(100);
            assert.throws(() => success.flatMap({}));
        });

    });
});
<|endoftext|>


<commit_before>'use strict';

var escapeNonWordsRegexp = /[_\W]+/g // precompile regex
function escapeNonWords(s) {
    return s.replace(escapeNonWordsRegexp, "-");
}

var socket = io();
var plots = {}; // Map of sensor -> chart
var rawlist = {};

//Variables used for the canvas.
var x_pos = 0;
var y_pos = 0;
var blocksize = 20;
var ball_size = 6;
var offset = ball_size/2; //Moves the ball object into center
//TODO: Find a dynamic offset value, maybe derive from c.height & c.width
var c, ctx, blocksize, ball;

setInterval(function() {
    for (var m in plots) {
        var plot = plots[m];
        if (typeof plot.redraw === "undefined") {
            continue
        }
        plot.redraw();
    }
}, 500);

socket.on('data', function(pkts){
	for (var i = 0; i < pkts.length; i++) {
		var pkt = pkts[i];

		if (~pkt.name.indexOf("request log")) {
			console.log(pkt);
			//var csvString = csvRows.join("\n");
			//var a = document.createElement('a');
			//a.href = 'data:attachment/csv;base64,' + btoa(csvString);
			//a.target = '_blank';
			//a.download = 'LogData.csv';

			//document.body.appendChild(a);

			//a.click();
		}
		else{
			var escapedName = escapeNonWords(pkt.name);
			if (pkt.name in rawlist) {
				document.getElementById(escapedName + '-val').innerHTML = pkt.value.toFixed(2);
			};
			if ((~pkt.name.indexOf("GX") || ~pkt.name.indexOf("GY")) && "GX" in plots) {
				update_g_plot(pkt);	//Update the g-force plot
			} else if (pkt.name in plots) {
				// Update the plot
				var shift = plots[pkt.name].series[0].data.length > 400;
				plots[pkt.name].series[0].addPoint(pkt.value, false, shift);
			} else {
				// Element does not exists, create it
				if (~pkt.name.indexOf("GX") || ~pkt.name.indexOf("GY")){
					create_g_plot();
				} else {
					//Element is a standard line plot
					//create_line_plot(pkt);
					var nameVal = escapedName + '-val';
					if ($('#' + nameVal).length > 0) {
						$('#' + nameVal).text(pkt.value.toFixed(2));
					} else {
						$('#rawlist').append(
							'
' +
							''+pkt.name+'	'+
							''+pkt.value.toFixed(2) +'	'+
							'
'
						);
						rawlist[pkt.name] = pkt;
					}
				}
			}
		}
		$(function() {
			$("#plots").sortable();
			$("#plots").disableSelection();
		});
	}
});

function is_in_circle(x) {
    x = x/4;                            //Only every 4th is a new pixel
    var y = Math.floor(x/ball_size);    //New line for every ball_size pixels
    x = x%ball_size;
    var dist_center = Math.sqrt(Math.pow(ball_size/2 - x, 2) + Math.pow(ball_size/2 - y, 2)); //Euclidian distance to center
    if (dist_center >= ball_size/2.5) {
        return false;
    } else {
        return true;
    }
}

function update_g_plot(packet){
	if (~packet.name.indexOf("GX")) {
        x_pos = packet.value;
    } else {
    //GY-event is usually sent directly after GX-event
    //so we do not update at both events
        y_pos = packet.value;
        ctx.clearRect(0,0,c.width,c.height);                                                //Clear the canvas
        ctx.stroke();                                                                       //Apply grid colors again
        ctx.putImageData(ball, c.width/2 + x_pos*blocksize - offset, c.height/2 + y_pos*blocksize - offset);  //Place ball object
    }
}

function create_g_plot() {
	//Element is a G-force graph - only make on GX event.
	//GX, GY is a html5 canvas element
	$('#plots').append('<canvas class="ui-state-default" id="GX"/>');
	c = document.getElementById("GX");
	ctx = c.getContext("2d");
	ctx.strokeStyle = "lightgrey";
	plots["GX"] = ctx; //Store canvas context in plots so it can be used out of scope.

	//Make the grid
	for (var i = 0; i < c.width/2; i+=blocksize) {
	    ctx.moveTo(c.width/2 + i, 0)
	    ctx.lineTo(c.width/2 + i, c.height)
	    ctx.moveTo(c.width/2 - i, 0)
	    ctx.lineTo(c.width/2 - i, c.height)
	};
	for (var i = 0; i < c.height/2; i+=blocksize) {
	    ctx.moveTo(0, c.height/2 + i)
	    ctx.lineTo(c.width, c.height/2 + i)
	    ctx.moveTo(0, c.height/2 - i)
	    ctx.lineTo(c.width, c.height/2 - i)
	};
	//Make the x and y axis more pronounced.
    ctx.moveTo(c.width/2, 0);
    ctx.lineTo(c.width/2, c.height);
    ctx.moveTo(0, c.height/2);
    ctx.lineTo(c.width, c.height/2);

	//Making a plot indicator object
	ball = ctx.createImageData(ball_size, ball_size); //Height = width => square

	//Paint it royal purple
	for (var i = 0; i < ball.data.length; i+=4) {
	    if (is_in_circle(i)) {
	        ball.data[i] = 120;     //Red 0-255
	        ball.data[i+1] = 81;     //Blue
	        ball.data[i+2] = 169;     //Green
	        ball.data[i+3] = 255;   //Alpha - transparancy
	    } else {
	        ball.data[i] = 0;       //Red
	        ball.data[i+1] = 0;     //Blue
	        ball.data[i+2] = 0;     //Green
	        ball.data[i+3] = 0;     //Alpha - transparancy
	    }
	};
	//Apply our lines onto ctx.
	ctx.stroke();
	ctx.putImageData(ball, c.width/2 - offset, c.height/2 - offset);
}

function create_line_plot(name, value) {
    //No graph exists, create it
    if ($('#' + escapeNonWords(name) + '-graph').length == 0) {
        $('#plots').append('
');
		$('#' + escapeNonWords(name)).css("background-color", "lightblue");
        plots[name] = new Highcharts.Chart({
            chart: {
                renderTo: escapeNonWords(name)+'-graph',
                defaultSeriesType: 'spline',
                valueDecimals: 2,
                animation: false,
            },
            title: {
                text: _.escape(name),
            },
            xAxis: {
                labels: {
                    format: '{value:.2f}',
                },
            },
            yAxis: {
                title: {
                    text: 'Value',
                },
                labels: {
                    format: '{value:.2f}'
                },
            },
            plotOptions: {
                series: {
                    enableMouseTracking: false,
                    animation: false,
                    marker : {
                        enabled: false
                    }
                },
            },
            series: [{
                name: _.escape(name),
                data: [value],
            }],
        });
    } else {  //ELement already exists, so we delete it
        plots[name].destroy();
        $('#'+ escapeNonWords(name) + '-graph').remove();
		$('#' + escapeNonWords(name)).css("background-color", "lightgrey");
        delete plots[name];
    }
}

function download_data(){
    socket.emit('download');
}
<commit_msg>Removed redundant updated of the rawlist in the sidebar<commit_after>'use strict';

var escapeNonWordsRegexp = /[_\W]+/g // precompile regex
function escapeNonWords(s) {
    return s.replace(escapeNonWordsRegexp, "-");
}

var socket = io();
var plots = {}; // Map of sensor -> chart
var rawlist = {};

//Variables used for the canvas.
var x_pos = 0;
var y_pos = 0;
var blocksize = 20;
var ball_size = 6;
var offset = ball_size/2; //Moves the ball object into center
//TODO: Find a dynamic offset value, maybe derive from c.height & c.width
var c, ctx, blocksize, ball;

setInterval(function() {
    for (var m in plots) {
        var plot = plots[m];
        if (typeof plot.redraw === "undefined") {
            continue
        }
        plot.redraw();
    }
}, 500);

socket.on('data', function(pkts){
	for (var i = 0; i < pkts.length; i++) {
		var pkt = pkts[i];

		if (~pkt.name.indexOf("request log")) {
			console.log(pkt);
			//var csvString = csvRows.join("\n");
			//var a = document.createElement('a');
			//a.href = 'data:attachment/csv;base64,' + btoa(csvString);
			//a.target = '_blank';
			//a.download = 'LogData.csv';

			//document.body.appendChild(a);

			//a.click();
		}
		else{
			var escapedName = escapeNonWords(pkt.name);
			var nameVal = escapedName + '-val';
			if (pkt.name in rawlist) {
				// In all case we need to update the sidebar raw value
				document.getElementById(nameVal).innerHTML = pkt.value.toFixed(2);
			};

			if ((~pkt.name.indexOf("GX") || ~pkt.name.indexOf("GY")) && "GX" in plots) {
				update_g_plot(pkt);	//Update the g-force plot
			} else if (pkt.name in plots) {
				// Update the plot
				var shift = plots[pkt.name].series[0].data.length > 400;
				plots[pkt.name].series[0].addPoint(pkt.value, false, shift);
			} else {
				// Element does not exists, create it
				if (~pkt.name.indexOf("GX") || ~pkt.name.indexOf("GY")){
					create_g_plot();
				} else {
					//Element is a standard line plot
					if ($('#' + nameVal).length === 0) {
						$('#rawlist').append(
							'
' +
							''+pkt.name+'	'+
							''+pkt.value.toFixed(2) +'	'+
							'
'
						);
						rawlist[pkt.name] = pkt;
					}
				}
			}
		}
		$(function() {
			$("#plots").sortable();
			$("#plots").disableSelection();
		});
	}
});

function is_in_circle(x) {
    x = x/4;                            //Only every 4th is a new pixel
    var y = Math.floor(x/ball_size);    //New line for every ball_size pixels
    x = x%ball_size;
    var dist_center = Math.sqrt(Math.pow(ball_size/2 - x, 2) + Math.pow(ball_size/2 - y, 2)); //Euclidian distance to center
    if (dist_center >= ball_size/2.5) {
        return false;
    } else {
        return true;
    }
}

function update_g_plot(packet){
	if (~packet.name.indexOf("GX")) {
        x_pos = packet.value;
    } else {
    //GY-event is usually sent directly after GX-event
    //so we do not update at both events
        y_pos = packet.value;
        ctx.clearRect(0,0,c.width,c.height);                                                //Clear the canvas
        ctx.stroke();                                                                       //Apply grid colors again
        ctx.putImageData(ball, c.width/2 + x_pos*blocksize - offset, c.height/2 + y_pos*blocksize - offset);  //Place ball object
    }
}

function create_g_plot() {
	//Element is a G-force graph - only make on GX event.
	//GX, GY is a html5 canvas element
	$('#plots').append('<canvas class="ui-state-default" id="GX"/>');
	c = document.getElementById("GX");
	ctx = c.getContext("2d");
	ctx.strokeStyle = "lightgrey";
	plots["GX"] = ctx; //Store canvas context in plots so it can be used out of scope.

	//Make the grid
	for (var i = 0; i < c.width/2; i+=blocksize) {
	    ctx.moveTo(c.width/2 + i, 0)
	    ctx.lineTo(c.width/2 + i, c.height)
	    ctx.moveTo(c.width/2 - i, 0)
	    ctx.lineTo(c.width/2 - i, c.height)
	};
	for (var i = 0; i < c.height/2; i+=blocksize) {
	    ctx.moveTo(0, c.height/2 + i)
	    ctx.lineTo(c.width, c.height/2 + i)
	    ctx.moveTo(0, c.height/2 - i)
	    ctx.lineTo(c.width, c.height/2 - i)
	};
	//Make the x and y axis more pronounced.
    ctx.moveTo(c.width/2, 0);
    ctx.lineTo(c.width/2, c.height);
    ctx.moveTo(0, c.height/2);
    ctx.lineTo(c.width, c.height/2);

	//Making a plot indicator object
	ball = ctx.createImageData(ball_size, ball_size); //Height = width => square

	//Paint it royal purple
	for (var i = 0; i < ball.data.length; i+=4) {
	    if (is_in_circle(i)) {
	        ball.data[i] = 120;     //Red 0-255
	        ball.data[i+1] = 81;     //Blue
	        ball.data[i+2] = 169;     //Green
	        ball.data[i+3] = 255;   //Alpha - transparancy
	    } else {
	        ball.data[i] = 0;       //Red
	        ball.data[i+1] = 0;     //Blue
	        ball.data[i+2] = 0;     //Green
	        ball.data[i+3] = 0;     //Alpha - transparancy
	    }
	};
	//Apply our lines onto ctx.
	ctx.stroke();
	ctx.putImageData(ball, c.width/2 - offset, c.height/2 - offset);
}

function create_line_plot(name, value) {
    //No graph exists, create it
    if ($('#' + escapeNonWords(name) + '-graph').length == 0) {
        $('#plots').append('
');
		$('#' + escapeNonWords(name)).css("background-color", "lightblue");
        plots[name] = new Highcharts.Chart({
            chart: {
                renderTo: escapeNonWords(name)+'-graph',
                defaultSeriesType: 'spline',
                valueDecimals: 2,
                animation: false,
            },
            title: {
                text: _.escape(name),
            },
            xAxis: {
                labels: {
                    format: '{value:.2f}',
                },
            },
            yAxis: {
                title: {
                    text: 'Value',
                },
                labels: {
                    format: '{value:.2f}'
                },
            },
            plotOptions: {
                series: {
                    enableMouseTracking: false,
                    animation: false,
                    marker : {
                        enabled: false
                    }
                },
            },
            series: [{
                name: _.escape(name),
                data: [value],
            }],
        });
    } else {  //ELement already exists, so we delete it
        plots[name].destroy();
        $('#'+ escapeNonWords(name) + '-graph').remove();
		$('#' + escapeNonWords(name)).css("background-color", "lightgrey");
        delete plots[name];
    }
}

function download_data(){
    socket.emit('download');
}
<|endoftext|>


<commit_before>function GoogleStaticMaps(){function e(e,r,a,t){var i=r[0];if(!a.mapWidth)throw new Error("The `mapWidth` is required.");if(!a.mapHeight)throw new Error("The `mapHeight` is required.");if(!a.address)throw new Error("The `address` is required.");var o="&zoom=";o+=a.zoom?a.zoom:"14";var s="//maps.googleapis.com/maps/api/staticmap?center=",p="&size="+a.mapWidth+"x"+a.mapHeight,d=encodeURIComponent(a.address),m="&markers=color:red|"+d;i.alt=a.address,i.src=s+d+p+o+m}var r={link:e,template:'',replace:!0,restrict:"E"};return r}angular.module("ngGoogleStaticMaps",[]).directive("staticMap",GoogleStaticMaps);<commit_msg>Minified everything for the next release<commit_after>!function(){function r(){var r;this.forceProtocol=function(t){return angular.isString(t)?(r=t?t.replace(/:$/,"")+":":t,this):r},this.$get=[function(){return{getProtocol:function(){return r||""}}}]}function t(r){function t(t,e,i){var o=e[0];if(!i.mapWidth)throw new Error("The `mapWidth` is required.");if(!i.mapHeight)throw new Error("The `mapHeight` is required.");if(!i.address)throw new Error("The `address` is required.");var a="&zoom=";a+=i.zoom?i.zoom:"14";var n=r.getProtocol()+"//maps.googleapis.com/maps/api/staticmap?center=",c="&size="+i.mapWidth+"x"+i.mapHeight,s=encodeURIComponent(i.address),p="&markers=color:red|"+s;o.alt=i.address,o.src=n+s+c+a+p}var e={link:t,template:'',replace:!0,restrict:"E"};return e}t.$inject=["staticMap"],angular.module("ngGoogleStaticMaps",[]).provider("staticMap",r).directive("staticMap",t)}();<|endoftext|>


<commit_before>"use strict"

var text = "";
var sugg = [];
var typeindex = 0;
var nodetypes = ["person", "project", "skill", "deliverable", "objective"];
var suggestionChange=false;
var sentenceStack = [];
var nodeindex, linkindex;
var typeStack = [];

var ExecutionStack = [];

var lastnode;

$('#textanalyser').autocompleteTrigger({
    triggerStart: '#',
    triggerEnd: '',
    source: sugg
});

$("#textanalyser").keypress(function(e) {
     if (graph.history !== undefined) {
         graph.history.record_keystrokes(KEYSTROKE_WHERE_TEXTANALYSIS, [e.which]);
     }
     if (e.which == 13) {
        if(!suggestionChange){
            text = $('#textanalyser').val();
            $('#textanalyser').val("");
            TextAnalyser2(text, true);
            typeStack=[];
        } else {
            suggestionChange=false;
        }
        return false;
    }

    if (e.which == 37) {//RIGHT
        $('body').scrollLeft(0);
        e.stopPropagation();
        return false;
    }
    if (e.which == 39) { //LEFT
        $('body').scrollLeft(0);
        e.stopPropagation();
        return false;
    }

});

$(document).keydown(function(e) {

    if (graph.history !== undefined) {
        graph.history.record_keystrokes(KEYSTROKE_WHERE_DOCUMENT, [e.KeyCode]);
    }
    if (e.keyCode == 9) {//TAB
        e.preventDefault();
        changeType("down", lastnode);
        return false;
    }

    if (e.keyCode == 37) {//UP
          $('html, body').scrollLeft(0);
    }
    if (e.keyCode == 39) {//DOWN
          $('html, body').scrollLeft(0);
    }

    if (e.keyCode == 38) {//UP
        suggestionChange=true;
    }
    if (e.keyCode == 40) {//DOWN
        suggestionChange=true;
    }

    if (e.keyCode == 9) {//TAB
        return false;
    }

});

function textSelect(inp, s, e) {
        e = e || s;
        if (inp.createTextRange) {
            var r = inp.createTextRange();
            r.collapse(true);
            r.moveEnd('character', e);
            r.moveStart('character', s);
            r.select();
        }else if(inp.setSelectionRange) {
            inp.focus();
            inp.setSelectionRange(s, e);
        }
    }

function changeType(arg, id) {
    if(!id)id="new node";
    if (arg === 'up') {
        if (typeindex < 4) typeindex++;
        else typeindex = 0;
        graph.editType(id, null, nodetypes[typeindex]);
        $('.typeselection').html('

' + "Chosen Type: " + nodetypes[typeindex] + '

');
        graph.findCoordinates(lastnode,null);
    } else {
        if (typeindex > 0) typeindex--;
        else typeindex = 4;

        graph.editType(id, null, nodetypes[typeindex]);
        $('.typeselection').html('

' + "Chosen Type: " + nodetypes[typeindex] + '

');
        graph.findCoordinates(lastnode,null);

    }
    graph.updateGraph();
}

window.setInterval(function() {
    if ($('#textanalyser').val() != text) {

        if(text.length*8>500)$('#textanalyser').css('width',text.length*8+20);
        // text changed
        text = $('#textanalyser').val();
        TextAnalyser2(text, false);
        suggestionChange=false;
    }
}, 5);

function TextAnalyser2(newtext, finalize) {
    var segment = [],
        subsegment = [],
        sentence = [];
    var newlinks = [];
    var newnodes = [];
    linkindex = 0;
    nodeindex = 0;
    var orderStack = [];
    var quoteword = "";
    var ANDcase = false;
    var ANDcount = 0;
    var prefix = "";

    //Sentence Sequencing
    //Build the words and cuts the main elements
    segment = newtext.split("#");
    for (var j = 0; j < segment.length; j++) {
        if (j !== 0) sentence.push("#");
        subsegment = segment[j].split(" ");
        if (subsegment.length === 0) {
            sentence.push(" ");
        }
        for (var k = 0; k < subsegment.length; k++) {
            if (subsegment[k] !== " " && subsegment[k] !== "") {
                if (subsegment[k].charAt(0) === '"') {
                    quoteword = "";
                    do {
                        quoteword += subsegment[k] + " ";
                        if(subsegment[k].charAt(subsegment[k].length-1) !== '"')k++;
                    } while (k < subsegment.length && subsegment[k].charAt(subsegment[k].length - 1) !== '"');
                     if(subsegment[k])if(subsegment[k]!==quoteword.replace(/ /g, ""))quoteword += subsegment[k];
                    sentence.push(quoteword.replace(/"/g, ""));
                } else {
                    sentence.push(subsegment[k]);
                }
            }
        }
    }

    //BUILD NEW NODE AND LINK ARRAYS WITH ORDER OF APPEARENCE
    for (var m = 0; m < sentence.length; m++) {
        switch (sentence[m]) {
            case "#":
                orderStack.push("START");
                break;
            case "and":
            case "+":
            case ",":
            case "&":
                sentence[m]=" and ";
                ANDcount++;
                //orderStack.push("AND");
            default:
                if (orderStack[orderStack.length - 1] === "START") {
                    orderStack.push("NODE");
                    newnodes.push(sentence[m]);
                    linkindex++;
                } else if (orderStack[orderStack.length - 1] === "NODE") {
                    orderStack.push("LINK");
                    if (!newlinks[linkindex]) {
                        newlinks[linkindex] = sentence[m] + " ";
                    } else {
                        newlinks[linkindex] += sentence[m] + " ";
                    }
                } else {
                    if (!newlinks[linkindex]) {
                        newlinks[linkindex] = sentence[m] + " ";
                    } else {
                        newlinks[linkindex] += sentence[m] + " ";
                    }
                }
                if (newnodes.length === 0) prefix += sentence[m] + " ";
                break;
        }
    }

    //ATTACH SENTENCE PREFIX
    if (prefix) newlinks[1] += "(" + prefix + ")";

    //WRITE COMPLETE SENTENCE
    linkindex = 0;
    nodeindex = 0;
    var word = "";
    var completeSentence = "";
    for (var m = 0; m < orderStack.length; m++) {
        if (orderStack[m] === "NODE") {
            word += " (" + newnodes[nodeindex] + ") ";
            if(newnodes[nodeindex].split(" ").length>1){
                completeSentence += '"'+newnodes[nodeindex]+'"' + " ";
            }else{
                completeSentence += newnodes[nodeindex] + " ";
            }
            nodeindex++;
        } else if (orderStack[m] === "LINK") {
            linkindex++;
            word += " -->" + newlinks[linkindex] + " --> ";
            completeSentence += newlinks[linkindex];
        }
    }

    //REBUILD GRAPH
    linkindex = 0;
    nodeindex = 0;

    //CHANGE TO PERMANENT STATE AND UPDATE SUGGESTIONLIST
    var typesetter = "";
    if (finalize === true) {
        typesetter = "perm";
        for (var n = 0; n < newnodes.length; n++) {
            if (Unique(newnodes[n])) {
                if(newnodes[n].split(" ").length>1){
                    sugg.push('"'+newnodes[n]+'"');
                }else{
                    sugg.push(newnodes[n]);
                }

            }
        }
        sugg.push(text);
    } else {
        typesetter = "temp";
    }

    //REINITIALISE GRAPH (DUMB BUT IT WORKS)
    graph.removeNodes("temp");
    graph.removeLinks("temp");

    //ADD SURROUNDING BUBBLE
    if (orderStack.length > 0) graph.addNode("", "bubble", "temp");

    var abnormalGraph=false;
    if((newlinks.length- ANDcount)>=3 )abnormalGraph=true;

    //0-N ORDER STACK
    for (var m = 0; m < orderStack.length - 1; m++) {
        switch (orderStack[m]) {
            case "START":
                if(!typeStack[nodeindex])typeStack[nodeindex]=nodetypes[typeindex];
                break;
            case "NODE":
                graph.addNode(newnodes[nodeindex], typeStack[nodeindex], typesetter);
                if (!abnormalGraph) graph.addLink(newnodes[nodeindex - 1], newnodes[nodeindex], newlinks[linkindex], typesetter);
                nodeindex++;
                break;
            case "LINK":
                linkindex++;
                break;
        }
    }

    //FINAL N ORDER
    switch (orderStack[orderStack.length - 1]) {
        case "START":
            typeStack[nodeindex]=nodetypes[typeindex];
            graph.addNode("new node", typeStack[nodeindex], "temp");
            if (!abnormalGraph){graph.addLink(newnodes[nodeindex - 1], "new node", newlinks[linkindex], "temp");
            ANDconnect("new node");}
            $('.typeselection').css({top:window.innerHeight/2-115,left:window.innerWidth/2-325});
            $('.typeselection').html('

Use [TAB] key to pick a type

');

            break;
        case "NODE":
            typeStack[nodeindex]=nodetypes[typeindex];
            graph.addNode(newnodes[nodeindex], typeStack[nodeindex], typesetter);
            if (!abnormalGraph){ graph.addLink(newnodes[nodeindex - 1], newnodes[nodeindex], newlinks[linkindex], typesetter);
            ANDconnect(newnodes[nodeindex]);}
            break;
        case "LINK":
            linkindex++;
            graph.addNode("new node", "empty", "temp");
            if (!abnormalGraph){ graph.addLink(newnodes[nodeindex - 1], "new node", newlinks[linkindex], "temp");
            ANDconnect("new node");}

            $('.typeselection').css('top', -300);
            $('.typeselection').css('left', 0);
            break;
    }

    //EXTERNAL AND CONNECTION CHECKING
    var verb = "";
    function ANDconnect(node) {
          for(var x=0;x<newlinks.length;x++){
            if(newlinks[x])if(newlinks[x].replace(/ /g,"")!=="and"){
                verb=newlinks[x];
                for(var y=0; y<x ;y++){
                    graph.addLink(newnodes[y],node,verb,typesetter);
                    for(var z=x; z<newnodes.length ;z++){
                        graph.addLink(newnodes[y],newnodes[z],verb,typesetter);
                    }
                }

            }
        }

    }

    /*console.log(sentence);
    console.log(completeSentence);
    console.log(orderStack);*/

    //STAR CASE
    verb = "";
    if (abnormalGraph) {
        for (var l = 1; l < newlinks.length; l++) {
            if (newlinks[l])
                if (newlinks[l].replace(/ /g, "") !== "and") {
                    verb = newlinks[l];
                }
        }
        graph.addNode(completeSentence, "chainlink", typesetter);
        for (var n = 0; n < newnodes.length; n++) {
            graph.addLink(newnodes[n], completeSentence, "", typesetter);
        }
    }

    //FOR THE EXTERNAL ARROW-TYPE CHANGER
    lastnode = newnodes[nodeindex];

    if(finalize){
        $('.typeselection').css('top', -300);
        $('.typeselection').css('left', 0);
    }

    //UPDATE GRAPH ONCE
    graph.update();
}

function Unique(newnode) {
    var truth = true;
    for (var p = 0; p < sugg.length; p++) {
        if (sugg[p] === newnode) {
            truth = false;
        }
    }
    return truth;
}
<commit_msg>textanalysis.js: some indentation and one if-bool rewrite<commit_after>"use strict"

var text = "";
var sugg = [];
var typeindex = 0;
var nodetypes = ["person", "project", "skill", "deliverable", "objective"];
var suggestionChange=false;
var sentenceStack = [];
var nodeindex, linkindex;
var typeStack = [];

var ExecutionStack = [];

var lastnode;

$('#textanalyser').autocompleteTrigger({
    triggerStart: '#',
    triggerEnd: '',
    source: sugg
});

$("#textanalyser").keypress(function(e) {
     if (graph.history !== undefined) {
         graph.history.record_keystrokes(KEYSTROKE_WHERE_TEXTANALYSIS, [e.which]);
     }
     if (e.which == 13) {
        if(!suggestionChange){
            text = $('#textanalyser').val();
            $('#textanalyser').val("");
            TextAnalyser2(text, true);
            typeStack=[];
        } else {
            suggestionChange=false;
        }
        return false;
    }

    if (e.which == 37) {//RIGHT
        $('body').scrollLeft(0);
        e.stopPropagation();
        return false;
    }
    if (e.which == 39) { //LEFT
        $('body').scrollLeft(0);
        e.stopPropagation();
        return false;
    }

});

$(document).keydown(function(e) {

    if (graph.history !== undefined) {
        graph.history.record_keystrokes(KEYSTROKE_WHERE_DOCUMENT, [e.KeyCode]);
    }
    if (e.keyCode == 9) {//TAB
        e.preventDefault();
        changeType("down", lastnode);
        return false;
    }

    if (e.keyCode == 37) {//UP
          $('html, body').scrollLeft(0);
    }
    if (e.keyCode == 39) {//DOWN
          $('html, body').scrollLeft(0);
    }

    if (e.keyCode == 38) {//UP
        suggestionChange=true;
    }
    if (e.keyCode == 40) {//DOWN
        suggestionChange=true;
    }

    if (e.keyCode == 9) {//TAB
        return false;
    }

});

function textSelect(inp, s, e) {
        e = e || s;
        if (inp.createTextRange) {
            var r = inp.createTextRange();
            r.collapse(true);
            r.moveEnd('character', e);
            r.moveStart('character', s);
            r.select();
        }else if(inp.setSelectionRange) {
            inp.focus();
            inp.setSelectionRange(s, e);
        }
    }

function changeType(arg, id) {
    if(!id)id="new node";
    if (arg === 'up') {
        if (typeindex < 4) typeindex++;
        else typeindex = 0;
        graph.editType(id, null, nodetypes[typeindex]);
        $('.typeselection').html('

' + "Chosen Type: " + nodetypes[typeindex] + '

');
        graph.findCoordinates(lastnode,null);
    } else {
        if (typeindex > 0) typeindex--;
        else typeindex = 4;

        graph.editType(id, null, nodetypes[typeindex]);
        $('.typeselection').html('

' + "Chosen Type: " + nodetypes[typeindex] + '

');
        graph.findCoordinates(lastnode,null);

    }
    graph.updateGraph();
}

window.setInterval(function() {
    if ($('#textanalyser').val() != text) {

        if(text.length*8>500)$('#textanalyser').css('width',text.length*8+20);
        // text changed
        text = $('#textanalyser').val();
        TextAnalyser2(text, false);
        suggestionChange=false;
    }
}, 5);

function TextAnalyser2(newtext, finalize) {
    var segment = [],
        subsegment = [],
        sentence = [];
    var newlinks = [];
    var newnodes = [];
    linkindex = 0;
    nodeindex = 0;
    var orderStack = [];
    var quoteword = "";
    var ANDcase = false;
    var ANDcount = 0;
    var prefix = "";

    //Sentence Sequencing
    //Build the words and cuts the main elements
    segment = newtext.split("#");
    for (var j = 0; j < segment.length; j++) {
        if (j !== 0) sentence.push("#");
        subsegment = segment[j].split(" ");
        if (subsegment.length === 0) {
            sentence.push(" ");
        }
        for (var k = 0; k < subsegment.length; k++) {
            if (subsegment[k] !== " " && subsegment[k] !== "") {
                if (subsegment[k].charAt(0) === '"') {
                    quoteword = "";
                    do {
                        quoteword += subsegment[k] + " ";
                        if(subsegment[k].charAt(subsegment[k].length-1) !== '"')k++;
                    } while (k < subsegment.length && subsegment[k].charAt(subsegment[k].length - 1) !== '"');
                     if(subsegment[k])if(subsegment[k]!==quoteword.replace(/ /g, ""))quoteword += subsegment[k];
                    sentence.push(quoteword.replace(/"/g, ""));
                } else {
                    sentence.push(subsegment[k]);
                }
            }
        }
    }

    //BUILD NEW NODE AND LINK ARRAYS WITH ORDER OF APPEARENCE
    for (var m = 0; m < sentence.length; m++) {
        switch (sentence[m]) {
            case "#":
                orderStack.push("START");
                break;
            case "and":
            case "+":
            case ",":
            case "&":
                sentence[m]=" and ";
                ANDcount++;
                //orderStack.push("AND");
            default:
                if (orderStack[orderStack.length - 1] === "START") {
                    orderStack.push("NODE");
                    newnodes.push(sentence[m]);
                    linkindex++;
                } else if (orderStack[orderStack.length - 1] === "NODE") {
                    orderStack.push("LINK");
                    if (!newlinks[linkindex]) {
                        newlinks[linkindex] = sentence[m] + " ";
                    } else {
                        newlinks[linkindex] += sentence[m] + " ";
                    }
                } else {
                    if (!newlinks[linkindex]) {
                        newlinks[linkindex] = sentence[m] + " ";
                    } else {
                        newlinks[linkindex] += sentence[m] + " ";
                    }
                }
                if (newnodes.length === 0) prefix += sentence[m] + " ";
                break;
        }
    }

    //ATTACH SENTENCE PREFIX
    if (prefix) newlinks[1] += "(" + prefix + ")";

    //WRITE COMPLETE SENTENCE
    linkindex = 0;
    nodeindex = 0;
    var word = "";
    var completeSentence = "";
    for (var m = 0; m < orderStack.length; m++) {
        if (orderStack[m] === "NODE") {
            word += " (" + newnodes[nodeindex] + ") ";
            if(newnodes[nodeindex].split(" ").length>1){
                completeSentence += '"'+newnodes[nodeindex]+'"' + " ";
            }else{
                completeSentence += newnodes[nodeindex] + " ";
            }
            nodeindex++;
        } else if (orderStack[m] === "LINK") {
            linkindex++;
            word += " -->" + newlinks[linkindex] + " --> ";
            completeSentence += newlinks[linkindex];
        }
    }

    //REBUILD GRAPH
    linkindex = 0;
    nodeindex = 0;

    //CHANGE TO PERMANENT STATE AND UPDATE SUGGESTIONLIST
    var typesetter = "";
    if (finalize === true) {
        typesetter = "perm";
        for (var n = 0; n < newnodes.length; n++) {
            if (Unique(newnodes[n])) {
                if(newnodes[n].split(" ").length>1){
                    sugg.push('"'+newnodes[n]+'"');
                }else{
                    sugg.push(newnodes[n]);
                }

            }
        }
        sugg.push(text);
    } else {
        typesetter = "temp";
    }

    //REINITIALISE GRAPH (DUMB BUT IT WORKS)
    graph.removeNodes("temp");
    graph.removeLinks("temp");

    //ADD SURROUNDING BUBBLE
    if (orderStack.length > 0) {
        graph.addNode("", "bubble", "temp");
    }

    var abnormalGraph = (newlinks.length - ANDcount) >= 3;

    //0-N ORDER STACK
    for (var m = 0; m < orderStack.length - 1; m++) {
        switch (orderStack[m]) {
            case "START":
                if (!typeStack[nodeindex]) {
                    typeStack[nodeindex] = nodetypes[typeindex];
                }
                break;
            case "NODE":
                graph.addNode(newnodes[nodeindex], typeStack[nodeindex], typesetter);
                if (!abnormalGraph) graph.addLink(newnodes[nodeindex - 1], newnodes[nodeindex], newlinks[linkindex], typesetter);
                nodeindex++;
                break;
            case "LINK":
                linkindex++;
                break;
        }
    }

    //FINAL N ORDER
    switch (orderStack[orderStack.length - 1]) {
        case "START":
            typeStack[nodeindex]=nodetypes[typeindex];
            graph.addNode("new node", typeStack[nodeindex], "temp");
            if (!abnormalGraph){graph.addLink(newnodes[nodeindex - 1], "new node", newlinks[linkindex], "temp");
            ANDconnect("new node");}
            $('.typeselection').css({top:window.innerHeight/2-115,left:window.innerWidth/2-325});
            $('.typeselection').html('

Use [TAB] key to pick a type

');

            break;
        case "NODE":
            typeStack[nodeindex]=nodetypes[typeindex];
            graph.addNode(newnodes[nodeindex], typeStack[nodeindex], typesetter);
            if (!abnormalGraph) {
                graph.addLink(newnodes[nodeindex - 1], newnodes[nodeindex], newlinks[linkindex], typesetter);
                ANDconnect(newnodes[nodeindex]);
            }
            break;
        case "LINK":
            linkindex++;
            graph.addNode("new node", "empty", "temp");
            if (!abnormalGraph){ graph.addLink(newnodes[nodeindex - 1], "new node", newlinks[linkindex], "temp");
            ANDconnect("new node");}

            $('.typeselection').css('top', -300);
            $('.typeselection').css('left', 0);
            break;
    }

    //EXTERNAL AND CONNECTION CHECKING
    var verb = "";
    function ANDconnect(node) {
          for(var x=0;x<newlinks.length;x++){
            if(newlinks[x])if(newlinks[x].replace(/ /g,"")!=="and"){
                verb=newlinks[x];
                for(var y=0; y<x ;y++){
                    graph.addLink(newnodes[y],node,verb,typesetter);
                    for(var z=x; z<newnodes.length ;z++){
                        graph.addLink(newnodes[y],newnodes[z],verb,typesetter);
                    }
                }

            }
        }

    }

    /*console.log(sentence);
    console.log(completeSentence);
    console.log(orderStack);*/

    //STAR CASE
    verb = "";
    if (abnormalGraph) {
        for (var l = 1; l < newlinks.length; l++) {
            if (newlinks[l])
                if (newlinks[l].replace(/ /g, "") !== "and") {
                    verb = newlinks[l];
                }
        }
        graph.addNode(completeSentence, "chainlink", typesetter);
        for (var n = 0; n < newnodes.length; n++) {
            graph.addLink(newnodes[n], completeSentence, "", typesetter);
        }
    }

    //FOR THE EXTERNAL ARROW-TYPE CHANGER
    lastnode = newnodes[nodeindex];

    if(finalize){
        $('.typeselection').css('top', -300);
        $('.typeselection').css('left', 0);
    }

    //UPDATE GRAPH ONCE
    graph.update();
}

function Unique(newnode) {
    var truth = true;
    for (var p = 0; p < sugg.length; p++) {
        if (sugg[p] === newnode) {
            truth = false;
        }
    }
    return truth;
}
<|endoftext|>


<commit_before>module.exports = {
  /**
   * A decorator is just a callable that takes a
   * function as an argument and returns a
   * replacement function. We’ll start simply
   * and work our way up to useful decorators.
   * @type {function}
   * @returns {function} decorate function.
   */
  singleton: (fun) => {
    var instance;

    return (...args) {
      if (instance)
        return instance()
    }
  };
};
<commit_msg>removes unused util<commit_after><|endoftext|>


<commit_before>import {isExist} from './objectUtils'

export const EVENTS = {
  MOUSE_ENTER: 'mouseenter',
  MOUSE_LEAVE: 'mouseleave',
  FOCUS: 'focus',
  BLUR: 'blur',
  CLICK: 'click',
  INPUT: 'input',
  KEY_DOWN: 'keydown',
  KEY_UP: 'keyup',
  KEY_PRESS: 'keypress',
  RESIZE: 'resize',
  SCROLL: 'scroll'
}

export const TRIGGERS = {
  CLICK: 'click',
  HOVER: 'hover',
  FOCUS: 'focus',
  HOVER_FOCUS: 'hover-focus',
  OUTSIDE_CLICK: 'outside-click',
  MANUAL: 'manual'
}

export const PLACEMENTS = {
  TOP: 'top',
  RIGHT: 'right',
  BOTTOM: 'bottom',
  LEFT: 'left'
}

export function getComputedStyle (el) {
  return window.getComputedStyle(el)
}

export function getViewportSize () {
  let width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
  let height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
  return {width, height}
}

let scrollbarWidth = null
let savedScreenSize = null

export function getScrollbarWidth (recalculate = false) {
  let screenSize = getViewportSize()
  // return directly when already calculated & not force recalculate & screen size not changed
  if (scrollbarWidth !== null && !recalculate &&
    screenSize.height === savedScreenSize.height && screenSize.width === savedScreenSize.width) {
    return scrollbarWidth
  }
  if (document.readyState === 'loading') {
    return null
  }
  const div1 = document.createElement('div')
  const div2 = document.createElement('div')
  div1.style.width = div2.style.width = div1.style.height = div2.style.height = '100px'
  div1.style.overflow = 'scroll'
  div2.style.overflow = 'hidden'
  document.body.appendChild(div1)
  document.body.appendChild(div2)
  scrollbarWidth = Math.abs(div1.scrollHeight - div2.scrollHeight)
  document.body.removeChild(div1)
  document.body.removeChild(div2)
  // save new screen size
  savedScreenSize = screenSize
  return scrollbarWidth
}

export function on (element, event, handler) {
  element.addEventListener(event, handler)
}

export function off (element, event, handler) {
  element.removeEventListener(event, handler)
}

export function isElement (el) {
  return el && el.nodeType === Node.ELEMENT_NODE
}

export function removeFromDom (el) {
  isElement(el) && isElement(el.parentNode) && el.parentNode.removeChild(el)
}

export function ensureElementMatchesFunction () {
  if (!Element.prototype.matches) {
    Element.prototype.matches =
      Element.prototype.matchesSelector ||
      Element.prototype.mozMatchesSelector ||
      Element.prototype.msMatchesSelector ||
      Element.prototype.oMatchesSelector ||
      Element.prototype.webkitMatchesSelector ||
      function (s) {
        let matches = (this.document || this.ownerDocument).querySelectorAll(s)
        let i = matches.length
        while (--i >= 0 && matches.item(i) !== this) {
        }
        return i > -1
      }
  }
}

export function addClass (el, className) {
  if (!isElement(el)) {
    return
  }
  if (el.className) {
    let classes = el.className.split(' ')
    if (classes.indexOf(className) < 0) {
      classes.push(className)
      el.className = classes.join(' ')
    }
  } else {
    el.className = className
  }
}

export function removeClass (el, className) {
  if (!isElement(el)) {
    return
  }
  if (el.className) {
    let classes = el.className.split(' ')
    let newClasses = []
    for (let i = 0, l = classes.length; i < l; i++) {
      if (classes[i] !== className) {
        newClasses.push(classes[i])
      }
    }
    el.className = newClasses.join(' ')
  }
}

export function hasClass (el, className) {
  if (!isElement(el)) {
    return false
  }
  let classes = el.className.split(' ')
  for (let i = 0, l = classes.length; i < l; i++) {
    if (classes[i] === className) {
      return true
    }
  }
  return false
}

export function setDropdownPosition (dropdown, trigger, options = {}) {
  let doc = document.documentElement
  let containerScrollLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0)
  let containerScrollTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)
  let rect = trigger.getBoundingClientRect()
  let dropdownRect = dropdown.getBoundingClientRect()
  dropdown.style.right = 'auto'
  dropdown.style.bottom = 'auto'
  if (options.menuRight) {
    dropdown.style.left = containerScrollLeft + rect.left + rect.width - dropdownRect.width + 'px'
  } else {
    dropdown.style.left = containerScrollLeft + rect.left + 'px'
  }
  if (options.dropup) {
    dropdown.style.top = containerScrollTop + rect.top - dropdownRect.height - 4 + 'px'
  } else {
    dropdown.style.top = containerScrollTop + rect.top + rect.height + 'px'
  }
}

export function isAvailableAtPosition (trigger, popup, placement) {
  let triggerRect = trigger.getBoundingClientRect()
  let popupRect = popup.getBoundingClientRect()
  let viewPortSize = getViewportSize()
  let top = true
  let right = true
  let bottom = true
  let left = true
  switch (placement) {
    case PLACEMENTS.TOP:
      top = triggerRect.top >= popupRect.height
      left = triggerRect.left + triggerRect.width / 2 >= popupRect.width / 2
      right = triggerRect.right - triggerRect.width / 2 + popupRect.width / 2 <= viewPortSize.width
      break
    case PLACEMENTS.BOTTOM:
      bottom = triggerRect.bottom + popupRect.height <= viewPortSize.height
      left = triggerRect.left + triggerRect.width / 2 >= popupRect.width / 2
      right = triggerRect.right - triggerRect.width / 2 + popupRect.width / 2 <= viewPortSize.width
      break
    case PLACEMENTS.RIGHT:
      right = triggerRect.right + popupRect.width <= viewPortSize.width
      top = triggerRect.top + triggerRect.height / 2 >= popupRect.height / 2
      bottom = triggerRect.bottom - triggerRect.height / 2 + popupRect.height / 2 <= viewPortSize.height
      break
    case PLACEMENTS.LEFT:
      left = triggerRect.left >= popupRect.width
      top = triggerRect.top + triggerRect.height / 2 >= popupRect.height / 2
      bottom = triggerRect.bottom - triggerRect.height / 2 + popupRect.height / 2 <= viewPortSize.height
      break
  }
  return top && right && bottom && left
}

export function setTooltipPosition (tooltip, trigger, placement, auto, appendToSelector) {
  let container
  let containerScrollTop
  let containerScrollLeft
  if (!isExist(appendToSelector) || appendToSelector === 'body') {
    container = document.body
    let doc = document.documentElement
    containerScrollLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0)
    containerScrollTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)
  } else {
    container = document.querySelector(appendToSelector)
    containerScrollLeft = container.scrollLeft
    containerScrollTop = container.scrollTop
  }
  // auto adjust placement
  if (auto) {
    // Try: right -> bottom -> left -> top
    // Cause the default placement is top
    let placements = [PLACEMENTS.RIGHT, PLACEMENTS.BOTTOM, PLACEMENTS.LEFT, PLACEMENTS.TOP]
    // The class switch helper function
    const changePlacementClass = (placement) => {
      // console.log(placement)
      placements.forEach(placement => {
        removeClass(tooltip, placement)
      })
      addClass(tooltip, placement)
    }
    // No need to adjust if the default placement fits
    if (!isAvailableAtPosition(trigger, tooltip, placement)) {
      for (let i = 0, l = placements.length; i < l; i++) {
        // Re-assign placement class
        changePlacementClass(placements[i])
        // Break if new placement fits
        if (isAvailableAtPosition(trigger, tooltip, placements[i])) {
          placement = placements[i]
          break
        }
      }
      changePlacementClass(placement)
    }
  }
  // fix left and top for tooltip
  let rect = trigger.getBoundingClientRect()
  let tooltipRect = tooltip.getBoundingClientRect()
  if (placement === PLACEMENTS.BOTTOM) {
    tooltip.style.top = containerScrollTop + rect.top + rect.height + 'px'
    tooltip.style.left = containerScrollLeft + rect.left + rect.width / 2 - tooltipRect.width / 2 + 'px'
  } else if (placement === PLACEMENTS.LEFT) {
    tooltip.style.top = containerScrollTop + rect.top + rect.height / 2 - tooltipRect.height / 2 + 'px'
    tooltip.style.left = containerScrollLeft + rect.left - tooltipRect.width + 'px'
  } else if (placement === PLACEMENTS.RIGHT) {
    tooltip.style.top = containerScrollTop + rect.top + rect.height / 2 - tooltipRect.height / 2 + 'px'
    tooltip.style.left = containerScrollLeft + rect.left + rect.width + 'px'
  } else {
    tooltip.style.top = containerScrollTop + rect.top - tooltipRect.height + 'px'
    tooltip.style.left = containerScrollLeft + rect.left + rect.width / 2 - tooltipRect.width / 2 + 'px'
  }
}

export function hasScrollbar (el) {
  const SCROLL = 'scroll'
  const hasVScroll = el.scrollHeight > el.clientHeight
  const style = getComputedStyle(el)
  return hasVScroll || style.overflow === SCROLL || style.overflowY === SCROLL
}

export function toggleBodyOverflow (enable) {
  const MODAL_OPEN = 'modal-open'
  const body = document.body
  if (enable) {
    removeClass(body, MODAL_OPEN)
    body.style.paddingRight = null
  } else {
    if (hasScrollbar(document.documentElement) || hasScrollbar(document.body)) {
      body.style.paddingRight = `${getScrollbarWidth()}px`
    }
    addClass(body, MODAL_OPEN)
  }
}

export function getClosest (el, selector) {
  ensureElementMatchesFunction()
  let parent
  let _el = el
  while (_el) {
    parent = _el.parentElement
    if (parent && parent.matches(selector)) {
      return parent
    }
    _el = parent
  }
  return null
}

export function getParents (el, selector, until = null) {
  ensureElementMatchesFunction()
  let parents = []
  let parent = el.parentElement
  while (parent) {
    if (parent.matches(selector)) {
      parents.push(parent)
    } else if (until && (until === parent || parent.matches(until))) {
      break
    }
    parent = parent.parentElement
  }
  return parents
}
<commit_msg>[Modal] fix body flashing on IE11 & IE10 (close #188)<commit_after>import {isExist} from './objectUtils'

export const EVENTS = {
  MOUSE_ENTER: 'mouseenter',
  MOUSE_LEAVE: 'mouseleave',
  FOCUS: 'focus',
  BLUR: 'blur',
  CLICK: 'click',
  INPUT: 'input',
  KEY_DOWN: 'keydown',
  KEY_UP: 'keyup',
  KEY_PRESS: 'keypress',
  RESIZE: 'resize',
  SCROLL: 'scroll'
}

export const TRIGGERS = {
  CLICK: 'click',
  HOVER: 'hover',
  FOCUS: 'focus',
  HOVER_FOCUS: 'hover-focus',
  OUTSIDE_CLICK: 'outside-click',
  MANUAL: 'manual'
}

export const PLACEMENTS = {
  TOP: 'top',
  RIGHT: 'right',
  BOTTOM: 'bottom',
  LEFT: 'left'
}

export function isIE11 () {
  return !!window.MSInputMethodContext && !!document.documentMode
}

export function isIE10 () {
  return window.navigator.appVersion.indexOf('MSIE 10') !== -1
}

export function getComputedStyle (el) {
  return window.getComputedStyle(el)
}

export function getViewportSize () {
  let width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
  let height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
  return {width, height}
}

let scrollbarWidth = null
let savedScreenSize = null

export function getScrollbarWidth (recalculate = false) {
  let screenSize = getViewportSize()
  // return directly when already calculated & not force recalculate & screen size not changed
  if (scrollbarWidth !== null && !recalculate &&
    screenSize.height === savedScreenSize.height && screenSize.width === savedScreenSize.width) {
    return scrollbarWidth
  }
  if (document.readyState === 'loading') {
    return null
  }
  const div1 = document.createElement('div')
  const div2 = document.createElement('div')
  div1.style.width = div2.style.width = div1.style.height = div2.style.height = '100px'
  div1.style.overflow = 'scroll'
  div2.style.overflow = 'hidden'
  document.body.appendChild(div1)
  document.body.appendChild(div2)
  scrollbarWidth = Math.abs(div1.scrollHeight - div2.scrollHeight)
  document.body.removeChild(div1)
  document.body.removeChild(div2)
  // save new screen size
  savedScreenSize = screenSize
  return scrollbarWidth
}

export function on (element, event, handler) {
  element.addEventListener(event, handler)
}

export function off (element, event, handler) {
  element.removeEventListener(event, handler)
}

export function isElement (el) {
  return el && el.nodeType === Node.ELEMENT_NODE
}

export function removeFromDom (el) {
  isElement(el) && isElement(el.parentNode) && el.parentNode.removeChild(el)
}

export function ensureElementMatchesFunction () {
  if (!Element.prototype.matches) {
    Element.prototype.matches =
      Element.prototype.matchesSelector ||
      Element.prototype.mozMatchesSelector ||
      Element.prototype.msMatchesSelector ||
      Element.prototype.oMatchesSelector ||
      Element.prototype.webkitMatchesSelector ||
      function (s) {
        let matches = (this.document || this.ownerDocument).querySelectorAll(s)
        let i = matches.length
        while (--i >= 0 && matches.item(i) !== this) {
        }
        return i > -1
      }
  }
}

export function addClass (el, className) {
  if (!isElement(el)) {
    return
  }
  if (el.className) {
    let classes = el.className.split(' ')
    if (classes.indexOf(className) < 0) {
      classes.push(className)
      el.className = classes.join(' ')
    }
  } else {
    el.className = className
  }
}

export function removeClass (el, className) {
  if (!isElement(el)) {
    return
  }
  if (el.className) {
    let classes = el.className.split(' ')
    let newClasses = []
    for (let i = 0, l = classes.length; i < l; i++) {
      if (classes[i] !== className) {
        newClasses.push(classes[i])
      }
    }
    el.className = newClasses.join(' ')
  }
}

export function hasClass (el, className) {
  if (!isElement(el)) {
    return false
  }
  let classes = el.className.split(' ')
  for (let i = 0, l = classes.length; i < l; i++) {
    if (classes[i] === className) {
      return true
    }
  }
  return false
}

export function setDropdownPosition (dropdown, trigger, options = {}) {
  let doc = document.documentElement
  let containerScrollLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0)
  let containerScrollTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)
  let rect = trigger.getBoundingClientRect()
  let dropdownRect = dropdown.getBoundingClientRect()
  dropdown.style.right = 'auto'
  dropdown.style.bottom = 'auto'
  if (options.menuRight) {
    dropdown.style.left = containerScrollLeft + rect.left + rect.width - dropdownRect.width + 'px'
  } else {
    dropdown.style.left = containerScrollLeft + rect.left + 'px'
  }
  if (options.dropup) {
    dropdown.style.top = containerScrollTop + rect.top - dropdownRect.height - 4 + 'px'
  } else {
    dropdown.style.top = containerScrollTop + rect.top + rect.height + 'px'
  }
}

export function isAvailableAtPosition (trigger, popup, placement) {
  let triggerRect = trigger.getBoundingClientRect()
  let popupRect = popup.getBoundingClientRect()
  let viewPortSize = getViewportSize()
  let top = true
  let right = true
  let bottom = true
  let left = true
  switch (placement) {
    case PLACEMENTS.TOP:
      top = triggerRect.top >= popupRect.height
      left = triggerRect.left + triggerRect.width / 2 >= popupRect.width / 2
      right = triggerRect.right - triggerRect.width / 2 + popupRect.width / 2 <= viewPortSize.width
      break
    case PLACEMENTS.BOTTOM:
      bottom = triggerRect.bottom + popupRect.height <= viewPortSize.height
      left = triggerRect.left + triggerRect.width / 2 >= popupRect.width / 2
      right = triggerRect.right - triggerRect.width / 2 + popupRect.width / 2 <= viewPortSize.width
      break
    case PLACEMENTS.RIGHT:
      right = triggerRect.right + popupRect.width <= viewPortSize.width
      top = triggerRect.top + triggerRect.height / 2 >= popupRect.height / 2
      bottom = triggerRect.bottom - triggerRect.height / 2 + popupRect.height / 2 <= viewPortSize.height
      break
    case PLACEMENTS.LEFT:
      left = triggerRect.left >= popupRect.width
      top = triggerRect.top + triggerRect.height / 2 >= popupRect.height / 2
      bottom = triggerRect.bottom - triggerRect.height / 2 + popupRect.height / 2 <= viewPortSize.height
      break
  }
  return top && right && bottom && left
}

export function setTooltipPosition (tooltip, trigger, placement, auto, appendToSelector) {
  let container
  let containerScrollTop
  let containerScrollLeft
  if (!isExist(appendToSelector) || appendToSelector === 'body') {
    container = document.body
    let doc = document.documentElement
    containerScrollLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0)
    containerScrollTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)
  } else {
    container = document.querySelector(appendToSelector)
    containerScrollLeft = container.scrollLeft
    containerScrollTop = container.scrollTop
  }
  // auto adjust placement
  if (auto) {
    // Try: right -> bottom -> left -> top
    // Cause the default placement is top
    let placements = [PLACEMENTS.RIGHT, PLACEMENTS.BOTTOM, PLACEMENTS.LEFT, PLACEMENTS.TOP]
    // The class switch helper function
    const changePlacementClass = (placement) => {
      // console.log(placement)
      placements.forEach(placement => {
        removeClass(tooltip, placement)
      })
      addClass(tooltip, placement)
    }
    // No need to adjust if the default placement fits
    if (!isAvailableAtPosition(trigger, tooltip, placement)) {
      for (let i = 0, l = placements.length; i < l; i++) {
        // Re-assign placement class
        changePlacementClass(placements[i])
        // Break if new placement fits
        if (isAvailableAtPosition(trigger, tooltip, placements[i])) {
          placement = placements[i]
          break
        }
      }
      changePlacementClass(placement)
    }
  }
  // fix left and top for tooltip
  let rect = trigger.getBoundingClientRect()
  let tooltipRect = tooltip.getBoundingClientRect()
  if (placement === PLACEMENTS.BOTTOM) {
    tooltip.style.top = containerScrollTop + rect.top + rect.height + 'px'
    tooltip.style.left = containerScrollLeft + rect.left + rect.width / 2 - tooltipRect.width / 2 + 'px'
  } else if (placement === PLACEMENTS.LEFT) {
    tooltip.style.top = containerScrollTop + rect.top + rect.height / 2 - tooltipRect.height / 2 + 'px'
    tooltip.style.left = containerScrollLeft + rect.left - tooltipRect.width + 'px'
  } else if (placement === PLACEMENTS.RIGHT) {
    tooltip.style.top = containerScrollTop + rect.top + rect.height / 2 - tooltipRect.height / 2 + 'px'
    tooltip.style.left = containerScrollLeft + rect.left + rect.width + 'px'
  } else {
    tooltip.style.top = containerScrollTop + rect.top - tooltipRect.height + 'px'
    tooltip.style.left = containerScrollLeft + rect.left + rect.width / 2 - tooltipRect.width / 2 + 'px'
  }
}

export function hasScrollbar (el) {
  const SCROLL = 'scroll'
  const hasVScroll = el.scrollHeight > el.clientHeight
  const style = getComputedStyle(el)
  return hasVScroll || style.overflow === SCROLL || style.overflowY === SCROLL
}

export function toggleBodyOverflow (enable) {
  const MODAL_OPEN = 'modal-open'
  const body = document.body
  if (enable) {
    removeClass(body, MODAL_OPEN)
    body.style.paddingRight = null
  } else {
    const browsersWithFloatingScrollbar = isIE10() || isIE11()
    const documentHasScrollbar = hasScrollbar(document.documentElement) || hasScrollbar(document.body)
    if (documentHasScrollbar && !browsersWithFloatingScrollbar) {
      body.style.paddingRight = `${getScrollbarWidth()}px`
    }
    addClass(body, MODAL_OPEN)
  }
}

export function getClosest (el, selector) {
  ensureElementMatchesFunction()
  let parent
  let _el = el
  while (_el) {
    parent = _el.parentElement
    if (parent && parent.matches(selector)) {
      return parent
    }
    _el = parent
  }
  return null
}

export function getParents (el, selector, until = null) {
  ensureElementMatchesFunction()
  let parents = []
  let parent = el.parentElement
  while (parent) {
    if (parent.matches(selector)) {
      parents.push(parent)
    } else if (until && (until === parent || parent.matches(until))) {
      break
    }
    parent = parent.parentElement
  }
  return parents
}
<|endoftext|>


<commit_before>/**
 * @file
 * Help container
 */

import React, {Component} from 'react';

export class HelpContainerComponent extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (

          DK5 - Decimalklassedeling

          DK5 er det fælles opstillings- og klassifikationssystem for de danske folke- og skolebiblioteker.

          DK betyder decimalklassedeling eller DecimalKlassifikation, og DK5 er inddelt i ti hovedgrupper med en talkode (0-9).
          Disse hovedgrupper er igen underdelt i op til ti grupper, som igen kan underinddeles i op til ti grupper og så videre.
          Hertil kommer særlige regler for underdeling, fx geografisk, geografisk-topografisk, sproglig, eller efter biograferede personers navne.
          I systemet oplyses specifikt, hvilke grupper der kan underdeles.

          De 10 hovedgrupper grupperer sig på følgende måde:

00-07
Værker af almindeligt og blandet indhold

10-19
Filosofi. Psykologi. Videnskab og forskning

20-29
Religion

30-39
Samfundsvidenskab. Pædagogik. Folkeliv

40-49
Geografi og rejser

50-59
Naturvidenskab og matematik

60-69
Praktiske fag

70-79
Kunst. Teater. Film. Musik. Spil. Idræt

80-89
Litteratur. Sprog

90-99
Historie

          DK5 er et enumerativt klassifikationssystem dvs. et hierarkisk opbygget system, hvor klasserne / grupperne og mulighed for underdeling på forhånd er opregnet.

    );
  }
}

HelpContainerComponent.displayName = 'Help';
<commit_msg>#33: Minor text change<commit_after>/**
 * @file
 * Help container
 */

import React, {Component} from 'react';

export class HelpContainerComponent extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (

          DK5 - Decimalklassedeling

          DK5 er det fælles opstillings- og klassifikationssystem for de danske folke- og skolebiblioteker.

          DK betyder decimalklassedeling eller DecimalKlassifikation, og DK5 er inddelt i ti hovedgrupper.
          Hovedgrupperne er underdelt i op til ti grupper, som igen kan underinddeles i op til ti grupper og så videre.
          Hertil kommer særlige regler for underdeling, fx geografisk, geografisk-topografisk, sproglig, eller efter biograferede personers navne.

          De 10 hovedgrupper grupperer sig på følgende måde:

00-07
Værker af almindeligt og blandet indhold

10-19
Filosofi. Psykologi. Videnskab og forskning

20-29
Religion

30-39
Samfundsvidenskab. Pædagogik. Folkeliv

40-49
Geografi og rejser

50-59
Naturvidenskab og matematik

60-69
Praktiske fag

70-79
Kunst. Teater. Film. Musik. Spil. Idræt

80-89
Litteratur. Sprog

90-99
Historie

          DK5 er et hierarkisk opbygget system (et enumerativt klassifikationssystem), som vedligeholdes af Dansk Biblioteks Center as

    );
  }
}

HelpContainerComponent.displayName = 'Help';
<|endoftext|>


<commit_before>module.exports = function trelloLogin(userID) {

var Trello = require('node-trello');
var encryption = require('./encryption.js');
var db = require('./mlab-login.js').db();
var Promise = require("bluebird");

var key = process.env.HUBOT_TRELLO_KEY;
var trello = {};

// db.bind('trelloTokens');
// db.trelloTokens.find().toArrayAsync()
//     .then(function (records) {
//         let length = Object.keys(records).length;
//         let i = 0;
//         console.log(`lenght = ${length}`);
//         for (i = 0; i < length; i++) {
//             let token = encryption.decrypt(records[i].token);
//             let userId = records[i].id;
//             let username = records[i].username;
//             let t = new Trello(key, token);
//             trello[userId] = Promise.promisifyAll(t);
//         }

//     })
//     .catch(error => {
//         console.log(error)
//     })

    var trello = {};

    db.bind('trelloTokens');
    db.trelloTokens.find({ id: userID }).toArrayAsync()
        .then(function (data) {
            let token = encryption.decrypt(data.token);
            let userId = data.id;
            let username = data.username;
            let t = new Trello(key, token);
            trello = Promise.promisifyAll(t);
        })
        .catch(error => {
    console.log(error)
})
return trello;
}
<commit_msg>trello login<commit_after>module.exports = function trelloLogin(userID) {

    var Trello = require('node-trello');
    var encryption = require('./encryption.js');
    var db = require('./mlab-login.js').db();
    var Promise = require("bluebird");

    var key = process.env.HUBOT_TRELLO_KEY;
    var trello = {};

    // db.bind('trelloTokens');
    // db.trelloTokens.find().toArrayAsync()
    //     .then(function (records) {
    //         let length = Object.keys(records).length;
    //         let i = 0;
    //         console.log(`lenght = ${length}`);
    //         for (i = 0; i < length; i++) {
    //             let token = encryption.decrypt(records[i].token);
    //             let userId = records[i].id;
    //             let username = records[i].username;
    //             let t = new Trello(key, token);
    //             trello[userId] = Promise.promisifyAll(t);
    //         }

    //     })
    //     .catch(error => {
    //         console.log(error)
    //     })

    var trello = {};

    db.bind('trelloTokens');
    db.trelloTokens.findOne({ id: userID }).toArray(function (err, data) {
        if (err) throw err;
        let token = encryption.decrypt(data.token);
        let userId = data.id;
        let username = data.username;
        let t = new Trello(key, token);
        trello = Promise.promisifyAll(t);
    })

    // db.bind('trelloTokens');
    // db.trelloTokens.find({ id: userID }).toArrayAsync()
    //     .then(function (data) {
    //         let token = encryption.decrypt(data.token);
    //         let userId = data.id;
    //         let username = data.username;
    //         let t = new Trello(key, token);
    //         trello = Promise.promisifyAll(t);
    //     })
    //     .catch(error => {
    //         console.log(error)
    //     })
    return trello;
}
<|endoftext|>


<commit_before>var slackMsgs = require('./slackMsgs.js');
var url = require('url');
var Trello = require('node-trello');
var rp = require('request-promise');
var app_key = process.env.HUBOT_TRELLO_KEY;
var oauth_secret = process.env.HUBOT_TRELLO_OAUTH;
var db = require("./mlab-login").db();
var bcrypt = require('bcryptjs');

module.exports = function(robot) {

    robot.respond(/bcrypt test/, function(res) {
        var t = 'testtoken';
        var k = getHash(t);
        res.send(k);
    })

    var oauth_secrets = {};
    var loginCallback = `https://andreasbot.herokuapp.com/hubot/trello-token`;
    var tOAuth = new Trello.OAuth(app_key, oauth_secret, loginCallback, 'Hubot');

    robot.respond(/trello auth/, function(res) {
        let userId = res.message.user.id;
        db.bind('trelloToken');
        db.trelloTokens.findOne({ id: userId }).then(function(result) {
            robot.logger.info(result);
        }).catch(function(err) {

        })
        tOAuth.getRequestToken(function(err, data) {
            robot.logger.warning(data)
            oauth_secrets['username'] = res.message.user.name;
            oauth_secrets['id'] = res.message.user.id;
            oauth_secrets[data.oauth_token] = data.oauth_token_secret;
            res.send(data.redirect);
        })
    })

    robot.router.get('/hubot/trello-token', function(req, res_r) {
        let args = req.query;
        let query = url.parse(req.url, true).query;
        let token = query.oauth_token;
        args['oauth_token_secret'] = oauth_secrets[token];
        robot.logger.info(args);
        tOAuth.getAccessToken(args, function(err, data) {
            if (err) throw err;
            let token = data['oauth_access_token'];
            let userName = oauth_secrets['username'];
            let userId = oauth_secrets['id'];
            // BCRYPT!!!!!!!!!!
            bcrypt.genSalt(10, function(err, salt) {
                bcrypt.hash(token, salt).then(function(hash) {
                    db.bind('trelloTokens');
                    db.trelloTokens.insert({ username: userName, id: userId, token: hash }, function(err, result) {
                        if (err) throw err;
                        if (result) robot.logger.info(`User's Token Added to DB!`);
                    })
                }).catch(error => robot.logger.error(error));
            });

        })
        res_r.redirect('/a');
    });

    robot.respond(/trello get token/i, function(res_r) {

        let scope = 'read,write,account';
        let name = 'Hubot';
        let expr = '30days';
        let cb_method = 'fragment';
        let return_url = 'https://andreasbot.herokuapp.com/hubot/trello-token';
        let url = `https://trello.com/1/authorize?expiration=${expr}&name=${name}&scope=${scope}&key=${key}&response_type=token&callback_method=${cb_method}&return_url=${return_url}`;
        var msg = slackMsgs.basicMessage();

        msg.attachments[0].pretext = "Please get a token to authorize your Trello account";
        msg.attachments[0].title = "Trello Token";
        msg.attachments[0].title_link = url;
        msg.attachments[0].text = "Copy the token from the link above and run\n *trello add token <YOUR TOKEN>*";
        msg.attachments[0].footer = "Trello";
        msg.attachments[0].footer_icon = "https://d2k1ftgv7pobq7.cloudfront.net/meta/u/res/images/b428584f224c42e98d158dad366351b0/trello-mark-blue.png";
        res_r.send(msg);
    })

    robot.respond(/trello add token (.*)/i, function(res_r) {
        var token = res_r.match[1];
        //***IMPORTANT***
        // the .env assignment doesnt work with HEROKU!
        // must set up a heroku client and communicate through their api
        process.env['HUBOT_TRELLO_TOKEN'] = token;
    })
}<commit_msg>trello token<commit_after>var slackMsgs = require('./slackMsgs.js');
var url = require('url');
var Trello = require('node-trello');
var rp = require('request-promise');
var app_key = process.env.HUBOT_TRELLO_KEY;
var oauth_secret = process.env.HUBOT_TRELLO_OAUTH;
var db = require("./mlab-login").db();
var bcrypt = require('bcryptjs');

module.exports = function(robot) {

    robot.respond(/bcrypt test/, function(res) {
        var t = 'testtoken';
        var k = getHash(t);
        res.send(k);
    })

    var oauth_secrets = {};
    var loginCallback = `https://andreasbot.herokuapp.com/hubot/trello-token`;
    var tOAuth = new Trello.OAuth(app_key, oauth_secret, loginCallback, 'Hubot');

    robot.respond(/trello auth/, function(res) {
        let userId = res.message.user.id;
        db.bind('trelloToken');
        db.trelloTokens.findOneAsync({id: userId}).then(function(result) {
            robot.logger.info(result);
        }).catch(function(err) {

        })
        tOAuth.getRequestToken(function(err, data) {
            robot.logger.warning(data)
            oauth_secrets['username'] = res.message.user.name;
            oauth_secrets['id'] = res.message.user.id;
            oauth_secrets[data.oauth_token] = data.oauth_token_secret;
            res.send(data.redirect);
        })
    })

    robot.router.get('/hubot/trello-token', function(req, res_r) {
        let args = req.query;
        let query = url.parse(req.url, true).query;
        let token = query.oauth_token;
        args['oauth_token_secret'] = oauth_secrets[token];
        robot.logger.info(args);
        tOAuth.getAccessToken(args, function(err, data) {
            if (err) throw err;
            let token = data['oauth_access_token'];
            let userName = oauth_secrets['username'];
            let userId = oauth_secrets['id'];
            // BCRYPT!!!!!!!!!!
            bcrypt.genSalt(10, function(err, salt) {
                bcrypt.hash(token, salt).then(function(hash) {
                    db.bind('trelloTokens');
                    db.trelloTokens.insert({ username: userName, id: userId, token: hash }, function(err, result) {
                        if (err) throw err;
                        if (result) robot.logger.info(`User's Token Added to DB!`);
                    })
                }).catch(error => robot.logger.error(error));
            });

        })
        res_r.redirect('/a');
    });

    robot.respond(/trello get token/i, function(res_r) {

        let scope = 'read,write,account';
        let name = 'Hubot';
        let expr = '30days';
        let cb_method = 'fragment';
        let return_url = 'https://andreasbot.herokuapp.com/hubot/trello-token';
        let url = `https://trello.com/1/authorize?expiration=${expr}&name=${name}&scope=${scope}&key=${key}&response_type=token&callback_method=${cb_method}&return_url=${return_url}`;
        var msg = slackMsgs.basicMessage();

        msg.attachments[0].pretext = "Please get a token to authorize your Trello account";
        msg.attachments[0].title = "Trello Token";
        msg.attachments[0].title_link = url;
        msg.attachments[0].text = "Copy the token from the link above and run\n *trello add token <YOUR TOKEN>*";
        msg.attachments[0].footer = "Trello";
        msg.attachments[0].footer_icon = "https://d2k1ftgv7pobq7.cloudfront.net/meta/u/res/images/b428584f224c42e98d158dad366351b0/trello-mark-blue.png";
        res_r.send(msg);
    })

    robot.respond(/trello add token (.*)/i, function(res_r) {
        var token = res_r.match[1];
        //***IMPORTANT***
        // the .env assignment doesnt work with HEROKU!
        // must set up a heroku client and communicate through their api
        process.env['HUBOT_TRELLO_TOKEN'] = token;
    })
}<|endoftext|>