<commit_before>define([
	'dojo/_base/lang',
	'dojo/_base/array',
	'dojo/json',
	'dojo/when',
	'dojo/_base/declare',
	'./Store',
	'./Memory'
], function (lang, arrayUtil, JSON, when, declare, Store, Memory) {

	// module:
	//		dstore/Cache

	return declare(Store, {
		cachingStore: null,
		constructor: function (options) {
			for (var i in options) {
				// mixin the options
				this[i] = options[i];
			}
			if (!this.cachingStore) {
				this.cachingStore = new Memory();
			}
			this.cachingStore.model = this.model;
			this.cachingStore.idProperty = this.idProperty;
			this._collectionCache = {};
		},
		_tryCacheForResults: function (method, serialized, args) {
			serialized = method + ':' + serialized;

			var cacheable = !this.canCacheQuery || this.canCacheQuery(method, args);

			if (cacheable && this._collectionCache[serialized]) {
				return this._collectionCache[serialized];
			} else {
				var self = this,
					subCollection;

				if (this.allLoaded) {
					subCollection = this._createSubCollection({});

					// if we have loaded everything, we can go to the caching store
					// for quick client side querying

					// wait for it to finish loading
					subCollection.allLoaded = subCollection.data = when(this.allLoaded, function () {
						var cachingStore = self.cachingStore,
							subCachingStore = cachingStore[method].apply(cachingStore, args);
						subCollection.cachingStore = subCachingStore;

						var data = subCachingStore.fetch();
						subCollection.total = subCachingStore.total;

						return data;
					});
				} else {
					// nothing in the cache, have to use the inherited method to perform the action
					subCollection = this.inherited(args);
				}

				if (cacheable) {
					this._collectionCache[serialized] = subCollection;
				}

				return subCollection;
			}
		},
		_createSubCollection: function (kwArgs) {
			kwArgs = lang.delegate(kwArgs);
			// each sub collection should have it's own collection cache and caching store
			kwArgs._collectionCache = {};
			if (!('cachingStore' in kwArgs)) {
				kwArgs.cachingStore = new this.cachingStore.constructor();
			}
			return this.inherited(arguments, [ kwArgs ]);
		},
		sort: function (property, descending) {
			return this._tryCacheForResults('sort',
				JSON.stringify(property) + (descending ? '-' : '+'), arguments);
		},
		filter: function (query) {
			return this._tryCacheForResults('filter',
				JSON.stringify(query), arguments);
		},
		range: function (start, end) {
			return this._tryCacheForResults('range',
				start + '-' + end, arguments);
		},
		fetch: function () {
			var cachingStore = this.cachingStore;
			var store = this;
			/* jshint boss: true */
			return this.allLoaded || (this.allLoaded = when(this.inherited(arguments), function (results) {
				// store each object before calling the callback
				arrayUtil.forEach(results, function (object) {
					// store each object before calling the callback
					if (!store.isLoaded || store.isLoaded(object)) {
						cachingStore.put(object);
					}
				});

				return results;
			}));
		},
		// canCacheQuery: Function
		//		This function can be overriden to provide more specific functionality for
		// 		determining if a query should go to the master store or the caching store.
		//		This will be called with the query method (sort, filter, or range), and the
		//		arguments, and should return true or false indicating if the query is cacheable.

		// isLoaded: Function
		//		This function can be overriden to specify if individual objects can be cached
		//		(if they are a fully loaded representation, that can be cached for later retrieval through
		//		get()). This is called with an object, and can return true or false to indicate
		//		if it is fully loaded cacheable object.

		allLoaded: false,
		get: function (id, directives) {
			var cachingStore = this.cachingStore;
			var masterGet = this.getInherited(arguments);
			var masterStore = this;
			// if everything is being loaded, we always wait for that to finish
			return when(this.allLoaded, function () {
				return when(cachingStore.get(id), function (result) {
					return result || when(masterGet.call(masterStore, id, directives), function (result) {
						if (result) {
							cachingStore.put(result, {id: id});
						}
						return result;
					});
				});
			});
		},
		add: function (object, directives) {
			var cachingStore = this.cachingStore;
			return when((this.store && this.store !== this) ? // check to see if we need to delegate to store
					this.store.add(object, directives) : this.inherited(arguments), function (result) {
				// now put result in cache (note we don't do add, because add may have
				// called put() and already added it)
				cachingStore.put(object && typeof result === 'object' ? result : object, directives);
				// the result from the add should be dictated by the master store and be unaffected by the cachingStore
				return result;
			});
		},
		put: function (object, directives) {
			// first remove from the cache, so it is empty until we get a response from the master store
			var cachingStore = this.cachingStore;
			cachingStore.remove((directives && directives.id) || this.getIdentity(object));
			return when((this.store && this.store !== this) ? // check to see if we need to delegate to store
					this.store.put(object, directives) : this.inherited(arguments), function (result) {
				// now put result in cache
				cachingStore.put(object && typeof result === 'object' ? result : object, directives);
				// the result from the put should be dictated by the master store and be unaffected by the cachingStore
				return result;
			});
		},
		remove: function (id, directives) {
			var cachingStore = this.cachingStore;
			return when((this.store && this.store !== this) ? // check to see if we need to delegate to store
					this.store.remove(id, directives) : this.inherited(arguments), function (result) {
				return when(cachingStore.remove(id, directives), function () {
					return result;
				});
			});
		},
		evict: function (id) {
			return this.cachingStore.remove(id);
		}
	});
});
<commit_msg>Update cache to tolerate absence of masterStore.get for RequestMemory<commit_after>define([
	'dojo/_base/lang',
	'dojo/_base/array',
	'dojo/json',
	'dojo/when',
	'dojo/_base/declare',
	'./Store',
	'./Memory'
], function (lang, arrayUtil, JSON, when, declare, Store, Memory) {

	// module:
	//		dstore/Cache

	return declare(Store, {
		cachingStore: null,
		constructor: function (options) {
			for (var i in options) {
				// mixin the options
				this[i] = options[i];
			}
			if (!this.cachingStore) {
				this.cachingStore = new Memory();
			}
			this.cachingStore.model = this.model;
			this.cachingStore.idProperty = this.idProperty;
			this._collectionCache = {};
		},
		_tryCacheForResults: function (method, serialized, args) {
			serialized = method + ':' + serialized;

			var cacheable = !this.canCacheQuery || this.canCacheQuery(method, args);

			if (cacheable && this._collectionCache[serialized]) {
				return this._collectionCache[serialized];
			} else {
				var self = this,
					subCollection;

				if (this.allLoaded) {
					subCollection = this._createSubCollection({});

					// if we have loaded everything, we can go to the caching store
					// for quick client side querying

					// wait for it to finish loading
					subCollection.allLoaded = subCollection.data = when(this.allLoaded, function () {
						var cachingStore = self.cachingStore,
							subCachingStore = cachingStore[method].apply(cachingStore, args);
						subCollection.cachingStore = subCachingStore;

						var data = subCachingStore.fetch();
						subCollection.total = subCachingStore.total;

						return data;
					});
				} else {
					// nothing in the cache, have to use the inherited method to perform the action
					subCollection = this.inherited(args);
				}

				if (cacheable) {
					this._collectionCache[serialized] = subCollection;
				}

				return subCollection;
			}
		},
		_createSubCollection: function (kwArgs) {
			kwArgs = lang.delegate(kwArgs);
			// each sub collection should have it's own collection cache and caching store
			kwArgs._collectionCache = {};
			if (!('cachingStore' in kwArgs)) {
				kwArgs.cachingStore = new this.cachingStore.constructor();
			}
			return this.inherited(arguments, [ kwArgs ]);
		},
		sort: function (property, descending) {
			return this._tryCacheForResults('sort',
				JSON.stringify(property) + (descending ? '-' : '+'), arguments);
		},
		filter: function (query) {
			return this._tryCacheForResults('filter',
				JSON.stringify(query), arguments);
		},
		range: function (start, end) {
			return this._tryCacheForResults('range',
				start + '-' + end, arguments);
		},
		fetch: function () {
			var cachingStore = this.cachingStore;
			var store = this;
			/* jshint boss: true */
			return this.allLoaded || (this.allLoaded = when(this.inherited(arguments), function (results) {
				// store each object before calling the callback
				arrayUtil.forEach(results, function (object) {
					// store each object before calling the callback
					if (!store.isLoaded || store.isLoaded(object)) {
						cachingStore.put(object);
					}
				});

				return results;
			}));
		},
		// canCacheQuery: Function
		//		This function can be overriden to provide more specific functionality for
		// 		determining if a query should go to the master store or the caching store.
		//		This will be called with the query method (sort, filter, or range), and the
		//		arguments, and should return true or false indicating if the query is cacheable.

		// isLoaded: Function
		//		This function can be overriden to specify if individual objects can be cached
		//		(if they are a fully loaded representation, that can be cached for later retrieval through
		//		get()). This is called with an object, and can return true or false to indicate
		//		if it is fully loaded cacheable object.

		allLoaded: false,
		get: function (id, directives) {
			var cachingStore = this.cachingStore;
			var masterGet = this.getInherited(arguments);
			var masterStore = this;
			// if everything is being loaded, we always wait for that to finish
			return when(this.allLoaded, function () {
				return when(cachingStore.get(id), function (result) {
					if (result !== undefined) {
						return result;
					} else if (masterGet) {
						return when(masterGet.call(masterStore, id, directives), function (result) {
							if (result) {
								cachingStore.put(result, {id: id});
							}
							return result;
						});
					}
				});
			});
		},
		add: function (object, directives) {
			var cachingStore = this.cachingStore;
			return when((this.store && this.store !== this) ? // check to see if we need to delegate to store
					this.store.add(object, directives) : this.inherited(arguments), function (result) {
				// now put result in cache (note we don't do add, because add may have
				// called put() and already added it)
				cachingStore.put(object && typeof result === 'object' ? result : object, directives);
				// the result from the add should be dictated by the master store and be unaffected by the cachingStore
				return result;
			});
		},
		put: function (object, directives) {
			// first remove from the cache, so it is empty until we get a response from the master store
			var cachingStore = this.cachingStore;
			cachingStore.remove((directives && directives.id) || this.getIdentity(object));
			return when((this.store && this.store !== this) ? // check to see if we need to delegate to store
					this.store.put(object, directives) : this.inherited(arguments), function (result) {
				// now put result in cache
				cachingStore.put(object && typeof result === 'object' ? result : object, directives);
				// the result from the put should be dictated by the master store and be unaffected by the cachingStore
				return result;
			});
		},
		remove: function (id, directives) {
			var cachingStore = this.cachingStore;
			return when((this.store && this.store !== this) ? // check to see if we need to delegate to store
					this.store.remove(id, directives) : this.inherited(arguments), function (result) {
				return when(cachingStore.remove(id, directives), function () {
					return result;
				});
			});
		},
		evict: function (id) {
			return this.cachingStore.remove(id);
		}
	});
});
<|endoftext|>


<commit_before>import storage from '../../database/storage';
import Folder from './folder';

/**
* File Object
*
* @param {Number} fileID
* @param {String} fileName
* @param {String} filePath
*/

export default function File(fileID, fileName, filePath, parentFolder) {
  this.id = fileID;
  this.name = fileName;
  this.path = filePath;
  this.parentFolder = parentFolder;
  console.log('new File created');
}

/**
 * Remove file from the database
 *
 * @param {}
 * @return {}
 */
File.prototype.remove = function remove() {
  console.log('file.remove');
  // Case 1a: file exist, file removed
  // Case 1b: file exist, file not removed (error)
  // Case 2: file does not exist (nothing removed)

  return storage.deleteFile(this.path)
    .then(() => {
      const parentFolder = this.parentFolder;
      const index = parentFolder.childFileList.findIndex(childFile => childFile.id === this.id);
      parentFolder.childFileList.splice(index, 1);
    })
    .catch((error) => {
      throw error;
    });
};

/**
 * Save data into file
 *
 * @param {String} data
 * @return {}
 */
File.prototype.save = function save(data) {
  console.log('file.save');
  // Case 1a: file exist, file saved
  // Case 1b: file exist, file not saved (error)
  // Case 2: file does not exist (nothing saved)

  return storage.saveFile(this.id, data);
};

/**
 * Load data from file
 *
 * @param {}
 * @return {String} data loaded from file
 */
File.prototype.load = function load() {
  console.log('file.load');
  // Case 1a: file exist, file loaded
  // Case 1b: file exist, file not loaded (error)
  // Case 2: file does not exist (nothing loaded)

  return storage.loadFile(this.id);
};

/**
 * Copy file
 *
 * @param {Folder} folder default: currentFolder
 * @return {}
 */
File.prototype.copy = function copy(folder) {
  console.log('file.copy');
  // Case 1a: file exist, valid folder, file copied
  // Case 1b: file exist, invalid folder, file not copied (error)
  // Case 2: file does not exist (not copied)
  // Case 3: file exist, folder not specified, default: current folder used
};

/**
 * Move file to a specified folder
 *
 * @param {Folder} folder
 * @return {}
 */
File.prototype.move = function move() {
  console.log('file.move');
  // Changing file path
  // Case 1a: file exist, valid folder, file moved
  // Case 1b: file exist, invalid folder, file not moved (error)
  // Case 1c: file exist, folder is where file currently reside in (not moved)
  // Case 2: file does not exist (not moved)
};

/**
 * Download file from database to drive
 *
 * @param {String} fileFormat deafult: md format
 * @return {}
 */
File.prototype.download = function download() {
  console.log('file.download');
};

/**
 * Upload file from drive to database
 *
 * @param {}
 * @return {}
 */
File.prototype.upload = function upload() {
  console.log('file.upload');
};

/**
 * Rename file
 *
 * @param {String} newFileName
 * @return {}
 */
File.prototype.rename = function rename(newFileName) {
  console.log('file.rename');
  this.fileName = newFileName;
  // update database
};
<commit_msg>changed import path and removed comments<commit_after>import storage from 'src/database/storage';

/**
* File Object
*
* @param {Number} fileID
* @param {String} fileName
* @param {String} filePath
*/

export default function File(fileID, fileName, filePath, parentFolder) {
  this.id = fileID;
  this.name = fileName;
  this.path = filePath;
  this.parentFolder = parentFolder;
}

/**
 * Remove file from the database
 *
 * @param {}
 * @return {}
 */
File.prototype.remove = function remove() {
  console.log('file.remove');
  // Case 1a: file exist, file removed
  // Case 1b: file exist, file not removed (error)
  // Case 2: file does not exist (nothing removed)

  return storage.deleteFile(this.path)
    .then(() => {
      const parentFolder = this.parentFolder;
      const index = parentFolder.childFileList.findIndex(childFile => childFile.id === this.id);
      parentFolder.childFileList.splice(index, 1);
    })
    .catch((error) => {
      throw error;
    });
};

/**
 * Save data into file
 *
 * @param {String} data
 * @return {}
 */
File.prototype.save = function save(data) {
  return storage.saveFile(this.id, data);
};

/**
 * Load data from file
 *
 * @param {}
 * @return {String} data loaded from file
 */
File.prototype.load = function load() {
  return storage.loadFile(this.id);
};

/**
 * Copy file
 *
 * @param {Folder} folder default: currentFolder
 * @return {}
 */
File.prototype.copy = function copy(folder) {
  console.log('file.copy');
  // Case 1a: file exist, valid folder, file copied
  // Case 1b: file exist, invalid folder, file not copied (error)
  // Case 2: file does not exist (not copied)
  // Case 3: file exist, folder not specified, default: current folder used
};

/**
 * Move file to a specified folder
 *
 * @param {Folder} folder
 * @return {}
 */
File.prototype.move = function move() {
  console.log('file.move');
  // Changing file path
  // Case 1a: file exist, valid folder, file moved
  // Case 1b: file exist, invalid folder, file not moved (error)
  // Case 1c: file exist, folder is where file currently reside in (not moved)
  // Case 2: file does not exist (not moved)
};

/**
 * Download file from database to drive
 *
 * @param {String} fileFormat deafult: md format
 * @return {}
 */
File.prototype.download = function download() {
  console.log('file.download');
};

/**
 * Upload file from drive to database
 *
 * @param {}
 * @return {}
 */
File.prototype.upload = function upload() {
  console.log('file.upload');
};

/**
 * Rename file
 *
 * @param {String} newFileName
 * @return {}
 */
File.prototype.rename = function rename(newFileName) {
  console.log('file.rename');
  this.fileName = newFileName;
  // update database
};
<|endoftext|>


<commit_before>
/*
 * DataColumn abstracts the functionality of each column
 * of a dataset. A column has a type (text|number|date).
 *
 * API:
 *
 * column.name() ... returns the name (string)
 * column.type() ... return column type (string)
 * column.length ... number of rows (number)
 * column.val(i) ... parsed value in row i
 * column.each(func) ... apply function to each value
 * column.raw() ... access raw, unparsed values
 *
 */
dw.column = function(name, rows, type) {

    function guessType(sample) {

        if (_.every(rows, _.isNumber)) return dw.column.types.number();
        if (_.every(rows, _.isDate)) return dw.column.types.date();
        // guessing column type by counting parsing errors
        // for every known type
        var types = [
                dw.column.types.date(sample),
                dw.column.types.number(sample),
                dw.column.types.text()
            ],
            type,
            k = rows.length,
            tolerance = 0.1; // allowing 10% mis-parsed values

        _.each(rows, function(val) {
            _.each(types, function(t) {
                t.parse(val);
            });
        });
        _.every(types, function(t) {
            if (t.errors() / k < tolerance) type = t;
            return !type;
        });
        return type;
    }

    // we pick random 100 values for column type testing
    var sample = _.map(_.shuffle(_.range(rows.length)).slice(0, 200), function(i) { return rows[i]; });

    type = type ? dw.column.types[type](sample) : guessType(sample);

    var range,
        total,
        origRows = rows.slice(0);

    // public interface
    var column = {
        // column label
        name: function() {
            if (arguments.length) {
                name = arguments[0];
                return column;
            }
            return name;
        },

        /**
         * number of rows
         */
        length: rows.length,

        /**
         * returns ith row of the col, parsed
         *
         * @param i
         * @param unfiltered  if set to true, precedent calls of filterRows are ignored
         */
        val: function(i, unfiltered) {
            if (!arguments.length) return undefined;
            var r = unfiltered ? origRows : rows;
            if (i < 0) i += r.length;
            return type.parse(r[i]);
        },

        /*
         * returns an array of parsed values
         */
        values: function(unfiltered) {
            return _.map(unfiltered ? origRows : rows, type.parse);
        },

        /**
         * apply function to each value
         */
        each: function(f) {
            for (i=0; i<rows.length; i++) {
                f(column.val(i), i);
            }
        },

        // access to raw values
        raw: function(i) {
            if (!arguments.length) return rows;
            return rows[i];
        },
        // column type
        type: function(o) { return o ? type : type.name(); },
        // [min,max] range
        range: function() {
            if (!type.toNum) return false;
            if (!range) {
                range = [Number.MAX_VALUE, -Number.MAX_VALUE];
                column.each(function(v) {
                    v = type.toNum(v);
                    if (v < range[0]) range[0] = v;
                    if (v > range[1]) range[1] = v;
                });
                range[0] = type.fromNum(range[0]);
                range[1] = type.fromNum(range[1]);
            }
            return range;
        },
        // sum of values
        total: function() {
            if (!type.toNum) return false;
            if (!total) {
                total = 0;
                column.each(function(v) {
                    total += type.toNum(v);
                });
                total = type.fromNum(total);
            }
            return total;
        },
        // remove rows from column, keep those whose index
        // is within @r
        filterRows: function(r) {
            rows = [];
            if (arguments.length) {
                _.each(r, function(i) {
                    rows.push(origRows[i]);
                });
            } else {
                rows = origRows.slice(0);
            }
            column.length = rows.length;
            // invalidate range and total
            range = total = false;
            return column;
        },

        toString: function() {
            return name + ' ('+type.name()+')';
        }
    };
    return column;
};
<commit_msg>allowed changing raw values<commit_after>
/*
 * DataColumn abstracts the functionality of each column
 * of a dataset. A column has a type (text|number|date).
 *
 * API:
 *
 * column.name() ... returns the name (string)
 * column.type() ... return column type (string)
 * column.length ... number of rows (number)
 * column.val(i) ... parsed value in row i
 * column.each(func) ... apply function to each value
 * column.raw() ... access raw, unparsed values
 *
 */
dw.column = function(name, rows, type) {

    function guessType(sample) {

        if (_.every(rows, _.isNumber)) return dw.column.types.number();
        if (_.every(rows, _.isDate)) return dw.column.types.date();
        // guessing column type by counting parsing errors
        // for every known type
        var types = [
                dw.column.types.date(sample),
                dw.column.types.number(sample),
                dw.column.types.text()
            ],
            type,
            k = rows.length,
            tolerance = 0.1; // allowing 10% mis-parsed values

        _.each(rows, function(val) {
            _.each(types, function(t) {
                t.parse(val);
            });
        });
        _.every(types, function(t) {
            if (t.errors() / k < tolerance) type = t;
            return !type;
        });
        return type;
    }

    // we pick random 100 values for column type testing
    var sample = _.map(_.shuffle(_.range(rows.length)).slice(0, 200), function(i) { return rows[i]; });

    type = type ? dw.column.types[type](sample) : guessType(sample);

    var range,
        total,
        origRows = rows.slice(0);

    // public interface
    var column = {
        // column label
        name: function() {
            if (arguments.length) {
                name = arguments[0];
                return column;
            }
            return name;
        },

        /**
         * number of rows
         */
        length: rows.length,

        /**
         * returns ith row of the col, parsed
         *
         * @param i
         * @param unfiltered  if set to true, precedent calls of filterRows are ignored
         */
        val: function(i, unfiltered) {
            if (!arguments.length) return undefined;
            var r = unfiltered ? origRows : rows;
            if (i < 0) i += r.length;
            return type.parse(r[i]);
        },

        /*
         * returns an array of parsed values
         */
        values: function(unfiltered) {
            return _.map(unfiltered ? origRows : rows, type.parse);
        },

        /**
         * apply function to each value
         */
        each: function(f) {
            for (i=0; i<rows.length; i++) {
                f(column.val(i), i);
            }
        },

        // access to raw values
        raw: function(i, val) {
            if (!arguments.length) return rows;
            if (arguments.length == 2) {
                rows[i] = val;
                return column;
            }
            return rows[i];
        },
        // column type
        type: function(o) { return o ? type : type.name(); },
        // [min,max] range
        range: function() {
            if (!type.toNum) return false;
            if (!range) {
                range = [Number.MAX_VALUE, -Number.MAX_VALUE];
                column.each(function(v) {
                    v = type.toNum(v);
                    if (v < range[0]) range[0] = v;
                    if (v > range[1]) range[1] = v;
                });
                range[0] = type.fromNum(range[0]);
                range[1] = type.fromNum(range[1]);
            }
            return range;
        },
        // sum of values
        total: function() {
            if (!type.toNum) return false;
            if (!total) {
                total = 0;
                column.each(function(v) {
                    total += type.toNum(v);
                });
                total = type.fromNum(total);
            }
            return total;
        },
        // remove rows from column, keep those whose index
        // is within @r
        filterRows: function(r) {
            rows = [];
            if (arguments.length) {
                _.each(r, function(i) {
                    rows.push(origRows[i]);
                });
            } else {
                rows = origRows.slice(0);
            }
            column.length = rows.length;
            // invalidate range and total
            range = total = false;
            return column;
        },

        toString: function() {
            return name + ' ('+type.name()+')';
        }
    };
    return column;
};
<|endoftext|>


<commit_before>var utils = require('../utils');

var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');

chai.use(chaiAsPromised);
var expect = chai.expect;

describe.only('search page', function() {
    before(async function(){
        browser.get('http://localhost:9001/');

        await utils.common.waitLoader();
    });

    it('lightbox', async function() {
        await utils.common.goToFirstProject();

        $('#nav-search').click();

        let searchLb = $('div[tg-search-box]');

        await utils.lightbox.open(searchLb);

        utils.common.takeScreenshot('search', 'search-lb');

        await $('#search-text').sendKeys('create');

        searchLb.$('button[type="submit"]').click();

        await browser.waitForAngular();

        let currentUrl = await browser.getCurrentUrl();

        utils.common.takeScreenshot('search', 'usertories');

        expect(currentUrl).to.be.equal('http://localhost:9001/project/project-0/search?text=create');
    });

    describe('tabs', function() {
        it('issues', async function() {
            let option = $$('.search-filter li').get(1).$('a');
            option.click();

            utils.common.takeScreenshot('search', 'issues');

            let active = await utils.common.hasClass(option, 'active');

            expect(active).to.be.true;
        });

        it('tasks', async function() {
            let option = $$('.search-filter li').get(2).$('a');
            option.click();

            utils.common.takeScreenshot('search', 'tasks');

            let active = await utils.common.hasClass(option, 'active');

            expect(active).to.be.true;
        });

        it('wiki', async function() {
            let option = $$('.search-filter li').get(3).$('a');
            option.click();

            utils.common.takeScreenshot('search', 'wiki');

            let active = await utils.common.hasClass(option, 'active');

            expect(active).to.be.true;
        });

        it('userstories', async function() {
            let option = $$('.search-filter li').get(0).$('a');
            option.click();

            let active = await utils.common.hasClass(option, 'active');

            expect(active).to.be.true;
        });
    });

    describe('new search', function() {
        it('change current tab content on typing in the right column', async function() {
            let text = await $$('.table-main').get(0).$('a').getText();

            let searchTerm = element(by.model('searchTerm'));

            searchTerm.clear();

            await searchTerm.sendKeys(text);

            await browser.waitForAngular();

            let count = await $$('.table-main').count();

            expect(count).to.equal(1);
        });
    });
});
<commit_msg>Remove only<commit_after>var utils = require('../utils');

var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');

chai.use(chaiAsPromised);
var expect = chai.expect;

describe('search page', function() {
    before(async function(){
        browser.get('http://localhost:9001/');

        await utils.common.waitLoader();
    });

    it('lightbox', async function() {
        await utils.common.goToFirstProject();

        $('#nav-search').click();

        let searchLb = $('div[tg-search-box]');

        await utils.lightbox.open(searchLb);

        utils.common.takeScreenshot('search', 'search-lb');

        await $('#search-text').sendKeys('create');

        searchLb.$('button[type="submit"]').click();

        await browser.waitForAngular();

        let currentUrl = await browser.getCurrentUrl();

        utils.common.takeScreenshot('search', 'usertories');

        expect(currentUrl).to.be.equal('http://localhost:9001/project/project-0/search?text=create');
    });

    describe('tabs', function() {
        it('issues', async function() {
            let option = $$('.search-filter li').get(1).$('a');
            option.click();

            utils.common.takeScreenshot('search', 'issues');

            let active = await utils.common.hasClass(option, 'active');

            expect(active).to.be.true;
        });

        it('tasks', async function() {
            let option = $$('.search-filter li').get(2).$('a');
            option.click();

            utils.common.takeScreenshot('search', 'tasks');

            let active = await utils.common.hasClass(option, 'active');

            expect(active).to.be.true;
        });

        it('wiki', async function() {
            let option = $$('.search-filter li').get(3).$('a');
            option.click();

            utils.common.takeScreenshot('search', 'wiki');

            let active = await utils.common.hasClass(option, 'active');

            expect(active).to.be.true;
        });

        it('userstories', async function() {
            let option = $$('.search-filter li').get(0).$('a');
            option.click();

            let active = await utils.common.hasClass(option, 'active');

            expect(active).to.be.true;
        });
    });

    describe('new search', function() {
        it('change current tab content on typing in the right column', async function() {
            let text = await $$('.table-main').get(0).$('a').getText();

            let searchTerm = element(by.model('searchTerm'));

            searchTerm.clear();

            await searchTerm.sendKeys(text);

            await browser.waitForAngular();

            let count = await $$('.table-main').count();

            expect(count).to.equal(1);
        });
    });
});
<|endoftext|>


<commit_before>'use strict'

var mongo = require('mongojs')
var inherits = require('inherits')
var MQEmitter = require('mqemitter')
var through = require('through2')
var pump = require('pump')

function MQEmitterMongoDB (opts) {
  if (!(this instanceof MQEmitterMongoDB)) {
    return new MQEmitterMongoDB(opts)
  }

  opts = opts || {}
  opts.size = opts.size || 10 * 1024 * 1024 // 10 MB
  opts.max = opts.max || 10000 // documents
  opts.collection = opts.collection || 'pubsub'

  var conn = opts.db || opts.url || 'mongodb://127.0.0.1/mqemitter?auto_reconnect=true'

  this._opts = opts

  var that = this

  this._db = mongo(conn)
  this._collection = this._db.collection(opts.collection)
  this._started = false

  function waitStartup () {
    that._db.runCommand({ ping: 1 }, function (err, res) {
      if (that.closed) { return }

      if (err || !res.ok) {
        return setTimeout(waitStartup, 1000)
      }

      that._collection.isCapped(function (err, capped) {
        if (that.closed) { return }

        // if it errs here, the collection might not be there
        if (err || !capped) {
          // the collection is not capped, make it so
          that._collection.runCommand('convertToCapped', {
            size: opts.size,
            max: opts.max
          }, start)
        } else {
          start()
        }
      })
    })
  }

  waitStartup()

  var oldEmit = MQEmitter.prototype.emit

  this._tounlock = []

  this._lastId = new mongo.ObjectId()

  var failures = 0

  function start () {
    if (that.closed) {
      return
    }

    that._stream = that._collection.find({
      _id: { $gt: that._lastId }
    }, {}, {
      tailable: true,
      timeout: false,
      awaitData: true,
      numberOfRetries: -1
    })

    pump(that._stream, through.obj(process), function () {
      if (that._started && ++failures === 10) {
        throw new Error('Lost connection to MongoDB')
      }
      setTimeout(start, 100)
    })

    function process (obj, enc, cb) {
      if (that.closed) {
        return cb()
      }

      that._started = true
      failures = 0
      that._lastId = obj._id
      oldEmit.call(that, obj, cb)
      setImmediate(unlock)
    }
  }

  MQEmitter.call(this, opts)

  function unlock () {
    var tounlock = that._tounlock
    for (var i = 0; i < tounlock.length; i++) {
      tounlock[i]()
    }
    that._tounlock = []
  }
}

inherits(MQEmitterMongoDB, MQEmitter)

MQEmitterMongoDB.prototype.emit = function (obj, cb) {
  var err
  var tounlock = this._tounlock
  if (this.closed) {
    err = new Error('MQEmitterMongoDB is closed')
    if (cb) {
      cb(err)
    } else {
      throw err
    }
  } else {
    if (cb) {
      tounlock.push(cb)
    }

    this._collection.insert(obj, function (err) {
      var i
      if (err) {
        if (cb) {
          i = tounlock.indexOf(cb)
          tounlock.splice(i, 1)
          return cb(err)
        }
      }
    })
  }
  return this
}

MQEmitterMongoDB.prototype.close = function (cb) {
  if (this.closed) {
    return
  }

  this.closed = true

  if (this._stream) {
    this._stream.destroy()
    this._stream.on('error', function () {})
    this._stream = null
  }

  var that = this
  MQEmitter.prototype.close.call(this, function () {
    if (that._opts.db) {
      cb()
    } else {
      // force close
      that._db.close(true, cb)
    }
  })

  return this
}

module.exports = MQEmitterMongoDB
<commit_msg>create the collection if it does not exists<commit_after>'use strict'

var mongo = require('mongojs')
var inherits = require('inherits')
var MQEmitter = require('mqemitter')
var through = require('through2')
var pump = require('pump')

function MQEmitterMongoDB (opts) {
  if (!(this instanceof MQEmitterMongoDB)) {
    return new MQEmitterMongoDB(opts)
  }

  opts = opts || {}
  opts.size = opts.size || 10 * 1024 * 1024 // 10 MB
  opts.max = opts.max || 10000 // documents
  opts.collection = opts.collection || 'pubsub'

  var conn = opts.db || opts.url || 'mongodb://127.0.0.1/mqemitter?auto_reconnect=true'

  this._opts = opts

  var that = this

  this._db = mongo(conn, [
    opts.collection
  ])
  this._collection = this._db[opts.collection]
  this._started = false

  function waitStartup () {
    that._db.runCommand({ ping: 1 }, function (err, res) {
      if (that.closed) { return }

      if (err || !res.ok) {
        return setTimeout(waitStartup, 1000)
      }

      that._collection.isCapped(function (err, capped) {
        if (that.closed) { return }

        if (err) {
          // if it errs here, the collection might not exist
          that._db.createCollection(opts.collection, {
            capped: true,
            size: opts.size,
            max: opts.max
          }, start)
        } else if (!capped) {
          // the collection is not capped, make it so
          that._collection.runCommand('convertToCapped', {
            size: opts.size,
            max: opts.max
          }, start)
        } else {
          start()
        }
      })
    })
  }

  waitStartup()

  var oldEmit = MQEmitter.prototype.emit

  this._tounlock = []

  this._lastId = new mongo.ObjectId()

  var failures = 0

  function start () {
    if (that.closed) {
      return
    }

    that._stream = that._collection.find({
      _id: { $gt: that._lastId }
    }, {}, {
      tailable: true,
      timeout: false,
      awaitData: true,
      numberOfRetries: -1
    })

    pump(that._stream, through.obj(process), function () {
      if (that._started && ++failures === 10) {
        throw new Error('Lost connection to MongoDB')
      }
      setTimeout(start, 100)
    })

    function process (obj, enc, cb) {
      if (that.closed) {
        return cb()
      }

      that._started = true
      failures = 0
      that._lastId = obj._id
      oldEmit.call(that, obj, cb)
      setImmediate(unlock)
    }
  }

  MQEmitter.call(this, opts)

  function unlock () {
    var tounlock = that._tounlock
    for (var i = 0; i < tounlock.length; i++) {
      tounlock[i]()
    }
    that._tounlock = []
  }
}

inherits(MQEmitterMongoDB, MQEmitter)

MQEmitterMongoDB.prototype.emit = function (obj, cb) {
  var err
  var tounlock = this._tounlock
  if (this.closed) {
    err = new Error('MQEmitterMongoDB is closed')
    if (cb) {
      cb(err)
    } else {
      throw err
    }
  } else {
    if (cb) {
      tounlock.push(cb)
    }

    this._collection.insert(obj, function (err) {
      var i
      if (err) {
        if (cb) {
          i = tounlock.indexOf(cb)
          tounlock.splice(i, 1)
          return cb(err)
        }
      }
    })
  }
  return this
}

MQEmitterMongoDB.prototype.close = function (cb) {
  if (this.closed) {
    return
  }

  this.closed = true

  if (this._stream) {
    this._stream.destroy()
    this._stream.on('error', function () {})
    this._stream = null
  }

  var that = this
  MQEmitter.prototype.close.call(this, function () {
    if (that._opts.db) {
      cb()
    } else {
      // force close
      that._db.close(true, cb)
    }
  })

  return this
}

module.exports = MQEmitterMongoDB
<|endoftext|>


<commit_before>// $Revision$

// Left menu panel - both on the main page and the popup config-type box
Ensembl.Panel.LocalContext = Ensembl.Panel.extend({
  init: function () {
    this.base();

    this.elLk.links = $('ul.local_context li', this.el);

    $('img.toggle', this.elLk.links).bind('click', function () {
      var li = $(this).parent();

      li.toggleClass('open closed');

      this.src = '/i/' + (li.hasClass('closed') ? 'closed' : 'open') + '.gif';

      li = null;

      return false;
    });
  }
});
<commit_msg>improvements to toggling<commit_after>// $Revision$

// Left menu panel - both on the main page and the popup config-type box
Ensembl.Panel.LocalContext = Ensembl.Panel.extend({
  init: function () {
    this.base();

    this.elLk.links = $('ul.local_context li', this.el);

    $('img.toggle', this.elLk.links).bind('click', function () {
      var li  = $(this).parent();

      li.toggleClass('closed');

      this.src = this.src.replace(/closed|open/, li.hasClass('closed') ? 'closed' : 'open');

      li = null;

      return false;
    });
  }
});
<|endoftext|>


<commit_before>'use strict';

module.exports = (router, models) => {
  let Score = models.Score;
  let User = models.User;
  let jwtAuth = require(__dirname + '/../lib/jwtAuth.js');

  router.route('/users/:user/scores')
    .get(jwtAuth, (req, res) => {
      if (!Object.keys(req.query).length) {
        Score.find({userId: req.params.user}, (err, scores) => {
          if (err) {
            return res.send(err);
          }
          res.status(200).json({message: 'Returned All Scores', data: scores});
        });
      } else {
        Score.find({userId: req.params.user, category: req.query.category, difficulty: req.query.difficulty}, (err, scores) => {
          if (err) {
            return res.send(err);
          }
          res.status(200).json({message: 'Returned ScoreId', data: {scoreId: scores[0]._id}});
        });
      }
    })
    .post((req, res) => {
      let newScore = new Score(req.body);
      newScore.userId = req.params.user;
      newScore.save((err, score) => {
        if (err) {
          return res.json({message: 'Error Saving New Score', error: err});
        }
        User.findByIdAndUpdate(req.params.user, {$push: {scores: score._id}}, {new: true}, (err, user) => {
          console.log(user);
        });
        res.status(200).json({message: 'Created Score', data: score});
      });
    });

  router.route('/users/:user/scores/:score')
    .get(jwtAuth, (req, res) => {
      Score.findById(req.params.score, (err, score) => {
        if (err) {
          return res.send(err);
        }
        res.status(200).json({message: 'Returned Score', data: score});
      });
    })
    .put(jwtAuth, (req, res) => {
      Score.findByIdAndUpdate(req.params.score, req.body, {new: true}, (err, score) => {
        if (err) {
          return res.send(err);
        }
        res.status(200).json({message: 'Updated Score', data: score});
      });
    })
    .delete(jwtAuth, (req, res) => {
      Score.findByIdAndRemove(req.params.score, (err, score) => {
        res.status(200).json({message: 'Deleted Score', data: score});
      });
    });
};
<commit_msg>updated score id to return last item (most recent)<commit_after>'use strict';

module.exports = (router, models) => {
  let Score = models.Score;
  let User = models.User;
  let jwtAuth = require(__dirname + '/../lib/jwtAuth.js');

  router.route('/users/:user/scores')
    .get(jwtAuth, (req, res) => {
      if (!Object.keys(req.query).length) {
        Score.find({userId: req.params.user}, (err, scores) => {
          if (err) {
            return res.send(err);
          }
          res.status(200).json({message: 'Returned All Scores', data: scores});
        });
      } else {
        Score.find({userId: req.params.user, category: req.query.category, difficulty: req.query.difficulty}, (err, scores) => {
          if (err) {
            return res.send(err);
          }
          res.status(200).json({message: 'Returned ScoreId', data: {scoreId: scores[scores.length-1]._id}});
        });
      }
    })
    .post((req, res) => {
      let newScore = new Score(req.body);
      newScore.userId = req.params.user;
      newScore.save((err, score) => {
        if (err) {
          return res.json({message: 'Error Saving New Score', error: err});
        }
        User.findByIdAndUpdate(req.params.user, {$push: {scores: score._id}}, {new: true}, (err, user) => {
          console.log(user);
        });
        res.status(200).json({message: 'Created Score', data: score});
      });
    });

  router.route('/users/:user/scores/:score')
    .get(jwtAuth, (req, res) => {
      Score.findById(req.params.score, (err, score) => {
        if (err) {
          return res.send(err);
        }
        res.status(200).json({message: 'Returned Score', data: score});
      });
    })
    .put(jwtAuth, (req, res) => {
      Score.findByIdAndUpdate(req.params.score, req.body, {new: true}, (err, score) => {
        if (err) {
          return res.send(err);
        }
        res.status(200).json({message: 'Updated Score', data: score});
      });
    })
    .delete(jwtAuth, (req, res) => {
      Score.findByIdAndRemove(req.params.score, (err, score) => {
        res.status(200).json({message: 'Deleted Score', data: score});
      });
    });
};
<|endoftext|>


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

  module('Node');

  test('constructor and getters', function() {
    var node1 = DivSugar.createNode('node1');
    strictEqual(node1.id, 'node1');
    strictEqual(node1.getWidth(), 0);
    strictEqual(node1.getHeight(), 0);
    strictEqual(node1.getPositionX(), 0);
    strictEqual(node1.getPositionY(), 0);
    strictEqual(node1.getPositionZ(), 0);
    strictEqual(node1.getVisible(), true);
    strictEqual(node1.getBackface(), true);
    strictEqual(node1.getClip(), false);
    strictEqual(node1.getOpacity(), 1);
    strictEqual(node1.getImage(), null);
    strictEqual(node1.getImageClipU1(), 0);
    strictEqual(node1.getImageClipV1(), 0);
    strictEqual(node1.getImageClipU2(), 1);
    strictEqual(node1.getImageClipV2(), 1);
  });

  test('getPosition', function() {
    var node1 = DivSugar.createNode();
    var vec1 = new DivSugar.Vector(1, 2, 3);
    node1.getPosition(vec1);
    deepEqual(vec1, DivSugar.Vector.ZERO);

    ok(node1.getPosition(vec1).getPosition(vec1));
  });

  test('getTransform', function() {
    var node1 = DivSugar.createNode();
    var mat1 = new DivSugar.Matrix(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
    node1.getTransform(mat1);
    deepEqual(mat1, DivSugar.Matrix.UNIT);

    ok(node1.getTransform(mat1).getTransform(mat1));
  });

  test('setSize', function() {
    var node1 = DivSugar.createNode();
    node1.setSize(10, 20);
    strictEqual(node1.getWidth(), 10);
    strictEqual(node1.getHeight(), 20);

    ok(node1.setSize(1, 1).setSize(1, 1));
  });

  test('setPosition', function() {
    var node1 = DivSugar.createNode();
    var vec1 = new DivSugar.Vector(40, 50, 60);

    node1.setPosition(10, 20, 30);
    strictEqual(node1.getPositionX(), 10);
    strictEqual(node1.getPositionY(), 20);
    strictEqual(node1.getPositionZ(), 30);

    node1.setPosition(vec1);
    strictEqual(node1.getPositionX(), 40);
    strictEqual(node1.getPositionY(), 50);
    strictEqual(node1.getPositionZ(), 60);

    ok(node1.setPosition(0, 0, 0).setPosition(vec1).setPosition(1, 1, 1));
  });

  test('setTransform', function() {
    var node1 = DivSugar.createNode();
    var mat1 = new DivSugar.Matrix(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
    var mat2 = new DivSugar.Matrix();
    node1.setTransform(mat1);
    node1.getTransform(mat2);
    deepEqual(mat2, mat1);

    ok(node1.setTransform(mat1).setTransform(mat1));
  });

  test('setVisible', function() {
    var node1 = DivSugar.createNode();
    node1.setVisible(false);
    strictEqual(node1.getVisible(), false);

    ok(node1.setVisible(true).setVisible(true));
  });

  test('setBackface', function() {
    var node1 = DivSugar.createNode();
    node1.setBackface(false);
    strictEqual(node1.getBackface(), false);

    ok(node1.setBackface(true).setBackface(true));
  });

  test('setClip', function() {
    var node1 = DivSugar.createNode();
    node1.setClip(true);
    strictEqual(node1.getClip(), true);

    ok(node1.setClip(true).setClip(true));
  });

  test('setOpacity', function() {
    var node1 = DivSugar.createNode();
    node1.setOpacity(0.5);
    strictEqual(node1.getOpacity(), 0.5);

    ok(node1.setOpacity(0).setOpacity(0));
  });

  test('setImage', function() {
    var node1 = DivSugar.createNode();

    node1.setImage('../examples/assets/coin.png');
    strictEqual(node1.getImage(), '../examples/assets/coin.png');

    node1.setImage('../examples/assets/coin.png', function(width, height) {
      start();
      strictEqual(width, 400);
      strictEqual(height, 200);
    });
    stop();

    ok(node1.setImage(null).setImage(null));
  });

  test('setImageClip', function() {
    var node1 = DivSugar.createNode();

    node1.setImageClip(0.1, 0.2, 0.3, 0.4);
    strictEqual(node1.getImageClipU1(), 0.1);
    strictEqual(node1.getImageClipV1(), 0.2);
    strictEqual(node1.getImageClipU2(), 0.3);
    strictEqual(node1.getImageClipV2(), 0.4);

    node1.setImageClip(-1, -2, -3, -4);
    strictEqual(node1.getImageClipU1(), 0);
    strictEqual(node1.getImageClipV1(), 0);
    strictEqual(node1.getImageClipU2(), 0);
    strictEqual(node1.getImageClipV2(), 0);

    node1.setImageClip(2, 3, 4, 5);
    strictEqual(node1.getImageClipU1(), 1);
    strictEqual(node1.getImageClipV1(), 1);
    strictEqual(node1.getImageClipU2(), 1);
    strictEqual(node1.getImageClipV2(), 1);

    ok(node1.setImageClip(0, 0, 0, 0).setImageClip(0, 0, 0, 0));
  });

  test('translate', function() {
    var node1 = DivSugar.createNode();
    var mat1 = new DivSugar.Matrix();
    var mat2 = new DivSugar.Matrix();
    node1.setTransform(mat1);
    node1.translate(10, 20, 30);
    mat1.translate(10, 20, 30);
    node1.getTransform(mat2);
    deepEqual(mat2, mat1);

    ok(node1.translate(0, 0, 0).translate(0, 0, 0));
  });

  test('rotate', function() {
    var node1 = DivSugar.createNode();
    var mat1 = new DivSugar.Matrix();
    var mat2 = new DivSugar.Matrix();

    node1.setTransform(mat1);
    node1.rotate(90, 0, 0);
    mat1.rotate(90, 0, 0);
    node1.getTransform(mat2);
    nearlyEqual(mat2, mat1);

    node1.setTransform(mat1);
    node1.rotate(0, 90, 0);
    mat1.rotate(0, 90, 0);
    node1.getTransform(mat2);
    nearlyEqual(mat2, mat1);

    node1.setTransform(mat1);
    node1.rotate(0, 0, 90);
    mat1.rotate(0, 0, 90);
    node1.getTransform(mat2);
    nearlyEqual(mat2, mat1);

    ok(node1.rotate(0, 0, 0).rotate(0, 0, 0));
  });

  test('scale', function() {
    var node1 = DivSugar.createNode();
    var mat1 = new DivSugar.Matrix();
    var mat2 = new DivSugar.Matrix();
    node1.setTransform(mat1);
    node1.scale(10, 20, 30);
    mat1.scale(10, 20, 30);
    node1.getTransform(mat2);
    deepEqual(mat2, mat1);

    ok(node1.scale(1, 1, 1).scale(1, 1, 1));
  });

  test('playAnimation', function() {
    var callCount = 0;
    var mat1 = new DivSugar.Matrix();
    var node1 = DivSugar.createNode();
    var anim1 = [
      ['to', {
          size: [100, 200],
          position: [1, 2, 3],
          transform: new DivSugar.Matrix().rotate(0, 90, 0),
          visible: false,
          backface: false,
          clip: true,
          opacity: 0.5,
          image: '../examples/assets/coin.png',
          imageClip: [0.1, 0.2, 0.3, 0.4],
          translate: [10, 20, 30],
          rotate: [10, 20, 30],
          scale: [1, 2, 3]
        }, 10, DivSugar.Ease.quadInOut ],
      ['call', function() { callCount++; }],
      ['wait', 5],
      ['repeat', 2],
      ['wait', 5]
    ];
    var task1 = node1.playAnimation(anim1);

    strictEqual(callCount, 0);
    strictEqual(task1.animation, anim1);
    strictEqual(task1.getParent(), DivSugar.rootTask);
    strictEqual(node1.getWidth(), 0);
    strictEqual(node1.getHeight(), 0);
    strictEqual(node1.getVisible(), true);
    strictEqual(node1.getBackface(), true);
    strictEqual(node1.getClip(), false);
    strictEqual(node1.getOpacity(), 1);
    strictEqual(node1.getImage(), null);
    strictEqual(node1.getImageClipU1(), 0);
    strictEqual(node1.getImageClipV1(), 0);
    strictEqual(node1.getImageClipU2(), 1);
    strictEqual(node1.getImageClipV2(), 1);
    node1.getTransform(mat1);
    deepEqual(mat1, DivSugar.Matrix.UNIT);

    DivSugar.rootTask.update(10);
    strictEqual(callCount, 0);
    strictEqual(task1.getParent(), DivSugar.rootTask);
    strictEqual(node1.getWidth(), 100);
    strictEqual(node1.getHeight(), 200);
    strictEqual(node1.getVisible(), false);
    strictEqual(node1.getBackface(), false);
    strictEqual(node1.getClip(), true);
    strictEqual(node1.getOpacity(), 0.5);
    strictEqual(node1.getImage(), '../examples/assets/coin.png');
    strictEqual(node1.getImageClipU1(), 0.1);
    strictEqual(node1.getImageClipV1(), 0.2);
    strictEqual(node1.getImageClipU2(), 0.3);
    strictEqual(node1.getImageClipV2(), 0.4);
    node1.getTransform(mat1);
    deepEqual(mat1, new DivSugar.Matrix().rotate(0, 90, 0).translate(10, 20, 30).rotate(10, 20, 30).scale(1, 2, 3));

    DivSugar.rootTask.update(1);
    strictEqual(callCount, 1);
    strictEqual(task1.getParent(), DivSugar.rootTask);

    DivSugar.rootTask.update(39);
    strictEqual(callCount, 3);
    strictEqual(task1.getParent(), DivSugar.rootTask);

    DivSugar.rootTask.update(1);
    strictEqual(callCount, 3);
    strictEqual(task1.getParent(), null);
  });

  test('clearAnimation', function() {
    var node1 = DivSugar.createNode();
    var task1 = node1.playAnimation([['wait', 10]]);
    var task2 = node1.playAnimation([['wait', 10]]);
    var task3 = node1.playAnimation([['wait', 10]]);

    DivSugar.rootTask.update(5);
    strictEqual(task1.getParent(), DivSugar.rootTask);
    strictEqual(task2.getParent(), DivSugar.rootTask);
    strictEqual(task3.getParent(), DivSugar.rootTask);

    node1.clearAnimation();
    strictEqual(task1.getParent(), null);
    strictEqual(task2.getParent(), null);
    strictEqual(task3.getParent(), null);
  });
})();
<commit_msg>Added a test for clearAnimation<commit_after>(function() {
  'use strict';

  module('Node');

  test('constructor and getters', function() {
    var node1 = DivSugar.createNode('node1');
    strictEqual(node1.id, 'node1');
    strictEqual(node1.getWidth(), 0);
    strictEqual(node1.getHeight(), 0);
    strictEqual(node1.getPositionX(), 0);
    strictEqual(node1.getPositionY(), 0);
    strictEqual(node1.getPositionZ(), 0);
    strictEqual(node1.getVisible(), true);
    strictEqual(node1.getBackface(), true);
    strictEqual(node1.getClip(), false);
    strictEqual(node1.getOpacity(), 1);
    strictEqual(node1.getImage(), null);
    strictEqual(node1.getImageClipU1(), 0);
    strictEqual(node1.getImageClipV1(), 0);
    strictEqual(node1.getImageClipU2(), 1);
    strictEqual(node1.getImageClipV2(), 1);
  });

  test('getPosition', function() {
    var node1 = DivSugar.createNode();
    var vec1 = new DivSugar.Vector(1, 2, 3);
    node1.getPosition(vec1);
    deepEqual(vec1, DivSugar.Vector.ZERO);

    ok(node1.getPosition(vec1).getPosition(vec1));
  });

  test('getTransform', function() {
    var node1 = DivSugar.createNode();
    var mat1 = new DivSugar.Matrix(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
    node1.getTransform(mat1);
    deepEqual(mat1, DivSugar.Matrix.UNIT);

    ok(node1.getTransform(mat1).getTransform(mat1));
  });

  test('setSize', function() {
    var node1 = DivSugar.createNode();
    node1.setSize(10, 20);
    strictEqual(node1.getWidth(), 10);
    strictEqual(node1.getHeight(), 20);

    ok(node1.setSize(1, 1).setSize(1, 1));
  });

  test('setPosition', function() {
    var node1 = DivSugar.createNode();
    var vec1 = new DivSugar.Vector(40, 50, 60);

    node1.setPosition(10, 20, 30);
    strictEqual(node1.getPositionX(), 10);
    strictEqual(node1.getPositionY(), 20);
    strictEqual(node1.getPositionZ(), 30);

    node1.setPosition(vec1);
    strictEqual(node1.getPositionX(), 40);
    strictEqual(node1.getPositionY(), 50);
    strictEqual(node1.getPositionZ(), 60);

    ok(node1.setPosition(0, 0, 0).setPosition(vec1).setPosition(1, 1, 1));
  });

  test('setTransform', function() {
    var node1 = DivSugar.createNode();
    var mat1 = new DivSugar.Matrix(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
    var mat2 = new DivSugar.Matrix();
    node1.setTransform(mat1);
    node1.getTransform(mat2);
    deepEqual(mat2, mat1);

    ok(node1.setTransform(mat1).setTransform(mat1));
  });

  test('setVisible', function() {
    var node1 = DivSugar.createNode();
    node1.setVisible(false);
    strictEqual(node1.getVisible(), false);

    ok(node1.setVisible(true).setVisible(true));
  });

  test('setBackface', function() {
    var node1 = DivSugar.createNode();
    node1.setBackface(false);
    strictEqual(node1.getBackface(), false);

    ok(node1.setBackface(true).setBackface(true));
  });

  test('setClip', function() {
    var node1 = DivSugar.createNode();
    node1.setClip(true);
    strictEqual(node1.getClip(), true);

    ok(node1.setClip(true).setClip(true));
  });

  test('setOpacity', function() {
    var node1 = DivSugar.createNode();
    node1.setOpacity(0.5);
    strictEqual(node1.getOpacity(), 0.5);

    ok(node1.setOpacity(0).setOpacity(0));
  });

  test('setImage', function() {
    var node1 = DivSugar.createNode();

    node1.setImage('../examples/assets/coin.png');
    strictEqual(node1.getImage(), '../examples/assets/coin.png');

    node1.setImage('../examples/assets/coin.png', function(width, height) {
      start();
      strictEqual(width, 400);
      strictEqual(height, 200);
    });
    stop();

    ok(node1.setImage(null).setImage(null));
  });

  test('setImageClip', function() {
    var node1 = DivSugar.createNode();

    node1.setImageClip(0.1, 0.2, 0.3, 0.4);
    strictEqual(node1.getImageClipU1(), 0.1);
    strictEqual(node1.getImageClipV1(), 0.2);
    strictEqual(node1.getImageClipU2(), 0.3);
    strictEqual(node1.getImageClipV2(), 0.4);

    node1.setImageClip(-1, -2, -3, -4);
    strictEqual(node1.getImageClipU1(), 0);
    strictEqual(node1.getImageClipV1(), 0);
    strictEqual(node1.getImageClipU2(), 0);
    strictEqual(node1.getImageClipV2(), 0);

    node1.setImageClip(2, 3, 4, 5);
    strictEqual(node1.getImageClipU1(), 1);
    strictEqual(node1.getImageClipV1(), 1);
    strictEqual(node1.getImageClipU2(), 1);
    strictEqual(node1.getImageClipV2(), 1);

    ok(node1.setImageClip(0, 0, 0, 0).setImageClip(0, 0, 0, 0));
  });

  test('translate', function() {
    var node1 = DivSugar.createNode();
    var mat1 = new DivSugar.Matrix();
    var mat2 = new DivSugar.Matrix();
    node1.setTransform(mat1);
    node1.translate(10, 20, 30);
    mat1.translate(10, 20, 30);
    node1.getTransform(mat2);
    deepEqual(mat2, mat1);

    ok(node1.translate(0, 0, 0).translate(0, 0, 0));
  });

  test('rotate', function() {
    var node1 = DivSugar.createNode();
    var mat1 = new DivSugar.Matrix();
    var mat2 = new DivSugar.Matrix();

    node1.setTransform(mat1);
    node1.rotate(90, 0, 0);
    mat1.rotate(90, 0, 0);
    node1.getTransform(mat2);
    nearlyEqual(mat2, mat1);

    node1.setTransform(mat1);
    node1.rotate(0, 90, 0);
    mat1.rotate(0, 90, 0);
    node1.getTransform(mat2);
    nearlyEqual(mat2, mat1);

    node1.setTransform(mat1);
    node1.rotate(0, 0, 90);
    mat1.rotate(0, 0, 90);
    node1.getTransform(mat2);
    nearlyEqual(mat2, mat1);

    ok(node1.rotate(0, 0, 0).rotate(0, 0, 0));
  });

  test('scale', function() {
    var node1 = DivSugar.createNode();
    var mat1 = new DivSugar.Matrix();
    var mat2 = new DivSugar.Matrix();
    node1.setTransform(mat1);
    node1.scale(10, 20, 30);
    mat1.scale(10, 20, 30);
    node1.getTransform(mat2);
    deepEqual(mat2, mat1);

    ok(node1.scale(1, 1, 1).scale(1, 1, 1));
  });

  test('playAnimation', function() {
    var callCount = 0;
    var mat1 = new DivSugar.Matrix();
    var node1 = DivSugar.createNode();
    var anim1 = [
      ['to', {
          size: [100, 200],
          position: [1, 2, 3],
          transform: new DivSugar.Matrix().rotate(0, 90, 0),
          visible: false,
          backface: false,
          clip: true,
          opacity: 0.5,
          image: '../examples/assets/coin.png',
          imageClip: [0.1, 0.2, 0.3, 0.4],
          translate: [10, 20, 30],
          rotate: [10, 20, 30],
          scale: [1, 2, 3]
        }, 10, DivSugar.Ease.quadInOut ],
      ['call', function() { callCount++; }],
      ['wait', 5],
      ['repeat', 2],
      ['wait', 5]
    ];
    var task1 = node1.playAnimation(anim1);

    strictEqual(callCount, 0);
    strictEqual(task1.animation, anim1);
    strictEqual(task1.getParent(), DivSugar.rootTask);
    strictEqual(node1.getWidth(), 0);
    strictEqual(node1.getHeight(), 0);
    strictEqual(node1.getVisible(), true);
    strictEqual(node1.getBackface(), true);
    strictEqual(node1.getClip(), false);
    strictEqual(node1.getOpacity(), 1);
    strictEqual(node1.getImage(), null);
    strictEqual(node1.getImageClipU1(), 0);
    strictEqual(node1.getImageClipV1(), 0);
    strictEqual(node1.getImageClipU2(), 1);
    strictEqual(node1.getImageClipV2(), 1);
    node1.getTransform(mat1);
    deepEqual(mat1, DivSugar.Matrix.UNIT);

    DivSugar.rootTask.update(10);
    strictEqual(callCount, 0);
    strictEqual(task1.getParent(), DivSugar.rootTask);
    strictEqual(node1.getWidth(), 100);
    strictEqual(node1.getHeight(), 200);
    strictEqual(node1.getVisible(), false);
    strictEqual(node1.getBackface(), false);
    strictEqual(node1.getClip(), true);
    strictEqual(node1.getOpacity(), 0.5);
    strictEqual(node1.getImage(), '../examples/assets/coin.png');
    strictEqual(node1.getImageClipU1(), 0.1);
    strictEqual(node1.getImageClipV1(), 0.2);
    strictEqual(node1.getImageClipU2(), 0.3);
    strictEqual(node1.getImageClipV2(), 0.4);
    node1.getTransform(mat1);
    deepEqual(mat1, new DivSugar.Matrix().rotate(0, 90, 0).translate(10, 20, 30).rotate(10, 20, 30).scale(1, 2, 3));

    DivSugar.rootTask.update(1);
    strictEqual(callCount, 1);
    strictEqual(task1.getParent(), DivSugar.rootTask);

    DivSugar.rootTask.update(39);
    strictEqual(callCount, 3);
    strictEqual(task1.getParent(), DivSugar.rootTask);

    DivSugar.rootTask.update(1);
    strictEqual(callCount, 3);
    strictEqual(task1.getParent(), null);
  });

  test('clearAnimation', function() {
    var node1 = DivSugar.createNode();
    var task1 = node1.playAnimation([['wait', 10]]);
    var task2 = node1.playAnimation([['wait', 10]]);
    var task3 = node1.playAnimation([['wait', 10]]);

    DivSugar.rootTask.update(5);
    strictEqual(task1.getParent(), DivSugar.rootTask);
    strictEqual(task2.getParent(), DivSugar.rootTask);
    strictEqual(task3.getParent(), DivSugar.rootTask);

    node1.clearAnimation();
    strictEqual(task1.getParent(), null);
    strictEqual(task2.getParent(), null);
    strictEqual(task3.getParent(), null);

    ok(node1.clearAnimation().clearAnimation());
  });
})();
<|endoftext|>


<commit_before>OV.GetDefaultCamera = function (direction)
{
    if (direction === OV.Direction.X) {
        return new OV.Camera (
            new OV.Coord3D (2.0, -3.0, 1.5),
            new OV.Coord3D (0.0, 0.0, 0.0),
            new OV.Coord3D (1.0, 0.0, 0.0)
        );
    } else if (direction === OV.Direction.Y) {
        return new OV.Camera (
            new OV.Coord3D (-1.5, 2.0, 3.0),
            new OV.Coord3D (0.0, 0.0, 0.0),
            new OV.Coord3D (0.0, 1.0, 0.0)
        );
    } else if (direction === OV.Direction.Z) {
        return new OV.Camera (
            new OV.Coord3D (-1.5, -3.0, 2.0),
            new OV.Coord3D (0.0, 0.0, 0.0),
            new OV.Coord3D (0.0, 0.0, 1.0)
        );
    }
    return null;
};

OV.UpVector = class
{
    constructor ()
    {
        this.direction = OV.Direction.Z;
        this.isFixed = true;
        this.isFlipped = false;
    }

    SetDirection (newDirection, oldCamera)
    {
        this.direction = newDirection;
        this.isFlipped = false;

        let defaultCamera = OV.GetDefaultCamera (this.direction);
        let defaultDir = OV.SubCoord3D (defaultCamera.eye, defaultCamera.center);

        let distance = OV.CoordDistance3D (oldCamera.center, oldCamera.eye);
        let newEye = oldCamera.center.Clone ().Offset (defaultDir, distance);

        let newCamera = oldCamera.Clone ();
        if (this.direction === OV.Direction.X) {
            newCamera.up = new OV.Coord3D (1.0, 0.0, 0.0);
            newCamera.eye = newEye;
        } if (this.direction === OV.Direction.Y) {
            newCamera.up = new OV.Coord3D (0.0, 1.0, 0.0);
            newCamera.eye = newEye;
        } else if (this.direction === OV.Direction.Z) {
            newCamera.up = new OV.Coord3D (0.0, 0.0, 1.0);
            newCamera.eye = newEye;
        }
        return newCamera;
    }

    SetFixed (isFixed, oldCamera)
    {
        this.isFixed = isFixed;
        if (this.isFixed) {
            return this.SetDirection (this.direction, oldCamera);
        }
        return null;
    }

    Flip (oldCamera)
    {
        this.isFlipped = !this.isFlipped;
        let newCamera = oldCamera.Clone ();
        newCamera.up.MultiplyScalar (-1.0);
        return newCamera;
    }
};

OV.Viewer = class
{
    constructor ()
    {
        this.canvas = null;
        this.renderer = null;
        this.scene = null;
        this.camera = null;
        this.light = null;
        this.navigation = null;
        this.upVector = null;
        this.settings = {
            animationSteps : 40
        };
    }

    Init (canvas)
    {
        this.canvas = canvas;
        this.canvas.id = 'viewer';
        this.canvas.addEventListener ('contenxtmenu', function (ev) {
            ev.preventDefault ();
        });

        let parameters = {
            canvas : this.canvas,
            antialias : true
        };

        this.renderer = new THREE.WebGLRenderer (parameters);
        this.renderer.setClearColor ('#ffffff', 1.0);
        this.renderer.setSize (this.canvas.width, this.canvas.height);

        this.scene = new THREE.Scene ();

        this.InitCamera ();
        this.InitLights ();

        this.Render ();
    }

    SetClickHandler (onClick)
    {
        this.navigation.SetClickHandler (onClick);
    }

    GetCamera ()
    {
        return this.navigation.GetCamera ();
    }

    SetCamera (camera)
    {
        this.navigation.SetCamera (camera);
        this.Render ();
    }

    Resize (width, height)
    {
        let innerSize = OV.GetInnerDimensions (this.canvas, width, height);
        this.ResizeRenderer (innerSize.width, innerSize.height);
    }

    ResizeRenderer (width, height)
    {
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix ();
        this.renderer.setSize (width, height);
        this.Render ();
    }

    FitToWindow (boundingSphere, animation)
    {
        if (boundingSphere === null) {
            return;
        }
        let center = new OV.Coord3D (boundingSphere.center.x, boundingSphere.center.y, boundingSphere.center.z);
        let radius = boundingSphere.radius;
        let fov = this.camera.fov;
        if (animation) {
            let newCamera = this.navigation.GetFitToSphereCamera (center, radius, fov);
            this.navigation.MoveCamera (newCamera, this.settings.animationSteps);
        } else {
            this.navigation.FitToSphere (center, radius, fov);
        }
    }

    AdjustClippingPlanes (boundingSphere)
    {
        if (boundingSphere === null) {
            return;
        }
        if (boundingSphere.radius < 10.0) {
            this.camera.near = 0.01;
            this.camera.far = 100.0;
        } else if (boundingSphere.radius < 100.0) {
            this.camera.near = 0.1;
            this.camera.far = 1000.0;
        } else if (boundingSphere.radius < 1000.0) {
            this.camera.near = 10.0;
            this.camera.far = 10000.0;
        } else {
            this.camera.near = 100.0;
            this.camera.far = 1000000.0;
        }
        this.camera.updateProjectionMatrix ();
        this.Render ();
    }

    IsFixUpVector ()
    {
        return this.navigation.IsFixUpVector ();
    }

    SetFixUpVector (fixUpVector)
    {
        let oldCamera = this.navigation.GetCamera ();
        let newCamera = this.upVector.SetFixed (fixUpVector, oldCamera);
        this.navigation.SetFixUpVector (fixUpVector);
        if (newCamera !== null) {
            this.navigation.MoveCamera (newCamera, this.settings.animationSteps);
        }
        this.Render ();
    }

    SetUpVector (upDirection, animate)
    {
        let oldCamera = this.navigation.GetCamera ();
        let newCamera = this.upVector.SetDirection (upDirection, oldCamera);
        let animationSteps = animate ? this.settings.animationSteps : 0;
        this.navigation.MoveCamera (newCamera, animationSteps);
        this.Render ();
    }

    FlipUpVector ()
    {
        let oldCamera = this.navigation.GetCamera ();
        let newCamera = this.upVector.Flip (oldCamera);
        this.navigation.MoveCamera (newCamera, 0);
        this.Render ();
    }

    Render ()
    {
        let navigationCamera = this.navigation.GetCamera ();
        this.camera.position.set (navigationCamera.eye.x, navigationCamera.eye.y, navigationCamera.eye.z);
        this.camera.up.set (navigationCamera.up.x, navigationCamera.up.y, navigationCamera.up.z);
        this.camera.lookAt (new THREE.Vector3 (navigationCamera.center.x, navigationCamera.center.y, navigationCamera.center.z));

        let lightDir = OV.SubCoord3D (navigationCamera.eye, navigationCamera.center);
        this.light.position.set (lightDir.x, lightDir.y, lightDir.z);
        this.renderer.render (this.scene, this.camera);
    }

    AddMeshes (meshes)
    {
        for (let i = 0; i < meshes.length; i++) {
            let mesh = meshes[i];
            this.scene.add (mesh);
        }
        this.Render ();
    }

    Clear ()
    {
        this.ClearMeshes ();
        this.Render ();
    }

    SetMeshesVisibility (isVisible)
    {
        this.EnumerateMeshes (function (mesh) {
            let visible = isVisible (mesh.userData);
            if (mesh.visible !== visible) {
                mesh.visible = visible;
            }
        });
        this.Render ();
    }

    SetMeshesHighlight (highlightMaterial, isHighlighted)
    {
        function CreateHighlightMaterials (originalMaterials, highlightMaterial)
        {
            let highlightMaterials = [];
            for (let i = 0; i < originalMaterials.length; i++) {
                highlightMaterials.push (highlightMaterial);
            }
            return highlightMaterials;
        }

        this.EnumerateMeshes (function (mesh) {
            let highlighted = isHighlighted (mesh.userData);
            if (highlighted) {
                if (mesh.userData.threeMaterials === null) {
                    mesh.userData.threeMaterials = mesh.material;
                    mesh.material = CreateHighlightMaterials (mesh.material, highlightMaterial);
                }
            } else {
                if (mesh.userData.threeMaterials !== null) {
                    mesh.material = mesh.userData.threeMaterials;
                    mesh.userData.threeMaterials = null;
                }
            }
        });
        this.Render ();
    }

    GetMeshUnderMouse (mouseCoords)
    {
        let raycaster = new THREE.Raycaster ();
        let mousePos = new THREE.Vector2 ();
        mousePos.x = (mouseCoords.x / this.canvas.width) * 2 - 1;
        mousePos.y = -(mouseCoords.y / this.canvas.height) * 2 + 1;
        raycaster.setFromCamera (mousePos, this.camera);
        let iSectObjects = raycaster.intersectObjects (this.scene.children);
        for (let i = 0; i < iSectObjects.length; i++) {
            let iSectObject = iSectObjects[i];
            if (iSectObject.object.type === 'Mesh' && iSectObject.object.visible) {
                return iSectObject.object.userData;
            }
        }
        return null;
    }

    GetBoundingBox (needToProcess)
    {
        let hasMesh = false;
        let boundingBox = new THREE.Box3 ();
        this.EnumerateMeshes (function (mesh) {
            if (needToProcess (mesh.userData)) {
                boundingBox.union (new THREE.Box3 ().setFromObject (mesh));
                hasMesh = true;
            }
        });

        if (!hasMesh) {
            return null;
        }
        return boundingBox;
    }

    GetBoundingSphere (needToProcess)
    {
        let boundingBox = this.GetBoundingBox (needToProcess);
        if (boundingBox === null) {
            return null;
        }

        let boundingSphere = new THREE.Sphere ();
        boundingBox.getBoundingSphere (boundingSphere);
        return boundingSphere;
    }

    EnumerateMeshesUserData (enumerator)
    {
        this.EnumerateMeshes (function (mesh) {
            enumerator (mesh.userData);
        });
    }

    EnumerateMeshes (enumerator)
    {
        this.scene.traverse (function (object) {
            if (object.isMesh) {
                enumerator (object);
            }
        });
    }

    ClearMeshes ()
    {
        for (let i = this.scene.children.length - 1; i >= 0; i--) {
            let object = this.scene.children[i];
            if (object.isMesh) {
                object.geometry.dispose ();
                this.scene.remove (object);
            }
        }
    }

    InitCamera ()
    {
        this.camera = new THREE.PerspectiveCamera (45.0, this.canvas.width / this.canvas.height, 0.1, 1000.0);
        this.scene.add (this.camera);

        let canvasElem = this.renderer.domElement;
        let camera = OV.GetDefaultCamera (OV.Direction.Z);

        let obj = this;
        this.navigation = new OV.Navigation (canvasElem, camera);
        this.navigation.SetUpdateHandler (function () {
            obj.Render ();
        });

        this.upVector = new OV.UpVector ();
    }

    InitLights  ()
    {
        let ambientLight = new THREE.AmbientLight (0x888888);
        this.scene.add (ambientLight);

        this.light = new THREE.DirectionalLight (0x888888);
        this.scene.add (this.light);
    }

    GetImageSize ()
    {
        let originalSize = new THREE.Vector2 ();
        this.renderer.getSize (originalSize);
        return {
            width : parseInt (originalSize.x, 10),
            height : parseInt (originalSize.y, 10)
        };
    }

    GetImageAsDataUrl (width, height)
    {
        let originalSize = this.GetImageSize ();
        this.ResizeRenderer (width, height);
        this.Render ();
        let url = this.renderer.domElement.toDataURL ();
        this.ResizeRenderer (originalSize.width, originalSize.height);
        return url;
    }
};
<commit_msg>Hi-DPI aware #60<commit_after>OV.GetDefaultCamera = function (direction)
{
    if (direction === OV.Direction.X) {
        return new OV.Camera (
            new OV.Coord3D (2.0, -3.0, 1.5),
            new OV.Coord3D (0.0, 0.0, 0.0),
            new OV.Coord3D (1.0, 0.0, 0.0)
        );
    } else if (direction === OV.Direction.Y) {
        return new OV.Camera (
            new OV.Coord3D (-1.5, 2.0, 3.0),
            new OV.Coord3D (0.0, 0.0, 0.0),
            new OV.Coord3D (0.0, 1.0, 0.0)
        );
    } else if (direction === OV.Direction.Z) {
        return new OV.Camera (
            new OV.Coord3D (-1.5, -3.0, 2.0),
            new OV.Coord3D (0.0, 0.0, 0.0),
            new OV.Coord3D (0.0, 0.0, 1.0)
        );
    }
    return null;
};

OV.UpVector = class
{
    constructor ()
    {
        this.direction = OV.Direction.Z;
        this.isFixed = true;
        this.isFlipped = false;
    }

    SetDirection (newDirection, oldCamera)
    {
        this.direction = newDirection;
        this.isFlipped = false;

        let defaultCamera = OV.GetDefaultCamera (this.direction);
        let defaultDir = OV.SubCoord3D (defaultCamera.eye, defaultCamera.center);

        let distance = OV.CoordDistance3D (oldCamera.center, oldCamera.eye);
        let newEye = oldCamera.center.Clone ().Offset (defaultDir, distance);

        let newCamera = oldCamera.Clone ();
        if (this.direction === OV.Direction.X) {
            newCamera.up = new OV.Coord3D (1.0, 0.0, 0.0);
            newCamera.eye = newEye;
        } if (this.direction === OV.Direction.Y) {
            newCamera.up = new OV.Coord3D (0.0, 1.0, 0.0);
            newCamera.eye = newEye;
        } else if (this.direction === OV.Direction.Z) {
            newCamera.up = new OV.Coord3D (0.0, 0.0, 1.0);
            newCamera.eye = newEye;
        }
        return newCamera;
    }

    SetFixed (isFixed, oldCamera)
    {
        this.isFixed = isFixed;
        if (this.isFixed) {
            return this.SetDirection (this.direction, oldCamera);
        }
        return null;
    }

    Flip (oldCamera)
    {
        this.isFlipped = !this.isFlipped;
        let newCamera = oldCamera.Clone ();
        newCamera.up.MultiplyScalar (-1.0);
        return newCamera;
    }
};

OV.Viewer = class
{
    constructor ()
    {
        this.canvas = null;
        this.renderer = null;
        this.scene = null;
        this.camera = null;
        this.light = null;
        this.navigation = null;
        this.upVector = null;
        this.settings = {
            animationSteps : 40
        };
    }

    Init (canvas)
    {
        this.canvas = canvas;
        this.canvas.id = 'viewer';
        this.canvas.addEventListener ('contenxtmenu', function (ev) {
            ev.preventDefault ();
        });

        let parameters = {
            canvas : this.canvas,
            antialias : true
        };

        this.renderer = new THREE.WebGLRenderer (parameters);
        if (window.devicePixelRatio) {
            this.renderer.setPixelRatio (window.devicePixelRatio);
        }
        this.renderer.setClearColor ('#ffffff', 1.0);
        this.renderer.setSize (this.canvas.width, this.canvas.height);

        this.scene = new THREE.Scene ();

        this.InitCamera ();
        this.InitLights ();

        this.Render ();
    }

    SetClickHandler (onClick)
    {
        this.navigation.SetClickHandler (onClick);
    }

    GetCamera ()
    {
        return this.navigation.GetCamera ();
    }

    SetCamera (camera)
    {
        this.navigation.SetCamera (camera);
        this.Render ();
    }

    Resize (width, height)
    {
        let innerSize = OV.GetInnerDimensions (this.canvas, width, height);
        this.ResizeRenderer (innerSize.width, innerSize.height);
    }

    ResizeRenderer (width, height)
    {
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix ();
        this.renderer.setSize (width, height);
        this.Render ();
    }

    FitToWindow (boundingSphere, animation)
    {
        if (boundingSphere === null) {
            return;
        }
        let center = new OV.Coord3D (boundingSphere.center.x, boundingSphere.center.y, boundingSphere.center.z);
        let radius = boundingSphere.radius;
        let fov = this.camera.fov;
        if (animation) {
            let newCamera = this.navigation.GetFitToSphereCamera (center, radius, fov);
            this.navigation.MoveCamera (newCamera, this.settings.animationSteps);
        } else {
            this.navigation.FitToSphere (center, radius, fov);
        }
    }

    AdjustClippingPlanes (boundingSphere)
    {
        if (boundingSphere === null) {
            return;
        }
        if (boundingSphere.radius < 10.0) {
            this.camera.near = 0.01;
            this.camera.far = 100.0;
        } else if (boundingSphere.radius < 100.0) {
            this.camera.near = 0.1;
            this.camera.far = 1000.0;
        } else if (boundingSphere.radius < 1000.0) {
            this.camera.near = 10.0;
            this.camera.far = 10000.0;
        } else {
            this.camera.near = 100.0;
            this.camera.far = 1000000.0;
        }
        this.camera.updateProjectionMatrix ();
        this.Render ();
    }

    IsFixUpVector ()
    {
        return this.navigation.IsFixUpVector ();
    }

    SetFixUpVector (fixUpVector)
    {
        let oldCamera = this.navigation.GetCamera ();
        let newCamera = this.upVector.SetFixed (fixUpVector, oldCamera);
        this.navigation.SetFixUpVector (fixUpVector);
        if (newCamera !== null) {
            this.navigation.MoveCamera (newCamera, this.settings.animationSteps);
        }
        this.Render ();
    }

    SetUpVector (upDirection, animate)
    {
        let oldCamera = this.navigation.GetCamera ();
        let newCamera = this.upVector.SetDirection (upDirection, oldCamera);
        let animationSteps = animate ? this.settings.animationSteps : 0;
        this.navigation.MoveCamera (newCamera, animationSteps);
        this.Render ();
    }

    FlipUpVector ()
    {
        let oldCamera = this.navigation.GetCamera ();
        let newCamera = this.upVector.Flip (oldCamera);
        this.navigation.MoveCamera (newCamera, 0);
        this.Render ();
    }

    Render ()
    {
        let navigationCamera = this.navigation.GetCamera ();
        this.camera.position.set (navigationCamera.eye.x, navigationCamera.eye.y, navigationCamera.eye.z);
        this.camera.up.set (navigationCamera.up.x, navigationCamera.up.y, navigationCamera.up.z);
        this.camera.lookAt (new THREE.Vector3 (navigationCamera.center.x, navigationCamera.center.y, navigationCamera.center.z));

        let lightDir = OV.SubCoord3D (navigationCamera.eye, navigationCamera.center);
        this.light.position.set (lightDir.x, lightDir.y, lightDir.z);
        this.renderer.render (this.scene, this.camera);
    }

    AddMeshes (meshes)
    {
        for (let i = 0; i < meshes.length; i++) {
            let mesh = meshes[i];
            this.scene.add (mesh);
        }
        this.Render ();
    }

    Clear ()
    {
        this.ClearMeshes ();
        this.Render ();
    }

    SetMeshesVisibility (isVisible)
    {
        this.EnumerateMeshes (function (mesh) {
            let visible = isVisible (mesh.userData);
            if (mesh.visible !== visible) {
                mesh.visible = visible;
            }
        });
        this.Render ();
    }

    SetMeshesHighlight (highlightMaterial, isHighlighted)
    {
        function CreateHighlightMaterials (originalMaterials, highlightMaterial)
        {
            let highlightMaterials = [];
            for (let i = 0; i < originalMaterials.length; i++) {
                highlightMaterials.push (highlightMaterial);
            }
            return highlightMaterials;
        }

        this.EnumerateMeshes (function (mesh) {
            let highlighted = isHighlighted (mesh.userData);
            if (highlighted) {
                if (mesh.userData.threeMaterials === null) {
                    mesh.userData.threeMaterials = mesh.material;
                    mesh.material = CreateHighlightMaterials (mesh.material, highlightMaterial);
                }
            } else {
                if (mesh.userData.threeMaterials !== null) {
                    mesh.material = mesh.userData.threeMaterials;
                    mesh.userData.threeMaterials = null;
                }
            }
        });
        this.Render ();
    }

    GetMeshUnderMouse (mouseCoords)
    {
        let raycaster = new THREE.Raycaster ();
        let mousePos = new THREE.Vector2 ();
        mousePos.x = (mouseCoords.x / this.canvas.width) * 2 - 1;
        mousePos.y = -(mouseCoords.y / this.canvas.height) * 2 + 1;
        raycaster.setFromCamera (mousePos, this.camera);
        let iSectObjects = raycaster.intersectObjects (this.scene.children);
        for (let i = 0; i < iSectObjects.length; i++) {
            let iSectObject = iSectObjects[i];
            if (iSectObject.object.type === 'Mesh' && iSectObject.object.visible) {
                return iSectObject.object.userData;
            }
        }
        return null;
    }

    GetBoundingBox (needToProcess)
    {
        let hasMesh = false;
        let boundingBox = new THREE.Box3 ();
        this.EnumerateMeshes (function (mesh) {
            if (needToProcess (mesh.userData)) {
                boundingBox.union (new THREE.Box3 ().setFromObject (mesh));
                hasMesh = true;
            }
        });

        if (!hasMesh) {
            return null;
        }
        return boundingBox;
    }

    GetBoundingSphere (needToProcess)
    {
        let boundingBox = this.GetBoundingBox (needToProcess);
        if (boundingBox === null) {
            return null;
        }

        let boundingSphere = new THREE.Sphere ();
        boundingBox.getBoundingSphere (boundingSphere);
        return boundingSphere;
    }

    EnumerateMeshesUserData (enumerator)
    {
        this.EnumerateMeshes (function (mesh) {
            enumerator (mesh.userData);
        });
    }

    EnumerateMeshes (enumerator)
    {
        this.scene.traverse (function (object) {
            if (object.isMesh) {
                enumerator (object);
            }
        });
    }

    ClearMeshes ()
    {
        for (let i = this.scene.children.length - 1; i >= 0; i--) {
            let object = this.scene.children[i];
            if (object.isMesh) {
                object.geometry.dispose ();
                this.scene.remove (object);
            }
        }
    }

    InitCamera ()
    {
        this.camera = new THREE.PerspectiveCamera (45.0, this.canvas.width / this.canvas.height, 0.1, 1000.0);
        this.scene.add (this.camera);

        let canvasElem = this.renderer.domElement;
        let camera = OV.GetDefaultCamera (OV.Direction.Z);

        let obj = this;
        this.navigation = new OV.Navigation (canvasElem, camera);
        this.navigation.SetUpdateHandler (function () {
            obj.Render ();
        });

        this.upVector = new OV.UpVector ();
    }

    InitLights  ()
    {
        let ambientLight = new THREE.AmbientLight (0x888888);
        this.scene.add (ambientLight);

        this.light = new THREE.DirectionalLight (0x888888);
        this.scene.add (this.light);
    }

    GetImageSize ()
    {
        let originalSize = new THREE.Vector2 ();
        this.renderer.getSize (originalSize);
        return {
            width : parseInt (originalSize.x, 10),
            height : parseInt (originalSize.y, 10)
        };
    }

    GetImageAsDataUrl (width, height)
    {
        let originalSize = this.GetImageSize ();
        let renderWidth = width;
        let renderHeight = height;
        if (window.devicePixelRatio) {
            renderWidth /= window.devicePixelRatio;
            renderHeight /= window.devicePixelRatio;
        }
        this.ResizeRenderer (renderWidth, renderHeight);
        this.Render ();
        let url = this.renderer.domElement.toDataURL ();
        this.ResizeRenderer (originalSize.width, originalSize.height);
        return url;
    }
};
<|endoftext|>


<commit_before>'use strict';
/*jshint browser: true*/

/*global require: false*/
var utils = require('./utils');

var months = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December'
];

var attr = utils.attr;
var query = utils.query;
var mkEl = utils.mkEl;
var keys = utils.keys;
var tmpl = utils.tmpl;

function mkListItems(target, texts, clickCb, that) {
  var items = [];
  that = that || {};

  texts.forEach(function (text, i) {
    var el = mkEl('li');
    el.innerHTML = '' + text + '';

    el.addEventListener('click', function (evt) {
      evt.preventDefault();
      items.forEach(function (e) {
        var cl = e.classList;
        if (e === el) {
          if (!cl.contains('active')) {
            cl.add('active');
          }
        }
        else {
          cl.remove('active');
        }
      });

      clickCb.call(that, i, el);
    });

    target.appendChild(el);

    items.push(el);
  });

  return items;
}

function camDownloadsWidget(info, holder) {
  var majorList = query('ul.major', holder);
  var patchList = query('ul.patch', holder);
  var serverList = query('ul.server', holder);
  var infoDiv = query('.selected-server', holder);
  var standaloneDiv = query('.standalone', infoDiv);

  var releaseTitle = query('.info h3', holder);
  var notesA = query('a.notes', holder);
  var dateSpan = query('span.date', holder);
  var zipA = query('a.zip', holder);
  var targzA = query('a.tar-gz', holder);
  var warA = query('a.war', holder);

  var branches = keys(info.branches).sort(function (a, b) {
    return (a > b ? -1 : (a < b ? 1 : 0));
  });

  function getReleaseInfo(branch, version) {
    return info.branches[branch].find(function (release) {
      return release.number === version;
    });
  }

  function getBranchVersions(branch) {
    return info.branches[branch].map(function (release) {
      return release.number;
    }).filter(function (item) { return !!item; });
  }

  function getServers(release) {
    var servers = keys(info.servers);
    if (release.excludeServers) {
      servers = servers.filter(function (name) {
        return release.excludeServers.indexOf(name) < 0;
      });
    }
    return servers;
  }

  function mkServerClickHandler(servers, version, branch) {
    return function (s) {
      var selectedServer = servers[s];
      var release = getReleaseInfo(branch, version);
      infoDiv.classList.add('accessible');

      var dl = tmpl('{server}/{branch}/{version}/camunda-bpm-ee-{server}-{version}-ee', {
        version:  version,
        branch:   version.indexOf('alpha') ? 'nightly' : branch,
        server:   selectedServer
      });

      releaseTitle.innerHTML = version + ' for ' + info.servers[selectedServer];

      var d = new Date(release.date);
      dateSpan.innerHTML = d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear();

      attr(notesA, 'href', release.note);

      attr(targzA, 'href', 'http://camunda.org/enterprise-release/camunda-bpm/' + dl + '.tar.gz');

      attr(zipA, 'href', 'http://camunda.org/enterprise-release/camunda-bpm/' + dl + '.zip');

      attr(warA, 'href', 'http://camunda.org/enterprise-release/camunda-bpm/' + dl + '.war');

      if (release.excludeFormats && release.excludeFormats.indexOf('war') > -1) {
        standaloneDiv.style.display = 'none';
      }
      else {
        standaloneDiv.style.display = 'block';
      }
    };
  }

  function mkVersionClickHandler(branchName) {
    var patchReleases = getBranchVersions(branchName);

    return function selectVersion(r) {
      serverList.innerHTML = '';

      infoDiv.classList.remove('accessible');

      var selectedVersion = patchReleases[r];

      var releaseInfo = getReleaseInfo(branchName, selectedVersion);

      var releaseServers = getServers(releaseInfo);

      return mkListItems(serverList, releaseServers.map(function (name) {
        return info.servers[name];
      }), mkServerClickHandler(releaseServers, selectedVersion, branchName));
    };
  }

  function selectBranch(b) {
    patchList.innerHTML = '';

    serverList.innerHTML = '';

    infoDiv.classList.remove('accessible');

    var branchName = branches[b];

    var patchReleases = getBranchVersions(branchName);

    return mkListItems(patchList, patchReleases, mkVersionClickHandler(branchName));
  }

  var branchEls = mkListItems(majorList, branches, selectBranch);

  if (info.selected) {
    var b = branches.indexOf(info.selected.branch);

    var versionEls = selectBranch(b);

    branchEls[b].classList.add('active');

    var patchReleases = getBranchVersions(branches[b]);

    var v = patchReleases.indexOf(info.selected.version);

    var serverEls = mkVersionClickHandler(branches[b])(v);

    versionEls[v].classList.add('active');

    var servers = getServers(patchReleases[v]);

    var s = servers.indexOf(info.selected.server);

    serverEls[s].classList.add('active');

    mkServerClickHandler(servers, info.selected.version, info.selected.branch)(s);
  }
}

var camDownloadsEl = query('.cam-downloads');
if (window.camDownloads && camDownloadsEl) {
  camDownloadsWidget(window.camDownloads, camDownloadsEl);
}
<commit_msg>fix(downloads): correct download links<commit_after>'use strict';
/*jshint browser: true*/

/*global require: false*/
var utils = require('./utils');

var months = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December'
];

var attr = utils.attr;
var query = utils.query;
var mkEl = utils.mkEl;
var keys = utils.keys;
var tmpl = utils.tmpl;

function mkListItems(target, texts, clickCb, that) {
  var items = [];
  that = that || {};

  texts.forEach(function (text, i) {
    var el = mkEl('li');
    el.innerHTML = '' + text + '';

    el.addEventListener('click', function (evt) {
      evt.preventDefault();
      items.forEach(function (e) {
        var cl = e.classList;
        if (e === el) {
          if (!cl.contains('active')) {
            cl.add('active');
          }
        }
        else {
          cl.remove('active');
        }
      });

      clickCb.call(that, i, el);
    });

    target.appendChild(el);

    items.push(el);
  });

  return items;
}

function camDownloadsWidget(info, holder) {
  var majorList = query('ul.major', holder);
  var patchList = query('ul.patch', holder);
  var serverList = query('ul.server', holder);
  var infoDiv = query('.selected-server', holder);
  var standaloneDiv = query('.standalone', infoDiv);

  var releaseTitle = query('.info h3', holder);
  var notesA = query('a.notes', holder);
  var dateSpan = query('span.date', holder);
  var zipA = query('a.zip', holder);
  var targzA = query('a.tar-gz', holder);
  var warA = query('a.war', holder);

  var branches = keys(info.branches).sort(function (a, b) {
    return (a > b ? -1 : (a < b ? 1 : 0));
  });

  function getReleaseInfo(branch, version) {
    return info.branches[branch].find(function (release) {
      return release.number === version;
    });
  }

  function getBranchVersions(branch) {
    return info.branches[branch].map(function (release) {
      return release.number;
    }).filter(function (item) { return !!item; });
  }

  function getServers(release) {
    var servers = keys(info.servers);
    if (release.excludeServers) {
      servers = servers.filter(function (name) {
        return release.excludeServers.indexOf(name) < 0;
      });
    }
    return servers;
  }

  function mkServerClickHandler(servers, version, branch) {
    return function (s) {
      var selectedServer = servers[s];
      var release = getReleaseInfo(branch, version);
      infoDiv.classList.add('accessible');

      var dl = tmpl('{server}/{branch}/{version}/camunda-bpm-ee-{server}-{version}-ee', {
        version:  version,
        branch:   (version.indexOf('alpha') > -1) ? 'nightly' : branch,
        server:   selectedServer
      });

      releaseTitle.innerHTML = version + ' for ' + info.servers[selectedServer];

      var d = new Date(release.date);
      dateSpan.innerHTML = d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear();

      attr(notesA, 'href', release.note);

      attr(targzA, 'href', 'http://camunda.org/enterprise-release/camunda-bpm/' + dl + '.tar.gz');

      attr(zipA, 'href', 'http://camunda.org/enterprise-release/camunda-bpm/' + dl + '.zip');

      attr(warA, 'href', 'http://camunda.org/enterprise-release/camunda-bpm/' + dl + '.war');

      if (release.excludeFormats && release.excludeFormats.indexOf('war') > -1) {
        standaloneDiv.style.display = 'none';
      }
      else {
        standaloneDiv.style.display = 'block';
      }
    };
  }

  function mkVersionClickHandler(branchName) {
    var patchReleases = getBranchVersions(branchName);

    return function selectVersion(r) {
      serverList.innerHTML = '';

      infoDiv.classList.remove('accessible');

      var selectedVersion = patchReleases[r];

      var releaseInfo = getReleaseInfo(branchName, selectedVersion);

      var releaseServers = getServers(releaseInfo);

      return mkListItems(serverList, releaseServers.map(function (name) {
        return info.servers[name];
      }), mkServerClickHandler(releaseServers, selectedVersion, branchName));
    };
  }

  function selectBranch(b) {
    patchList.innerHTML = '';

    serverList.innerHTML = '';

    infoDiv.classList.remove('accessible');

    var branchName = branches[b];

    var patchReleases = getBranchVersions(branchName);

    return mkListItems(patchList, patchReleases, mkVersionClickHandler(branchName));
  }

  var branchEls = mkListItems(majorList, branches, selectBranch);

  if (info.selected) {
    var b = branches.indexOf(info.selected.branch);

    var versionEls = selectBranch(b);

    branchEls[b].classList.add('active');

    var patchReleases = getBranchVersions(branches[b]);

    var v = patchReleases.indexOf(info.selected.version);

    var serverEls = mkVersionClickHandler(branches[b])(v);

    versionEls[v].classList.add('active');

    var servers = getServers(patchReleases[v]);

    var s = servers.indexOf(info.selected.server);

    serverEls[s].classList.add('active');

    mkServerClickHandler(servers, info.selected.version, info.selected.branch)(s);
  }
}

var camDownloadsEl = query('.cam-downloads');
if (window.camDownloads && camDownloadsEl) {
  camDownloadsWidget(window.camDownloads, camDownloadsEl);
}
<|endoftext|>