<commit_before>/** @babel */

import fs from "fs";
import path from "path";
import {promisify} from "promisificator";

export default {

	/**
	 * Remove selected files where a parent folder is also selected and group by parent folder.
	 * @param  {Object[]} cwdDirs The result of getDirectories()
	 * @return {Object} Keys will be cwds and values will be an array of files for that cwd
	 */
	consolidateFiles(cwdDirs) {
		const dirs = cwdDirs.filter(cwdFile => cwdFile.isDir).map(cwdFile => cwdFile.filePath);
		const files = {};
		cwdDirs.forEach(cwdFile => {
			const isInSelectedDir = dirs.some(dir => (cwdFile.filePath !== dir && cwdFile.filePath.startsWith(dir)));
			if (!isInSelectedDir) {
				if (!(cwdFile.cwd in files)) {
					files[cwdFile.cwd] = [];
				}
				files[cwdFile.cwd].push(cwdFile.filePath);
			}
		});
		return files;
	},

	/**
	 * Get the paths of the context target
	 * @param  {EventTarget} target The context target
	 * @return {string[]} The selected paths for the target
	 */
	getPaths(target) {
		if (!target) {
			return atom.project.getPaths();
		}

		const treeView = target.closest(".tree-view");
		if (treeView) {
			// called from treeview
			const selected = treeView.querySelectorAll(".selected > .list-item > .name, .selected > .name");
			if (selected.length > 0) {
				return [].map.call(selected, el => el.dataset.path);
			}
			return [];
		}

		const tab = target.closest(".tab-bar > .tab");
		if (tab) {
			// called from tab
			const title = tab.querySelector(".title");
			if (title && title.dataset.path) {
				return [title.dataset.path];
			}
			return [];
		}

		const paneItem = atom.workspace.getActivePaneItem();
		if (paneItem && typeof paneItem.getPath === "function") {
			// called from active pane
			return [paneItem.getPath()];
		}

		const textEditor = atom.workspace.getActiveTextEditor();
		if (textEditor && typeof textEditor.getPath === "function") {
			// fallback to activeTextEditor if activePaneItem is not a file
			return [textEditor.getPath()];
		}

		return [];
	},

	/**
	 * Get cwds of filePaths
	 * @param  {string[]} filePaths The files to check
	 * @return {Promise} {Object[]} Will resolve to {cwd, isDir, filePath}
	 */
	getDirectories(filePaths) {
		const directories = Promise.all(filePaths.map(async filePath => {
			const stats = await promisify(fs.stat)(filePath);

			let cwd;
			const isDir = stats.isDirectory();

			if (isDir) {
				cwd = filePath;
			} else {
				cwd = path.dirname(filePath);
			}

			return {
				cwd,
				isDir,
				filePath
			};
		}));

		return directories;
	},

	/**
	 * Get a list of unsaved files
	 * @param {string[]} filePaths The file paths to check for unsaved
	 * @return {string[]} Unsaved files;
	 */
	getUnsavedFiles(filePaths) {
		const unsavedTabs = document.querySelectorAll(".tab-bar > .tab.modified > .title");
		const unsavedFiles = [].map.call(unsavedTabs, el => el.dataset.path);
		return unsavedFiles.filter(file => (!!file && filePaths.some(filePath => file.startsWith(filePath))));
	},

	/**
	 * Refresh Atom git repositories
	 * @param {string|string[]} root Root directory(s) of the repo(s)
	 * @return {Promise} {void}
	 */
	async refreshAtom(root) {
		let directories;
		if (typeof root === "undefined") {
			directories = atom.project.getDirectories();
		} else {
			const roots = (
				!Array.isArray(root)
					? new Set([root.toLowerCase()])
					: new Set(root.map(r => r.toLowerCase()))
			);
			directories = atom.project.getDirectories().filter(dir => roots.has(dir.getPath().toLowerCase()));
		}
		await Promise.all(directories.map(async dir => {
			const repo = await atom.project.repositoryForDirectory(dir);
			repo.refreshStatus();
		}));
	},

	/**
	 * Get files inside directory
	 * @param  {string} dir The file paths to look for files
	 * @return {Promise} {string[]} The list of files in directory
	 */
	async getFilesInDir(dir) {
		const stats = await promisify(fs.stat)(dir);

		if (stats.isDirectory()) {
			const filePaths = await promisify(fs.readdir)(dir);

			const files = await Promise.all(filePaths.map(filePath => this.getFilesInDir(path.resolve(dir, filePath))));
			return files.reduce((prev, file) => prev.concat(file), []);
		}

		return [dir];
	},

	/**
	 * Get file statuses
	 * @param  {string[]} filePaths A list of file/folder paths
	 * @param  {Object} git git-cmd
	 * @return {Promise} {Object[]} The file statuses
	 */
	async getStatuses(filePaths, git) {
		const cwdDirs = await this.getDirectories(filePaths);

		// remove duplicates
		const cwdFiles = this.consolidateFiles(cwdDirs);
		const cwds = Object.keys(cwdFiles);

		const statuses = await Promise.all(cwds.map(cwd => git.status(cwd, cwdFiles[cwd])));

		// flatten statuses
		return statuses.reduce((prev, status) => prev.concat(status), []);
	},

	/**
	 * Get the git root directory
	 * @param  {string[]} filePaths A list of file/folder paths
	 * @param  {Object} git git-cmd
	 * @return {Promise} {string} The root directory
	 */
	async getRoot(filePaths, git) {
		if (filePaths.length === 0) {
			// eslint-disable-next-line no-param-reassign
			filePaths = atom.project.getPaths();
		}

		const cwdDirs = await this.getDirectories(filePaths);

		// remove duplicates
		const cwdFiles = this.consolidateFiles(cwdDirs);

		const rootDirs = await Promise.all(Object.keys(cwdFiles).map(cwd => git.rootDir(cwd)));
		// remove duplicates
		const roots = [...new Set(rootDirs)];
		if (roots.length > 1) {
			throw "Selected files are not in the same repository";
			// TODO: should we be able to handle this instead of throwing an error?
		}
		return roots[0];
	},

	/**
	 * Get all files associated with context files
	 * @param  {string[]} filePaths The context files
	 * @param  {Object} git git-cmd
	 * @return {Promise} {[string[], string]} Resolves to [files, root]
	 */
	async getRootAndAllFiles(filePaths, git) {

		const getFiles = await Promise.all(filePaths.map(filePath => this.getFilesInDir(filePath)));

		// flatten files
		const allFiles = getFiles.reduce((prev, file) => prev.concat(file), []);
		const files = [...new Set(allFiles)];
		const root = await this.getRoot(filePaths, git);
		return [files, root];
	},

	/**
	 * Get files git statuses associated with context files
	 * @param  {string[]} filePaths The context files
	 * @param  {Object} git git-cmd
	 * @return {Promise} {[Object[], string]} Resolves to [files, root]
	 */
	async getRootAndFilesStatuses(filePaths, git) {

		if (this.getUnsavedFiles(filePaths).length > 0) {
			throw "Save files before running git.";
		}

		const [files, root] = await Promise.all([this.getStatuses(filePaths, git), this.getRoot(filePaths, git)]);

		return [files, root];
	},

	/**
	 * Get files associated with context files
	 * @param  {string[]} filePaths The context files
	 * @param  {Object} git git-cmd
	 * @return {Promise} {[Object[], string]} Resolves to [files, root]
	 */
	async getRootAndFiles(filePaths, git) {
		const [statuses, root] = await this.getRootAndFilesStatuses(filePaths, git);
		const files = statuses.map(status => status.file);
		return [files, root];
	},

	/**
	 * Check if index.lock exists and ask the user to remove it
	 * @param  {string} root The root if the git repository
	 * @param  {integer} retry Check again after this much time (in ms) to see if the lock file still exists before showing the dialog. A falsey value means no retry.
	 * @return {Promise} {void}
	 */
	async checkGitLock(root, retry = 100) {
		const lockPath = path.resolve(root, ".git/index.lock");
		const fileExistsAsync = file => {
			return new Promise(resolve => {
				fs.access(file, err => {
					resolve(!err);
				});
			});
		};

		if (!await fileExistsAsync(lockPath)) {
			return;
		}

		if (retry) {
			const stillThere = await new Promise(resolve => {
				setTimeout(async () => {
					if (await fileExistsAsync(lockPath)) {
						resolve(true);
					}
					resolve(false);
				}, retry);
			});

			if (!stillThere) {
				return;
			}
		}

		const [confirmButton, removeLock] = await promisify(atom.confirm.bind(atom), {rejectOnError: false, alwaysReturnArray: true})({
			type: "error",
			checkboxLabel: "Remove Lock",
			checkboxChecked: true,
			message: "Another git process seems to be running in this repository, do you want to remove the lock file and continue?",
			detail: `You are deleting:\n${lockPath}`,
			buttons: [
				"Continue",
				"Cancel",
			]
		});

		if (confirmButton === 1) {
			return Promise.reject();
		}

		if (removeLock) {
			try {
				await promisify(fs.unlink)(lockPath);
			} catch (ex) {
				// if files no longer exists skip error
				if (!ex.code === "ENOENT") {
					throw ex;
				}
			}
		}
	},

	/**
	 * Reduce files to their folder if all files in that folder are selected
	 * @param  {string[]} selectedFiles The selected files to reduce
	 * @param  {string[]} allFiles All files to check for each folder
	 * @return {string[]} The list of files replaced by folders if all files in a folder are selected
	 */
	reduceFilesToCommonFolders(selectedFiles, allFiles) {
		if (selectedFiles.length === 0 || allFiles.length === 0) {
			return [];
		}

		// filter out selected files not in all files
		let reducedFiles = selectedFiles.filter(file => allFiles.includes(file));
		if (reducedFiles.length === allFiles.length) {
			if (allFiles[0].startsWith("/")) {
				return ["/"];
			}
			return ["."];
		}

		// count selected files by folder
		const selectedHash = reducedFiles.reduce((prev, file) => {
			let folder = path.dirname(file);
			while (![".", "/"].includes(folder)) {
				if (`${folder}/` in prev) {
					prev[`${folder}/`]++;
				} else {
					prev[`${folder}/`] = 1;
				}
				folder = path.dirname(folder);
			}

			return prev;
		}, {});

		// count all files by folder
		const allHash = allFiles.reduce((prev, file) => {
			let folder = path.dirname(file);
			while (![".", "/"].includes(folder)) {
				if (`${folder}/` in prev) {
					prev[`${folder}/`]++;
				} else {
					prev[`${folder}/`] = 1;
				}
				folder = path.dirname(folder);
			}

			return prev;
		}, {});

		// check each folder for all files selected
		let replaceFolders = Object.keys(selectedHash).reduce((prev, folder) => {
			if (allHash[folder] === selectedHash[folder]) {
				prev.push(folder);
			}

			return prev;
		}, []);

		// remove replaceFolders that are children of replaceFolders
		replaceFolders = replaceFolders.reduce((prev, folder) => {
			const isChildFolder = replaceFolders.some(otherFolder => {
				if (otherFolder === folder) {
					return false;
				}

				return folder.startsWith(otherFolder);
			});

			if (!isChildFolder) {
				prev.push(folder);
			}

			return prev;
		}, []);

		// remove files in replaceFolders
		reducedFiles = reducedFiles.reduce((prev, file) => {
			const shouldReplace = replaceFolders.some(folder => {
				if (file.startsWith(folder)) {
					return true;
				}
			});
			if (!shouldReplace) {
				prev.push(file);
			}
			return prev;
		}, []);

		// add replaceFolders
		reducedFiles = reducedFiles.concat(replaceFolders);

		return reducedFiles;
	},
};
<commit_msg>fix(helper): fix fs.stat in v1.41.0<commit_after>/** @babel */

import fs from "fs";
import path from "path";
import {promisify} from "promisificator";

export default {

	/**
	 * Remove selected files where a parent folder is also selected and group by parent folder.
	 * @param  {Object[]} cwdDirs The result of getDirectories()
	 * @return {Object} Keys will be cwds and values will be an array of files for that cwd
	 */
	consolidateFiles(cwdDirs) {
		const dirs = cwdDirs.filter(cwdFile => cwdFile.isDir).map(cwdFile => cwdFile.filePath);
		const files = {};
		cwdDirs.forEach(cwdFile => {
			const isInSelectedDir = dirs.some(dir => (cwdFile.filePath !== dir && cwdFile.filePath.startsWith(dir)));
			if (!isInSelectedDir) {
				if (!(cwdFile.cwd in files)) {
					files[cwdFile.cwd] = [];
				}
				files[cwdFile.cwd].push(cwdFile.filePath);
			}
		});
		return files;
	},

	/**
	 * Get the paths of the context target
	 * @param  {EventTarget} target The context target
	 * @return {string[]} The selected paths for the target
	 */
	getPaths(target) {
		if (!target) {
			return atom.project.getPaths();
		}

		const treeView = target.closest(".tree-view");
		if (treeView) {
			// called from treeview
			const selected = treeView.querySelectorAll(".selected > .list-item > .name, .selected > .name");
			if (selected.length > 0) {
				return [].map.call(selected, el => el.dataset.path);
			}
			return [];
		}

		const tab = target.closest(".tab-bar > .tab");
		if (tab) {
			// called from tab
			const title = tab.querySelector(".title");
			if (title && title.dataset.path) {
				return [title.dataset.path];
			}
			return [];
		}

		const paneItem = atom.workspace.getActivePaneItem();
		if (paneItem && typeof paneItem.getPath === "function") {
			// called from active pane
			return [paneItem.getPath()];
		}

		const textEditor = atom.workspace.getActiveTextEditor();
		if (textEditor && typeof textEditor.getPath === "function") {
			// fallback to activeTextEditor if activePaneItem is not a file
			return [textEditor.getPath()];
		}

		return [];
	},

	/**
	 * Get cwds of filePaths
	 * @param  {string[]} filePaths The files to check
	 * @return {Promise} {Object[]} Will resolve to {cwd, isDir, filePath}
	 */
	getDirectories(filePaths) {
		const directories = Promise.all(filePaths.map(async filePath => {
			const stats = await promisify(fs.stat, {callbackArg: 1})(filePath);

			let cwd;
			const isDir = stats.isDirectory();

			if (isDir) {
				cwd = filePath;
			} else {
				cwd = path.dirname(filePath);
			}

			return {
				cwd,
				isDir,
				filePath
			};
		}));

		return directories;
	},

	/**
	 * Get a list of unsaved files
	 * @param {string[]} filePaths The file paths to check for unsaved
	 * @return {string[]} Unsaved files;
	 */
	getUnsavedFiles(filePaths) {
		const unsavedTabs = document.querySelectorAll(".tab-bar > .tab.modified > .title");
		const unsavedFiles = [].map.call(unsavedTabs, el => el.dataset.path);
		return unsavedFiles.filter(file => (!!file && filePaths.some(filePath => file.startsWith(filePath))));
	},

	/**
	 * Refresh Atom git repositories
	 * @param {string|string[]} root Root directory(s) of the repo(s)
	 * @return {Promise} {void}
	 */
	async refreshAtom(root) {
		let directories;
		if (typeof root === "undefined") {
			directories = atom.project.getDirectories();
		} else {
			const roots = (
				!Array.isArray(root)
					? new Set([root.toLowerCase()])
					: new Set(root.map(r => r.toLowerCase()))
			);
			directories = atom.project.getDirectories().filter(dir => roots.has(dir.getPath().toLowerCase()));
		}
		await Promise.all(directories.map(async dir => {
			const repo = await atom.project.repositoryForDirectory(dir);
			repo.refreshStatus();
		}));
	},

	/**
	 * Get files inside directory
	 * @param  {string} dir The file paths to look for files
	 * @return {Promise} {string[]} The list of files in directory
	 */
	async getFilesInDir(dir) {
		const stats = await promisify(fs.stat, {callbackArg: 1})(dir);

		if (stats.isDirectory()) {
			const filePaths = await promisify(fs.readdir)(dir);

			const files = await Promise.all(filePaths.map(filePath => this.getFilesInDir(path.resolve(dir, filePath))));
			return files.reduce((prev, file) => prev.concat(file), []);
		}

		return [dir];
	},

	/**
	 * Get file statuses
	 * @param  {string[]} filePaths A list of file/folder paths
	 * @param  {Object} git git-cmd
	 * @return {Promise} {Object[]} The file statuses
	 */
	async getStatuses(filePaths, git) {
		const cwdDirs = await this.getDirectories(filePaths);

		// remove duplicates
		const cwdFiles = this.consolidateFiles(cwdDirs);
		const cwds = Object.keys(cwdFiles);

		const statuses = await Promise.all(cwds.map(cwd => git.status(cwd, cwdFiles[cwd])));

		// flatten statuses
		return statuses.reduce((prev, status) => prev.concat(status), []);
	},

	/**
	 * Get the git root directory
	 * @param  {string[]} filePaths A list of file/folder paths
	 * @param  {Object} git git-cmd
	 * @return {Promise} {string} The root directory
	 */
	async getRoot(filePaths, git) {
		if (filePaths.length === 0) {
			// eslint-disable-next-line no-param-reassign
			filePaths = atom.project.getPaths();
		}

		const cwdDirs = await this.getDirectories(filePaths);

		// remove duplicates
		const cwdFiles = this.consolidateFiles(cwdDirs);

		const rootDirs = await Promise.all(Object.keys(cwdFiles).map(cwd => git.rootDir(cwd)));
		// remove duplicates
		const roots = [...new Set(rootDirs)];
		if (roots.length > 1) {
			throw "Selected files are not in the same repository";
			// TODO: should we be able to handle this instead of throwing an error?
		}
		return roots[0];
	},

	/**
	 * Get all files associated with context files
	 * @param  {string[]} filePaths The context files
	 * @param  {Object} git git-cmd
	 * @return {Promise} {[string[], string]} Resolves to [files, root]
	 */
	async getRootAndAllFiles(filePaths, git) {

		const getFiles = await Promise.all(filePaths.map(filePath => this.getFilesInDir(filePath)));

		// flatten files
		const allFiles = getFiles.reduce((prev, file) => prev.concat(file), []);
		const files = [...new Set(allFiles)];
		const root = await this.getRoot(filePaths, git);
		return [files, root];
	},

	/**
	 * Get files git statuses associated with context files
	 * @param  {string[]} filePaths The context files
	 * @param  {Object} git git-cmd
	 * @return {Promise} {[Object[], string]} Resolves to [files, root]
	 */
	async getRootAndFilesStatuses(filePaths, git) {

		if (this.getUnsavedFiles(filePaths).length > 0) {
			throw "Save files before running git.";
		}

		const [files, root] = await Promise.all([this.getStatuses(filePaths, git), this.getRoot(filePaths, git)]);

		return [files, root];
	},

	/**
	 * Get files associated with context files
	 * @param  {string[]} filePaths The context files
	 * @param  {Object} git git-cmd
	 * @return {Promise} {[Object[], string]} Resolves to [files, root]
	 */
	async getRootAndFiles(filePaths, git) {
		const [statuses, root] = await this.getRootAndFilesStatuses(filePaths, git);
		const files = statuses.map(status => status.file);
		return [files, root];
	},

	/**
	 * Check if index.lock exists and ask the user to remove it
	 * @param  {string} root The root if the git repository
	 * @param  {integer} retry Check again after this much time (in ms) to see if the lock file still exists before showing the dialog. A falsey value means no retry.
	 * @return {Promise} {void}
	 */
	async checkGitLock(root, retry = 100) {
		const lockPath = path.resolve(root, ".git/index.lock");
		const fileExistsAsync = file => {
			return new Promise(resolve => {
				fs.access(file, err => {
					resolve(!err);
				});
			});
		};

		if (!await fileExistsAsync(lockPath)) {
			return;
		}

		if (retry) {
			const stillThere = await new Promise(resolve => {
				setTimeout(async () => {
					if (await fileExistsAsync(lockPath)) {
						resolve(true);
					}
					resolve(false);
				}, retry);
			});

			if (!stillThere) {
				return;
			}
		}

		const [confirmButton, removeLock] = await promisify(atom.confirm.bind(atom), {rejectOnError: false, alwaysReturnArray: true})({
			type: "error",
			checkboxLabel: "Remove Lock",
			checkboxChecked: true,
			message: "Another git process seems to be running in this repository, do you want to remove the lock file and continue?",
			detail: `You are deleting:\n${lockPath}`,
			buttons: [
				"Continue",
				"Cancel",
			]
		});

		if (confirmButton === 1) {
			return Promise.reject();
		}

		if (removeLock) {
			try {
				await promisify(fs.unlink)(lockPath);
			} catch (ex) {
				// if files no longer exists skip error
				if (!ex.code === "ENOENT") {
					throw ex;
				}
			}
		}
	},

	/**
	 * Reduce files to their folder if all files in that folder are selected
	 * @param  {string[]} selectedFiles The selected files to reduce
	 * @param  {string[]} allFiles All files to check for each folder
	 * @return {string[]} The list of files replaced by folders if all files in a folder are selected
	 */
	reduceFilesToCommonFolders(selectedFiles, allFiles) {
		if (selectedFiles.length === 0 || allFiles.length === 0) {
			return [];
		}

		// filter out selected files not in all files
		let reducedFiles = selectedFiles.filter(file => allFiles.includes(file));
		if (reducedFiles.length === allFiles.length) {
			if (allFiles[0].startsWith("/")) {
				return ["/"];
			}
			return ["."];
		}

		// count selected files by folder
		const selectedHash = reducedFiles.reduce((prev, file) => {
			let folder = path.dirname(file);
			while (![".", "/"].includes(folder)) {
				if (`${folder}/` in prev) {
					prev[`${folder}/`]++;
				} else {
					prev[`${folder}/`] = 1;
				}
				folder = path.dirname(folder);
			}

			return prev;
		}, {});

		// count all files by folder
		const allHash = allFiles.reduce((prev, file) => {
			let folder = path.dirname(file);
			while (![".", "/"].includes(folder)) {
				if (`${folder}/` in prev) {
					prev[`${folder}/`]++;
				} else {
					prev[`${folder}/`] = 1;
				}
				folder = path.dirname(folder);
			}

			return prev;
		}, {});

		// check each folder for all files selected
		let replaceFolders = Object.keys(selectedHash).reduce((prev, folder) => {
			if (allHash[folder] === selectedHash[folder]) {
				prev.push(folder);
			}

			return prev;
		}, []);

		// remove replaceFolders that are children of replaceFolders
		replaceFolders = replaceFolders.reduce((prev, folder) => {
			const isChildFolder = replaceFolders.some(otherFolder => {
				if (otherFolder === folder) {
					return false;
				}

				return folder.startsWith(otherFolder);
			});

			if (!isChildFolder) {
				prev.push(folder);
			}

			return prev;
		}, []);

		// remove files in replaceFolders
		reducedFiles = reducedFiles.reduce((prev, file) => {
			const shouldReplace = replaceFolders.some(folder => {
				if (file.startsWith(folder)) {
					return true;
				}
			});
			if (!shouldReplace) {
				prev.push(file);
			}
			return prev;
		}, []);

		// add replaceFolders
		reducedFiles = reducedFiles.concat(replaceFolders);

		return reducedFiles;
	},
};
<|endoftext|>


<commit_before>// this is all about using jade, so, yah.., jade
jade = require('jade');

// an ad-hoc minifier created with uglify
minifier = require('./uglyMinifier').minifier;

var exports = module.exports;

exports.version = '0.0.1';

// note that we use __dirname to get the directory that this source file is in
// and use that to reference to the views folder to get to our includes
exports.clientHexMapTemplate = minifier(jade.compile("include hexMapMixin\nmixin hexMap(ranks, files, width, height, defaultImageURL, boardClass, boardRowClass, boardRowEvenClass, boardRowOddClass, boardTileClass,boardFirstTileClass)", { filename: __dirname + '/../views/.', compileDebug: false, client: true }).toString());

// more to come?
exports.clientSquareMapTemplate = minifier(jade.compile("include squareMapMixin\nmixin squareMap(ranks, files, width, height, defaultImageURL, boardClass, boardRowClass, boardTileClass)", { filename: __dirname + '/../views/.', compileDebug: false, client: true }).toString());<commit_msg>export compiled templates and client-side minified templates for maps and divs containing maps<commit_after>// this is all about using jade, so, yah.., jade
jade = require('jade');

// an ad-hoc minifier created with uglify
minifier = require('./uglyMinifier').minifier;

var exports = module.exports;

exports.version = '0.0.1';

// note that we use __dirname to get the directory that this source file is in
// and use that to reference to the views folder to get to our includes

// template for creating a hex map
exports.hexMap = jade.compile("include hexMapMixin\nmixin hexMap(ranks, files, width, height, defaultImageURL, boardClass, boardRowClass, boardRowEvenClass, boardRowOddClass, boardTileClass, boardFirstTileClass)", { filename: __dirname + '/../views/.', compileDebug: false, client: true });

// client side
exports.clientHexMapTemplate = minifier(exports.hexMap.toString());

// template for creating a hex map inside of a correctly sized div
exports.hexMapDiv = jade.compile("include hexMapDivMixin\nmixin hexMapDiv(ranks, files, width, height, defaultImageURL, divClass, boardClass, boardRowClass, boardRowEvenClass, boardRowOddClass, boardTileClass, boardFirstTileClass)", { filename: __dirname + '/../views/.', compileDebug: false, client: true });

// client-side
exports.clientHexMapDivTemplate = minifier(exports.hexMapDiv.toString());

// template for creating a squares map
exports.squareMap = jade.compile("include squareMapMixin\nmixin squareMap(ranks, files, width, height, defaultImageURL, boardClass, boardRowClass, boardTileClass)", { filename: __dirname + '/../views/.', compileDebug: false, client: true });

// client-side
exports.clientSquareMapTemplate = minifier(exports.squareMap.toString());

// template for creating a squares map inside of a correctly sized div
exports.squareMapDiv = jade.compile("include squareMapDivMixin\nmixin squareMapDiv(ranks, files, width, height, defaultImageURL, divClass, boardClass, boardRowClass, boardTileClass)", { filename: __dirname + '/../views/.', compileDebug: false, client: true });

// client-side
exports.clientSquareMapDivTemplate = minifier(exports.squareMapDiv.toString());<|endoftext|>


<commit_before>import React from 'react'
import { graphql, Link } from 'gatsby'
import mediumZoom from 'medium-zoom'
import {
  Wrapper,
  Content,
  BlogContent,
  Buttons,
} from '../components/general/Utils'

import SEO from './../components/general/SEO'
import Arrow from './../components/general/Arrow'
import Hero from './../components/general/Hero'

const zoom = mediumZoom('figure div img')

zoom.toggle()

const BlogPost = ({ data, pageContext, location }) => {
  const post = data.contentfulPost
  const comments = `https://mobile.twitter.com/search?q=${encodeURIComponent(
    `https://iammatthias.com/blog/${post.slug}/`
  )}`
  const previous = pageContext.prev
  const next = pageContext.next
  return (
    <>
      <SEO
        title={post.title}
        image={post.heroImage}
        description={post.body.childMarkdownRemark.metaExcerpt}
      />
      <Wrapper>
        <Content>

{post.title}

              Published: {post.publishDate} {'// '}
              Est. {post.body.childMarkdownRemark.timeToRead} minutes to read

            <Arrow anchor={location.pathname + '#bottom'} />

        </Content>
        <BlogContent>

            <Hero image={post.heroImage} />

            <Buttons>
              {previous && (
                <Link className="button" to={`/blog/${previous.slug}/`}>
                  ← Prev Post
                </Link>
              )}
              {next && (
                <Link className="button" to={`/blog/${next.slug}/`}>
                  Next Post →
                </Link>
              )}

                Discuss on Twitter

            </Buttons>

        </BlogContent>
      </Wrapper>
    </>
  )
}

export const query = graphql`
  query($slug: String!) {
    contentfulPost(slug: { eq: $slug }) {
      title
      id
      slug
      metaDescription {
        internal {
          content
        }
      }
      publishDate(formatString: "DD MMM YYYY")
      publishDateISO: publishDate(formatString: "YYYY-MM-DD")
      tags {
        title
        id
        slug
      }
      heroImage {
        title
        fluid(maxWidth: 1600, quality: 50) {
          ...GatsbyContentfulFluid_withWebp
          src
        }
        ogimg: fluid(maxWidth: 900, quality: 50) {
          ...GatsbyContentfulFluid_withWebp
          src
        }
      }
      body {
        childMarkdownRemark {
          html
          excerpt(pruneLength: 320)
          metaExcerpt: excerpt(pruneLength: 120)
          timeToRead
        }
      }
    }
  }
`

export default BlogPost
<commit_msg>medium-zoom<commit_after>import React from 'react'
import { graphql, Link } from 'gatsby'
import mediumZoom from 'medium-zoom'
import {
  Wrapper,
  Content,
  BlogContent,
  Buttons,
} from '../components/general/Utils'

import SEO from './../components/general/SEO'
import Arrow from './../components/general/Arrow'
import Hero from './../components/general/Hero'

const zoom = mediumZoom('figure div img', { margin: 64 })

zoom.toggle()

const BlogPost = ({ data, pageContext, location }) => {
  const post = data.contentfulPost
  const comments = `https://mobile.twitter.com/search?q=${encodeURIComponent(
    `https://iammatthias.com/blog/${post.slug}/`
  )}`
  const previous = pageContext.prev
  const next = pageContext.next
  return (
    <>
      <SEO
        title={post.title}
        image={post.heroImage}
        description={post.body.childMarkdownRemark.metaExcerpt}
      />
      <Wrapper>
        <Content>

{post.title}

              Published: {post.publishDate} {'// '}
              Est. {post.body.childMarkdownRemark.timeToRead} minutes to read

            <Arrow anchor={location.pathname + '#bottom'} />

        </Content>
        <BlogContent>

            <Hero image={post.heroImage} />

            <Buttons>
              {previous && (
                <Link className="button" to={`/blog/${previous.slug}/`}>
                  ← Prev Post
                </Link>
              )}
              {next && (
                <Link className="button" to={`/blog/${next.slug}/`}>
                  Next Post →
                </Link>
              )}

                Discuss on Twitter

            </Buttons>

        </BlogContent>
      </Wrapper>
    </>
  )
}

export const query = graphql`
  query($slug: String!) {
    contentfulPost(slug: { eq: $slug }) {
      title
      id
      slug
      metaDescription {
        internal {
          content
        }
      }
      publishDate(formatString: "DD MMM YYYY")
      publishDateISO: publishDate(formatString: "YYYY-MM-DD")
      tags {
        title
        id
        slug
      }
      heroImage {
        title
        fluid(maxWidth: 1600, quality: 50) {
          ...GatsbyContentfulFluid_withWebp
          src
        }
        ogimg: fluid(maxWidth: 900, quality: 50) {
          ...GatsbyContentfulFluid_withWebp
          src
        }
      }
      body {
        childMarkdownRemark {
          html
          excerpt(pruneLength: 320)
          metaExcerpt: excerpt(pruneLength: 120)
          timeToRead
        }
      }
    }
  }
`

export default BlogPost
<|endoftext|>


<commit_before>var patt = /xml/;

module.exports = function(mimeType){
  if (!mimeType){
    return false;
  } else {
    return patt.test(mimeType);
  }
};
<commit_msg>Added comments in is-xml module<commit_after>/*
 * Copyright (c) 2015 by Greg Reimer <gregreimer@gmail.com>
 * MIT License. See mit-license.txt for more info.
 */

// TODO: This simple regex will cover many cases but
// will probably need some improvements.

var patt = /xml/;

module.exports = function(mimeType){
  if (!mimeType){
    return false;
  } else {
    return patt.test(mimeType);
  }
};
<|endoftext|>


<commit_before>/*
 * CutJS viewer for PhysicsJS
 */

Cut.PJS = function(world, options) {
  Cut.PJS.prototype._super.apply(this, arguments);

  var self = this;
  this.world = world;

  options = options || {};

  this.ratio = options.ratio || 1;

  this.lineWidth = 'lineWidth' in options ? Cut._function(options.lineWidth)
      : Cut._function(2);
  this.lineColor = 'lineColor' in options ? Cut._function(options.lineColor)
      : Cut._function('#000000');
  this.fillColor = 'fillColor' in options ? Cut._function(options.fillColor)
      : Cut._function(Cut.PJS.randomColor);

  var subscribe = world.subscribe || world.on;

  subscribe.call(world, 'add:body', function(data) {
    data.body && self.addRenderable(data.body);
  });

  subscribe.call(world, 'remove:body', function(data) {
    data.body && self.removeRenderable(data.body);
  });

  var bodies = world.getBodies();
  for (var i = 0; i < bodies.length; i++) {
    var body = bodies[i];
    this.addRenderable(body);
  }

  var time = 0;
  this.tick(function(t) {
    time += t;
    world.step(time);
    var bodies = world.getBodies();
    for (var i = 0; i < bodies.length; i++) {
      var body = bodies[i];
      if (body.view) {
        body.view.pin({
          offsetX : body.state.pos.get(0),
          offsetY : body.state.pos.get(1),
          rotation : body.state.angular.pos
        });
      }
    }
  });

};

Cut.PJS.prototype = Cut._create(Cut.prototype);
Cut.PJS.prototype._super = Cut;
Cut.PJS.prototype.constructor = Cut.PJS;

Cut.PJS.prototype.addRenderable = function(obj) {
  console.log('add');
  if (obj.view || !obj.geometry) {
    return;
  }
  var geometry = obj.geometry;
  var cutout = null;
  if ('circle' == geometry.name) {
    cutout = this.drawCircle(geometry.radius);
    // } else {
    // if (shape.points.length) {
    // cutout = this.drawConvex(shape.points);
    // }
  }
  obj.view = Cut.create().append(Cut.image(cutout).pin({
    handle : 0.5
  })).appendTo(this);
};

Cut.PJS.prototype.removeRenderable = function(obj) {
  console.log('remove');
  obj.view && obj.view.remove();
  return this;
};

Cut.PJS.prototype.drawCircle = function(radius, options) {
  options = this.options(options);
  var lineWidth = options.lineWidth, lineColor = options.lineColor, fillColor = options.fillColor;

  var width = radius * 2 + lineWidth * 2;
  var height = radius * 2 + lineWidth * 2;

  return Cut.Out.drawing(width, height, this.ratio, function(ctx, ratio) {
    ctx.scale(ratio, ratio);
    ctx.beginPath();
    ctx.arc(width / 2, height / 2, radius, 0, 2 * Math.PI);
    if (fillColor) {
      ctx.fillStyle = fillColor;
      ctx.fill();
    }

    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = lineColor;
    ctx.stroke();
  });
};

Cut.PJS.prototype.drawConvex = function(verts, options) {
  options = this.options(options);
  var lineWidth = options.lineWidth, lineColor = options.lineColor, fillColor = options.fillColor;

  if (!verts.length) {
    return;
  }

  var width = 0, height = 0;
  for (var i = 0; i < verts.length; i++) {
    var v = verts[i], x = v.x, y = v.y;
    width = Math.max(Math.abs(x), width);
    height = Math.max(Math.abs(y), height);
  }

  var cutout = Cut.Out.drawing(2 * width + 2 * lineWidth, 2 * height + 2
      * lineWidth, this.ratio, function(ctx, ratio) {
    ctx.scale(ratio, ratio);

    ctx.beginPath();
    for (var i = 0; i < verts.length; i++) {
      var v = verts[i], x = v.x + width + lineWidth, y = v.y + height
          + lineWidth;
      if (i == 0)
        ctx.moveTo(x, y);
      else
        ctx.lineTo(x, y);
    }

    if (verts.length > 2) {
      ctx.closePath();
    }

    if (fillColor) {
      ctx.fillStyle = fillColor;
      ctx.fill();
      ctx.closePath();
    }

    ctx.lineWidth = lineWidth;
    ctx.lineCap = 'round';
    ctx.strokeStyle = lineColor;
    ctx.stroke();
  });

  return cutout;
};

Cut.PJS.prototype.options = function(options) {
  options = typeof options === 'object' ? options : {};
  options.lineWidth = options.lineWidth || this.lineWidth();
  options.lineColor = options.lineColor || this.lineColor();
  options.fillColor = options.fillColor || this.fillColor();
  return options;
};

Cut.PJS.randomColor = function() {
  var red = Cut.Math.random(192, 256) | 0;
  var green = Cut.Math.random(192, 256) | 0;
  var blue = Cut.Math.random(192, 256) | 0;
  return '#' + red.toString(16) + green.toString(16) + blue.toString(16);
};<commit_msg>refactoring<commit_after>/*
 * CutJS viewer for PhysicsJS
 */

Cut.PJS = function(world, options) {
  Cut.PJS.prototype._super.apply(this, arguments);

  var self = this;
  this.world = world;

  this.options = {
    lineWidth : 2,
    lineColor : '#000000',
    fillColor : Cut.PJS.randomColor,
    ratio : 1,
    get : function(name) {
      return typeof this[name] == 'function' ? this[name]() : this[name];
    },
    merge : function(object) {
      object = typeof target === 'object' ? object : {};
      for ( var name in this) {
        object[name] = name in object ? object[name] : this[name];
      }
      return object;
    }
  }.merge(options);

  var subscribe = world.subscribe || world.on;
  subscribe.call(world, 'add:body', function(data) {
    data.body && self.addRenderable(data.body);
  });
  subscribe.call(world, 'remove:body', function(data) {
    data.body && self.removeRenderable(data.body);
  });

  var bodies = world.getBodies();
  for (var i = 0; i < bodies.length; i++) {
    var body = bodies[i];
    this.addRenderable(body);
  }

  var time = 0;
  this.tick(function(t) {
    time += t;
    world.step(time);
    var bodies = world.getBodies();
    for (var i = 0; i < bodies.length; i++) {
      var body = bodies[i];
      if (body.view) {
        body.view.pin({
          offsetX : body.state.pos.get(0),
          offsetY : body.state.pos.get(1),
          rotation : body.state.angular.pos
        });
      }
    }
  });

};

Cut.PJS.prototype = Cut._create(Cut.prototype);
Cut.PJS.prototype._super = Cut;
Cut.PJS.prototype.constructor = Cut.PJS;

Cut.PJS.prototype.addRenderable = function(obj) {
  console.log('add');
  if (obj.view || !obj.geometry) {
    return;
  }
  var geometry = obj.geometry;
  var cutout = null;
  if ('circle' == geometry.name) {
    cutout = this.drawCircle(geometry.radius);
    // } else {
    // if (shape.points.length) {
    // cutout = this.drawConvex(shape.points);
    // }
  }
  obj.view = Cut.create().append(Cut.image(cutout).pin({
    handle : 0.5
  })).appendTo(this);
};

Cut.PJS.prototype.removeRenderable = function(obj) {
  console.log('remove');
  obj.view && obj.view.remove();
  return this;
};

Cut.PJS.prototype.drawCircle = function(radius, options) {
  options = this.options.merge(options);
  var lineWidth = options.get('lineWidth'), lineColor = options
      .get('lineColor'), fillColor = options.get('fillColor');

  var width = radius * 2 + lineWidth * 2;
  var height = radius * 2 + lineWidth * 2;

  return Cut.Out.drawing(width * 1, height * 1, this.options.ratio, function(
      ctx, ratio) {
    ctx.scale(ratio, ratio);
    ctx.beginPath();
    ctx.arc(width / 2, height / 2, radius, 0, 2 * Math.PI);
    if (fillColor) {
      ctx.fillStyle = fillColor;
      ctx.fill();
    }

    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = lineColor;
    ctx.stroke();
  });
};

Cut.PJS.prototype.drawConvex = function(verts, options) {
  options = this.options.merge(options);
  var lineWidth = options.get('lineWidth'), lineColor = options
      .get('lineColor'), fillColor = options.get('fillColor');

  if (!verts.length) {
    return;
  }

  var width = 0, height = 0;
  for (var i = 0; i < verts.length; i++) {
    var v = verts[i], x = v.x, y = v.y;
    width = Math.max(Math.abs(x), width);
    height = Math.max(Math.abs(y), height);
  }

  var cutout = Cut.Out.drawing(2 * width + 2 * lineWidth, 2 * height + 2
      * lineWidth, this.options.ratio, function(ctx, ratio) {
    ctx.scale(ratio, ratio);

    ctx.beginPath();
    for (var i = 0; i < verts.length; i++) {
      var v = verts[i], x = v.x + width + lineWidth, y = v.y + height
          + lineWidth;
      if (i == 0)
        ctx.moveTo(x, y);
      else
        ctx.lineTo(x, y);
    }

    if (verts.length > 2) {
      ctx.closePath();
    }

    if (fillColor) {
      ctx.fillStyle = fillColor;
      ctx.fill();
      ctx.closePath();
    }

    ctx.lineWidth = lineWidth;
    ctx.lineCap = 'round';
    ctx.strokeStyle = lineColor;
    ctx.stroke();
  });

  return cutout;
};

Cut.PJS.randomColor = function() {
  var red = Cut.Math.random(192, 256) | 0;
  var green = Cut.Math.random(192, 256) | 0;
  var blue = Cut.Math.random(192, 256) | 0;
  return '#' + red.toString(16) + green.toString(16) + blue.toString(16);
};<|endoftext|>


<commit_before><commit_msg>small fix<commit_after><|endoftext|>


<commit_before>var SourceMapGenerator = require('source-map').SourceMapGenerator;

var lineBreak = require('os').EOL;

function SourceMapStringifier(options, restoreCallback, inputMapTracker) {
  this.keepBreaks = options.keepBreaks;
  this.restoreCallback = restoreCallback;
  this.outputMap = new SourceMapGenerator();
  this.inputMapTracker = inputMapTracker;
}

function valueRebuilder(list, store, separator) {
  for (var i = 0, l = list.length; i < l; i++) {
    store(list[i]);
    store(i < l - 1 ? separator : '');
  }
}

function rebuild(tokens, store, keepBreaks, isFlatBlock) {
  var joinCharacter = isFlatBlock ? ';' : (keepBreaks ? lineBreak : '');

  for (var i = 0, l = tokens.length; i < l; i++) {
    var token = tokens[i];

    if (token.kind === 'text' || token.kind == 'at-rule') {
      store(token);
      continue;
    }

    // FIXME: broken due to joining/splitting
    if (token.body && (token.body.length === 0 || (token.body.length == 1 && token.body[0].value === '')))
      continue;

    if (token.kind == 'block') {
      if (token.body.length > 0) {
        valueRebuilder([{ value: token.value, metadata: token.metadata }], store, '');
        store('{');
        if (token.isFlatBlock)
          valueRebuilder(token.body, store, ';');
        else
          rebuild(token.body, store, keepBreaks, false);
        store('}');
      }
    } else {
      valueRebuilder(token.value, store, ',');
      store('{');
      valueRebuilder(token.body, store, ';');
      store('}');
    }

    store(joinCharacter);
  }
}

function track(context, value, metadata) {
  if (metadata) {
    var original = context.inputMapTracker.isTracking() ?
      context.inputMapTracker.originalPositionFor(metadata) :
      {};

    context.outputMap.addMapping({
      generated: {
        line: context.line,
        column: context.column,
      },
      source: original.source || metadata.source || '__stdin__.css',
      original: {
        line: original.line || metadata.line,
        column: original.column || metadata.column
      },
      name: value
    });
  }

  var parts = value.split('\n');
  context.line += parts.length - 1;
  context.column = parts.length > 1 ? 1 : (context.column + parts.pop().length);
}

SourceMapStringifier.prototype.toString = function (tokens) {
  var self = this;
  var output = [];
  var context = {
    column: 1,
    line: 1,
    inputMapTracker: this.inputMapTracker,
    outputMap: this.outputMap
  };

  function store(token) {
    if (typeof token == 'string') {
      track(context, token);
      output.push(token);
    } else {
      var val = self.restoreCallback(token.value);
      track(context, val, token.metadata);
      output.push(val);
    }
  }

  rebuild(tokens, store, this.keepBreaks, false);

  return {
    sourceMap: this.outputMap,
    styles: output.join('').trim()
  };
};

module.exports = SourceMapStringifier;
<commit_msg>Speeds up source maps by restoring escaped content only if needed.<commit_after>var SourceMapGenerator = require('source-map').SourceMapGenerator;

var lineBreak = require('os').EOL;

function SourceMapStringifier(options, restoreCallback, inputMapTracker) {
  this.keepBreaks = options.keepBreaks;
  this.restoreCallback = restoreCallback;
  this.outputMap = new SourceMapGenerator();
  this.inputMapTracker = inputMapTracker;
}

function valueRebuilder(list, store, separator) {
  for (var i = 0, l = list.length; i < l; i++) {
    store(list[i]);
    store(i < l - 1 ? separator : '');
  }
}

function rebuild(tokens, store, keepBreaks, isFlatBlock) {
  var joinCharacter = isFlatBlock ? ';' : (keepBreaks ? lineBreak : '');

  for (var i = 0, l = tokens.length; i < l; i++) {
    var token = tokens[i];

    if (token.kind === 'text' || token.kind == 'at-rule') {
      store(token);
      continue;
    }

    // FIXME: broken due to joining/splitting
    if (token.body && (token.body.length === 0 || (token.body.length == 1 && token.body[0].value === '')))
      continue;

    if (token.kind == 'block') {
      if (token.body.length > 0) {
        valueRebuilder([{ value: token.value, metadata: token.metadata }], store, '');
        store('{');
        if (token.isFlatBlock)
          valueRebuilder(token.body, store, ';');
        else
          rebuild(token.body, store, keepBreaks, false);
        store('}');
      }
    } else {
      valueRebuilder(token.value, store, ',');
      store('{');
      valueRebuilder(token.body, store, ';');
      store('}');
    }

    store(joinCharacter);
  }
}

function track(context, value, metadata) {
  if (metadata) {
    var original = context.inputMapTracker.isTracking() ?
      context.inputMapTracker.originalPositionFor(metadata) :
      {};

    context.outputMap.addMapping({
      generated: {
        line: context.line,
        column: context.column,
      },
      source: original.source || metadata.source || '__stdin__.css',
      original: {
        line: original.line || metadata.line,
        column: original.column || metadata.column
      },
      name: value
    });
  }

  var parts = value.split('\n');
  context.line += parts.length - 1;
  context.column = parts.length > 1 ? 1 : (context.column + parts.pop().length);
}

SourceMapStringifier.prototype.toString = function (tokens) {
  var self = this;
  var output = [];
  var context = {
    column: 1,
    line: 1,
    inputMapTracker: this.inputMapTracker,
    outputMap: this.outputMap
  };

  function store(token) {
    if (typeof token == 'string') {
      track(context, token);
      output.push(token);
    } else {
      var val = token.value.indexOf('_') > -1 ?
        self.restoreCallback(token.value) :
        token.value;
      track(context, val, token.metadata);
      output.push(val);
    }
  }

  rebuild(tokens, store, this.keepBreaks, false);

  return {
    sourceMap: this.outputMap,
    styles: output.join('').trim()
  };
};

module.exports = SourceMapStringifier;
<|endoftext|>


<commit_before>var message;

var page = tabris.create("Page", {
  title: "Oceanic Flight 815 Booking",
  topLevel: true
});

var firstNameTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: 18, width: 120},
  alignment: "left",
  text: "First Name:"
}).appendTo(page);

var firstNameInput = tabris.create("TextInput", {
  layoutData: {left: [firstNameTextView, 10], right: 10, baseline: firstNameTextView},
  message: "First Name"
}).appendTo(page);

var lastNameTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [firstNameTextView, 18], width: 120},
  alignment: "left",
  text: "Last Name:"
}).appendTo(page);

var lastNameInput = tabris.create("TextInput", {
  layoutData: {left: [lastNameTextView, 10], right: 10, baseline: lastNameTextView},
  message: "Last Name"
}).appendTo(page);

var passphraseTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [lastNameTextView, 18], width: 120},
  alignment: "left",
  text: "Passphrase:"
}).appendTo(page);

tabris.create("TextInput", {
  type: "password",
  layoutData: {left: [passphraseTextView, 10], right: 10, baseline: passphraseTextView},
  message: "Passphrase"
}).appendTo(page);

var countryTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [passphraseTextView, 18], width: 120},
  alignment: "left",
  text: "Country:"
}).appendTo(page);

tabris.create("Picker", {
  layoutData: {left: [countryTextView, 10], right: 10, baseline: countryTextView},
  items: ["Germany", "Canada", "USA", "Bulgaria"],
  selectionIndex: 0
}).appendTo(page);

var classTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [countryTextView, 18], width: 120},
  alignment: "left",
  text: "Class:"
}).appendTo(page);

tabris.create("Picker", {
  layoutData: {left: [classTextView, 10], right: 10, baseline: classTextView},
  items: ["Business", "Economy", "Economy Plus"],
  selectionIndex: 0
}).appendTo(page);

var dateTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [classTextView, 18], width: 120},
  alignment: "left",
  text: "Date:"
}).appendTo(page);

var luggageTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [dateTextView, 18], width: 120},
  alignment: "left",
  text: "Luggage:"
}).appendTo(page);

var luggageWeight = tabris.create("TextView", {
  layoutData: {right: 10, baseline: luggageTextView, width: 50},
  alignment: "left",
  text: "0 Kg"
}).appendTo(page);

var luggage = tabris.create("Slider", {
  layoutData: {left: [luggageTextView, 10], right: [luggageWeight, 10], top: [dateTextView, 18]}
}).on("change:selection", function() {
  luggageWeight.set("text", this.get("selection") + " Kg");
}).appendTo(page);

var checkbox = tabris.create("CheckBox", {
  layoutData: {left: [dateTextView, 10], right: 10, top: [luggage, 10]},
  text: "Vegetarian"
}).appendTo(page);

var button = tabris.create("Button", {
  layoutData: {left: 10, right: 10, top: [checkbox, 18]},
  text: "Place Reservation",
  background: "#8b0000",
  foreground: "white"
}).on("selection", function() {
  populateMessage();
}).appendTo(page);

function populateMessage() {
  if (message) {
    message.dispose();
  }
  message = tabris.create("TextView", {
    layoutData: {left: 10, right: 10, top: [button, 10]},
    alignment: "left",
    text: "Flight booked for: " + createName() + "\n"
  }).appendTo(page);
}

function createName() {
  return [firstNameInput.get("text"), lastNameInput.get("text")].join(" ");
}

page.open();
<commit_msg>Remove "Date" label from input example<commit_after>var message;

var page = tabris.create("Page", {
  title: "Oceanic Flight 815 Booking",
  topLevel: true
});

var firstNameTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: 18, width: 120},
  alignment: "left",
  text: "First Name:"
}).appendTo(page);

var firstNameInput = tabris.create("TextInput", {
  layoutData: {left: [firstNameTextView, 10], right: 10, baseline: firstNameTextView},
  message: "First Name"
}).appendTo(page);

var lastNameTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [firstNameTextView, 18], width: 120},
  alignment: "left",
  text: "Last Name:"
}).appendTo(page);

var lastNameInput = tabris.create("TextInput", {
  layoutData: {left: [lastNameTextView, 10], right: 10, baseline: lastNameTextView},
  message: "Last Name"
}).appendTo(page);

var passphraseTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [lastNameTextView, 18], width: 120},
  alignment: "left",
  text: "Passphrase:"
}).appendTo(page);

tabris.create("TextInput", {
  type: "password",
  layoutData: {left: [passphraseTextView, 10], right: 10, baseline: passphraseTextView},
  message: "Passphrase"
}).appendTo(page);

var countryTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [passphraseTextView, 18], width: 120},
  alignment: "left",
  text: "Country:"
}).appendTo(page);

tabris.create("Picker", {
  layoutData: {left: [countryTextView, 10], right: 10, baseline: countryTextView},
  items: ["Germany", "Canada", "USA", "Bulgaria"],
  selectionIndex: 0
}).appendTo(page);

var classTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [countryTextView, 18], width: 120},
  alignment: "left",
  text: "Class:"
}).appendTo(page);

tabris.create("Picker", {
  layoutData: {left: [classTextView, 10], right: 10, baseline: classTextView},
  items: ["Business", "Economy", "Economy Plus"],
  selectionIndex: 0
}).appendTo(page);

var luggageTextView = tabris.create("TextView", {
  layoutData: {left: 10, top: [classTextView, 18], width: 120},
  alignment: "left",
  text: "Luggage:"
}).appendTo(page);

var luggageWeight = tabris.create("TextView", {
  layoutData: {right: 10, baseline: luggageTextView, width: 50},
  alignment: "left",
  text: "0 Kg"
}).appendTo(page);

var luggage = tabris.create("Slider", {
  layoutData: {left: [luggageTextView, 10], right: [luggageWeight, 10], top: [classTextView, 18]}
}).on("change:selection", function() {
  luggageWeight.set("text", this.get("selection") + " Kg");
}).appendTo(page);

var checkbox = tabris.create("CheckBox", {
  layoutData: {left: [classTextView, 10], right: 10, top: [luggage, 10]},
  text: "Vegetarian"
}).appendTo(page);

var button = tabris.create("Button", {
  layoutData: {left: 10, right: 10, top: [checkbox, 18]},
  text: "Place Reservation",
  background: "#8b0000",
  foreground: "white"
}).on("selection", function() {
  populateMessage();
}).appendTo(page);

function populateMessage() {
  if (message) {
    message.dispose();
  }
  message = tabris.create("TextView", {
    layoutData: {left: 10, right: 10, top: [button, 10]},
    alignment: "left",
    text: "Flight booked for: " + createName() + "\n"
  }).appendTo(page);
}

function createName() {
  return [firstNameInput.get("text"), lastNameInput.get("text")].join(" ");
}

page.open();
<|endoftext|>


<commit_before><commit_msg>go back to mongo binding<commit_after><|endoftext|>


<commit_before>"use strict";

var router = require("../../router.js");

var config = require("../../../shared/config.js"),
    routes = config.routes;

//handlers for routes
var httpMiddleware = require("./httpMiddleware.js");

/**
 * register dynamic-alamid-routes
 * @param {Object} server
 */
function initRoutes(server, whichRoutes) {

    whichRoutes = whichRoutes || { static : true, dynamic : true };

    var httpRouter = router.get("http")
        //applied on every request
        .add("/*", httpMiddleware.request);

    if (whichRoutes.dynamic) {
        //dynamic routes end the request themselves
        httpRouter
            .add(routes.services + "/*", httpMiddleware.serviceRequest)
            .add(routes.validators + "/*", httpMiddleware.validatorRequest);
    }

    if (whichRoutes.static) {
        httpRouter
            .add(routes.bundle + "/*", httpMiddleware.staticRequest)
            .add(routes.bundle + "/*", httpMiddleware.unhandledRequest);
    }

    //we always have a error handler for all http-request paths
    httpRouter.on("error", httpMiddleware.requestError);

    server.use(httpRouter.handler);
}

exports.initRoutes = initRoutes;<commit_msg>- fixed bundle path<commit_after>"use strict";

var router = require("../../router.js");

var config = require("../../../shared/config.js"),
    routes = config.routes;

//handlers for routes
var httpMiddleware = require("./httpMiddleware.js");

/**
 * register dynamic-alamid-routes
 * @param {Object} server
 */
function initRoutes(server, whichRoutes) {

    whichRoutes = whichRoutes || { static : true, dynamic : true };

    var httpRouter = router.get("http")
        //applied on every request
        .add("/*", httpMiddleware.request);

    if (whichRoutes.dynamic) {
        //dynamic routes end the request themselves
        httpRouter
            .add(routes.services + "/*", httpMiddleware.serviceRequest)
            .add(routes.validators + "/*", httpMiddleware.validatorRequest);
    }

    if (whichRoutes.static) {
        httpRouter
            .add(routes.bundle + "*", httpMiddleware.staticRequest)
            .add(routes.bundle + "*", httpMiddleware.unhandledRequest);
    }

    //we always have a error handler for all http-request paths
    httpRouter.on("error", httpMiddleware.requestError);

    server.use(httpRouter.handler);
}

exports.initRoutes = initRoutes;<|endoftext|>


<commit_before>'use strict'

var dgram = require('dgram')
var Q = require('q')
var winston = require('winston')

function UdpWrapper (socket) {
  this._socket = (socket === undefined) ? dgram.createSocket('udp4') : socket
}

UdpWrapper.prototype.init = function (host, port) {
  this._host = host
  this._port = port
  // store original message and error listeners, if any
  this._messageListeners = this._socket.listeners('message')
  this._errorListeners = this._socket.listeners('error')
  // temp remove these listeners ...
  var self = this
  this._messageListeners.forEach(function (callback) {
    self._socket.removeListener('message', callback)
  })
  this._errorListeners.forEach(function (callback) {
    self._socket.removeListener('error', callback)
  })
  // ... and put temp handlers in place
  this._socket.on('message', this._onMessage)
  this._socket.on('error', this._onError)
}

UdpWrapper.prototype.send = function (bytes, onSuccess, onFailure) {
  if (onSuccess === undefined || onFailure === undefined) {
    var error = '[stun-js] udp send bytes callback handlers are undefined'
    winston.error(error)
    throw new Error(error)
  }
  console.log(this._host + ':' + this._port)
  this._socket.send(bytes, 0, bytes.length, this._port, this._host, function (error) {
    if (error) {
      onFailure(error)
      return
    }
    onSuccess()
  })
}

UdpWrapper.prototype.sendP = function (bytes) {
  var deferred = Q.defer()
  var self = this
  this.send(
    bytes,
    function () { // on success
      deferred.resolve()
    },
    function (error) {
      var errorMsg = '[stun-js] udp wrapper could not send bytes to ' + self._host + ':' + self._port + '. ' + error
      winston.error(errorMsg)
      deferred.reject(errorMsg)
    }
  )
  return deferred.promise
}

UdpWrapper.prototype.release = function () {
  var self = this
  // remove temp listeners
  this._socket.listeners('message').forEach(function (callback) {
    self._socket.removeListener('message', callback)
  })
  this._socket.listeners('error').forEach(function (callback) {
    self._socket.removeListener('error', callback)
  })
  // restore the original listeners
  this._messageListeners.forEach(function (callback) {
    self._socket.on('message', callback)
  })
  this._errorListeners.forEach(function (callback) {
    self._socket.on('error', callback)
  })
  // and remove refs to these original listeners
  this._messageListeners = this._errorListeners = []
}

UdpWrapper.prototype.onMessage = function (callback) {
  this._onMessage = callback
}

UdpWrapper.prototype.onError = function (callback) {
  this._onError = callback
}

module.exports = UdpWrapper
<commit_msg>drop ref to dgram socket when releasing the wrapper<commit_after>'use strict'

var dgram = require('dgram')
var Q = require('q')
var winston = require('winston')

function UdpWrapper (socket) {
  this._socket = (socket === undefined) ? dgram.createSocket('udp4') : socket
}

UdpWrapper.prototype.init = function (host, port) {
  this._host = host
  this._port = port
  // store original message and error listeners, if any
  this._messageListeners = this._socket.listeners('message')
  this._errorListeners = this._socket.listeners('error')
  // temp remove these listeners ...
  var self = this
  this._messageListeners.forEach(function (callback) {
    self._socket.removeListener('message', callback)
  })
  this._errorListeners.forEach(function (callback) {
    self._socket.removeListener('error', callback)
  })
  // ... and put temp handlers in place
  this._socket.on('message', this._onMessage)
  this._socket.on('error', this._onError)
}

UdpWrapper.prototype.send = function (bytes, onSuccess, onFailure) {
  if (onSuccess === undefined || onFailure === undefined) {
    var error = '[stun-js] udp send bytes callback handlers are undefined'
    winston.error(error)
    throw new Error(error)
  }
  console.log(this._host + ':' + this._port)
  this._socket.send(bytes, 0, bytes.length, this._port, this._host, function (error) {
    if (error) {
      onFailure(error)
      return
    }
    onSuccess()
  })
}

UdpWrapper.prototype.sendP = function (bytes) {
  var deferred = Q.defer()
  var self = this
  this.send(
    bytes,
    function () { // on success
      deferred.resolve()
    },
    function (error) {
      var errorMsg = '[stun-js] udp wrapper could not send bytes to ' + self._host + ':' + self._port + '. ' + error
      winston.error(errorMsg)
      deferred.reject(errorMsg)
    }
  )
  return deferred.promise
}

UdpWrapper.prototype.release = function () {
  var self = this
  // remove temp listeners
  this._socket.listeners('message').forEach(function (callback) {
    self._socket.removeListener('message', callback)
  })
  this._socket.listeners('error').forEach(function (callback) {
    self._socket.removeListener('error', callback)
  })
  // restore the original listeners
  this._messageListeners.forEach(function (callback) {
    self._socket.on('message', callback)
  })
  this._errorListeners.forEach(function (callback) {
    self._socket.on('error', callback)
  })
  // and remove refs to these original listeners
  this._messageListeners = this._errorListeners = []
  // finally drop ref to this socket
  this._socket = null
}

UdpWrapper.prototype.onMessage = function (callback) {
  this._onMessage = callback
}

UdpWrapper.prototype.onError = function (callback) {
  this._onError = callback
}

module.exports = UdpWrapper
<|endoftext|>


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

  function sequoiaTreeDirective(Tree, BUTTONS){

    return {
      restrict: 'AE',
      replace: true,
      templateUrl: 'angular-sequoia.html',
      scope: {
        'treeNodes': '=sequoiaTree',
        'model': '=ngModel',
        'template': '=nodeTemplate',
        'options': '='
      },
      link: function(scope) {
        function init() {
          scope.canEdit = scope.options.canEdit ? true : false;

          scope.model = _.isArray(scope.model) ? scope.model : [];
          scope.breadcrumbs = [];

          scope.tree = new Tree(scope.treeNodes, scope.template);

          scope.buttons = {
            edit: scope.options.buttons.edit ? scope.options.buttons.edit : BUTTONS.edit,
            select: scope.options.buttons.select ? scope.options.buttons.select : BUTTONS.select,
            deselect: scope.options.buttons.deselect ? scope.options.buttons.deselect : BUTTONS.deselect,
            goToSubitems: scope.options.buttons.goToSubitems ? scope.options.buttons.goToSubitems : BUTTONS.goToSubitems,
            addSubitems: scope.options.buttons.addSubitems ? scope.options.buttons.addSubitems : BUTTONS.addSubitems,
            addNode: scope.options.buttons.addNode ? scope.options.buttons.addNode : BUTTONS.addNode,
            remove: scope.options.buttons.remove ? scope.options.buttons.remove : BUTTONS.remove,
            done: scope.options.buttons.done ? scope.options.buttons.done : BUTTONS.done,
            searchClear: scope.options.buttons.searchClear ? scope.options.buttons.searchClear : BUTTONS.searchClear,
            showSelected: scope.options.buttons.showSelected ? scope.options.buttons.showSelected : BUTTONS.showSelected,
            hideSelected: scope.options.buttons.hideSelected ? scope.options.buttons.hideSelected : BUTTONS.hideSelected,
            backToList: scope.options.buttons.backToList ? scope.options.buttons.backToList : BUTTONS.backToList
          };

          console.log(scope.buttons);
        }

        scope.load = function(node) {
          scope.onlySelected = false;
          if(scope.tree.isValidNode(node)) {
            scope.tree.setCurrentNodes(node[scope.tree.template.nodes]);
            scope.breadcrumbs = scope.tree.breadcrumbs(node[scope.tree.template.id]);
          } else {
            scope.tree.setCurrentNodes();
            scope.breadcrumbs = [];
          }
        };

        scope.select = function(node) {
          if(node[scope.tree.template.id]) {
            scope.model.push(node[scope.tree.template.id]);
          }
        };

        scope.deselect = function(node) {
          var index = node[scope.tree.template.id] ? _.indexOf(scope.model,node[scope.tree.template.id]) : -1;
          if(index !== -1) {
            scope.model.splice(index, 1);
          }
        };

        scope.isSelected = function(node) {
          return _.indexOf(scope.model, node[scope.tree.template.id]) !== -1 ? true : false;
        };

        scope.toggleSelected = function() {
          if(scope.onlySelected) {
            scope.onlySelected = false;
            scope.tree.setCurrentNodes(scope.tree.getNodesInPath());
          } else {
            scope.onlySelected = true;
            var selected = scope.tree.findSelected(scope.model);
            scope.tree.setNodesInPath(scope.tree.nodes);
            scope.tree.setCurrentNodes(selected);
          }
        };

        init();
        scope.load();

        /* Handle adding and editing nodes */
        scope.toggleEditing = function() {
          scope.isEditing = !scope.isEditing;
        };

        scope.addNode = function(node) {
          if(scope.tree.isValidNode(node)) {
            scope.load(node);
          }
          scope.options.addNode.call(scope,scope.tree.nodes);
        };

        scope.remove = function(node) {
          var index = node ? _.indexOf(scope.tree.nodes, node) : -1;
          if(index !== -1) {
            scope.tree.nodes.splice(index, 1);
          }
        };
      }
    };

  }

  sequoiaTreeDirective.$inject = ['SequoiaTree', 'BUTTONS'];

  angular.module('ngSequoia')
    .directive('sequoiaTree', sequoiaTreeDirective);

})();<commit_msg>Remove console.log #nochangelog<commit_after>(function() {
  'use strict';

  function sequoiaTreeDirective(Tree, BUTTONS){

    return {
      restrict: 'AE',
      replace: true,
      templateUrl: 'angular-sequoia.html',
      scope: {
        'treeNodes': '=sequoiaTree',
        'model': '=ngModel',
        'template': '=nodeTemplate',
        'options': '='
      },
      link: function(scope) {
        function init() {
          scope.canEdit = scope.options.canEdit ? true : false;

          scope.model = _.isArray(scope.model) ? scope.model : [];
          scope.breadcrumbs = [];

          scope.tree = new Tree(scope.treeNodes, scope.template);

          scope.buttons = {
            edit: scope.options.buttons.edit ? scope.options.buttons.edit : BUTTONS.edit,
            select: scope.options.buttons.select ? scope.options.buttons.select : BUTTONS.select,
            deselect: scope.options.buttons.deselect ? scope.options.buttons.deselect : BUTTONS.deselect,
            goToSubitems: scope.options.buttons.goToSubitems ? scope.options.buttons.goToSubitems : BUTTONS.goToSubitems,
            addSubitems: scope.options.buttons.addSubitems ? scope.options.buttons.addSubitems : BUTTONS.addSubitems,
            addNode: scope.options.buttons.addNode ? scope.options.buttons.addNode : BUTTONS.addNode,
            remove: scope.options.buttons.remove ? scope.options.buttons.remove : BUTTONS.remove,
            done: scope.options.buttons.done ? scope.options.buttons.done : BUTTONS.done,
            searchClear: scope.options.buttons.searchClear ? scope.options.buttons.searchClear : BUTTONS.searchClear,
            showSelected: scope.options.buttons.showSelected ? scope.options.buttons.showSelected : BUTTONS.showSelected,
            hideSelected: scope.options.buttons.hideSelected ? scope.options.buttons.hideSelected : BUTTONS.hideSelected,
            backToList: scope.options.buttons.backToList ? scope.options.buttons.backToList : BUTTONS.backToList
          };
        }

        scope.load = function(node) {
          scope.onlySelected = false;
          if(scope.tree.isValidNode(node)) {
            scope.tree.setCurrentNodes(node[scope.tree.template.nodes]);
            scope.breadcrumbs = scope.tree.breadcrumbs(node[scope.tree.template.id]);
          } else {
            scope.tree.setCurrentNodes();
            scope.breadcrumbs = [];
          }
        };

        scope.select = function(node) {
          if(node[scope.tree.template.id]) {
            scope.model.push(node[scope.tree.template.id]);
          }
        };

        scope.deselect = function(node) {
          var index = node[scope.tree.template.id] ? _.indexOf(scope.model,node[scope.tree.template.id]) : -1;
          if(index !== -1) {
            scope.model.splice(index, 1);
          }
        };

        scope.isSelected = function(node) {
          return _.indexOf(scope.model, node[scope.tree.template.id]) !== -1 ? true : false;
        };

        scope.toggleSelected = function() {
          if(scope.onlySelected) {
            scope.onlySelected = false;
            scope.tree.setCurrentNodes(scope.tree.getNodesInPath());
          } else {
            scope.onlySelected = true;
            var selected = scope.tree.findSelected(scope.model);
            scope.tree.setNodesInPath(scope.tree.nodes);
            scope.tree.setCurrentNodes(selected);
          }
        };

        init();
        scope.load();

        /* Handle adding and editing nodes */
        scope.toggleEditing = function() {
          scope.isEditing = !scope.isEditing;
        };

        scope.addNode = function(node) {
          if(scope.tree.isValidNode(node)) {
            scope.load(node);
          }
          scope.options.addNode.call(scope,scope.tree.nodes);
        };

        scope.remove = function(node) {
          var index = node ? _.indexOf(scope.tree.nodes, node) : -1;
          if(index !== -1) {
            scope.tree.nodes.splice(index, 1);
          }
        };
      }
    };

  }

  sequoiaTreeDirective.$inject = ['SequoiaTree', 'BUTTONS'];

  angular.module('ngSequoia')
    .directive('sequoiaTree', sequoiaTreeDirective);

})();<|endoftext|>


<commit_before>/* eslint-disable */
/* SQB
 ------------------------
 (c) 2017-present Panates
 SQB may be freely distributed under the MIT license.
 For details and documentation:
 https://panates.github.io/sqb/
 */
'use strict';

/**
 * Module dependencies.
 * @private
 */
const Operator = require('../Operator');
const Serializable = require('../../Serializable');

/**
 *
 * @class
 * @abstract
 */
class CompOperator extends Operator {

  /**
   * @param {String|Serializable} expression
   * @param {*} value...
   * @constructor
   * @public
   */
  constructor(expression, ...value) {
    super();
    this._expression = expression;
    this._values = value;
    this._symbol = '';
  }

  /**
   * Performs serialization
   *
   * @param {Object} ctx
   * @return {string}
   * @override
   */
  _serialize(ctx) {
    ctx.operatorType = this.operatorType;

    const expression = this._expression.isSerializable ?
        this._expression._serialize(ctx) : this._expression;
    const o = {
      operatorType: this.operatorType,
      expression: this._expression.isQuery ?
          '(' + expression + ')' : expression,
      symbol: this._symbol
    };

    if (this._values.length > 1) {
      o.value1 = Serializable.serializeObject(ctx, this._values[0]);
      o.value2 = Serializable.serializeObject(ctx, this._values[1]);
    } else
      o.value = Serializable.serializeObject(ctx, this._values[0]);

    this._beforeSerialize(ctx, o);

    return Serializable.serializeFallback(ctx, 'comparison', o, (_ctx, _o) => {
      return this.__serialize(_ctx || ctx, _o || o);
    });
  }

  /**
   *
   * @param {Object} ctx
   * @param {Object} o
   * @protected
   */
  _beforeSerialize(ctx, o) {
    // Do nothing
  }

  /**
   * @param {Object} ctx
   * @param {Object} o
   * @protected
   * @return {String}
   */
  __serialize /* istanbul ignore next : This is an abstract method */(ctx, o) {
    return (Array.isArray(o.expression) ?
        '(' + o.expression.join(',') + ')' : o.expression) +
        ' ' + o.symbol + ' ' + o.value;
  }

}

/**
 * Expose `CompOperator`.
 */
module.exports = CompOperator;
<commit_msg>Added getters and setters for "expression" and "values"<commit_after>/* eslint-disable */
/* SQB
 ------------------------
 (c) 2017-present Panates
 SQB may be freely distributed under the MIT license.
 For details and documentation:
 https://panates.github.io/sqb/
 */
'use strict';

/**
 * Module dependencies.
 * @private
 */
const Operator = require('../Operator');
const Serializable = require('../../Serializable');

/**
 *
 * @class
 * @abstract
 */
class CompOperator extends Operator {

  /**
   * @param {String|Serializable} expression
   * @param {*} value...
   * @constructor
   * @public
   */
  constructor(expression, ...value) {
    super();
    this._expression = expression;
    this._values = value;
    this._symbol = '';
  }

  /**
   *
   * @return {String|Serializable}
   */
  get expression() {
    return this._expression;
  }

  /**
   *
   * @param {String|Serializable} x
   */
  set expression(x) {
    this._expression = x;
  }

  /**
   *
   * @return {Array<*>}
   */
  get values() {
    return this._values;
  }

  /**
   * Performs serialization
   *
   * @param {Object} ctx
   * @return {string}
   * @override
   */
  _serialize(ctx) {
    ctx.operatorType = this.operatorType;

    const expression = this.expression.isSerializable ?
        this.expression._serialize(ctx) : this.expression;
    const o = {
      operatorType: this.operatorType,
      expression: this.expression.isQuery ?
          '(' + expression + ')' : expression,
      symbol: this._symbol
    };

    if (this.values.length > 1) {
      o.value1 = Serializable.serializeObject(ctx, this.values[0]);
      o.value2 = Serializable.serializeObject(ctx, this.values[1]);
    } else
      o.value = Serializable.serializeObject(ctx, this.values[0]);

    this._beforeSerialize(ctx, o);

    return Serializable.serializeFallback(ctx, 'comparison', o, (_ctx, _o) => {
      return this.__serialize(_ctx || ctx, _o || o);
    });
  }

  /**
   *
   * @param {Object} ctx
   * @param {Object} o
   * @protected
   */
  _beforeSerialize(ctx, o) {
    // Do nothing
  }

  /**
   * @param {Object} ctx
   * @param {Object} o
   * @protected
   * @return {String}
   */
  __serialize /* istanbul ignore next : This is an abstract method */(ctx, o) {
    return (Array.isArray(o.expression) ?
        '(' + o.expression.join(',') + ')' : o.expression) +
        ' ' + o.symbol + ' ' + o.value;
  }

}

/**
 * Expose `CompOperator`.
 */
module.exports = CompOperator;
<|endoftext|>


<commit_before>/*
 * lib/jsprim.js: utilities for primitive JavaScript types
 */

var mod_assert = require('assert');
var mod_util = require('util');

var mod_extsprintf = require('extsprintf');
var mod_verror = require('verror');
var mod_jsonschema = require('json-schema');

var mod_jsv;		/* lazy-loaded because it may not be here */

/*
 * Public interface
 */
exports.deepCopy = deepCopy;
exports.deepEqual = deepEqual;
exports.isEmpty = isEmpty;
exports.forEachKey = forEachKey;
exports.pluck = pluck;
exports.flattenObject = flattenObject;
exports.flattenIter = flattenIter;
exports.validateJsonObject = validateJsonObjectJS;
exports.validateJsonObjectJS = validateJsonObjectJS;
exports.validateJsonObjectJSV = validateJsonObjectJSV;
exports.randElt = randElt;

exports.startsWith = startsWith;
exports.endsWith = endsWith;

exports.iso8601 = iso8601;
exports.parseDateTime = parseDateTime;

/*
 * Deep copy an acyclic *basic* Javascript object.  This only handles basic
 * scalars (strings, numbers, booleans) and arbitrarily deep arrays and objects
 * containing these.  This does *not* handle instances of other classes.
 */
function deepCopy(obj)
{
	var ret, key;
	var marker = '__deepCopy';

	if (obj && obj[marker])
		throw (new Error('attempted deep copy of cyclic object'));

	if (obj && obj.constructor == Object) {
		ret = {};
		obj[marker] = true;

		for (key in obj) {
			if (key == marker)
				continue;

			ret[key] = deepCopy(obj[key]);
		}

		delete (obj[marker]);
		return (ret);
	}

	if (obj && obj.constructor == Array) {
		ret = [];
		obj[marker] = true;

		for (key = 0; key < obj.length; key++)
			ret.push(deepCopy(obj[key]));

		delete (obj[marker]);
		return (ret);
	}

	/*
	 * It must be a primitive type -- just return it.
	 */
	return (obj);
}

function deepEqual(obj1, obj2)
{
	if (typeof (obj1) != typeof (obj2))
		return (false);

	if (obj1 === null || obj2 === null || typeof (obj1) != 'object')
		return (obj1 === obj2);

	if (obj1.constructor != obj2.constructor)
		return (false);

	var k;
	for (k in obj1) {
		if (!obj2.hasOwnProperty(k))
			return (false);

		if (!deepEqual(obj1[k], obj2[k]))
			return (false);
	}

	for (k in obj2) {
		if (!obj1.hasOwnProperty(k))
			return (false);
	}

	return (true);
}

function isEmpty(obj)
{
	var key;
	for (key in obj)
		return (false);
	return (true);
}

function forEachKey(obj, callback)
{
	for (var key in obj)
		callback(key, obj[key]);
}

function pluck(obj, key)
{
	mod_assert.equal(typeof (key), 'string');
	return (pluckv(obj, key));
}

function pluckv(obj, key)
{
	if (obj === null || typeof (obj) !== 'object')
		return (undefined);

	if (obj.hasOwnProperty(key))
		return (obj[key]);

	var i = key.indexOf('.');
	if (i == -1)
		return (undefined);

	var key1 = key.substr(0, i);
	if (!obj.hasOwnProperty(key1))
		return (undefined);

	return (pluckv(obj[key1], key.substr(i + 1)));
}

/*
 * Invoke callback(row) for each entry in the array that would be returned by
 * flattenObject(data, depth).  This is just like flattenObject(data,
 * depth).forEach(callback), except that the intermediate array is never
 * created.
 */
function flattenIter(data, depth, callback)
{
	doFlattenIter(data, depth, [], callback);
}

function doFlattenIter(data, depth, accum, callback)
{
	var each;
	var key;

	if (depth === 0) {
		each = accum.slice(0);
		each.push(data);
		callback(each);
		return;
	}

	mod_assert.ok(data !== null);
	mod_assert.equal(typeof (data), 'object');
	mod_assert.equal(typeof (depth), 'number');
	mod_assert.ok(depth >= 0);

	for (key in data) {
		each = accum.slice(0);
		each.push(key);
		doFlattenIter(data[key], depth - 1, each, callback);
	}
}

function flattenObject(data, depth)
{
	if (depth === 0)
		return ([ data ]);

	mod_assert.ok(data !== null);
	mod_assert.equal(typeof (data), 'object');
	mod_assert.equal(typeof (depth), 'number');
	mod_assert.ok(depth >= 0);

	var rv = [];
	var key;

	for (key in data) {
		flattenObject(data[key], depth - 1).forEach(function (p) {
			rv.push([ key ].concat(p));
		});
	}

	return (rv);
}

function startsWith(str, prefix)
{
	return (str.substr(0, prefix.length) == prefix);
}

function endsWith(str, suffix)
{
	return (str.substr(
	    str.length - suffix.length, suffix.length) == suffix);
}

function iso8601(d)
{
	if (typeof (d) == 'number')
		d = new Date(d);
	mod_assert.ok(d.constructor === Date);
	return (mod_extsprintf.sprintf('%4d-%02d-%02dT%02d:%02d:%02d.%03dZ',
	    d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate(),
	    d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(),
	    d.getUTCMilliseconds()));
}

/*
 * Parses a date expressed as a string, as either a number of milliseconds since
 * the epoch or any string format that Date accepts, giving preference to the
 * former where these two sets overlap (e.g., small numbers).
 */
function parseDateTime(str)
{
	/*
	 * This is irritatingly implicit, but significantly more concise than
	 * alternatives.  The "+str" will convert a string containing only a
	 * number directly to a Number, or NaN for other strings.  Thus, if the
	 * conversion succeeds, we use it (this is the milliseconds-since-epoch
	 * case).  Otherwise, we pass the string directly to the Date
	 * constructor to parse.
	 */
	return (new Date(+str || str));
}

function validateJsonObjectJSV(schema, input)
{
	if (!mod_jsv)
		mod_jsv = require('jsv');

	var env = mod_jsv.JSV.createEnvironment();
	var report = env.validate(input, schema);

	if (report.errors.length === 0)
		return (null);

	/* Currently, we only do anything useful with the first error. */
	mod_assert.ok(report.errors.length > 0);
	var error = report.errors[0];

	/* The failed property is given by a URI with an irrelevant prefix. */
	var propname = error['uri'].substr(error['uri'].indexOf('#') + 2);
	var reason;

	/*
	 * Some of the default error messages are pretty arcane, so we define
	 * new ones here.
	 */
	switch (error['attribute']) {
	case 'type':
		reason = 'expected ' + error['details'];
		break;
	default:
		reason = error['message'].toLowerCase();
		break;
	}

	var message = reason + ': "' + propname + '"';
	var rv = new Error(message);
	rv.jsv_details = error;
	return (rv);
}

function validateJsonObjectJS(schema, input)
{
	var report = mod_jsonschema.validate(input, schema);

	if (report.errors.length === 0)
		return (null);

	/* Currently, we only do anything useful with the first error. */
	var error = report.errors[0];

	/* The failed property is given by a URI with an irrelevant prefix. */
	var propname = error['property'];
	var reason = error['message'].toLowerCase();
	var i, j;

	/*
	 * There's at least one case where the property error message is
	 * confusing at best.  We work around this here.
	 */
	if ((i = reason.indexOf('the property ')) != -1 &&
	    (j = reason.indexOf(' is not defined in the schema and the ' +
	    'schema does not allow additional properties')) != -1) {
		i += 'the property '.length;
		if (propname === '')
			propname = reason.substr(i, j - i);
		else
			propname = propname + '.' + reason.substr(i, j - i);

		reason = 'unsupported property';
	}

	var rv = new mod_verror.VError('property "%s": %s', propname, reason);
	rv.jsv_details = error;
	return (rv);
}

function randElt(arr)
{
	mod_assert.ok(Array.isArray(arr) && arr.length > 0,
	    'randElt argument must be a non-empty array');

	return (arr[Math.floor(Math.random() * arr.length)]);
}
<commit_msg>Fix case sensitivity of module JSV<commit_after>/*
 * lib/jsprim.js: utilities for primitive JavaScript types
 */

var mod_assert = require('assert');
var mod_util = require('util');

var mod_extsprintf = require('extsprintf');
var mod_verror = require('verror');
var mod_jsonschema = require('json-schema');

var mod_jsv;		/* lazy-loaded because it may not be here */

/*
 * Public interface
 */
exports.deepCopy = deepCopy;
exports.deepEqual = deepEqual;
exports.isEmpty = isEmpty;
exports.forEachKey = forEachKey;
exports.pluck = pluck;
exports.flattenObject = flattenObject;
exports.flattenIter = flattenIter;
exports.validateJsonObject = validateJsonObjectJS;
exports.validateJsonObjectJS = validateJsonObjectJS;
exports.validateJsonObjectJSV = validateJsonObjectJSV;
exports.randElt = randElt;

exports.startsWith = startsWith;
exports.endsWith = endsWith;

exports.iso8601 = iso8601;
exports.parseDateTime = parseDateTime;

/*
 * Deep copy an acyclic *basic* Javascript object.  This only handles basic
 * scalars (strings, numbers, booleans) and arbitrarily deep arrays and objects
 * containing these.  This does *not* handle instances of other classes.
 */
function deepCopy(obj)
{
	var ret, key;
	var marker = '__deepCopy';

	if (obj && obj[marker])
		throw (new Error('attempted deep copy of cyclic object'));

	if (obj && obj.constructor == Object) {
		ret = {};
		obj[marker] = true;

		for (key in obj) {
			if (key == marker)
				continue;

			ret[key] = deepCopy(obj[key]);
		}

		delete (obj[marker]);
		return (ret);
	}

	if (obj && obj.constructor == Array) {
		ret = [];
		obj[marker] = true;

		for (key = 0; key < obj.length; key++)
			ret.push(deepCopy(obj[key]));

		delete (obj[marker]);
		return (ret);
	}

	/*
	 * It must be a primitive type -- just return it.
	 */
	return (obj);
}

function deepEqual(obj1, obj2)
{
	if (typeof (obj1) != typeof (obj2))
		return (false);

	if (obj1 === null || obj2 === null || typeof (obj1) != 'object')
		return (obj1 === obj2);

	if (obj1.constructor != obj2.constructor)
		return (false);

	var k;
	for (k in obj1) {
		if (!obj2.hasOwnProperty(k))
			return (false);

		if (!deepEqual(obj1[k], obj2[k]))
			return (false);
	}

	for (k in obj2) {
		if (!obj1.hasOwnProperty(k))
			return (false);
	}

	return (true);
}

function isEmpty(obj)
{
	var key;
	for (key in obj)
		return (false);
	return (true);
}

function forEachKey(obj, callback)
{
	for (var key in obj)
		callback(key, obj[key]);
}

function pluck(obj, key)
{
	mod_assert.equal(typeof (key), 'string');
	return (pluckv(obj, key));
}

function pluckv(obj, key)
{
	if (obj === null || typeof (obj) !== 'object')
		return (undefined);

	if (obj.hasOwnProperty(key))
		return (obj[key]);

	var i = key.indexOf('.');
	if (i == -1)
		return (undefined);

	var key1 = key.substr(0, i);
	if (!obj.hasOwnProperty(key1))
		return (undefined);

	return (pluckv(obj[key1], key.substr(i + 1)));
}

/*
 * Invoke callback(row) for each entry in the array that would be returned by
 * flattenObject(data, depth).  This is just like flattenObject(data,
 * depth).forEach(callback), except that the intermediate array is never
 * created.
 */
function flattenIter(data, depth, callback)
{
	doFlattenIter(data, depth, [], callback);
}

function doFlattenIter(data, depth, accum, callback)
{
	var each;
	var key;

	if (depth === 0) {
		each = accum.slice(0);
		each.push(data);
		callback(each);
		return;
	}

	mod_assert.ok(data !== null);
	mod_assert.equal(typeof (data), 'object');
	mod_assert.equal(typeof (depth), 'number');
	mod_assert.ok(depth >= 0);

	for (key in data) {
		each = accum.slice(0);
		each.push(key);
		doFlattenIter(data[key], depth - 1, each, callback);
	}
}

function flattenObject(data, depth)
{
	if (depth === 0)
		return ([ data ]);

	mod_assert.ok(data !== null);
	mod_assert.equal(typeof (data), 'object');
	mod_assert.equal(typeof (depth), 'number');
	mod_assert.ok(depth >= 0);

	var rv = [];
	var key;

	for (key in data) {
		flattenObject(data[key], depth - 1).forEach(function (p) {
			rv.push([ key ].concat(p));
		});
	}

	return (rv);
}

function startsWith(str, prefix)
{
	return (str.substr(0, prefix.length) == prefix);
}

function endsWith(str, suffix)
{
	return (str.substr(
	    str.length - suffix.length, suffix.length) == suffix);
}

function iso8601(d)
{
	if (typeof (d) == 'number')
		d = new Date(d);
	mod_assert.ok(d.constructor === Date);
	return (mod_extsprintf.sprintf('%4d-%02d-%02dT%02d:%02d:%02d.%03dZ',
	    d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate(),
	    d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(),
	    d.getUTCMilliseconds()));
}

/*
 * Parses a date expressed as a string, as either a number of milliseconds since
 * the epoch or any string format that Date accepts, giving preference to the
 * former where these two sets overlap (e.g., small numbers).
 */
function parseDateTime(str)
{
	/*
	 * This is irritatingly implicit, but significantly more concise than
	 * alternatives.  The "+str" will convert a string containing only a
	 * number directly to a Number, or NaN for other strings.  Thus, if the
	 * conversion succeeds, we use it (this is the milliseconds-since-epoch
	 * case).  Otherwise, we pass the string directly to the Date
	 * constructor to parse.
	 */
	return (new Date(+str || str));
}

function validateJsonObjectJSV(schema, input)
{
	if (!mod_jsv)
		mod_jsv = require('JSV');

	var env = mod_jsv.JSV.createEnvironment();
	var report = env.validate(input, schema);

	if (report.errors.length === 0)
		return (null);

	/* Currently, we only do anything useful with the first error. */
	mod_assert.ok(report.errors.length > 0);
	var error = report.errors[0];

	/* The failed property is given by a URI with an irrelevant prefix. */
	var propname = error['uri'].substr(error['uri'].indexOf('#') + 2);
	var reason;

	/*
	 * Some of the default error messages are pretty arcane, so we define
	 * new ones here.
	 */
	switch (error['attribute']) {
	case 'type':
		reason = 'expected ' + error['details'];
		break;
	default:
		reason = error['message'].toLowerCase();
		break;
	}

	var message = reason + ': "' + propname + '"';
	var rv = new Error(message);
	rv.jsv_details = error;
	return (rv);
}

function validateJsonObjectJS(schema, input)
{
	var report = mod_jsonschema.validate(input, schema);

	if (report.errors.length === 0)
		return (null);

	/* Currently, we only do anything useful with the first error. */
	var error = report.errors[0];

	/* The failed property is given by a URI with an irrelevant prefix. */
	var propname = error['property'];
	var reason = error['message'].toLowerCase();
	var i, j;

	/*
	 * There's at least one case where the property error message is
	 * confusing at best.  We work around this here.
	 */
	if ((i = reason.indexOf('the property ')) != -1 &&
	    (j = reason.indexOf(' is not defined in the schema and the ' +
	    'schema does not allow additional properties')) != -1) {
		i += 'the property '.length;
		if (propname === '')
			propname = reason.substr(i, j - i);
		else
			propname = propname + '.' + reason.substr(i, j - i);

		reason = 'unsupported property';
	}

	var rv = new mod_verror.VError('property "%s": %s', propname, reason);
	rv.jsv_details = error;
	return (rv);
}

function randElt(arr)
{
	mod_assert.ok(Array.isArray(arr) && arr.length > 0,
	    'randElt argument must be a non-empty array');

	return (arr[Math.floor(Math.random() * arr.length)]);
}
<|endoftext|>