<commit_before>/*
 angular-diff-match-patch
 http://amweiss.github.io/angular-diff-match-patch/
 @license: MIT
*/
angular.module('diff-match-patch', [])
	.constant('DiffMatchPatch', diff_match_patch)
	.factory('DIFF_INSERT', ['DiffMatchPatch', function (DiffMatchPatch) {
		return DiffMatchPatch.DIFF_INSERT === undefined ? DIFF_INSERT : DiffMatchPatch.DIFF_INSERT;
	}])
	.factory('DIFF_DELETE', ['DiffMatchPatch', function (DiffMatchPatch) {
		return DiffMatchPatch.DIFF_DELETE === undefined ? DIFF_DELETE : DiffMatchPatch.DIFF_DELETE;
	}])
	.factory('dmp', ['DiffMatchPatch', 'DIFF_INSERT', 'DIFF_DELETE', function (DiffMatchPatch, DIFF_INSERT, DIFF_DELETE) {
		const displayType = {
			INSDEL: 0,
			LINEDIFF: 1,
		};

		function diffClass(op) {
			switch (op) {
				case DIFF_INSERT:
					return 'ins';
				case DIFF_DELETE:
					return 'del';
				default: // case DIFF_EQUAL:
					return 'match';
			}
		}

		function diffSymbol(op) {
			switch (op) {
				case DIFF_INSERT:
					return '+';
				case DIFF_DELETE:
					return '-';
				default: // case DIFF_EQUAL:
					return ' ';
			}
		}

		function diffTag(op) {
			switch (op) {
				case DIFF_INSERT:
					return 'ins';
				case DIFF_DELETE:
					return 'del';
				default: // case DIFF_EQUAL:
					return 'span';
			}
		}

		function diffAttrName(op) {
			switch (op) {
				case DIFF_INSERT:
					return 'insert';
				case DIFF_DELETE:
					return 'delete';
				default: // case DIFF_EQUAL:
					return 'equal';
			}
		}

		function getTagAttrs(options, op, attrs) {
			const tagOptions = {};
			const returnValue = [];
			const opName = diffAttrName(op);

			if (angular.isDefined(options) && angular.isDefined(options.attrs)) {
				const attributesFromOptions = options.attrs[opName];
				if (angular.isDefined(attributesFromOptions)) {
					angular.merge(tagOptions, attributesFromOptions);
				}
			}

			if (angular.isDefined(attrs)) {
				angular.merge(tagOptions, attrs);
			}

			if (Object.keys(tagOptions).length === 0) {
				return '';
			}

			for (const [key, value] of Object.entries(tagOptions)) {
				returnValue.push(key + '="' + value + '"');
			}

			return ' ' + returnValue.join(' ');
		}

		function getHtmlPrefix(op, display, options) {
			switch (display) {
				case displayType.LINEDIFF:
					return '
' + diffSymbol(op) + '';
				default: // case displayType.INSDEL:
					return '<' + diffTag(op) + getTagAttrs(options, op) + '>';
			}
		}

		function getHtmlSuffix(op, display) {
			switch (display) {
				case displayType.LINEDIFF:
					return '
';
				default: // case displayType.INSDEL:
					return '</' + diffTag(op) + '>';
			}
		}

		function createHtmlLines(text, op, options) {
			const lines = text.split('\n');
			let y;
			for (y = 0; y < lines.length; y++) {
				if (lines[y].length === 0) {
					continue;
				}

				lines[y] = getHtmlPrefix(op, displayType.LINEDIFF, options) + lines[y] + getHtmlSuffix(op, displayType.LINEDIFF);
			}

			return lines.join('');
		}

		function createHtmlFromDiffs(diffs, display, options, excludeOp) {
			let x;
			const html = [];
			let y;
			let op;
			let text;
			const diffData = diffs;
			const dmp = (display === displayType.LINEDIFF) ? new DiffMatchPatch() : null;
			let intraDiffs;
			let intraHtml1;
			let intraHtml2;

			for (x = 0; x < diffData.length; x++) {
				diffData[x][1] = diffData[x][1].replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
			}

			for (y = 0; y < diffData.length; y++) {
				op = diffData[y][0];
				text = diffData[y][1];
				if (display === displayType.LINEDIFF) {
					if (angular.isDefined(options) && angular.isDefined(options.interLineDiff) && options.interLineDiff && diffs[y][0] === DIFF_DELETE && angular.isDefined(diffs[y + 1]) && diffs[y + 1][0] === DIFF_INSERT && !diffs[y][1].includes('\n')) {
						intraDiffs = dmp.diff_main(diffs[y][1], diffs[y + 1][1]);
						dmp.diff_cleanupSemantic(intraDiffs);
						intraHtml1 = createHtmlFromDiffs(intraDiffs, displayType.INSDEL, options, DIFF_INSERT);
						intraHtml2 = createHtmlFromDiffs(intraDiffs, displayType.INSDEL, options, DIFF_DELETE);
						html[y] = createHtmlLines(intraHtml1, DIFF_DELETE, options);
						html[y + 1] = createHtmlLines(intraHtml2, DIFF_INSERT, options);
						y++;
					} else {
						html[y] = createHtmlLines(text, op, options);
					}
				} else if (typeof excludeOp === 'undefined' || op !== excludeOp) {
					html[y] = getHtmlPrefix(op, display, options) + text + getHtmlSuffix(op, display);
				}
			}

			return html.join('');
		}

		function assertArgumentsIsStrings(left, right) {
			return angular.isString(left) && angular.isString(right);
		}

		// Taken from source https://code.google.com/p/google-diff-match-patch/
		// and then modified for style and to strip newline
		function linesToChars(text1, text2, ignoreTrailingNewLines) {
			const lineArray = [];
			const lineHash = {};
			lineArray[0] = '';

			function linesToCharsMunge(text) {
				let chars = '';
				let lineStart = 0;
				let lineEnd = -1;
				let lineArrayLength = lineArray.length;
				let hasNewLine = false;
				while (lineEnd < text.length - 1) {
					lineEnd = text.indexOf('\n', lineStart);
					hasNewLine = (lineEnd !== -1);
					if (!hasNewLine) {
						lineEnd = text.length - 1;
					}

					const line = text.slice(lineStart, lineEnd + ((ignoreTrailingNewLines && hasNewLine) ? 0 : 1));
					lineStart = lineEnd + 1;

					if (Object.prototype.hasOwnProperty.call(lineHash, line)) {
						chars += String.fromCharCode(lineHash[line]);
					} else {
						chars += String.fromCharCode(lineArrayLength);
						lineHash[line] = lineArrayLength;
						lineArray[lineArrayLength++] = line;
					}
				}

				return chars;
			}

			const chars1 = linesToCharsMunge(text1);
			const chars2 = linesToCharsMunge(text2);
			return {chars1, chars2, lineArray};
		}

		// Taken from source https://code.google.com/p/google-diff-match-patch/
		// and then modified for style and to strip newline
		function charsToLines(diffs, lineArray, ignoreTrailingNewLines) {
			for (let i = 0; i < diffs.length; i++) { // eslint-disable-line unicorn/no-for-loop
				const chars = diffs[i][1];
				const text = [];
				for (let y = 0; y < chars.length; y++) {
					text[y] = lineArray[chars.charCodeAt(y)];
				}

				diffs[i][1] = text.join((ignoreTrailingNewLines) ? '\n' : '');
			}
		}

		return {
			createDiffHtml(left, right, options) {
				let diffs;
				if (assertArgumentsIsStrings(left, right)) {
					diffs = new DiffMatchPatch().diff_main(left, right);
					return createHtmlFromDiffs(diffs, displayType.INSDEL, options);
				}

				return '';
			},

			createProcessingDiffHtml(left, right, options) {
				let dmp;
				let diffs;
				if (assertArgumentsIsStrings(left, right)) {
					dmp = new DiffMatchPatch();
					diffs = dmp.diff_main(left, right);

					if (angular.isDefined(options) && angular.isDefined(options.editCost) && Number.isFinite(options.editCost)) {
						dmp.Diff_EditCost = options.editCost; // eslint-disable-line camelcase
					}

					dmp.diff_cleanupEfficiency(diffs);
					return createHtmlFromDiffs(diffs, displayType.INSDEL, options);
				}

				return '';
			},

			createSemanticDiffHtml(left, right, options) {
				let dmp;
				let diffs;
				if (assertArgumentsIsStrings(left, right)) {
					dmp = new DiffMatchPatch();
					diffs = dmp.diff_main(left, right);
					dmp.diff_cleanupSemantic(diffs);
					return createHtmlFromDiffs(diffs, displayType.INSDEL, options);
				}

				return '';
			},

			createLineDiffHtml(left, right, options) {
				let dmp;
				let chars;
				let diffs;
				if (assertArgumentsIsStrings(left, right)) {
					dmp = new DiffMatchPatch();
					const ignoreTrailingNewLines = angular.isDefined(options) && angular.isDefined(options.ignoreTrailingNewLines) && options.ignoreTrailingNewLines;
					chars = linesToChars(left, right, ignoreTrailingNewLines);
					diffs = dmp.diff_main(chars.chars1, chars.chars2, false);
					charsToLines(diffs, chars.lineArray, ignoreTrailingNewLines);
					return createHtmlFromDiffs(diffs, displayType.LINEDIFF, options);
				}

				return '';
			},
		};
	}])
	.directive('diff', ['$compile', 'dmp', function ($compile, dmp) {
		const ddo = {
			scope: {
				left: '=leftObj',
				right: '=rightObj',
				options: '=options',
			},
			link(scope, iElement) {
				const listener = function () {
					iElement.html(dmp.createDiffHtml(scope.left, scope.right, scope.options));
					// If no options given, or, we have been given options and don't want to skip angular compiling
					// Then compile angular in the diff.
					if (!scope.options || (scope.options && !scope.options.skipAngularCompilingOnDiff)) {
						$compile(iElement.contents())(scope);
					}
				};

				scope.$watch('left', listener);
				scope.$watch('right', listener);
			},
		};
		return ddo;
	}])
	.directive('processingDiff', ['$compile', 'dmp', function ($compile, dmp) {
		const ddo = {
			scope: {
				left: '=leftObj',
				right: '=rightObj',
				options: '=options',
			},
			link(scope, iElement) {
				const listener = function () {
					iElement.html(dmp.createProcessingDiffHtml(scope.left, scope.right, scope.options));
					// If no options given, or, we have been given options and don't want to skip angular compiling
					// Then compile angular in the diff.
					if (!scope.options || (scope.options && !scope.options.skipAngularCompilingOnDiff)) {
						$compile(iElement.contents())(scope);
					}
				};

				scope.$watch('left', listener);
				scope.$watch('right', listener);
				scope.$watch('options.editCost', listener, true);
			},
		};
		return ddo;
	}])
	.directive('semanticDiff', ['$compile', 'dmp', function ($compile, dmp) {
		const ddo = {
			scope: {
				left: '=leftObj',
				right: '=rightObj',
				options: '=options',
			},
			link(scope, iElement) {
				const listener = function () {
					iElement.html(dmp.createSemanticDiffHtml(scope.left, scope.right, scope.options));
					// If no options given, or, we have been given options and don't want to skip angular compiling
					// Then compile angular in the diff.
					if (!scope.options || (scope.options && !scope.options.skipAngularCompilingOnDiff)) {
						$compile(iElement.contents())(scope);
					}
				};

				scope.$watch('left', listener);
				scope.$watch('right', listener);
			},
		};
		return ddo;
	}])
	.directive('lineDiff', ['$compile', 'dmp', function ($compile, dmp) {
		const ddo = {
			scope: {
				left: '=leftObj',
				right: '=rightObj',
				options: '=options',
			},
			link(scope, iElement) {
				const listener = function () {
					iElement.html(dmp.createLineDiffHtml(scope.left, scope.right, scope.options));
					// If no options given, or, we have been given options and don't want to skip angular compiling
					// Then compile angular in the diff.
					if (!scope.options || (scope.options && !scope.options.skipAngularCompilingOnDiff)) {
						$compile(iElement.contents())(scope);
					}
				};

				scope.$watch('left', listener);
				scope.$watch('right', listener);
				scope.$watch('options.interLineDiff', listener, true);
				scope.$watch('options.ignoreTrailingNewLines', listener, true);
			},
		};
		return ddo;
	}]);
<commit_msg>Ignore unicorn/prefer-code-point<commit_after>/*
 angular-diff-match-patch
 http://amweiss.github.io/angular-diff-match-patch/
 @license: MIT
*/
angular.module('diff-match-patch', [])
	.constant('DiffMatchPatch', diff_match_patch)
	.factory('DIFF_INSERT', ['DiffMatchPatch', function (DiffMatchPatch) {
		return DiffMatchPatch.DIFF_INSERT === undefined ? DIFF_INSERT : DiffMatchPatch.DIFF_INSERT;
	}])
	.factory('DIFF_DELETE', ['DiffMatchPatch', function (DiffMatchPatch) {
		return DiffMatchPatch.DIFF_DELETE === undefined ? DIFF_DELETE : DiffMatchPatch.DIFF_DELETE;
	}])
	.factory('dmp', ['DiffMatchPatch', 'DIFF_INSERT', 'DIFF_DELETE', function (DiffMatchPatch, DIFF_INSERT, DIFF_DELETE) {
		const displayType = {
			INSDEL: 0,
			LINEDIFF: 1,
		};

		function diffClass(op) {
			switch (op) {
				case DIFF_INSERT:
					return 'ins';
				case DIFF_DELETE:
					return 'del';
				default: // case DIFF_EQUAL:
					return 'match';
			}
		}

		function diffSymbol(op) {
			switch (op) {
				case DIFF_INSERT:
					return '+';
				case DIFF_DELETE:
					return '-';
				default: // case DIFF_EQUAL:
					return ' ';
			}
		}

		function diffTag(op) {
			switch (op) {
				case DIFF_INSERT:
					return 'ins';
				case DIFF_DELETE:
					return 'del';
				default: // case DIFF_EQUAL:
					return 'span';
			}
		}

		function diffAttrName(op) {
			switch (op) {
				case DIFF_INSERT:
					return 'insert';
				case DIFF_DELETE:
					return 'delete';
				default: // case DIFF_EQUAL:
					return 'equal';
			}
		}

		function getTagAttrs(options, op, attrs) {
			const tagOptions = {};
			const returnValue = [];
			const opName = diffAttrName(op);

			if (angular.isDefined(options) && angular.isDefined(options.attrs)) {
				const attributesFromOptions = options.attrs[opName];
				if (angular.isDefined(attributesFromOptions)) {
					angular.merge(tagOptions, attributesFromOptions);
				}
			}

			if (angular.isDefined(attrs)) {
				angular.merge(tagOptions, attrs);
			}

			if (Object.keys(tagOptions).length === 0) {
				return '';
			}

			for (const [key, value] of Object.entries(tagOptions)) {
				returnValue.push(key + '="' + value + '"');
			}

			return ' ' + returnValue.join(' ');
		}

		function getHtmlPrefix(op, display, options) {
			switch (display) {
				case displayType.LINEDIFF:
					return '
' + diffSymbol(op) + '';
				default: // case displayType.INSDEL:
					return '<' + diffTag(op) + getTagAttrs(options, op) + '>';
			}
		}

		function getHtmlSuffix(op, display) {
			switch (display) {
				case displayType.LINEDIFF:
					return '
';
				default: // case displayType.INSDEL:
					return '</' + diffTag(op) + '>';
			}
		}

		function createHtmlLines(text, op, options) {
			const lines = text.split('\n');
			let y;
			for (y = 0; y < lines.length; y++) {
				if (lines[y].length === 0) {
					continue;
				}

				lines[y] = getHtmlPrefix(op, displayType.LINEDIFF, options) + lines[y] + getHtmlSuffix(op, displayType.LINEDIFF);
			}

			return lines.join('');
		}

		function createHtmlFromDiffs(diffs, display, options, excludeOp) {
			let x;
			const html = [];
			let y;
			let op;
			let text;
			const diffData = diffs;
			const dmp = (display === displayType.LINEDIFF) ? new DiffMatchPatch() : null;
			let intraDiffs;
			let intraHtml1;
			let intraHtml2;

			for (x = 0; x < diffData.length; x++) {
				diffData[x][1] = diffData[x][1].replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
			}

			for (y = 0; y < diffData.length; y++) {
				op = diffData[y][0];
				text = diffData[y][1];
				if (display === displayType.LINEDIFF) {
					if (angular.isDefined(options) && angular.isDefined(options.interLineDiff) && options.interLineDiff && diffs[y][0] === DIFF_DELETE && angular.isDefined(diffs[y + 1]) && diffs[y + 1][0] === DIFF_INSERT && !diffs[y][1].includes('\n')) {
						intraDiffs = dmp.diff_main(diffs[y][1], diffs[y + 1][1]);
						dmp.diff_cleanupSemantic(intraDiffs);
						intraHtml1 = createHtmlFromDiffs(intraDiffs, displayType.INSDEL, options, DIFF_INSERT);
						intraHtml2 = createHtmlFromDiffs(intraDiffs, displayType.INSDEL, options, DIFF_DELETE);
						html[y] = createHtmlLines(intraHtml1, DIFF_DELETE, options);
						html[y + 1] = createHtmlLines(intraHtml2, DIFF_INSERT, options);
						y++;
					} else {
						html[y] = createHtmlLines(text, op, options);
					}
				} else if (typeof excludeOp === 'undefined' || op !== excludeOp) {
					html[y] = getHtmlPrefix(op, display, options) + text + getHtmlSuffix(op, display);
				}
			}

			return html.join('');
		}

		function assertArgumentsIsStrings(left, right) {
			return angular.isString(left) && angular.isString(right);
		}

		// Taken from source https://code.google.com/p/google-diff-match-patch/
		// and then modified for style and to strip newline
		function linesToChars(text1, text2, ignoreTrailingNewLines) {
			const lineArray = [];
			const lineHash = {};
			lineArray[0] = '';

			function linesToCharsMunge(text) {
				let chars = '';
				let lineStart = 0;
				let lineEnd = -1;
				let lineArrayLength = lineArray.length;
				let hasNewLine = false;
				while (lineEnd < text.length - 1) {
					lineEnd = text.indexOf('\n', lineStart);
					hasNewLine = (lineEnd !== -1);
					if (!hasNewLine) {
						lineEnd = text.length - 1;
					}

					const line = text.slice(lineStart, lineEnd + ((ignoreTrailingNewLines && hasNewLine) ? 0 : 1));
					lineStart = lineEnd + 1;

					if (Object.prototype.hasOwnProperty.call(lineHash, line)) {
						chars += String.fromCharCode(lineHash[line]); // eslint-disable-line unicorn/prefer-code-point
					} else {
						chars += String.fromCharCode(lineArrayLength); // eslint-disable-line unicorn/prefer-code-point
						lineHash[line] = lineArrayLength;
						lineArray[lineArrayLength++] = line;
					}
				}

				return chars;
			}

			const chars1 = linesToCharsMunge(text1);
			const chars2 = linesToCharsMunge(text2);
			return {chars1, chars2, lineArray};
		}

		// Taken from source https://code.google.com/p/google-diff-match-patch/
		// and then modified for style and to strip newline
		function charsToLines(diffs, lineArray, ignoreTrailingNewLines) {
			for (let i = 0; i < diffs.length; i++) { // eslint-disable-line unicorn/no-for-loop
				const chars = diffs[i][1];
				const text = [];
				for (let y = 0; y < chars.length; y++) {
					text[y] = lineArray[chars.charCodeAt(y)]; // eslint-disable-line unicorn/prefer-code-point
				}

				diffs[i][1] = text.join((ignoreTrailingNewLines) ? '\n' : '');
			}
		}

		return {
			createDiffHtml(left, right, options) {
				let diffs;
				if (assertArgumentsIsStrings(left, right)) {
					diffs = new DiffMatchPatch().diff_main(left, right);
					return createHtmlFromDiffs(diffs, displayType.INSDEL, options);
				}

				return '';
			},

			createProcessingDiffHtml(left, right, options) {
				let dmp;
				let diffs;
				if (assertArgumentsIsStrings(left, right)) {
					dmp = new DiffMatchPatch();
					diffs = dmp.diff_main(left, right);

					if (angular.isDefined(options) && angular.isDefined(options.editCost) && Number.isFinite(options.editCost)) {
						dmp.Diff_EditCost = options.editCost; // eslint-disable-line camelcase
					}

					dmp.diff_cleanupEfficiency(diffs);
					return createHtmlFromDiffs(diffs, displayType.INSDEL, options);
				}

				return '';
			},

			createSemanticDiffHtml(left, right, options) {
				let dmp;
				let diffs;
				if (assertArgumentsIsStrings(left, right)) {
					dmp = new DiffMatchPatch();
					diffs = dmp.diff_main(left, right);
					dmp.diff_cleanupSemantic(diffs);
					return createHtmlFromDiffs(diffs, displayType.INSDEL, options);
				}

				return '';
			},

			createLineDiffHtml(left, right, options) {
				let dmp;
				let chars;
				let diffs;
				if (assertArgumentsIsStrings(left, right)) {
					dmp = new DiffMatchPatch();
					const ignoreTrailingNewLines = angular.isDefined(options) && angular.isDefined(options.ignoreTrailingNewLines) && options.ignoreTrailingNewLines;
					chars = linesToChars(left, right, ignoreTrailingNewLines);
					diffs = dmp.diff_main(chars.chars1, chars.chars2, false);
					charsToLines(diffs, chars.lineArray, ignoreTrailingNewLines);
					return createHtmlFromDiffs(diffs, displayType.LINEDIFF, options);
				}

				return '';
			},
		};
	}])
	.directive('diff', ['$compile', 'dmp', function ($compile, dmp) {
		const ddo = {
			scope: {
				left: '=leftObj',
				right: '=rightObj',
				options: '=options',
			},
			link(scope, iElement) {
				const listener = function () {
					iElement.html(dmp.createDiffHtml(scope.left, scope.right, scope.options));
					// If no options given, or, we have been given options and don't want to skip angular compiling
					// Then compile angular in the diff.
					if (!scope.options || (scope.options && !scope.options.skipAngularCompilingOnDiff)) {
						$compile(iElement.contents())(scope);
					}
				};

				scope.$watch('left', listener);
				scope.$watch('right', listener);
			},
		};
		return ddo;
	}])
	.directive('processingDiff', ['$compile', 'dmp', function ($compile, dmp) {
		const ddo = {
			scope: {
				left: '=leftObj',
				right: '=rightObj',
				options: '=options',
			},
			link(scope, iElement) {
				const listener = function () {
					iElement.html(dmp.createProcessingDiffHtml(scope.left, scope.right, scope.options));
					// If no options given, or, we have been given options and don't want to skip angular compiling
					// Then compile angular in the diff.
					if (!scope.options || (scope.options && !scope.options.skipAngularCompilingOnDiff)) {
						$compile(iElement.contents())(scope);
					}
				};

				scope.$watch('left', listener);
				scope.$watch('right', listener);
				scope.$watch('options.editCost', listener, true);
			},
		};
		return ddo;
	}])
	.directive('semanticDiff', ['$compile', 'dmp', function ($compile, dmp) {
		const ddo = {
			scope: {
				left: '=leftObj',
				right: '=rightObj',
				options: '=options',
			},
			link(scope, iElement) {
				const listener = function () {
					iElement.html(dmp.createSemanticDiffHtml(scope.left, scope.right, scope.options));
					// If no options given, or, we have been given options and don't want to skip angular compiling
					// Then compile angular in the diff.
					if (!scope.options || (scope.options && !scope.options.skipAngularCompilingOnDiff)) {
						$compile(iElement.contents())(scope);
					}
				};

				scope.$watch('left', listener);
				scope.$watch('right', listener);
			},
		};
		return ddo;
	}])
	.directive('lineDiff', ['$compile', 'dmp', function ($compile, dmp) {
		const ddo = {
			scope: {
				left: '=leftObj',
				right: '=rightObj',
				options: '=options',
			},
			link(scope, iElement) {
				const listener = function () {
					iElement.html(dmp.createLineDiffHtml(scope.left, scope.right, scope.options));
					// If no options given, or, we have been given options and don't want to skip angular compiling
					// Then compile angular in the diff.
					if (!scope.options || (scope.options && !scope.options.skipAngularCompilingOnDiff)) {
						$compile(iElement.contents())(scope);
					}
				};

				scope.$watch('left', listener);
				scope.$watch('right', listener);
				scope.$watch('options.interLineDiff', listener, true);
				scope.$watch('options.ignoreTrailingNewLines', listener, true);
			},
		};
		return ddo;
	}]);
<|endoftext|>


<commit_before>'use strict';

module.exports = createOrUpdateSystemIntegration;

var async = require('async');
var mongoose = require('mongoose');
var _ = require('underscore');
var url = require('url');

var VaultAdapter = require('../common/VaultAdapter.js');

function createOrUpdateSystemIntegration(
  postgresClient, vaultUrl, vaultToken, systemIntegration, callback) {
  var bag = {
    postgresClient: postgresClient,
    systemIntegration: systemIntegration,
    vaultUrl: vaultUrl,
    vaultToken: vaultToken,
    systemIntegrationId: null,
    providerId: null
  };

  bag.who = util.format('migrate|%s', createOrUpdateSystemIntegration.name);

  async.series([
      _getSystemIntegration.bind(null, bag),
      _getMasterIntegration.bind(null, bag),
      _createSystemIntegration.bind(null, bag),
      _getExistingProvider.bind(null, bag),
      _createProvider.bind(null, bag),
      _getUpdatedSystemIntegration.bind(null, bag),
      _postSystemIntegrationFieldsToVault.bind(null, bag),
      _enableMasterIntegration.bind(null, bag)
    ],
    function (err) {
      logger.info(bag.who, 'Completed');
      return callback(err);
    }
  );
}

function _getSystemIntegration(bag, next) {
  var who = bag.who + '|' + _getSystemIntegration.name;
  logger.verbose(who, 'Inside');

  var query = util.format('SELECT * from "systemIntegrations" ' +
    'WHERE name=\'%s\' AND "masterName"=\'%s\';',
    bag.systemIntegration.name, bag.systemIntegration.masterName);

  bag.postgresClient.query(query,
    function (err, res) {
      if (err)
        return next(
          new ActErr(who, ActErr.OperationFailed,
            'Failed to get systemIntegration with error: ' + util.inspect(err))
        );

      if (!_.isEmpty(res.rows))
        bag.systemIntegrationId = res.rows[0].id;

      return next();
    }
  );
}

function _getMasterIntegration(bag, next) {
  if (bag.systemIntegrationId) return next();

  var who = bag.who + '|' + _getMasterIntegration.name;
  logger.verbose(who, 'Inside');

  var selectStatement = util.format('SELECT * FROM "masterIntegrations" ' +
    ' WHERE name=\'%s\'', bag.systemIntegration.masterName);

  bag.postgresClient.query(selectStatement,
    function (err, res) {
      if (err)
        return next(
          new ActErr(who, ActErr.DBOperationFailed,
            'Failed to get masterIntegrations with error: ' + util.inspect(err))
        );

      if (_.isEmpty(res.rows) || _.isEmpty(res.rows[0]))
        return next(
          new ActErr(who, ActErr.DataNotFound,
            'No master integration found for name ' +
            bag.systemIntegration.masterName)
        );

      bag.systemIntegration.masterIntegrationId = res.rows[0].id;
      return next();
    }
  );
}

function _createSystemIntegration(bag, next) {
  if (bag.systemIntegrationId) return next();

  var who = bag.who + '|' + _createSystemIntegration.name;
  logger.verbose(who, 'Inside');

  bag.systemIntegrationId = mongoose.Types.ObjectId().toString();

  var insertStatement = util.format('INSERT INTO "systemIntegrations" ' +
    '("id", "name", "masterIntegrationId", "masterName", "isEnabled", ' +
    '"createdBy", "updatedBy", "createdAt", "updatedAt") ' +
    'values (\'%s\', \'%s\', \'%s\', \'%s\', true,' +
    ' \'54188262bc4d591ba438d62a\', \'54188262bc4d591ba438d62a\',' +
    ' \'2016-06-01\', \'2016-06-01\')',
    bag.systemIntegrationId, bag.systemIntegration.name,
    bag.systemIntegration.masterIntegrationId,
    bag.systemIntegration.masterName);

  bag.postgresClient.query(insertStatement,
    function (err) {
      if (err)
        return next(
          new ActErr(who, ActErr.DBOperationFailed,
            'Failed to create systemIntegration with error: ' +
            util.inspect(err))
        );

      return next();
    }
  );
}

function _getExistingProvider(bag, next) {
  if (!bag.systemIntegration.data.url) return next();

  var who = bag.who + '|' + _getExistingProvider.name;
  logger.verbose(who, 'Inside');

  var providerUrl = bag.systemIntegration.data.url.
    toLowerCase().replace(/\/+$/, '');

  var query = util.format('SELECT * FROM "providers" WHERE "url"=\'%s\'',
    providerUrl);

  bag.postgresClient.query(query,
    function (err, providers) {
      if (err)
        return next(
          new ActErr(who, ActErr.DBOperationFailed,
            'Failed to find providers with error: ' + util.inspect(err))
        );

      if (!_.isEmpty(providers.rows) && !_.isEmpty(providers.rows[0]))
        bag.providerId = providers.rows[0];

      return next();
    }
  );
}

function _createProvider(bag, next) {
  if (!bag.systemIntegration.data.url) return next();
  if (bag.providerId) return next();

  var who = bag.who + '|' + _createProvider.name;
  logger.verbose(who, 'Inside');

  var retryOpts = {times: 4};

  bag.providerId = mongoose.Types.ObjectId().toString();

  var urlHostname =
    url.parse(bag.systemIntegration.data.url, true, true).hostname;
  var urlSlug = urlHostname;
  var providerUrl = bag.systemIntegration.data.url.
    toLowerCase().replace(/\/+$/, '');

  var name = bag.systemIntegration.masterName;
  if (name.endsWith('Keys'))
    name = name.replace('Keys', '');

  async.retry(retryOpts,
    function (callback) {

      var insertStatement = util.format('INSERT INTO "providers" ' +
        '("id", "url", "name", "urlSlug", ' +
        '"createdAt", "updatedAt") ' +
        'values (\'%s\', \'%s\', \'%s\', \'%s\',' +
        ' \'2016-06-01\', \'2016-06-01\')',
        bag.providerId, providerUrl, name, urlSlug);

      bag.postgresClient.query(insertStatement,
        function (err) {
          if (err) {
            // 23505 is duplicate key error
            if (err.code === '23505') {
              urlSlug = urlHostname + '-';
              var possible = 'abcdefghijklmnopqrstuvwxyz';
              for (var i = 0; i < 2; i++) {
                urlSlug +=
                  possible.charAt(Math.floor(Math.random() * possible.length));
              }
              return callback(err);
            } else {
              return callback(
                new ActErr(who, ActErr.DBOperationFailed,
                  'Failed to create provider with error: ' + util.inspect(err))
              );
            }
          }
          return callback();
        }
      );
    },
    function (err) {
      return next(err);
    }
  );
}

function _getUpdatedSystemIntegration(bag, next) {
  var who = bag.who + '|' + _getUpdatedSystemIntegration.name;
  logger.verbose(who, 'Inside');

  var query = util.format('SELECT * FROM "systemIntegrations" WHERE id=\'%s\'',
    bag.systemIntegrationId);

  bag.postgresClient.query(query,
    function (err, systemIntegrations) {
      if (err)
        return next(
          new ActErr(who, ActErr.DBOperationFailed,
            'Failed to get systemIntegrations with error: ' + util.inspect(err))
        );

      if (_.isEmpty(systemIntegrations.rows))
        return next(
          new ActErr(who, ActErr.DBEntityNotFound,
            'systemIntegration not found for id: ' +
            bag.systemIntegrationId)
        );

      bag.updatedSystemIntegration = systemIntegrations.rows[0];
      return next();
    }
  );
}

function _postSystemIntegrationFieldsToVault(bag, next) {
  var who = bag.who + '|' + _postSystemIntegrationFieldsToVault.name;
  logger.verbose(who, 'Inside');

  var vaultAdapter = new VaultAdapter(bag.vaultUrl, bag.vaultToken);

  var vaultSecret = {
    id: bag.updatedSystemIntegration.id,
    systemIntegrationId: bag.updatedSystemIntegration.systemIntegrationId,
    name: bag.updatedSystemIntegration.name,
    masterIntegrationId: bag.updatedSystemIntegration.masterIntegrationId,
    masterName: bag.updatedSystemIntegration.masterName,
    isEnabled: bag.updatedSystemIntegration.isEnabled,
    createdBy: bag.updatedSystemIntegration.createdBy,
    updatedBy: bag.updatedSystemIntegration.updatedBy,
    createdAt: bag.updatedSystemIntegration.createdAt,
    updatedAt: bag.updatedSystemIntegration.updatedAt,
    data: bag.systemIntegration.data
  };

  if (bag.providerId)
    vaultSecret.data.providerId = bag.providerId;

  var key = util.format('shippable/systemIntegrations/%s',
    bag.updatedSystemIntegration.id);
  vaultAdapter.postSecret(key, vaultSecret,
    function (err, body) {
      if (err)
        return next(
          new ActErr(who, ActErr.OperationFailed,
            'Failed to :postSecret for systemIntegrationId: ' +
            bag.updatedSystemIntegration.id + ' with status code ' + err, body)
        );

      return next();
    }
  );
}

function _enableMasterIntegration(bag, next) {
  var who = bag.who + '|' + _enableMasterIntegration.name;
  logger.verbose(who, 'Inside');

  var query = util.format(
    'UPDATE "masterIntegrations" SET "isEnabled"=true WHERE "name"=\'%s\';',
    bag.systemIntegration.masterName);

  bag.postgresClient.query(query,
    function (err) {
      if (err)
        return next(
          new ActErr(who, ActErr.OperationFailed,
            'Failed to enable masterIntegration with error: ' +
            util.inspect(err))
        );

      return next();
    }
  );
}
<commit_msg>#602; fixes existing provider ID.<commit_after>'use strict';

module.exports = createOrUpdateSystemIntegration;

var async = require('async');
var mongoose = require('mongoose');
var _ = require('underscore');
var url = require('url');

var VaultAdapter = require('../common/VaultAdapter.js');

function createOrUpdateSystemIntegration(
  postgresClient, vaultUrl, vaultToken, systemIntegration, callback) {
  var bag = {
    postgresClient: postgresClient,
    systemIntegration: systemIntegration,
    vaultUrl: vaultUrl,
    vaultToken: vaultToken,
    systemIntegrationId: null,
    providerId: null
  };

  bag.who = util.format('migrate|%s', createOrUpdateSystemIntegration.name);

  async.series([
      _getSystemIntegration.bind(null, bag),
      _getMasterIntegration.bind(null, bag),
      _createSystemIntegration.bind(null, bag),
      _getExistingProvider.bind(null, bag),
      _createProvider.bind(null, bag),
      _getUpdatedSystemIntegration.bind(null, bag),
      _postSystemIntegrationFieldsToVault.bind(null, bag),
      _enableMasterIntegration.bind(null, bag)
    ],
    function (err) {
      logger.info(bag.who, 'Completed');
      return callback(err);
    }
  );
}

function _getSystemIntegration(bag, next) {
  var who = bag.who + '|' + _getSystemIntegration.name;
  logger.verbose(who, 'Inside');

  var query = util.format('SELECT * from "systemIntegrations" ' +
    'WHERE name=\'%s\' AND "masterName"=\'%s\';',
    bag.systemIntegration.name, bag.systemIntegration.masterName);

  bag.postgresClient.query(query,
    function (err, res) {
      if (err)
        return next(
          new ActErr(who, ActErr.OperationFailed,
            'Failed to get systemIntegration with error: ' + util.inspect(err))
        );

      if (!_.isEmpty(res.rows))
        bag.systemIntegrationId = res.rows[0].id;

      return next();
    }
  );
}

function _getMasterIntegration(bag, next) {
  if (bag.systemIntegrationId) return next();

  var who = bag.who + '|' + _getMasterIntegration.name;
  logger.verbose(who, 'Inside');

  var selectStatement = util.format('SELECT * FROM "masterIntegrations" ' +
    ' WHERE name=\'%s\'', bag.systemIntegration.masterName);

  bag.postgresClient.query(selectStatement,
    function (err, res) {
      if (err)
        return next(
          new ActErr(who, ActErr.DBOperationFailed,
            'Failed to get masterIntegrations with error: ' + util.inspect(err))
        );

      if (_.isEmpty(res.rows) || _.isEmpty(res.rows[0]))
        return next(
          new ActErr(who, ActErr.DataNotFound,
            'No master integration found for name ' +
            bag.systemIntegration.masterName)
        );

      bag.systemIntegration.masterIntegrationId = res.rows[0].id;
      return next();
    }
  );
}

function _createSystemIntegration(bag, next) {
  if (bag.systemIntegrationId) return next();

  var who = bag.who + '|' + _createSystemIntegration.name;
  logger.verbose(who, 'Inside');

  bag.systemIntegrationId = mongoose.Types.ObjectId().toString();

  var insertStatement = util.format('INSERT INTO "systemIntegrations" ' +
    '("id", "name", "masterIntegrationId", "masterName", "isEnabled", ' +
    '"createdBy", "updatedBy", "createdAt", "updatedAt") ' +
    'values (\'%s\', \'%s\', \'%s\', \'%s\', true,' +
    ' \'54188262bc4d591ba438d62a\', \'54188262bc4d591ba438d62a\',' +
    ' \'2016-06-01\', \'2016-06-01\')',
    bag.systemIntegrationId, bag.systemIntegration.name,
    bag.systemIntegration.masterIntegrationId,
    bag.systemIntegration.masterName);

  bag.postgresClient.query(insertStatement,
    function (err) {
      if (err)
        return next(
          new ActErr(who, ActErr.DBOperationFailed,
            'Failed to create systemIntegration with error: ' +
            util.inspect(err))
        );

      return next();
    }
  );
}

function _getExistingProvider(bag, next) {
  if (!bag.systemIntegration.data.url) return next();

  var who = bag.who + '|' + _getExistingProvider.name;
  logger.verbose(who, 'Inside');

  var providerUrl = bag.systemIntegration.data.url.
    toLowerCase().replace(/\/+$/, '');

  var query = util.format('SELECT * FROM "providers" WHERE "url"=\'%s\'',
    providerUrl);

  bag.postgresClient.query(query,
    function (err, providers) {
      if (err)
        return next(
          new ActErr(who, ActErr.DBOperationFailed,
            'Failed to find providers with error: ' + util.inspect(err))
        );

      if (!_.isEmpty(providers.rows) && !_.isEmpty(providers.rows[0]))
        bag.providerId = providers.rows[0].id;

      return next();
    }
  );
}

function _createProvider(bag, next) {
  if (!bag.systemIntegration.data.url) return next();
  if (bag.providerId) return next();

  var who = bag.who + '|' + _createProvider.name;
  logger.verbose(who, 'Inside');

  var retryOpts = {times: 4};

  bag.providerId = mongoose.Types.ObjectId().toString();

  var urlHostname =
    url.parse(bag.systemIntegration.data.url, true, true).hostname;
  var urlSlug = urlHostname;
  var providerUrl = bag.systemIntegration.data.url.
    toLowerCase().replace(/\/+$/, '');

  var name = bag.systemIntegration.masterName;
  if (name.endsWith('Keys'))
    name = name.replace('Keys', '');

  async.retry(retryOpts,
    function (callback) {

      var insertStatement = util.format('INSERT INTO "providers" ' +
        '("id", "url", "name", "urlSlug", ' +
        '"createdAt", "updatedAt") ' +
        'values (\'%s\', \'%s\', \'%s\', \'%s\',' +
        ' \'2016-06-01\', \'2016-06-01\')',
        bag.providerId, providerUrl, name, urlSlug);

      bag.postgresClient.query(insertStatement,
        function (err) {
          if (err) {
            // 23505 is duplicate key error
            if (err.code === '23505') {
              urlSlug = urlHostname + '-';
              var possible = 'abcdefghijklmnopqrstuvwxyz';
              for (var i = 0; i < 2; i++) {
                urlSlug +=
                  possible.charAt(Math.floor(Math.random() * possible.length));
              }
              return callback(err);
            } else {
              return callback(
                new ActErr(who, ActErr.DBOperationFailed,
                  'Failed to create provider with error: ' + util.inspect(err))
              );
            }
          }
          return callback();
        }
      );
    },
    function (err) {
      return next(err);
    }
  );
}

function _getUpdatedSystemIntegration(bag, next) {
  var who = bag.who + '|' + _getUpdatedSystemIntegration.name;
  logger.verbose(who, 'Inside');

  var query = util.format('SELECT * FROM "systemIntegrations" WHERE id=\'%s\'',
    bag.systemIntegrationId);

  bag.postgresClient.query(query,
    function (err, systemIntegrations) {
      if (err)
        return next(
          new ActErr(who, ActErr.DBOperationFailed,
            'Failed to get systemIntegrations with error: ' + util.inspect(err))
        );

      if (_.isEmpty(systemIntegrations.rows))
        return next(
          new ActErr(who, ActErr.DBEntityNotFound,
            'systemIntegration not found for id: ' +
            bag.systemIntegrationId)
        );

      bag.updatedSystemIntegration = systemIntegrations.rows[0];
      return next();
    }
  );
}

function _postSystemIntegrationFieldsToVault(bag, next) {
  var who = bag.who + '|' + _postSystemIntegrationFieldsToVault.name;
  logger.verbose(who, 'Inside');

  var vaultAdapter = new VaultAdapter(bag.vaultUrl, bag.vaultToken);

  var vaultSecret = {
    id: bag.updatedSystemIntegration.id,
    systemIntegrationId: bag.updatedSystemIntegration.systemIntegrationId,
    name: bag.updatedSystemIntegration.name,
    masterIntegrationId: bag.updatedSystemIntegration.masterIntegrationId,
    masterName: bag.updatedSystemIntegration.masterName,
    isEnabled: bag.updatedSystemIntegration.isEnabled,
    createdBy: bag.updatedSystemIntegration.createdBy,
    updatedBy: bag.updatedSystemIntegration.updatedBy,
    createdAt: bag.updatedSystemIntegration.createdAt,
    updatedAt: bag.updatedSystemIntegration.updatedAt,
    data: bag.systemIntegration.data
  };

  if (bag.providerId)
    vaultSecret.data.providerId = bag.providerId;

  var key = util.format('shippable/systemIntegrations/%s',
    bag.updatedSystemIntegration.id);
  vaultAdapter.postSecret(key, vaultSecret,
    function (err, body) {
      if (err)
        return next(
          new ActErr(who, ActErr.OperationFailed,
            'Failed to :postSecret for systemIntegrationId: ' +
            bag.updatedSystemIntegration.id + ' with status code ' + err, body)
        );

      return next();
    }
  );
}

function _enableMasterIntegration(bag, next) {
  var who = bag.who + '|' + _enableMasterIntegration.name;
  logger.verbose(who, 'Inside');

  var query = util.format(
    'UPDATE "masterIntegrations" SET "isEnabled"=true WHERE "name"=\'%s\';',
    bag.systemIntegration.masterName);

  bag.postgresClient.query(query,
    function (err) {
      if (err)
        return next(
          new ActErr(who, ActErr.OperationFailed,
            'Failed to enable masterIntegration with error: ' +
            util.inspect(err))
        );

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


<commit_before>import AdaptiveApplication from "sap/a/app/Application";

import MapView from "../map/MapView";

export default class Application extends AdaptiveApplication
{
    init()
    {
        super.init();
        this.addStyleClass("mb-app");
        this._initMapView();
    }

    _initMapView()
    {
        this.mapView = new MapView("map-view", {
            defaultValue: 10
        });
        this.addSubview(this.mapView);
    }
}
<commit_msg>Change init.<commit_after>import AdaptiveApplication from "sap/a/app/Application";

import MapView from "../map/MapView";

export default class Application extends AdaptiveApplication
{
    afterInit()
    {
        super.afterInit();
        this.addStyleClass("mb-app");
        this._initMapView();
    }

    _initMapView()
    {
        this.mapView = new MapView("map-view", {
            defaultValue: 10
        });
        this.addSubview(this.mapView);
    }
}
<|endoftext|>


<commit_before>/* ========================================================================
 * Bootstrap: button.js v3.1.1
 * http://getbootstrap.com/javascript/#buttons
 * ========================================================================
 * Copyright 2011-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */

+function ($) {
  'use strict';

  // BUTTON PUBLIC CLASS DEFINITION
  // ==============================

  var Button = function (element, options) {
    this.$element  = $(element)
    this.options   = $.extend({}, Button.DEFAULTS, options)
    this.isLoading = false
  }

  Button.VERSION  = '3.1.1'

  Button.DEFAULTS = {
    loadingText: 'loading...'
  }

  Button.prototype.setState = function (state) {
    var d    = 'disabled'
    var $el  = this.$element
    var val  = $el.is('input') ? 'val' : 'html'
    var data = $el.data()

    state = state + 'Text'

    if (data.resetText == null) $el.data('resetText', $el[val]())

    $el[val](data[state] == null ? this.options[state] : data[state])

    // push to event loop to allow forms to submit
    setTimeout($.proxy(function () {
      if (state == 'loadingText') {
        this.isLoading = true
        $el.addClass(d).attr(d, d)
      } else if (this.isLoading) {
        this.isLoading = false
        $el.removeClass(d).removeAttr(d)
      }
    }, this), 0)
  }

  Button.prototype.toggle = function () {
    var changed = true
    var $parent = this.$element.closest('[data-toggle="buttons"]')

    if ($parent.length) {
      var $input = this.$element.find('input')
      if ($input.prop('type') == 'radio') {
        if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
        else $parent.find('.active').removeClass('active')
      }
      if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
    }

    if (changed) this.$element.toggleClass('active')
  }

  // BUTTON PLUGIN DEFINITION
  // ========================

  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.button')
      var options = typeof option == 'object' && option

      if (!data) $this.data('bs.button', (data = new Button(this, options)))

      if (option == 'toggle') data.toggle()
      else if (option) data.setState(option)
    })
  }

  var old = $.fn.button

  $.fn.button             = Plugin
  $.fn.button.Constructor = Button

  // BUTTON NO CONFLICT
  // ==================

  $.fn.button.noConflict = function () {
    $.fn.button = old
    return this
  }

  // BUTTON DATA-API
  // ===============

  $(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
    var $btn = $(e.target)
    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
    Plugin.call($btn, 'toggle')
    e.preventDefault()
  })

}(jQuery);
<commit_msg>add "focus" to focused btns with button plugin<commit_after>/* ========================================================================
 * Bootstrap: button.js v3.1.1
 * http://getbootstrap.com/javascript/#buttons
 * ========================================================================
 * Copyright 2011-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */

+function ($) {
  'use strict';

  // BUTTON PUBLIC CLASS DEFINITION
  // ==============================

  var Button = function (element, options) {
    this.$element  = $(element)
    this.options   = $.extend({}, Button.DEFAULTS, options)
    this.isLoading = false
  }

  Button.VERSION  = '3.1.1'

  Button.DEFAULTS = {
    loadingText: 'loading...'
  }

  Button.prototype.setState = function (state) {
    var d    = 'disabled'
    var $el  = this.$element
    var val  = $el.is('input') ? 'val' : 'html'
    var data = $el.data()

    state = state + 'Text'

    if (data.resetText == null) $el.data('resetText', $el[val]())

    $el[val](data[state] == null ? this.options[state] : data[state])

    // push to event loop to allow forms to submit
    setTimeout($.proxy(function () {
      if (state == 'loadingText') {
        this.isLoading = true
        $el.addClass(d).attr(d, d)
      } else if (this.isLoading) {
        this.isLoading = false
        $el.removeClass(d).removeAttr(d)
      }
    }, this), 0)
  }

  Button.prototype.toggle = function () {
    var changed = true
    var $parent = this.$element.closest('[data-toggle="buttons"]')

    if ($parent.length) {
      var $input = this.$element.find('input')
      if ($input.prop('type') == 'radio') {
        if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
        else $parent.find('.active').removeClass('active')
      }
      if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
    }

    if (changed) this.$element.toggleClass('active')
  }

  // BUTTON PLUGIN DEFINITION
  // ========================

  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.button')
      var options = typeof option == 'object' && option

      if (!data) $this.data('bs.button', (data = new Button(this, options)))

      if (option == 'toggle') data.toggle()
      else if (option) data.setState(option)
    })
  }

  var old = $.fn.button

  $.fn.button             = Plugin
  $.fn.button.Constructor = Button

  // BUTTON NO CONFLICT
  // ==================

  $.fn.button.noConflict = function () {
    $.fn.button = old
    return this
  }

  // FOCUS SHIM (FOR BUTTON GROUPS)
  // ==============================

  function getBtnTarget(target) {
    var $target = $(target)
    return $target.hasClass('btn') ? $target : $target.parent('.btn')
  }

  // BUTTON DATA-API
  // ===============

  $(document)
    .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
      var $btn = $(e.target)
      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
      Plugin.call($btn, 'toggle')
      e.preventDefault()
    })
    .on('focus.bs.button.data-api', '[data-toggle^="button"]', function (e) {
      getBtnTarget(e.target).addClass('focus')
    })
    .on('blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
      getBtnTarget(e.target).removeClass('focus')
    })

}(jQuery);
<|endoftext|>


<commit_before>'use strict';

var datasets = [{
  name: 'Barley',
  url: 'data/barley.json',
  table: 'barley_json'
},{
  name: 'Cars',
  url: 'data/cars.json',
  table: 'cars_json'
},{
  name: 'Crimea',
  url: 'data/crimea.json',
  table: 'crimea_json'
},{
  name: 'Driving',
  url: 'data/driving.json',
  table: 'driving_json'
},{
  name: 'Iris',
  url: 'data/iris.json',
  table: 'iris_json'
},{
  name: 'Jobs',
  url: 'data/jobs.json',
  table: 'jobs_json'
},{
  name: 'Population',
  url: 'data/population.json',
  table: 'population_json'
},{
  name: 'Movies',
  url: 'data/movies.json',
  table: 'movies_json'
},{
  name: 'Birdstrikes',
  url: 'data/birdstrikes.json',
  table: 'birdstrikes_json'
},{
  name: "Burtin",
  url: "data/burtin.json",
  table: 'burtin_json'
},{
  name: "Budget 2016",
  url: "data/budget.json",
  table: 'budget_json'
},{
  name: "Climate Normals",
  url: "data/climate.json",
  table: 'climate_json'
},{
  name: "Campaigns",
  url: "data/weball26.json",
  table: 'weball26_json'
}];

function getNameMap(dataschema) {
  return dataschema.reduce(function(m, field) {
    m[field.name] = field;
    return m;
  }, {});
}

angular.module('vleApp')
  .factory('Dataset', function($http, Config, _, Papa, vl, consts) {
    var Dataset = {};

    var countField = vl.field.count();

    Dataset.datasets = datasets;
    Dataset.dataset = datasets[7]; //Movies
    Dataset.dataschema = [];
    Dataset.dataschema.byName = {};
    Dataset.stats = {};

    // TODO move these to constant to a universal vlui constant file
    Dataset.typeNames = {
      O: 'text',
      Q: 'number',
      T: 'time',
      G: 'geo'
    };

    Dataset.fieldOrder = vl.field.order.typeThenName;

    // update the schema and stats
    Dataset.update = function (dataset) {

      //set schema and stats
      if (Config.useVegaServer) {
        var url = Config.serverUrl + '/stats/?name=' + dataset.table;
        return $http.get(url, {cache: true}).then(function(response) {
          var parsed = Papa.parse(response.data, {header: true});
          var dataschema=[], stats = {};
          _.each(_.filter(parsed.data, function(d) {return d.name;}), function(row) {
            var fieldStats = {};
            fieldStats.min = +row.min;
            fieldStats.max = +row.max;
            fieldStats.cardinality = +row.cardinality;
            stats[row.name] = fieldStats;

            // TODO add "geo" and "time"
            var type = row.type === 'integer' || row.type === 'real' ? 'Q' : 'O';

            dataschema.push({name: row.name, type: type});
            stats.count = row.count;
          });
          if (consts.addCount) {
            dataschema.push(countField);
          }

          Dataset.dataschema = dataschema;
          Dataset.dataschema.byName = getNameMap(Dataset.dataschema);
          Dataset.stats = stats;
        });
      } else {
        return $http.get(dataset.url, {cache: true}).then(function(response) {
          Dataset.data = response.data;
          var dataschema = vl.data.getSchema(response.data);
          if (consts.addCount) {
            dataschema.push(countField);
          }

          Dataset.dataschema = dataschema;
          Dataset.dataschema.byName = getNameMap(Dataset.dataschema);
          Dataset.stats = vl.data.getStats(response.data);
        });
      }
    };

    return Dataset;
  });
<commit_msg>Change type to ordinal if there are few unique values. <commit_after>'use strict';

var datasets = [{
  name: 'Barley',
  url: 'data/barley.json',
  table: 'barley_json'
},{
  name: 'Cars',
  url: 'data/cars.json',
  table: 'cars_json'
},{
  name: 'Crimea',
  url: 'data/crimea.json',
  table: 'crimea_json'
},{
  name: 'Driving',
  url: 'data/driving.json',
  table: 'driving_json'
},{
  name: 'Iris',
  url: 'data/iris.json',
  table: 'iris_json'
},{
  name: 'Jobs',
  url: 'data/jobs.json',
  table: 'jobs_json'
},{
  name: 'Population',
  url: 'data/population.json',
  table: 'population_json'
},{
  name: 'Movies',
  url: 'data/movies.json',
  table: 'movies_json'
},{
  name: 'Birdstrikes',
  url: 'data/birdstrikes.json',
  table: 'birdstrikes_json'
},{
  name: "Burtin",
  url: "data/burtin.json",
  table: 'burtin_json'
},{
  name: "Budget 2016",
  url: "data/budget.json",
  table: 'budget_json'
},{
  name: "Climate Normals",
  url: "data/climate.json",
  table: 'climate_json'
},{
  name: "Campaigns",
  url: "data/weball26.json",
  table: 'weball26_json'
}];

function getNameMap(dataschema) {
  return dataschema.reduce(function(m, field) {
    m[field.name] = field;
    return m;
  }, {});
}

angular.module('vleApp')
  .factory('Dataset', function($http, Config, _, Papa, vl, consts) {
    var Dataset = {};

    var countField = vl.field.count();

    Dataset.datasets = datasets;
    Dataset.dataset = datasets[7]; //Movies
    Dataset.dataschema = [];
    Dataset.dataschema.byName = {};
    Dataset.stats = {};

    // TODO move these to constant to a universal vlui constant file
    Dataset.typeNames = {
      O: 'text',
      Q: 'number',
      T: 'time',
      G: 'geo'
    };

    Dataset.fieldOrder = vl.field.order.typeThenName;

    // update the schema and stats
    Dataset.update = function (dataset) {

      //set schema and stats
      if (Config.useVegaServer) {
        var url = Config.serverUrl + '/stats/?name=' + dataset.table;
        return $http.get(url, {cache: true}).then(function(response) {
          var parsed = Papa.parse(response.data, {header: true});
          var dataschema=[], stats = {};
          _.each(_.filter(parsed.data, function(d) {return d.name;}), function(row) {
            var fieldStats = {};
            fieldStats.min = +row.min;
            fieldStats.max = +row.max;
            fieldStats.cardinality = +row.cardinality;
            stats[row.name] = fieldStats;

            // TODO add "geo" and "time"
            var type = row.type === 'integer' || row.type === 'real' ? 'Q' : 'O';

            dataschema.push({name: row.name, type: type});
            stats.count = row.count;
          });
          if (consts.addCount) {
            dataschema.push(countField);
          }

          Dataset.dataschema = dataschema;
          Dataset.dataschema.byName = getNameMap(Dataset.dataschema);
          Dataset.stats = stats;
        });
      } else {
        return $http.get(dataset.url, {cache: true}).then(function(response) {
          Dataset.data = response.data;
          var dataschema = vl.data.getSchema(response.data);
          if (consts.addCount) {
            dataschema.push(countField);
          }

          Dataset.dataschema = dataschema;
          Dataset.dataschema.byName = getNameMap(Dataset.dataschema);
          Dataset.stats = vl.data.getStats(response.data);

          _.each(Dataset.dataschema, function(field) {
            // if fewer than 2% of values or unique, assume the field to be ordinal,
            // or <= 7 unique values
            var stats = Dataset.stats[field.name];
            if (stats !== undefined && (field.type === 'Q' && stats.cardinality < (stats.count - stats.numNulls)/50 || stats.cardinality <= 7)) {
              field.type = 'O';
            }
          });

        });
      }
    };

    return Dataset;
  });
<|endoftext|>


<commit_before>/* ***************************************
 * PROTOTYPE: For
 * ***************************************/
$.for = ( obj , execute )=>{

	for (let i = 0; i < obj.length; i++)
	{
		execute(i, obj[i])
	}

}<commit_msg>Delete 11_Proto_For.js<commit_after><|endoftext|>


<commit_before>angular.module('headcount.auth', [])

.controller('AuthController', function ($scope, $window, $location, $http, Auth) {

  /**
   * $scope.user holds onto any input on the signin.html and signup.html input
   * fields.
   */

  $scope.user = {};

  /**
   * $scope.signin & $scope.signup both make a POST request to the routes/auth.js file
   * with the attempted login information from $scope.user. On successful authentication,
   * it sets the session item 'user' to the username, so that we can render the content
   * specifically to the user that's currently signed in.
   */

  $scope.signin = function () {

    return $http({
      method: 'POST',
      url: '/auth/local',
      data: $scope.user
    })
    .then(function (resp) {
      $window.sessionStorage.setItem('user', resp.config.data.username);
      $window.location.href = "/";
    })
    .catch(function(error) {
      $window.alert("Incorrect login, please try again!");
    });
  };

  $scope.signup = function () {

    return $http({
      method: 'POST',
      url: '/auth/local-signup',
      data: $scope.user
    })
    .then(function (resp) {
        $window.sessionStorage.setItem('user', resp.config.data.username);
        $window.location.href = "/";
    })
    .catch(function(error) {
      $window.alert("Username already exists, please try again!");
    });
  };

  /**
  * $scope.signout calls Auth.signout on the 'Auth' factory, under the services.js
  * file. It destroys the session item 'user', and then resets the view to the sign-in
  * page. It also makes a GET request to routes/auth.js's logout route, which will also
  * destroy the express-session token on the backend, then alerts the user on a
  * successful request.
  */

  $scope.signout = function(){

    Auth.signout();
    $scope.auth = Auth.isAuth();
    return $http({
      method: 'GET',
      url: '/auth/logout'
    })
    .then(function(resp) {
      $window.alert("You've signed out!");
    });
  };

});
<commit_msg>Remove deprecated auth code<commit_after>angular.module('headcount.auth', [])

.controller('AuthController', function ($scope, $window, $location, $http, Auth) {

  /**
   * $scope.user holds onto any input on the signin.html and signup.html input
   * fields.
   */

  $scope.user = {};

  /**
   * $scope.signin & $scope.signup both make a POST request to the routes/auth.js file
   * with the attempted login information from $scope.user. On successful authentication,
   * it sets the session item 'user' to the username, so that we can render the content
   * specifically to the user that's currently signed in.
   */

  $scope.signin = function () {

    return $http({
      method: 'POST',
      url: '/auth/local',
      data: $scope.user
    })
    .then(function (resp) {
      $window.sessionStorage.setItem('user', resp.config.data.username);
      $window.location.href = "/";
    })
    .catch(function(error) {
      $window.alert("Incorrect login, please try again!");
    });
  };

  $scope.signup = function () {

    return $http({
      method: 'POST',
      url: '/auth/local-signup',
      data: $scope.user
    })
    .then(function (resp) {
        $window.sessionStorage.setItem('user', resp.config.data.username);
        $window.location.href = "/";
    })
    .catch(function(error) {
      $window.alert("Username already exists, please try again!");
    });
  };

  /**
  * $scope.signout calls Auth.signout on the 'Auth' factory, under the services.js
  * file. It destroys the session item 'user', and then resets the view to the sign-in
  * page. It also makes a GET request to routes/auth.js's logout route, which will also
  * destroy the express-session token on the backend, then alerts the user on a
  * successful request.
  */

  $scope.signout = function(){

    Auth.signout();
    return $http({
      method: 'GET',
      url: '/auth/logout'
    })
    .then(function(resp) {
      $window.alert("You've signed out!");
    });
  };

});
<|endoftext|>


<commit_before>// @flow
export const serialize = {}
const initialState = {}

export const deserialize = (state: any = initialState, props: any) => {
  if (!props) return state

  return {
    ...state,
    ...props,
  }
}
<commit_msg>WIP (#14062)<commit_after>// @flow
export const serialize = {
  devices: (v: any) => v,
  paperkeyError: (v: any) => v,
  phase: (v: any) => v,
  waiting: (v: any) => v,
  windowComponent: (v: any) => v,
  windowOpts: (v: any) => v,
  windowParam: (v: any) => v,
  windowPositionBottomRight: (v: any) => v,
  windowTitle: (v: any) => v,
}
const initialState = {}

export const deserialize = (state: any = initialState, props: any) => {
  if (!props) return state

  return {
    ...state,
    ...props,
  }
}
<|endoftext|>


<commit_before>function getInput() {
    var input =prompt("Please choose either rock, paper, or scissors.");
    if ((input==="rock")|| (input==="paper") || (input==="scissors")){
        return input;
    } else {
        return getInput();
    }
} //simple function which yields the result of the user's prompt

function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber <= 0.33) {
        return "rock";
    } else if (randomNumber <= 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
} //simple function which yields either rock paper or scissors

//console.log(getInput());
//console.log(randomPlay());

function getPlayerMove(move) {
    // If a `move` has a value, your expression should evaluate to that value
    if ((move===undefined)||(move===null)){
        return getInput();
    } else {
        //console.log("hmm I'm not understanding something!");
        return move;
    }
} //function which takes getInput's yield and uses it to say the player's move assuming that was not entered.

function getComputerMove(move) {
    //If `move` is not specified / is null, your expression should equal `randomPlay()`.
    if ((move===undefined) || (move===null)){
        return randomPlay();
    } else if ((move==="rock")||(move==="paper")||(move==="scissors")){
        return move;
    } else {
        //console.log("hmm I'm not understanding something!");
        return "errorofcomp";
    }
} //function which takes randomPlay and uses it to determine what the computer will do assuming it wasn't entered.

//console.log(getComputerMove())

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    if (playerMove === computerMove){
        winner="tie";
    } else if (playerMove==="rock"){
        if (computerMove==="paper"){
            winner="computer";
        } else if (computerMove==="scissors"){
            winner="player";
        }
    } else if (playerMove==="paper"){
        if (computerMove==="scissors"){
            //console.log("computerps");
            winner="computer";
        } else if (computerMove==="rock"){
            winner="player";
        }
    } else if (playerMove==="scissors"){
        if (computerMove==="rock"){
            //console.log("computersr");
            winner="computer";
        } else if (computerMove==="paper"){
            winner="player";
        }
    } else {
        winner="errorgetwinner";
    }
    //console.log(winner);
    return winner;
}//function which returns variable winner (which should be either player, computer, or tie)
//if (getWinner(getPlayerMove(),getComputerMove())==="player"){console.log("yes");}
//console.log(getWinner(getPlayerMove(),getComputerMove()));

function playTo(x) {
    console.log("Let's play Rock, Paper, Scissors");
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    var compWins=0;
    var playerWins=0;
    var ties=0;
    while ( (compWins<x) || (playerWins<x) ) {
        if (getWinner(getPlayerMove(null),getComputerMove(null) )==='player'){
            //console.log("player");
            playerWins=playerWins+1;
        } else if (getWinner(getPlayerMove(null),getComputerMove(null))==='computer'){
            //console.log("computer");
            compWins=compWins+1;
        } else if (getWinner(getPlayerMove(null), getComputerMove(null))==='tie') {
            //console.log("tie");
            ties=ties+1;
        }
        else {
            return 'errorPlayto';
        }
    }
    return [compWins, playerWins];
}
playTo(5);<commit_msg>newest update with small edits<commit_after>function getInput() {
    var input =prompt("Please choose either rock, paper, or scissors.");
    if ((input==="rock")|| (input==="paper") || (input==="scissors")){
        return input;
    } else {
        return getInput();
    }
} //simple function which yields the result of the user's prompt

function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber <= 0.33) {
        return "rock";
    } else if (randomNumber <= 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
} //simple function which yields either rock paper or scissors

//console.log(getInput());
//console.log(randomPlay());

function getPlayerMove(move) {
    // If a `move` has a value, your expression should evaluate to that value
    if ((move===undefined)||(move===null)){
        return getInput();
    } else {
        //console.log("hmm I'm not understanding something!");
        return move;
    }
} //function which takes getInput's yield and uses it to say the player's move assuming that was not entered.

function getComputerMove(move) {
    //If `move` is not specified / is null, your expression should equal `randomPlay()`.
    if ((move===undefined) || (move===null)){
        return randomPlay();
    } else if ((move==="rock")||(move==="paper")||(move==="scissors")){
        return move;
    } else {
        //console.log("hmm I'm not understanding something!");
        return "errorofcomp";
    }
} //function which takes randomPlay and uses it to determine what the computer will do assuming it wasn't entered.

//console.log(getComputerMove())

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    if (playerMove === computerMove){
        winner="tie";
    } else if (playerMove==="rock"){
        if (computerMove==="paper"){
            winner="computer";
        } else if (computerMove==="scissors"){
            winner="player";
        }
    } else if (playerMove==="paper"){
        if (computerMove==="scissors"){
            //console.log("computerps");
            winner="computer";
        } else if (computerMove==="rock"){
            winner="player";
        }
    } else if (playerMove==="scissors"){
        if (computerMove==="rock"){
            //console.log("computersr");
            winner="computer";
        } else if (computerMove==="paper"){
            winner="player";
        }
    } else {
        winner="errorgetwinner";
    }
    //console.log(winner);
    return winner;
}//function which returns variable winner (which should be either player, computer, or tie)
//if (getWinner(getPlayerMove(),getComputerMove())==="player"){console.log("yes");}
//console.log(getWinner(getPlayerMove(),getComputerMove()));

function playTo(x) {
    console.log("Let's play Rock, Paper, Scissors");
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    var compWins=0;
    var playerWins=0;
    var ties=0;
    while ( (compWins<x) || (playerWins<x) ) {
        if ( getWinner( getPlayerMove(), getComputerMove() )==='player'){
            //console.log("player");
            playerWins=playerWins+1;
        } else if ( getWinner( getPlayerMove(), getComputerMove() )==='computer'){
            //console.log("computer");
            compWins=compWins+1;
        } else if ( getWinner( getPlayerMove(), getComputerMove() )==='tie') {
            //console.log("tie");
            ties=ties+1;
        }
        else {
            return 'errorPlayto';
        }
    }
    return [compWins, playerWins];
}
playTo(5);<|endoftext|>


<commit_before>/**
 * Created by neoqmin on 2016. 6. 21..
 *
 * @brief       보건기상지수를 Area Number를 기준으로 가져와서 DB에 저장
 *
 * */

var mongoose = require('mongoose');

var healthDaySchema = new mongoose.Schema({
    areaNo: Number,             ///< 지역 코드
    date: Date,               ///< 날짜
    indexType: String,          ///< 지수 종류
    index: Number               ///< 지수
});

healthDaySchema.index({areaNo: 1});
healthDaySchema.index({date: 1});
healthDaySchema.index({indexType: 'text'});

module.exports = mongoose.model('healthDayKma', healthDaySchema);
<commit_msg>TW-10 indexType 정보 주석에 추가<commit_after>/**
 * Created by neoqmin on 2016. 6. 21..
 *
 * @brief       보건기상지수를 Area Number를 기준으로 가져와서 DB에 저장
 *
 * */

var mongoose = require('mongoose');

/**
 * indexType
 * asthma-lunt: 폐질환가능지수, brain: 뇌졸중가능지수, skin: 피부질환가능지수, flowerWoody: 꽃가루농도위험지수(참나무),
 * flowerPine: 꽃가루농도위험지수(소나무), flowerWeeds: 꽃가루농도위험지수(잡초류), influenza: 감기가능지수
 */
var healthDaySchema = new mongoose.Schema({
    areaNo: Number,             ///< 지역 코드
    date: Date,               ///< 날짜
    indexType: String,          ///< 지수 종류
    index: Number               ///< 지수
});

healthDaySchema.index({areaNo: 1});
healthDaySchema.index({date: 1});
healthDaySchema.index({indexType: 'text'});

module.exports = mongoose.model('healthDayKma', healthDaySchema);
<|endoftext|>


<commit_before>/**
 * This module allows to customize the built-in toolbar of the Rich Text Editor and use commands from the [HTML Editing APIs](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand).
 * It's highly recommended to keep this toolbar as small as possible, especially from styling commands (eg. 'fontSize') and leave this task to the Style Manager
 *
 * You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/rich_text_editor/config/config.js)
 * ```js
 * const editor = grapesjs.init({
 *  richTextEditor: {
 *    // options
 *  }
 * })
 * ```
 *
 * Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
 *
 * ```js
 * // Listen to events
 * editor.on('rte:enable', () => { ... });
 *
 * // Use the API
 * const rte = editor.RichTextEditor;
 * rte.add(...);
 * ```
 *
 * ## Available Events
 * * `rte:enable` - RTE enabled. The view, on which RTE is enabled, is passed as an argument
 * * `rte:disable` - RTE disabled. The view, on which RTE is disabled, is passed as an argument
 *
 * ## Methods
 * * [add](#add)
 * * [get](#get)
 * * [getAll](#getall)
 * * [remove](#remove)
 * * [getToolbarEl](#gettoolbarel)
 *
 * @module RichTextEditor
 */

import RichTextEditor from './model/RichTextEditor';
import { on, hasWin } from 'utils/mixins';
import defaults from './config/config';

const eventsUp = 'change:canvasOffset frame:scroll component:update';

export default () => {
  let toolbar;

  const hideToolbar = () => {
    const style = toolbar.style;
    const size = '-1000px';
    style.top = size;
    style.left = size;
    style.display = 'none';
  };

  return {
    customRte: null,

    /**
     * Name of the module
     * @type {String}
     * @private
     */
    name: 'RichTextEditor',

    getConfig() {
      return this.config;
    },

    /**
     * Initialize module. Automatically called with a new instance of the editor
     * @param {Object} opts Options
     * @private
     */
    init(opts = {}) {
      const config = { ...defaults, ...opts };
      const ppfx = config.pStylePrefix;

      if (ppfx) {
        config.stylePrefix = ppfx + config.stylePrefix;
      }

      this.config = config;
      this.pfx = config.stylePrefix;
      this.em = config.em;
      this.actions = config.actions || [];
      if (!hasWin()) return this;
      toolbar = document.createElement('div');
      toolbar.className = `${ppfx}rte-toolbar ${ppfx}one-bg`;

      //Avoid closing on toolbar clicking
      on(toolbar, 'mousedown', e => e.stopPropagation());
      return this;
    },

    destroy() {
      this.globalRte?.destroy();
      this.customRte?.destroy?.();
      toolbar = 0;
      ['actionbar', 'actions', 'em', 'config', 'globalRte', 'lastEl'].map(i => {
        delete this[i];
      });
    },

    /**
     * Post render callback
     * @param  {View} ev
     * @private
     */
    postRender(ev) {
      const canvas = ev.model.get('Canvas');
      toolbar.style.pointerEvents = 'all';
      hideToolbar();
      canvas.getToolsEl().appendChild(toolbar);
    },

    /**
     * Init the built-in RTE
     * @param  {HTMLElement} el
     * @return {RichTextEditor}
     * @private
     */
    initRte(el) {
      let { globalRte } = this;
      const { em, pfx, actionbar, config } = this;
      const actionbarContainer = toolbar;
      const actions = this.actions || [...config.actions];
      const classes = {
        actionbar: `${pfx}actionbar`,
        button: `${pfx}action`,
        active: `${pfx}active`,
        inactive: `${pfx}inactive`,
        disabled: `${pfx}disabled`,
      };

      if (!globalRte) {
        globalRte = new RichTextEditor({
          em,
          el,
          classes,
          actions,
          actionbar,
          actionbarContainer,
        });
        this.globalRte = globalRte;
      } else {
        globalRte.em = em;
        globalRte.setEl(el);
      }

      if (globalRte.actionbar) {
        this.actionbar = globalRte.actionbar;
      }

      if (globalRte.actions) {
        this.actions = globalRte.actions;
      }

      return globalRte;
    },

    /**
     * Add a new action to the built-in RTE toolbar
     * @param {string} name Action name
     * @param {Object} action Action options
     * @example
     * rte.add('bold', {
     *   icon: 'B',
     *   attributes: {title: 'Bold'},
     *   result: rte => rte.exec('bold')
     * });
     * rte.add('link', {
     *   icon: document.getElementById('t'),
     *   attributes: {title: 'Link',}
     *   // Example on it's easy to wrap a selected content
     *   result: rte => rte.insertHTML(`<a href="#">${rte.selection()}</a>`)
     * });
     * // An example with fontSize
     * rte.add('fontSize', {
     *   icon: `<select class="gjs-field">
     *         <option>1</option>
     *         <option>4</option>
     *         <option>7</option>
     *       </select>`,
     *     // Bind the 'result' on 'change' listener
     *   event: 'change',
     *   result: (rte, action) => rte.exec('fontSize', action.btn.firstChild.value),
     *   // Callback on any input change (mousedown, keydown, etc..)
     *   update: (rte, action) => {
     *     const value = rte.doc.queryCommandValue(action.name);
     *     if (value != 'false') { // value is a string
     *       action.btn.firstChild.value = value;
     *     }
     *    }
     *   })
     * // An example with state
     * const isValidAnchor = (rte) => {
     *   // a utility function to help determine if the selected is a valid anchor node
     *   const anchor = rte.selection().anchorNode;
     *   const parentNode  = anchor && anchor.parentNode;
     *   const nextSibling = anchor && anchor.nextSibling;
     *   return (parentNode && parentNode.nodeName == 'A') || (nextSibling && nextSibling.nodeName == 'A')
     * }
     * rte.add('toggleAnchor', {
     *   icon: `<span style="transform:rotate(45deg)">⫘</span>`,
     *   state: (rte, doc) => {
     *    if (rte && rte.selection()) {
     *      // `btnState` is a integer, -1 for disabled, 0 for inactive, 1 for active
     *      return isValidAnchor(rte) ? btnState.ACTIVE : btnState.INACTIVE;
     *    } else {
     *      return btnState.INACTIVE;
     *    }
     *   },
     *   result: (rte, action) => {
     *     if (isValidAnchor(rte)) {
     *       rte.exec('unlink');
     *     } else {
     *       rte.insertHTML(`<a class="link" href="">${rte.selection()}</a>`);
     *     }
     *   }
     * })
     */
    add(name, action = {}) {
      action.name = name;
      this.globalRte?.addAction(action, { sync: 1 });
    },

    /**
     * Get the action by its name
     * @param {string} name Action name
     * @return {Object}
     * @example
     * const action = rte.get('bold');
     * // {name: 'bold', ...}
     */
    get(name) {
      let result;
      this.globalRte?.getActions().forEach(action => {
        if (action.name == name) {
          result = action;
        }
      });
      return result;
    },

    /**
     * Get all actions
     * @return {Array}
     */
    getAll() {
      return this.globalRte?.getActions();
    },

    /**
     * Remove the action from the toolbar
     * @param  {string} name
     * @return {Object} Removed action
     * @example
     * const action = rte.remove('bold');
     * // {name: 'bold', ...}
     */
    remove(name) {
      const actions = this.getAll();
      const action = this.get(name);

      if (action) {
        const btn = action.btn;
        const index = actions.indexOf(action);
        btn.parentNode.removeChild(btn);
        actions.splice(index, 1);
      }

      return action;
    },

    /**
     * Get the toolbar element
     * @return {HTMLElement}
     */
    getToolbarEl() {
      return toolbar;
    },

    /**
     * Triggered when the offset of the editor is changed
     * @private
     */
    updatePosition() {
      const { em } = this;
      const un = 'px';
      const canvas = em.get('Canvas');
      const { style } = toolbar;
      const pos = canvas.getTargetToElementFixed(this.lastEl, toolbar, {
        event: 'rteToolbarPosUpdate',
        left: 0,
      });
      style.top = (pos.top || 0) + un;
      style.left = (pos.left || 0) + un;
    },

    /**
     * Enable rich text editor on the element
     * @param {View} view Component view
     * @param {Object} rte The instance of already defined RTE
     * @private
     * */
    async enable(view, rte, opts) {
      this.lastEl = view.el;
      const { customRte, em } = this;
      const el = view.getChildrenContainer();

      toolbar.style.display = '';
      const rteInst = await (customRte ? customRte.enable(el, rte) : this.initRte(el).enable(opts));

      if (em) {
        setTimeout(this.updatePosition.bind(this), 0);
        em.off(eventsUp, this.updatePosition, this);
        em.on(eventsUp, this.updatePosition, this);
        em.trigger('rte:enable', view, rteInst);
      }

      return rteInst;
    },

    /**
     * Unbind rich text editor from the element
     * @param {View} view
     * @param {Object} rte The instance of already defined RTE
     * @private
     * */
    disable(view, rte) {
      const { em } = this;
      const customRte = this.customRte;
      var el = view.getChildrenContainer();

      if (customRte) {
        customRte.disable(el, rte);
      } else {
        rte && rte.disable();
      }

      hideToolbar();
      if (em) {
        em.off(eventsUp, this.updatePosition, this);
        em.trigger('rte:disable', view, rte);
      }
    },
  };
};
<commit_msg>Init default RTE<commit_after>/**
 * This module allows to customize the built-in toolbar of the Rich Text Editor and use commands from the [HTML Editing APIs](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand).
 * It's highly recommended to keep this toolbar as small as possible, especially from styling commands (eg. 'fontSize') and leave this task to the Style Manager
 *
 * You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/rich_text_editor/config/config.js)
 * ```js
 * const editor = grapesjs.init({
 *  richTextEditor: {
 *    // options
 *  }
 * })
 * ```
 *
 * Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance.
 *
 * ```js
 * // Listen to events
 * editor.on('rte:enable', () => { ... });
 *
 * // Use the API
 * const rte = editor.RichTextEditor;
 * rte.add(...);
 * ```
 *
 * ## Available Events
 * * `rte:enable` - RTE enabled. The view, on which RTE is enabled, is passed as an argument
 * * `rte:disable` - RTE disabled. The view, on which RTE is disabled, is passed as an argument
 *
 * ## Methods
 * * [add](#add)
 * * [get](#get)
 * * [getAll](#getall)
 * * [remove](#remove)
 * * [getToolbarEl](#gettoolbarel)
 *
 * @module RichTextEditor
 */

import RichTextEditor from './model/RichTextEditor';
import { on, hasWin } from 'utils/mixins';
import defaults from './config/config';

const eventsUp = 'change:canvasOffset frame:scroll component:update';

export default () => {
  let toolbar;

  const hideToolbar = () => {
    const style = toolbar.style;
    const size = '-1000px';
    style.top = size;
    style.left = size;
    style.display = 'none';
  };

  return {
    customRte: null,

    /**
     * Name of the module
     * @type {String}
     * @private
     */
    name: 'RichTextEditor',

    getConfig() {
      return this.config;
    },

    /**
     * Initialize module. Automatically called with a new instance of the editor
     * @param {Object} opts Options
     * @private
     */
    init(opts = {}) {
      const config = { ...defaults, ...opts };
      const ppfx = config.pStylePrefix;

      if (ppfx) {
        config.stylePrefix = ppfx + config.stylePrefix;
      }

      this.config = config;
      this.pfx = config.stylePrefix;
      this.em = config.em;
      this.actions = config.actions || [];
      if (!hasWin()) return this;
      toolbar = document.createElement('div');
      toolbar.className = `${ppfx}rte-toolbar ${ppfx}one-bg`;
      this.initRte(document.createElement('div'));

      //Avoid closing on toolbar clicking
      on(toolbar, 'mousedown', e => e.stopPropagation());
      return this;
    },

    destroy() {
      this.globalRte?.destroy();
      this.customRte?.destroy?.();
      toolbar = 0;
      ['actionbar', 'actions', 'em', 'config', 'globalRte', 'lastEl'].map(i => {
        delete this[i];
      });
    },

    /**
     * Post render callback
     * @param  {View} ev
     * @private
     */
    postRender(ev) {
      const canvas = ev.model.get('Canvas');
      toolbar.style.pointerEvents = 'all';
      hideToolbar();
      canvas.getToolsEl().appendChild(toolbar);
    },

    /**
     * Init the built-in RTE
     * @param  {HTMLElement} el
     * @return {RichTextEditor}
     * @private
     */
    initRte(el) {
      let { globalRte } = this;
      const { em, pfx, actionbar, config } = this;
      const actionbarContainer = toolbar;
      const actions = this.actions || [...config.actions];
      const classes = {
        actionbar: `${pfx}actionbar`,
        button: `${pfx}action`,
        active: `${pfx}active`,
        inactive: `${pfx}inactive`,
        disabled: `${pfx}disabled`,
      };

      if (!globalRte) {
        globalRte = new RichTextEditor({
          em,
          el,
          classes,
          actions,
          actionbar,
          actionbarContainer,
        });
        this.globalRte = globalRte;
      } else {
        globalRte.em = em;
        globalRte.setEl(el);
      }

      if (globalRte.actionbar) {
        this.actionbar = globalRte.actionbar;
      }

      if (globalRte.actions) {
        this.actions = globalRte.actions;
      }

      return globalRte;
    },

    /**
     * Add a new action to the built-in RTE toolbar
     * @param {string} name Action name
     * @param {Object} action Action options
     * @example
     * rte.add('bold', {
     *   icon: 'B',
     *   attributes: {title: 'Bold'},
     *   result: rte => rte.exec('bold')
     * });
     * rte.add('link', {
     *   icon: document.getElementById('t'),
     *   attributes: {title: 'Link',}
     *   // Example on it's easy to wrap a selected content
     *   result: rte => rte.insertHTML(`<a href="#">${rte.selection()}</a>`)
     * });
     * // An example with fontSize
     * rte.add('fontSize', {
     *   icon: `<select class="gjs-field">
     *         <option>1</option>
     *         <option>4</option>
     *         <option>7</option>
     *       </select>`,
     *     // Bind the 'result' on 'change' listener
     *   event: 'change',
     *   result: (rte, action) => rte.exec('fontSize', action.btn.firstChild.value),
     *   // Callback on any input change (mousedown, keydown, etc..)
     *   update: (rte, action) => {
     *     const value = rte.doc.queryCommandValue(action.name);
     *     if (value != 'false') { // value is a string
     *       action.btn.firstChild.value = value;
     *     }
     *    }
     *   })
     * // An example with state
     * const isValidAnchor = (rte) => {
     *   // a utility function to help determine if the selected is a valid anchor node
     *   const anchor = rte.selection().anchorNode;
     *   const parentNode  = anchor && anchor.parentNode;
     *   const nextSibling = anchor && anchor.nextSibling;
     *   return (parentNode && parentNode.nodeName == 'A') || (nextSibling && nextSibling.nodeName == 'A')
     * }
     * rte.add('toggleAnchor', {
     *   icon: `<span style="transform:rotate(45deg)">⫘</span>`,
     *   state: (rte, doc) => {
     *    if (rte && rte.selection()) {
     *      // `btnState` is a integer, -1 for disabled, 0 for inactive, 1 for active
     *      return isValidAnchor(rte) ? btnState.ACTIVE : btnState.INACTIVE;
     *    } else {
     *      return btnState.INACTIVE;
     *    }
     *   },
     *   result: (rte, action) => {
     *     if (isValidAnchor(rte)) {
     *       rte.exec('unlink');
     *     } else {
     *       rte.insertHTML(`<a class="link" href="">${rte.selection()}</a>`);
     *     }
     *   }
     * })
     */
    add(name, action = {}) {
      action.name = name;
      this.globalRte?.addAction(action, { sync: 1 });
    },

    /**
     * Get the action by its name
     * @param {string} name Action name
     * @return {Object}
     * @example
     * const action = rte.get('bold');
     * // {name: 'bold', ...}
     */
    get(name) {
      let result;
      this.globalRte?.getActions().forEach(action => {
        if (action.name == name) {
          result = action;
        }
      });
      return result;
    },

    /**
     * Get all actions
     * @return {Array}
     */
    getAll() {
      return this.globalRte?.getActions();
    },

    /**
     * Remove the action from the toolbar
     * @param  {string} name
     * @return {Object} Removed action
     * @example
     * const action = rte.remove('bold');
     * // {name: 'bold', ...}
     */
    remove(name) {
      const actions = this.getAll();
      const action = this.get(name);

      if (action) {
        const btn = action.btn;
        const index = actions.indexOf(action);
        btn.parentNode.removeChild(btn);
        actions.splice(index, 1);
      }

      return action;
    },

    /**
     * Get the toolbar element
     * @return {HTMLElement}
     */
    getToolbarEl() {
      return toolbar;
    },

    /**
     * Triggered when the offset of the editor is changed
     * @private
     */
    updatePosition() {
      const { em } = this;
      const un = 'px';
      const canvas = em.get('Canvas');
      const { style } = toolbar;
      const pos = canvas.getTargetToElementFixed(this.lastEl, toolbar, {
        event: 'rteToolbarPosUpdate',
        left: 0,
      });
      style.top = (pos.top || 0) + un;
      style.left = (pos.left || 0) + un;
    },

    /**
     * Enable rich text editor on the element
     * @param {View} view Component view
     * @param {Object} rte The instance of already defined RTE
     * @private
     * */
    async enable(view, rte, opts) {
      this.lastEl = view.el;
      const { customRte, em } = this;
      const el = view.getChildrenContainer();

      toolbar.style.display = '';
      const rteInst = await (customRte ? customRte.enable(el, rte) : this.initRte(el).enable(opts));

      if (em) {
        setTimeout(this.updatePosition.bind(this), 0);
        em.off(eventsUp, this.updatePosition, this);
        em.on(eventsUp, this.updatePosition, this);
        em.trigger('rte:enable', view, rteInst);
      }

      return rteInst;
    },

    /**
     * Unbind rich text editor from the element
     * @param {View} view
     * @param {Object} rte The instance of already defined RTE
     * @private
     * */
    disable(view, rte) {
      const { em } = this;
      const customRte = this.customRte;
      var el = view.getChildrenContainer();

      if (customRte) {
        customRte.disable(el, rte);
      } else {
        rte && rte.disable();
      }

      hideToolbar();
      if (em) {
        em.off(eventsUp, this.updatePosition, this);
        em.trigger('rte:disable', view, rte);
      }
    },
  };
};
<|endoftext|>


<commit_before>var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var minifyCSS = require('gulp-minify-css');
var rename = require('gulp-rename');
var bourbon = require('node-bourbon').includePaths;
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var replace = require('gulp-replace');
var plumber = require('gulp-plumber');
var notify = require("gulp-notify");
var package = require('./package.json');

var dist = './dist';
var src = './src';

gulp.task('manifest', function() {
    return gulp.src(src + 'manifest.json')
    .pipe(replace('{{package.title}}', package.title))
    .pipe(replace('{{package.description}}', package.description))
    .pipe(replace('{{package.version}}', package.version))
    .pipe(replace('{{package.author}}', package.author))
    .pipe(gulp.dest(dist))
});

gulp.task('css', function () {
    return gulp.src(src + '/stylesheets/main.scss')
    .pipe(plumber({
        errorHandler: notify.onError("Error: <%= error.message %>")
    }))
    .pipe(sass.sync({
        includePaths: bourbon
    }))
    .pipe(autoprefixer('last 2 version'))
    .pipe(replace(';', ' !important;'))
    .pipe(rename({
        basename: 'readmore-flat-theme'
    }))
    .pipe(gulp.dest(dist + '/assets/css'))
    .pipe(minifyCSS())
    .pipe(rename({
        suffix: '.min'
    }))
    .pipe(gulp.dest(dist + '/assets/css'))
});

gulp.task('js', function() {
    return gulp.src([
        src + '/javascripts/vendor/*js',
        src + '/javascripts/*.js'
    ])
    .pipe(plumber({
        errorHandler: notify.onError("Error: <%= error.message %>")
    }))
    .pipe(concat('readmore-flat-theme.js'))
    .pipe(gulp.dest(dist + '/assets/js'))
    .pipe(uglify())
    .pipe(rename({
        suffix: '.min'
    }))
    .pipe(gulp.dest(dist + '/assets/js'))
});

gulp.task('default', ['manifest', 'css', 'js'], function () {
    gulp.watch(src + 'manifest.json', ['manifest']);
    gulp.watch(src + '/stylesheets/**/*.scss', ['css']);
    gulp.watch(src + '/javascripts/**/*.js', ['js']);
});
<commit_msg>moved manifest task to bottom<commit_after>var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var minifyCSS = require('gulp-minify-css');
var rename = require('gulp-rename');
var bourbon = require('node-bourbon').includePaths;
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var replace = require('gulp-replace');
var plumber = require('gulp-plumber');
var notify = require("gulp-notify");
var package = require('./package.json');

var dist = './dist';
var src = './src';

gulp.task('css', function () {
    return gulp.src(src + '/stylesheets/main.scss')
    .pipe(plumber({
        errorHandler: notify.onError("Error: <%= error.message %>")
    }))
    .pipe(sass.sync({
        includePaths: bourbon
    }))
    .pipe(autoprefixer('last 2 version'))
    .pipe(replace(';', ' !important;'))
    .pipe(rename({
        basename: 'readmore-flat-theme'
    }))
    .pipe(gulp.dest(dist + '/assets/css'))
    .pipe(minifyCSS())
    .pipe(rename({
        suffix: '.min'
    }))
    .pipe(gulp.dest(dist + '/assets/css'))
});

gulp.task('js', function() {
    return gulp.src([
        src + '/javascripts/vendor/*js',
        src + '/javascripts/*.js'
    ])
    .pipe(plumber({
        errorHandler: notify.onError("Error: <%= error.message %>")
    }))
    .pipe(concat('readmore-flat-theme.js'))
    .pipe(gulp.dest(dist + '/assets/js'))
    .pipe(uglify())
    .pipe(rename({
        suffix: '.min'
    }))
    .pipe(gulp.dest(dist + '/assets/js'))
});

gulp.task('manifest', function() {
    return gulp.src(src + 'manifest.json')
    .pipe(replace('{{package.title}}', package.title))
    .pipe(replace('{{package.description}}', package.description))
    .pipe(replace('{{package.version}}', package.version))
    .pipe(replace('{{package.author}}', package.author))
    .pipe(gulp.dest(dist))
});

gulp.task('default', ['css', 'js', 'manifest'], function () {
    gulp.watch(src + '/stylesheets/**/*.scss', ['css']);
    gulp.watch(src + '/javascripts/**/*.js', ['js']);
    gulp.watch(src + 'manifest.json', ['manifest']);
});
<|endoftext|>