<commit_before>;(function($, window, document, undefined) {

	var pluginName = 'hovercap',
			defaults = {
				toggleElement: '',
				toggleAnimataion: 'slide',
				toggleDirection: 'toTop',
				animationSpeed: 200,
				animationEasing: 'swing',
				onSetup: function() {},
				onShow: function() {},
				onHide: function() {}
			};

	function Plugin(element, options) {
		this.element = element;
		this.settings = $.extend({}, defaults, options);
		this._defualts = defaults;
		this._name = pluginName;

		this.init();
	}

	Plugin.prototype.init = function() {
		var self = this;

		self.$element = $(self.element);
		self.$toggleElement = self.$element.find(self.settings.toggleElement);
		self.elementWidth = self.$element.outerWidth();
		self.elementHeight = self.$element.outerHeight();
		self.toggleElementProps = {};

		self.initToggleElement();

		self.$element.on({
			mouseenter: function() {
				if(self.settings.toggleAnimataion == 'fade') {
					self.fadeShowElement();
					return;
				}
				self.slideShowElement();
			},
			mouseleave: function() {
				if(self.settings.toggleAnimataion == 'fade') {
					self.fadeHideElement();
					return;
				}
				self.slideHideElement();
			}
		});
	}

	Plugin.prototype.initToggleElement = function() {
		var self = this;

		if(self.settings.toggleAnimataion == 'slide') {
			switch(self.settings.toggleDirection) {
				case 'toRight':
					self.toggleElementProps = {
						top: 0,
						left: -self.elementWidth
					}
					break;
				case 'toBottom':
					self.toggleElementProps = {
						top: -self.elementHeight,
						left: 0
					}
					break;
				case 'toLeft':
					self.toggleElementProps = {
						top: 0,
						left: self.elementWidth
					}
					break;
				default:
					// default == toTop
					self.toggleElementProps = {
						top: self.elementHeight,
						left: 0
					}
					break;
			}
		}

		if(self.settings.toggleAnimataion == 'fade') {
			self.toggleElementProps = {
				top: 0,
				left: 0,
				display: 'none'
			}
		}

		self.$toggleElement.css(self.toggleElementProps);
		self.settings.onSetup();
	}

	Plugin.prototype.fadeToggleElement = function() {
		var self = this;

		self.$toggleElement
			.stop()
			.fadeToggle(self.settings.animationSpeed, function() {
				self.settings.callBack();
			});
	}

	Plugin.prototype.fadeShowElement = function() {
		var self = this;

		self.$toggleElement
			.stop()
			.fadeIn(
				self.settings.animationSpeed,
				self.settings.animationEasing,
				function() { self.settings.onShow(); });
	}

	Plugin.prototype.fadeHideElement = function() {
		var self = this;

		self.$toggleElement
			.stop()
			.fadeOut(
				self.settings.animationSpeed,
				self.settings.animationEasing,
				function() { self.settings.onShow(); });
	}

	Plugin.prototype.slideShowElement = function() {
		var self = this;

		switch(self.settings.toggleDirection) {
			case 'toRight':
			case 'toLeft':
				self.toggleElementProps.left = 0;
				break;
			default:
				self.toggleElementProps.top = 0;
				break;
		}

		self.$toggleElement
			.stop()
			.animate(
				self.toggleElementProps,
				self.settings.animationSpeed,
				self.settings.animationEasing,
				function() { self.settings.onShow(); });
	}

	Plugin.prototype.slideHideElement = function() {
		var self = this;

		switch(self.settings.toggleDirection) {
			case 'toRight':
				self.toggleElementProps.left = -self.elementWidth;
				break;
			case 'toBottom':
				self.toggleElementProps.top = -self.elementHeight;
				break;
			case 'toLeft':
				self.toggleElementProps.left = self.elementWidth;
				break;
			default:
				self.toggleElementProps.top = self.elementHeight;
				break;
		}

		self.$toggleElement
			.stop()
			.animate(
				self.toggleElementProps,
				self.settings.animationSpeed,
				self.settings.animationEasing,
				function() { self.settings.onHide(); });
	}

	$.fn[pluginName] = function(options) {
		this.each(function() {
			if(!$.data(this, 'plugin_' + pluginName)) {
				$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
			}
		});

		return this;
	}

})($, window, document, undefined);<commit_msg>Animataion to Animation<commit_after>;(function($, window, document, undefined) {

	var pluginName = 'hovercap',
			defaults = {
				toggleElement: '',
				toggleAnimation: 'slide',
				toggleDirection: 'toTop',
				animationSpeed: 200,
				animationEasing: 'swing',
				onSetup: function() {},
				onShow: function() {},
				onHide: function() {}
			};

	function Plugin(element, options) {
		this.element = element;
		this.settings = $.extend({}, defaults, options);
		this._defualts = defaults;
		this._name = pluginName;

		this.init();
	}

	Plugin.prototype.init = function() {
		var self = this;

		self.$element = $(self.element);
		self.$toggleElement = self.$element.find(self.settings.toggleElement);
		self.elementWidth = self.$element.outerWidth();
		self.elementHeight = self.$element.outerHeight();
		self.toggleElementProps = {};

		self.initToggleElement();

		self.$element.on({
			mouseenter: function() {
				if(self.settings.toggleAnimation == 'fade') {
					self.fadeShowElement();
					return;
				}
				self.slideShowElement();
			},
			mouseleave: function() {
				if(self.settings.toggleAnimation == 'fade') {
					self.fadeHideElement();
					return;
				}
				self.slideHideElement();
			}
		});
	}

	Plugin.prototype.initToggleElement = function() {
		var self = this;

		if(self.settings.toggleAnimation == 'slide') {
			switch(self.settings.toggleDirection) {
				case 'toRight':
					self.toggleElementProps = {
						top: 0,
						left: -self.elementWidth
					}
					break;
				case 'toBottom':
					self.toggleElementProps = {
						top: -self.elementHeight,
						left: 0
					}
					break;
				case 'toLeft':
					self.toggleElementProps = {
						top: 0,
						left: self.elementWidth
					}
					break;
				default:
					// default == toTop
					self.toggleElementProps = {
						top: self.elementHeight,
						left: 0
					}
					break;
			}
		}

		if(self.settings.toggleAnimation == 'fade') {
			self.toggleElementProps = {
				top: 0,
				left: 0,
				display: 'none'
			}
		}

		self.$toggleElement.css(self.toggleElementProps);
		self.settings.onSetup();
	}

	Plugin.prototype.fadeToggleElement = function() {
		var self = this;

		self.$toggleElement
			.stop()
			.fadeToggle(self.settings.animationSpeed, function() {
				self.settings.callBack();
			});
	}

	Plugin.prototype.fadeShowElement = function() {
		var self = this;

		self.$toggleElement
			.stop()
			.fadeIn(
				self.settings.animationSpeed,
				self.settings.animationEasing,
				function() { self.settings.onShow(); });
	}

	Plugin.prototype.fadeHideElement = function() {
		var self = this;

		self.$toggleElement
			.stop()
			.fadeOut(
				self.settings.animationSpeed,
				self.settings.animationEasing,
				function() { self.settings.onShow(); });
	}

	Plugin.prototype.slideShowElement = function() {
		var self = this;

		switch(self.settings.toggleDirection) {
			case 'toRight':
			case 'toLeft':
				self.toggleElementProps.left = 0;
				break;
			default:
				self.toggleElementProps.top = 0;
				break;
		}

		self.$toggleElement
			.stop()
			.animate(
				self.toggleElementProps,
				self.settings.animationSpeed,
				self.settings.animationEasing,
				function() { self.settings.onShow(); });
	}

	Plugin.prototype.slideHideElement = function() {
		var self = this;

		switch(self.settings.toggleDirection) {
			case 'toRight':
				self.toggleElementProps.left = -self.elementWidth;
				break;
			case 'toBottom':
				self.toggleElementProps.top = -self.elementHeight;
				break;
			case 'toLeft':
				self.toggleElementProps.left = self.elementWidth;
				break;
			default:
				self.toggleElementProps.top = self.elementHeight;
				break;
		}

		self.$toggleElement
			.stop()
			.animate(
				self.toggleElementProps,
				self.settings.animationSpeed,
				self.settings.animationEasing,
				function() { self.settings.onHide(); });
	}

	$.fn[pluginName] = function(options) {
		this.each(function() {
			if(!$.data(this, 'plugin_' + pluginName)) {
				$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
			}
		});

		return this;
	}

})($, window, document, undefined);
<|endoftext|>


<commit_before>'use strict';

angular.module('kalabox.installedSites', [])
/*
 * Class for seamless caching and updating.
 */
.factory('Cache', function($q, moment) {

  function Cache(duration) {
    // Cache duration, always in seconds.
    this.duration = duration;
    this.lastUpdated = null;
    this.result = $q.resolve();
  }

  /*
   * Callback function is only executed if cache has become stale.
   */
  Cache.prototype.update = function(cb) {
    var self = this;
    // Get the last time cache was updated.
    var last = this.lastUpdated || moment().subtract(1, 'years');
    // Get number of seconds since last time cache was updated.
    var sinceLastUpdate = last.diff(moment(), 'seconds');
    // If since last update is more than duration, then we should update.
    var shouldUpdate = sinceLastUpdate < (-self.duration);
    if (shouldUpdate) {
      // Update cached result.
      return $q.try(cb)
      .tap(function(result) {
        self.result = $q.resolve(result);
        self.lastUpdated = moment();
      });
    } else {
      // Used cached result.
      return self.result;
    }
  };

  /*
   * Reset cache.
   */
  Cache.prototype.reset = function() {
    this.lastUpdated = null;
  };

  return Cache;

})
/*
 * Class for encapsulating a site instance.
 */
.factory('Site', function(kbox, siteStateMap, jobQueueService) {

  // Constructor.
  function Site(opts) {
    this.name = opts.name;
    this.url = opts.url;
    this.folder = opts.folder;
    this.codeFolder = opts.codeFolder;
    this.image = 'http://placehold.it/300x250';
    this.provider = 'pantheon';
    this.framework = 'drupal';
  }

  /*
   * Returns boolean set to true if site is running.
   */
  Site.prototype.isRunning = function() {
    var self = this;
    return siteStateMap.get(self.name);
  };

  /*
   * Start site.
   */
  Site.prototype.start = function() {
    var self = this;
    return kbox.then(function(kbox) {
      return kbox.app.get(self.name)
      .tap(function(app) {
        return kbox.setAppContext(app);
      })
      .then(function(app) {
        return kbox.app.start(app);
      })
      .then(function() {
        return siteStateMap.cache.reset();
      });
    });
  };

  /*
   * Stop site.
   */
  Site.prototype.stop = function() {
    var self = this;
    return kbox.then(function(kbox) {
      return kbox.app.get(self.name)
      .tap(function(app) {
        return kbox.setAppContext(app);
      })
      .then(function(app) {
        return kbox.app.stop(app);
      })
      .then(function() {
        return siteStateMap.cache.reset();
      });
    });
  };

  /*
   * Pull site.
   */
  Site.prototype.pull = function() {
    var self = this;
    return kbox.then(function(kbox) {
      return kbox.app.get(self.name)
      .then(function(app) {
        return kbox.setAppContext(app);
      })
      .then(function() {
        return kbox.integrations.get('pantheon').pull();
      });
    });
  };

  /*
   * Remove site.
   */
  Site.prototype.trash = function() {
    var self = this;
    return kbox.then(function(kbox) {
      return kbox.app.get(self.name)
      .tap(function(app) {
        return kbox.setAppContext(app);
      })
      .then(function(app) {
        return kbox.app.destroy(app);
      })
      .then(function() {
        return siteStateMap.cache.reset();
      });
    });
  };

  // Static helper function to create from a kalabox app object.
  Site.fromApp = function(app) {
    return new Site({
      name: app.name,
      url: app.url,
      folder: app.root,
      codeFolder: app.config.codeRoot
    });
  };

  return Site;

})
/*
 * Object for controlling caches.
 */
.factory('siteCache', function(siteList, siteStateMap) {
  return {
    reset: function() {
      siteList.cache.reset();
      siteStateMap.cache.reset();
    }
  };
})
/*
 * Object for getting a cached list of site instances.
 */
.factory('siteList', function(Cache, kbox, Site) {
  var cache = new Cache(15);
  return {
    cache: cache,
    get: function(name) {
      return cache.update(function() {
        return kbox.then(function(kbox) {
          // Get list of apps.
          return kbox.app.list()
          // Only include apps with installed containers.
          .filter(function(app) {
            return kbox.app.isInstalled(app);
          })
          // Map to sites.
          .map(Site.fromApp);
        });
      })
      .then(function(sites) {
        return name ? sites[name] : sites;
      });
    }
  };
})
/*
 * Object for getting a cached list of site instance states.
 */
.factory('siteStateMap', function($q, kbox, Cache) {
  var cache = new Cache(15);
  return {
    cache: cache,
    get: function(name) {
      return cache.update(function() {
        var map = {};
        return kbox.then(function(kbox) {
          return kbox.app.list()
          .map(function(app) {
            return kbox.engine.list(app.name)
            .reduce(function(result, container) {
              return result || kbox.engine.isRunning(container.name);
            }, false)
            .then(function(result) {
              map[app.name] = result;
            });
          });
        })
        .then(function() {
          return map;
        });
      })
      .then(function(map) {
        if (name) {
          return map[name] !== undefined ? map[name] : false;
        } else {
          return map;
        }
      });
    }
  };

})
/*
 * Object for getting cached lists of sites etc.
 */
.factory('installedSitesService', function(siteList, siteStateMap) {

  return {
    sites: siteList.get,
    states: siteStateMap.get
  };

});
<commit_msg>Getting rid of reference to jobQueueService that was causing hinting to fail.<commit_after>'use strict';

angular.module('kalabox.installedSites', [])
/*
 * Class for seamless caching and updating.
 */
.factory('Cache', function($q, moment) {

  function Cache(duration) {
    // Cache duration, always in seconds.
    this.duration = duration;
    this.lastUpdated = null;
    this.result = $q.resolve();
  }

  /*
   * Callback function is only executed if cache has become stale.
   */
  Cache.prototype.update = function(cb) {
    var self = this;
    // Get the last time cache was updated.
    var last = this.lastUpdated || moment().subtract(1, 'years');
    // Get number of seconds since last time cache was updated.
    var sinceLastUpdate = last.diff(moment(), 'seconds');
    // If since last update is more than duration, then we should update.
    var shouldUpdate = sinceLastUpdate < (-self.duration);
    if (shouldUpdate) {
      // Update cached result.
      return $q.try(cb)
      .tap(function(result) {
        self.result = $q.resolve(result);
        self.lastUpdated = moment();
      });
    } else {
      // Used cached result.
      return self.result;
    }
  };

  /*
   * Reset cache.
   */
  Cache.prototype.reset = function() {
    this.lastUpdated = null;
  };

  return Cache;

})
/*
 * Class for encapsulating a site instance.
 */
.factory('Site', function(kbox, siteStateMap) {

  // Constructor.
  function Site(opts) {
    this.name = opts.name;
    this.url = opts.url;
    this.folder = opts.folder;
    this.codeFolder = opts.codeFolder;
    this.image = 'http://placehold.it/300x250';
    this.provider = 'pantheon';
    this.framework = 'drupal';
  }

  /*
   * Returns boolean set to true if site is running.
   */
  Site.prototype.isRunning = function() {
    var self = this;
    return siteStateMap.get(self.name);
  };

  /*
   * Start site.
   */
  Site.prototype.start = function() {
    var self = this;
    return kbox.then(function(kbox) {
      return kbox.app.get(self.name)
      .tap(function(app) {
        return kbox.setAppContext(app);
      })
      .then(function(app) {
        return kbox.app.start(app);
      })
      .then(function() {
        return siteStateMap.cache.reset();
      });
    });
  };

  /*
   * Stop site.
   */
  Site.prototype.stop = function() {
    var self = this;
    return kbox.then(function(kbox) {
      return kbox.app.get(self.name)
      .tap(function(app) {
        return kbox.setAppContext(app);
      })
      .then(function(app) {
        return kbox.app.stop(app);
      })
      .then(function() {
        return siteStateMap.cache.reset();
      });
    });
  };

  /*
   * Pull site.
   */
  Site.prototype.pull = function() {
    var self = this;
    return kbox.then(function(kbox) {
      return kbox.app.get(self.name)
      .then(function(app) {
        return kbox.setAppContext(app);
      })
      .then(function() {
        return kbox.integrations.get('pantheon').pull();
      });
    });
  };

  /*
   * Remove site.
   */
  Site.prototype.trash = function() {
    var self = this;
    return kbox.then(function(kbox) {
      return kbox.app.get(self.name)
      .tap(function(app) {
        return kbox.setAppContext(app);
      })
      .then(function(app) {
        return kbox.app.destroy(app);
      })
      .then(function() {
        return siteStateMap.cache.reset();
      });
    });
  };

  // Static helper function to create from a kalabox app object.
  Site.fromApp = function(app) {
    return new Site({
      name: app.name,
      url: app.url,
      folder: app.root,
      codeFolder: app.config.codeRoot
    });
  };

  return Site;

})
/*
 * Object for controlling caches.
 */
.factory('siteCache', function(siteList, siteStateMap) {
  return {
    reset: function() {
      siteList.cache.reset();
      siteStateMap.cache.reset();
    }
  };
})
/*
 * Object for getting a cached list of site instances.
 */
.factory('siteList', function(Cache, kbox, Site) {
  var cache = new Cache(15);
  return {
    cache: cache,
    get: function(name) {
      return cache.update(function() {
        return kbox.then(function(kbox) {
          // Get list of apps.
          return kbox.app.list()
          // Only include apps with installed containers.
          .filter(function(app) {
            return kbox.app.isInstalled(app);
          })
          // Map to sites.
          .map(Site.fromApp);
        });
      })
      .then(function(sites) {
        return name ? sites[name] : sites;
      });
    }
  };
})
/*
 * Object for getting a cached list of site instance states.
 */
.factory('siteStateMap', function($q, kbox, Cache) {
  var cache = new Cache(15);
  return {
    cache: cache,
    get: function(name) {
      return cache.update(function() {
        var map = {};
        return kbox.then(function(kbox) {
          return kbox.app.list()
          .map(function(app) {
            return kbox.engine.list(app.name)
            .reduce(function(result, container) {
              return result || kbox.engine.isRunning(container.name);
            }, false)
            .then(function(result) {
              map[app.name] = result;
            });
          });
        })
        .then(function() {
          return map;
        });
      })
      .then(function(map) {
        if (name) {
          return map[name] !== undefined ? map[name] : false;
        } else {
          return map;
        }
      });
    }
  };

})
/*
 * Object for getting cached lists of sites etc.
 */
.factory('installedSitesService', function(siteList, siteStateMap) {

  return {
    sites: siteList.get,
    states: siteStateMap.get
  };

});
<|endoftext|>


<commit_before>/*==================================================
 *  Span Highlight Decorator
 *==================================================
 */

Timeline.SpanHighlightDecorator = function(params) {
    // When evaluating params, test against null. Not "p in params". Testing against
    // null enables caller to explicitly request the default. Testing against "in" means
    // that the param has to be ommitted to get the default.
    this._unit = params.unit != null ? params.unit : SimileAjax.NativeDateUnit;
    this._startDate = (typeof params.startDate == "string") ?
        this._unit.parseFromObject(params.startDate) : params.startDate;
    this._endDate = (typeof params.endDate == "string") ?
        this._unit.parseFromObject(params.endDate) : params.endDate;
    this._startLabel = params.startLabel != null ? params.startLabel : ""; // not null!
    this._endLabel   = params.endLabel   != null ? params.endLabel   : ""; // not null!
    this._color = params.color;
    this._cssClass = params.cssClass != null ? params.cssClass : null;
    this._opacity = params.opacity != null ? params.opacity : 100;
         // Default z is 10, behind everything but background grid.
         // If inFront, then place just behind events, in front of everything else
    this._zIndex = (params.inFront != null && params.inFront) ? 113 : 10;
};

Timeline.SpanHighlightDecorator.prototype.initialize = function(band, timeline) {
    this._band = band;
    this._timeline = timeline;

    this._layerDiv = null;
};

Timeline.SpanHighlightDecorator.prototype.paint = function() {
    if (this._layerDiv != null) {
        this._band.removeLayerDiv(this._layerDiv);
    }
    this._layerDiv = this._band.createLayerDiv(this._zIndex);
    this._layerDiv.setAttribute("name", "span-highlight-decorator"); // for debugging
    this._layerDiv.style.display = "none";

    var minDate = this._band.getMinDate();
    var maxDate = this._band.getMaxDate();

    if (this._unit.compare(this._startDate, maxDate) < 0 &&
        this._unit.compare(this._endDate, minDate) > 0) {

        minDate = this._unit.later(minDate, this._startDate);
        maxDate = this._unit.earlier(maxDate, this._endDate);

        var minPixel = this._band.dateToPixelOffset(minDate);
        var maxPixel = this._band.dateToPixelOffset(maxDate);

        var doc = this._timeline.getDocument();

        var createTable = function() {
            var table = doc.createElement("table");
            table.insertRow(0).insertCell(0);
            return table;
        };

        var div = doc.createElement("div");
        div.className='timeline-highlight-decorator'
        if(this._cssClass) {
        	  div.className += ' ' + this._cssClass;
        }
        if(this._color != null) {
        	  div.style.backgroundColor = this._color;
        }
        if (this._opacity < 100) {
            SimileAjax.Graphics.setOpacity(div, this._opacity);
        }
        this._layerDiv.appendChild(div);

        var tableStartLabel = createTable();
        tableStartLabel.className = 'timeline-highlight-label timeline-highlight-label-start'
        var tdStart =  tableStartLabel.rows[0].cells[0]
        tdStart.innerHTML = this._startLabel;
        if (this._cssClass) {
        	  tdStart.className = 'label_' + this._cssClass;
        }
        this._layerDiv.appendChild(tableStartLabel);

        var tableEndLabel = createTable();
        tableEndLabel.className = 'timeline-highlight-label timeline-highlight-label-end'
        var tdEnd = tableEndLabel.rows[0].cells[0]
        tdEnd.innerHTML = this._endLabel;
        if (this._cssClass) {
        	   tdEnd.className = 'label_' + this._cssClass;
        }
        this._layerDiv.appendChild(tableEndLabel);

        if (this._timeline.isHorizontal()){
            div.style.left = minPixel + "px";
            div.style.width = (maxPixel - minPixel) + "px";

            tableStartLabel.style.right = (this._band.getTotalViewLength() - minPixel) + "px";
            tableStartLabel.style.width = (this._startLabel.length) + "em";

            tableEndLabel.style.left = maxPixel + "px";
            tableEndLabel.style.width = (this._endLabel.length) + "em";

        } else {
            div.style.top = minPixel + "px";
            div.style.height = (maxPixel - minPixel) + "px";

            tableStartLabel.style.bottom = minPixel + "px";
            tableStartLabel.style.height = "1.5px";

            tableEndLabel.style.top = maxPixel + "px";
            tableEndLabel.style.height = "1.5px";
        }
    }
    this._layerDiv.style.display = "block";
};

Timeline.SpanHighlightDecorator.prototype.softPaint = function() {
};

/*==================================================
 *  Point Highlight Decorator
 *==================================================
 */

Timeline.PointHighlightDecorator = function(params) {
    this._unit = params.unit != null ? params.unit : SimileAjax.NativeDateUnit;
    this._date = (typeof params.date == "string") ?
        this._unit.parseFromObject(params.date) : params.date;
    this._width = params.width != null ? params.width : 10;
      // Since the width is used to calculate placements (see minPixel, below), we
      // specify width here, not in css.
    this._color = params.color;
    this._cssClass = params.cssClass != null ? params.cssClass : '';
    this._opacity = params.opacity != null ? params.opacity : 100;
};

Timeline.PointHighlightDecorator.prototype.initialize = function(band, timeline) {
    this._band = band;
    this._timeline = timeline;
    this._layerDiv = null;
};

Timeline.PointHighlightDecorator.prototype.paint = function() {
    if (this._layerDiv != null) {
        this._band.removeLayerDiv(this._layerDiv);
    }
    this._layerDiv = this._band.createLayerDiv(10);
    this._layerDiv.setAttribute("name", "span-highlight-decorator"); // for debugging
    this._layerDiv.style.display = "none";

    var minDate = this._band.getMinDate();
    var maxDate = this._band.getMaxDate();

    if (this._unit.compare(this._date, maxDate) < 0 &&
        this._unit.compare(this._date, minDate) > 0) {

        var pixel = this._band.dateToPixelOffset(this._date);
        var minPixel = pixel - Math.round(this._width / 2);

        var doc = this._timeline.getDocument();

        var div = doc.createElement("div");
        div.className='timeline-highlight-point-decorator';
        div.className += ' ' + this._cssClass;

        if(this._color != null) {
        	  div.style.backgroundColor = this._color;
        }
        if (this._opacity < 100) {
            SimileAjax.Graphics.setOpacity(div, this._opacity);
        }
        this._layerDiv.appendChild(div);

        if (this._timeline.isHorizontal()) {
            div.style.left = minPixel + "px";
            div.style.width = this._width;
        } else {
            div.style.top = minPixel + "px";
            div.style.height = this._width;
        }
    }
    this._layerDiv.style.display = "block";
};

Timeline.PointHighlightDecorator.prototype.softPaint = function() {
};
<commit_msg>TIMELINE: fixed point highlight decorators that weren't showing because the width was not set in pixels<commit_after>/*==================================================
 *  Span Highlight Decorator
 *==================================================
 */

Timeline.SpanHighlightDecorator = function(params) {
    // When evaluating params, test against null. Not "p in params". Testing against
    // null enables caller to explicitly request the default. Testing against "in" means
    // that the param has to be ommitted to get the default.
    this._unit = params.unit != null ? params.unit : SimileAjax.NativeDateUnit;
    this._startDate = (typeof params.startDate == "string") ?
        this._unit.parseFromObject(params.startDate) : params.startDate;
    this._endDate = (typeof params.endDate == "string") ?
        this._unit.parseFromObject(params.endDate) : params.endDate;
    this._startLabel = params.startLabel != null ? params.startLabel : ""; // not null!
    this._endLabel   = params.endLabel   != null ? params.endLabel   : ""; // not null!
    this._color = params.color;
    this._cssClass = params.cssClass != null ? params.cssClass : null;
    this._opacity = params.opacity != null ? params.opacity : 100;
         // Default z is 10, behind everything but background grid.
         // If inFront, then place just behind events, in front of everything else
    this._zIndex = (params.inFront != null && params.inFront) ? 113 : 10;
};

Timeline.SpanHighlightDecorator.prototype.initialize = function(band, timeline) {
    this._band = band;
    this._timeline = timeline;

    this._layerDiv = null;
};

Timeline.SpanHighlightDecorator.prototype.paint = function() {
    if (this._layerDiv != null) {
        this._band.removeLayerDiv(this._layerDiv);
    }
    this._layerDiv = this._band.createLayerDiv(this._zIndex);
    this._layerDiv.setAttribute("name", "span-highlight-decorator"); // for debugging
    this._layerDiv.style.display = "none";

    var minDate = this._band.getMinDate();
    var maxDate = this._band.getMaxDate();

    if (this._unit.compare(this._startDate, maxDate) < 0 &&
        this._unit.compare(this._endDate, minDate) > 0) {

        minDate = this._unit.later(minDate, this._startDate);
        maxDate = this._unit.earlier(maxDate, this._endDate);

        var minPixel = this._band.dateToPixelOffset(minDate);
        var maxPixel = this._band.dateToPixelOffset(maxDate);

        var doc = this._timeline.getDocument();

        var createTable = function() {
            var table = doc.createElement("table");
            table.insertRow(0).insertCell(0);
            return table;
        };

        var div = doc.createElement("div");
        div.className='timeline-highlight-decorator'
        if(this._cssClass) {
        	  div.className += ' ' + this._cssClass;
        }
        if(this._color != null) {
        	  div.style.backgroundColor = this._color;
        }
        if (this._opacity < 100) {
            SimileAjax.Graphics.setOpacity(div, this._opacity);
        }
        this._layerDiv.appendChild(div);

        var tableStartLabel = createTable();
        tableStartLabel.className = 'timeline-highlight-label timeline-highlight-label-start'
        var tdStart =  tableStartLabel.rows[0].cells[0]
        tdStart.innerHTML = this._startLabel;
        if (this._cssClass) {
        	  tdStart.className = 'label_' + this._cssClass;
        }
        this._layerDiv.appendChild(tableStartLabel);

        var tableEndLabel = createTable();
        tableEndLabel.className = 'timeline-highlight-label timeline-highlight-label-end'
        var tdEnd = tableEndLabel.rows[0].cells[0]
        tdEnd.innerHTML = this._endLabel;
        if (this._cssClass) {
        	   tdEnd.className = 'label_' + this._cssClass;
        }
        this._layerDiv.appendChild(tableEndLabel);

        if (this._timeline.isHorizontal()){
            div.style.left = minPixel + "px";
            div.style.width = (maxPixel - minPixel) + "px";

            tableStartLabel.style.right = (this._band.getTotalViewLength() - minPixel) + "px";
            tableStartLabel.style.width = (this._startLabel.length) + "em";

            tableEndLabel.style.left = maxPixel + "px";
            tableEndLabel.style.width = (this._endLabel.length) + "em";

        } else {
            div.style.top = minPixel + "px";
            div.style.height = (maxPixel - minPixel) + "px";

            tableStartLabel.style.bottom = minPixel + "px";
            tableStartLabel.style.height = "1.5px";

            tableEndLabel.style.top = maxPixel + "px";
            tableEndLabel.style.height = "1.5px";
        }
    }
    this._layerDiv.style.display = "block";
};

Timeline.SpanHighlightDecorator.prototype.softPaint = function() {
};

/*==================================================
 *  Point Highlight Decorator
 *==================================================
 */

Timeline.PointHighlightDecorator = function(params) {
    this._unit = params.unit != null ? params.unit : SimileAjax.NativeDateUnit;
    this._date = (typeof params.date == "string") ?
        this._unit.parseFromObject(params.date) : params.date;
    this._width = params.width != null ? params.width : 10;
      // Since the width is used to calculate placements (see minPixel, below), we
      // specify width here, not in css.
    this._color = params.color;
    this._cssClass = params.cssClass != null ? params.cssClass : '';
    this._opacity = params.opacity != null ? params.opacity : 100;
};

Timeline.PointHighlightDecorator.prototype.initialize = function(band, timeline) {
    this._band = band;
    this._timeline = timeline;
    this._layerDiv = null;
};

Timeline.PointHighlightDecorator.prototype.paint = function() {
    if (this._layerDiv != null) {
        this._band.removeLayerDiv(this._layerDiv);
    }
    this._layerDiv = this._band.createLayerDiv(10);
    this._layerDiv.setAttribute("name", "span-highlight-decorator"); // for debugging
    this._layerDiv.style.display = "none";

    var minDate = this._band.getMinDate();
    var maxDate = this._band.getMaxDate();

    if (this._unit.compare(this._date, maxDate) < 0 &&
        this._unit.compare(this._date, minDate) > 0) {

        var pixel = this._band.dateToPixelOffset(this._date);
        var minPixel = pixel - Math.round(this._width / 2);

        var doc = this._timeline.getDocument();

        var div = doc.createElement("div");
        div.className='timeline-highlight-point-decorator';
        div.className += ' ' + this._cssClass;

        if(this._color != null) {
        	  div.style.backgroundColor = this._color;
        }
        if (this._opacity < 100) {
            SimileAjax.Graphics.setOpacity(div, this._opacity);
        }
        this._layerDiv.appendChild(div);

        if (this._timeline.isHorizontal()) {
            div.style.left = minPixel + "px";
            div.style.width = this._width + "px";
        } else {
            div.style.top = minPixel + "px";
            div.style.height = this._width + "px";
        }
    }
    this._layerDiv.style.display = "block";
};

Timeline.PointHighlightDecorator.prototype.softPaint = function() {
};
<|endoftext|>


<commit_before>// Copyright 2017-2020, University of Colorado Boulder

/**
 * Bar chart for sims that need to display separate values. This chart is vertically aligned, with bars that represent
 * values within a specified range.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 * @author Denzell Barnett (PhET Interactive Simulations)
 */

import merge from '../../phet-core/js/merge.js';
import ArrowNode from '../../scenery-phet/js/ArrowNode.js';
import PhetFont from '../../scenery-phet/js/PhetFont.js';
import HBox from '../../scenery/js/nodes/HBox.js';
import Line from '../../scenery/js/nodes/Line.js';
import Node from '../../scenery/js/nodes/Node.js';
import RichText from '../../scenery/js/nodes/RichText.js';
import VBox from '../../scenery/js/nodes/VBox.js';
import Color from '../../scenery/js/util/Color.js';
import Panel from '../../sun/js/Panel.js';
import BarNode from './BarNode.js';
import griddle from './griddle.js';

class BarChartNode extends Node {
  /**
   * NOTE: update() should be called manually to update the view of this Node. For performance, it doesn't update on
   * every change.
   *
   * @param {Array.<Object>} bars - Entries of the format:
   *   {
   *     entries: {Array.<{ property: {Property.<number>}, color: {paint} }>}
   *     [labelString]: {string} formatted for RichText
   *     [labelColor]: {PaintDef} if provided, sets color of the bar label, otherwise label match color of bar
   *     [labelNode]: {node} displayed below the label string if the label string exist
   *     [offScaleArrowFill]: {paint} - If provided, allows bar-specific arrow fills (that are different than the color)
   *   }
   * @param {Property.<Range>} rangeProperty
   * @param {Object} [options]
   */
  constructor( bars, rangeProperty, options ) {

    options = merge( {

      // {number} - Space in-between each bar
      barSpacing: 12,

      // provided to the x-axis Line
      xAxisOptions: {
        stroke: 'black',
        lineWidth: 1,

        minPadding: 8,
        maxExtension: 5
      },
      barOptions: {
        // See BarNode's options.
      },

      // {*|null} - options for the bar RichText labels, see extended options below
      barLabelOptions: null,

      // {Color}  Color of the background behind the labels
      labelBackgroundColor: Color.TRANSPARENT
    }, options );

    super();

    // @private {Array.<Object>}
    this.bars = bars;

    // For vertical orientation
    options.barOptions = merge( {}, options.barOptions, {
      rotation: Math.PI
    } );

    // passed along to the RichText
    options.barLabelOptions = merge( {
      font: new PhetFont( { size: 12, weight: 'bold' } ),

      // good for vertical bars that are close to each other
      rotation: -Math.PI / 2,

      // chosen by inspection, good for short labels
      maxWidth: 40
    }, options.barLabelOptions );

    assert && assert( options.barLabelOptions.fill === undefined, 'label fill set by entries, see constructor' );

    // @private {Array.<BarNode>} Initializing barNodes.
    this.barNodes = bars.map( function( bar ) {
      assert && assert( bar.entries && Array.isArray( bar.entries ) );
      const barOptions = merge( {
        offScaleArrowFill: bar.offScaleArrowFill === undefined ? ( bar.entries.length > 1 ? '#bbb' : bar.entries[ 0 ].color ) : bar.offScaleArrowFill
      }, options.barOptions );
      return new BarNode( bar.entries, rangeProperty, barOptions );
    } );

    // @private {Array.<Node>}
    this.barLabelNodes = bars.map( function( bar ) {
      const barLabelVBox = new VBox( { spacing: 4 } );
      if ( bar.labelString ) {

        const labelText = new RichText( bar.labelString, merge( {}, options.barLabelOptions, {
          fill: bar.labelColor || 'black'
        } ) );

        // Transparent background for each label, used to make the label standout against bar if the bar falls beneath the x-Axis.
        const valuePanel = new Panel( labelText, {
          stroke: null,
          fill: options.labelBackgroundColor, // put transparency in the color so that the children aren't transparent
          cornerRadius: 3,
          xMargin: 0,
          yMargin: 2
        } );
        barLabelVBox.addChild( valuePanel );
      }
      if ( bar.labelNode ) {
        barLabelVBox.addChild( bar.labelNode );
      }
      return barLabelVBox;
    } );

    // Adding barNodes into HBox
    const barBox = new HBox( {
      spacing: options.barSpacing,
      align: 'origin',
      children: this.barNodes
    } );

    // Adding barNode labels into Node.
    const labelBox = new Node( {
      children: this.barLabelNodes
    } );

    // Manual positioning of labels to match position of barNodes in HBox.
    for ( let i = 0; i < bars.length; i++ ) {

      // Checks if the labelBox's VBox has any children.
      if ( typeof ( labelBox.children[ i ].children[ 0 ] ) !== 'undefined' ) {
        labelBox.children[ i ].centerX = this.barNodes[ i ].centerX;
        labelBox.children[ i ].top = 3;
      }
    }
    this.addChild( barBox );
    this.addChild( labelBox );

    // Initializing xAxis
    const xAxis = new Line( -options.xAxisOptions.minPadding, 0, barBox.width + options.xAxisOptions.maxExtension, 0, options.xAxisOptions );
    this.addChild( xAxis );

    // Initializing yAxis
    const yAxis = new ArrowNode( 0, 0, 0, -rangeProperty.value.max, {
      tailWidth: 0.5,
      headHeight: 9,
      headWidth: 8
    } );
    rangeProperty.link( function( range ) {
      yAxis.setTailAndTip( -options.xAxisOptions.minPadding, 0, -options.xAxisOptions.minPadding, -range.max );
    } );
    this.addChild( yAxis );

    // Update localBounds to the correct value
    rangeProperty.link( range => {
      this.localBounds = this.localBounds.withMinY( Math.min( yAxis.bottom, -range.max ) )
        .withMaxY( Math.max( options.xAxisOptions.lineWidth / 2, -range.min, labelBox.bottom ) );
    } );

    this.mutate( options );
  }

  /**
   * Updates all of the bar nodes.
   * @public
   */
  update() {
    for ( let i = 0; i < this.barNodes.length; i++ ) {
      this.barNodes[ i ].update();
    }
  }
}

griddle.register( 'BarChartNode', BarChartNode );
export default BarChartNode;<commit_msg>fix memory leak in BarChartsNode, https://github.com/phetsims/griddle/issues/68<commit_after>// Copyright 2017-2020, University of Colorado Boulder

/**
 * Bar chart for sims that need to display separate values. This chart is vertically aligned, with bars that represent
 * values within a specified range.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 * @author Denzell Barnett (PhET Interactive Simulations)
 */

import merge from '../../phet-core/js/merge.js';
import ArrowNode from '../../scenery-phet/js/ArrowNode.js';
import PhetFont from '../../scenery-phet/js/PhetFont.js';
import HBox from '../../scenery/js/nodes/HBox.js';
import Line from '../../scenery/js/nodes/Line.js';
import Node from '../../scenery/js/nodes/Node.js';
import RichText from '../../scenery/js/nodes/RichText.js';
import VBox from '../../scenery/js/nodes/VBox.js';
import Color from '../../scenery/js/util/Color.js';
import Panel from '../../sun/js/Panel.js';
import BarNode from './BarNode.js';
import griddle from './griddle.js';

class BarChartNode extends Node {

  /**
   * NOTE: update() should be called manually to update the view of this Node. For performance, it doesn't update on
   * every change.
   *
   * @param {Array.<Object>} bars - Entries of the format:
   *   {
   *     entries: {Array.<{ property: {Property.<number>}, color: {paint} }>}
   *     [labelString]: {string} formatted for RichText
   *     [labelColor]: {PaintDef} if provided, sets color of the bar label, otherwise label match color of bar
   *     [labelNode]: {node} displayed below the label string if the label string exist
   *     [offScaleArrowFill]: {paint} - If provided, allows bar-specific arrow fills (that are different than the color)
   *   }
   * @param {Property.<Range>} yRangeProperty - range of the y axis
   * @param {Object} [options]
   */
  constructor( bars, yRangeProperty, options ) {

    options = merge( {

      // {number} - Space in-between each bar
      barSpacing: 12,

      // provided to the x-axis Line
      xAxisOptions: {
        stroke: 'black',
        lineWidth: 1,

        minPadding: 8,
        maxExtension: 5
      },
      barOptions: {
        // See BarNode's options.
      },

      // {*|null} - options for the bar RichText labels, see extended options below
      barLabelOptions: null,

      // {Color}  Color of the background behind the labels
      labelBackgroundColor: Color.TRANSPARENT
    }, options );

    super();

    // @private {Array.<Object>}
    this.bars = bars;

    // For vertical orientation
    options.barOptions = merge( {}, options.barOptions, {
      rotation: Math.PI
    } );

    // passed along to the RichText
    options.barLabelOptions = merge( {
      font: new PhetFont( { size: 12, weight: 'bold' } ),

      // good for vertical bars that are close to each other
      rotation: -Math.PI / 2,

      // chosen by inspection, good for short labels
      maxWidth: 40
    }, options.barLabelOptions );

    assert && assert( options.barLabelOptions.fill === undefined, 'label fill set by entries, see constructor' );

    // @private {Array.<BarNode>} Initializing barNodes.
    this.barNodes = bars.map( function( bar ) {
      assert && assert( bar.entries && Array.isArray( bar.entries ) );
      const barOptions = merge( {
        offScaleArrowFill: bar.offScaleArrowFill === undefined ? ( bar.entries.length > 1 ? '#bbb' : bar.entries[ 0 ].color ) : bar.offScaleArrowFill
      }, options.barOptions );
      return new BarNode( bar.entries, yRangeProperty, barOptions );
    } );

    // @private {Array.<Node>}
    this.barLabelNodes = bars.map( function( bar ) {
      const barLabelVBox = new VBox( { spacing: 4 } );
      if ( bar.labelString ) {

        const labelText = new RichText( bar.labelString, merge( {}, options.barLabelOptions, {
          fill: bar.labelColor || 'black'
        } ) );

        // Transparent background for each label, used to make the label standout against bar if the bar falls beneath the x-Axis.
        const valuePanel = new Panel( labelText, {
          stroke: null,
          fill: options.labelBackgroundColor, // put transparency in the color so that the children aren't transparent
          cornerRadius: 3,
          xMargin: 0,
          yMargin: 2
        } );
        barLabelVBox.addChild( valuePanel );
      }
      if ( bar.labelNode ) {
        barLabelVBox.addChild( bar.labelNode );
      }
      return barLabelVBox;
    } );

    // Adding barNodes into HBox
    const barBox = new HBox( {
      spacing: options.barSpacing,
      align: 'origin',
      children: this.barNodes
    } );

    // Adding barNode labels into Node.
    const labelBox = new Node( {
      children: this.barLabelNodes
    } );

    // Manual positioning of labels to match position of barNodes in HBox.
    for ( let i = 0; i < bars.length; i++ ) {

      // Checks if the labelBox's VBox has any children.
      if ( typeof ( labelBox.children[ i ].children[ 0 ] ) !== 'undefined' ) {
        labelBox.children[ i ].centerX = this.barNodes[ i ].centerX;
        labelBox.children[ i ].top = 3;
      }
    }
    this.addChild( barBox );
    this.addChild( labelBox );

    // Initializing xAxis
    const xAxis = new Line( -options.xAxisOptions.minPadding, 0, barBox.width + options.xAxisOptions.maxExtension, 0, options.xAxisOptions );
    this.addChild( xAxis );

    // Initializing yAxis
    const yAxis = new ArrowNode( 0, 0, 0, -yRangeProperty.value.max, {
      tailWidth: 0.5,
      headHeight: 9,
      headWidth: 8
    } );
    this.addChild( yAxis );

    const rangeObserver = range => {

      yAxis.setTailAndTip( -options.xAxisOptions.minPadding, 0, -options.xAxisOptions.minPadding, -range.max );

      // Update localBounds to the correct value
      this.localBounds = this.localBounds.withMinY( Math.min( yAxis.bottom, -range.max ) )
        .withMaxY( Math.max( options.xAxisOptions.lineWidth / 2, -range.min, labelBox.bottom ) );
    };
    yRangeProperty.link( rangeObserver );

    this.mutate( options );

    // @private
    this.disposeBarChartNode = () => {
      yRangeProperty.unlink( rangeObserver );
    };
  }

  /**
   * @public
   * @override
   */
  dispose() {
    this.disposeBarChartNode();
    super.dispose();
  }

  /**
   * Updates all of the bar nodes.
   * @public
   */
  update() {
    for ( let i = 0; i < this.barNodes.length; i++ ) {
      this.barNodes[ i ].update();
    }
  }
}

griddle.register( 'BarChartNode', BarChartNode );
export default BarChartNode;<|endoftext|>


<commit_before>/**
 * PDP-11 Emulation for JavaScript
 */

/**
 * MemoryUnibus prototype
 *
 * This prototype provides a UNIBUS memory system.
 * @author Takashi Toyoshima <toyoshim@gmail.com>
 */
function MemoryUnibus () {
    this.logging = false;
    this.rk = new DeviceRk(this);
    this.tt = new DeviceTt(this);
    this.ram = new Uint16Array(65536);  // 128KB
    for (var i = 0; i < 65536; i++)
        this.ram[i] = 0;
}

/**
 * Inherit Memory prototype.
 */
MemoryUnibus.prototype = new Memory();
MemoryUnibus.prototype.constructor = MemoryUnibus;

/**
 * Write 8-bit data to addressed memory.
 * @param address memory address to write
 * @param data data to write
 */
MemoryUnibus.prototype.writeChar = function (address, data) {
    if (this.logging)
        Log.getLog().info("WC " + Log.toOct(address, 7) + " <= $" +
                Log.toHex(data , 2));
    var result = this._read(address);
    if (result < 0)
        throw RangeError("Memory " + Log.toOct(address, 7) +
                " write not implemented.");
    if ((address & 1) == 0)
        result = (result & 0xff00) | data;
    else
        result = (result & 0x00ff) | (data << 8);
    if (!this._write(address, result))
        throw RangeError("Memory " + Log.toOct(address, 7) +
                " write not implemented.");
};

/**
 * Read 8-bit data from addressed memory.
 * @param address memory address to read
 * @return read data
 */
MemoryUnibus.prototype.readChar = function (address) {
    var result = -1;
    result = this._read(address);
    if (result >= 0) {
        if ((address & 1) == 0)
            result &= 0xff;
        else
            result = (result >> 8) & 0xff;
    }
    if (this.logging)
        Log.getLog().info("RC " + Log.toOct(address, 7) + " => $" +
                Log.toHex(result , 2));
    if (result < 0)
        throw RangeError("Memory " + Log.toOct(address, 7) +
                " read not implemented.");
    return result;
};

/**
 * Write 16-bit data to addressed memory.
 * @param address memory address to write
 * @param data data to write
 */
MemoryUnibus.prototype.writeShort = function (address, data) {
    if (this.logging)
        Log.getLog().info("WS " + Log.toOct(address, 7) + " <= $" +
                Log.toHex(data , 4));
    if ((address & 1) != 0)
        throw RangeError("Memory alignment error.");
    if (!this._write(address, data))
        throw RangeError("Memory " + Log.toOct(address, 7) +
                " write not implemented.");
};

/**
 * Read 16-bit data from addressed memory.
 * @param address memory address to read
 * @return read data
 */
MemoryUnibus.prototype.readShort = function (address) {
    var result = this._read(address);
    if (this.logging)
        Log.getLog().info("RS " + Log.toOct(address, 7) + " => $" +
                Log.toHex(result , 4));
    if ((address & 1) != 0)
        throw RangeError("Memory alignment error.");
    if (result < 0)
        throw RangeError("Memory " + Log.toOct(address, 7) +
                " read not implemented.");
    return result;
};

/**
 * Internally write 16-bit data to addressed memory.
 * @param address memory address to write
 * @param data data to write
 * @return success
 */
MemoryUnibus.prototype._write = function (address, data) {
    if (data < 0)
        Log.getLog().fatal("Internal error: write negative value.");
    if (address < 0x20000) {
        this.ram[address >> 1] = data;
        return true;
    }
    if (this.rk.write(address, data)) return true;
    if (this.tt.write(address, data)) return true;
    return false;
};

/**
 * Internally read 16-bit data from addressed memory.
 * @param address memory address to read
 * @return read data (-1: failure)
 */
MemoryUnibus.prototype._read = function (address) {
    if (address < 0x20000)
        return this.ram[address >> 1];
    var result = -1;
    if (result < 0)
        result = this.rk.read(address);
    if (result < 0)
        result = this.tt.read(address);
    return result;
};
<commit_msg>Change memory logging format<commit_after>/**
 * PDP-11 Emulation for JavaScript
 */

/**
 * MemoryUnibus prototype
 *
 * This prototype provides a UNIBUS memory system.
 * @author Takashi Toyoshima <toyoshim@gmail.com>
 */
function MemoryUnibus () {
    this.logging = false;
    this.rk = new DeviceRk(this);
    this.tt = new DeviceTt(this);
    this.ram = new Uint16Array(65536);  // 128KB
    for (var i = 0; i < 65536; i++)
        this.ram[i] = 0;
}

/**
 * Inherit Memory prototype.
 */
MemoryUnibus.prototype = new Memory();
MemoryUnibus.prototype.constructor = MemoryUnibus;

/**
 * Write 8-bit data to addressed memory.
 * @param address memory address to write
 * @param data data to write
 */
MemoryUnibus.prototype.writeChar = function (address, data) {
    if (this.logging)
        Log.getLog().info("WC: " + Log.toOct(address, 7) + " <= " +
                Log.toOct(data , 4));
    var result = this._read(address);
    if (result < 0)
        throw RangeError("Memory " + Log.toOct(address, 7) +
                " write not implemented.");
    if ((address & 1) == 0)
        result = (result & 0xff00) | data;
    else
        result = (result & 0x00ff) | (data << 8);
    if (!this._write(address, result))
        throw RangeError("Memory " + Log.toOct(address, 7) +
                " write not implemented.");
};

/**
 * Read 8-bit data from addressed memory.
 * @param address memory address to read
 * @return read data
 */
MemoryUnibus.prototype.readChar = function (address) {
    var result = -1;
    result = this._read(address);
    if (result >= 0) {
        if ((address & 1) == 0)
            result &= 0xff;
        else
            result = (result >> 8) & 0xff;
    }
    if (result < 0)
        throw RangeError("Memory " + Log.toOct(address, 7) +
                " read not implemented.");
    return result;
};

/**
 * Write 16-bit data to addressed memory.
 * @param address memory address to write
 * @param data data to write
 */
MemoryUnibus.prototype.writeShort = function (address, data) {
    if (this.logging)
        Log.getLog().info("WS: " + Log.toOct(address, 7) + " <= " +
                Log.toOct(data , 7));
    if ((address & 1) != 0)
        throw RangeError("Memory alignment error.");
    if (!this._write(address, data))
        throw RangeError("Memory " + Log.toOct(address, 7) +
                " write not implemented.");
};

/**
 * Read 16-bit data from addressed memory.
 * @param address memory address to read
 * @return read data
 */
MemoryUnibus.prototype.readShort = function (address) {
    var result = this._read(address);
    if ((address & 1) != 0)
        throw RangeError("Memory alignment error.");
    if (result < 0)
        throw RangeError("Memory " + Log.toOct(address, 7) +
                " read not implemented.");
    return result;
};

/**
 * Internally write 16-bit data to addressed memory.
 * @param address memory address to write
 * @param data data to write
 * @return success
 */
MemoryUnibus.prototype._write = function (address, data) {
    if (data < 0)
        Log.getLog().fatal("Internal error: write negative value.");
    if (address < 0x20000) {
        this.ram[address >> 1] = data;
        return true;
    }
    if (this.rk.write(address, data)) return true;
    if (this.tt.write(address, data)) return true;
    return false;
};

/**
 * Internally read 16-bit data from addressed memory.
 * @param address memory address to read
 * @return read data (-1: failure)
 */
MemoryUnibus.prototype._read = function (address) {
    if (address < 0x20000)
        return this.ram[address >> 1];
    var result = -1;
    if (result < 0)
        result = this.rk.read(address);
    if (result < 0)
        result = this.tt.read(address);
    return result;
};
<|endoftext|>


<commit_before>/*global define, console*/

/*
 | Copyright 2015 ESRI (UK) Limited
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */

define([
    'dojo/text!./templates/NearestLayer.html',
    'dojo/_base/declare',
    "dojo/_base/lang",
    'dijit/_Widget',
    'dijit/_TemplatedMixin',
    'dijit/_WidgetsInTemplateMixin',
    'dojo/dom-construct',
    './_NearestBase',
    './NearestItem',
    'esri/dijit/PopupTemplate',
    'dojo/topic',
    'dojo/on',
    'esri/dijit/PopupRenderer',
    'esri/graphic',
    'dojo/i18n!./nls/Nearest'
],
function (
    template, declare, lang, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, domConstruct, _NearestBase, NearestItem, PopupTemplate, topic, on, PopupRenderer, Graphic, i18n) {

    return declare([_Widget, _NearestBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
        // description:
        //    Find the nearest features around a point

        templateString: template,
        baseClass: 'nearestLayer',
        widgetsInTemplate: true,
        titleText: "",
        titleField: [],
        expanded: false,

        // Properties to be sent into constructor

        constructor: function (options, srcRefNode) {
            this.options = {
                results: null,
                layerInfo: null,
                maxFeatures: 5,
                distance: 0,
                distanceUnits: "m",
                layerOptions: null,
                parentId: ""
            };

            // mix in settings and defaults
            var defaults = lang.mixin({}, this.options, options);

            // Set properties
            this.set("results", defaults.results);
            this.set("layerInfo", defaults.layerInfo);
            this.set("maxFeatures", defaults.maxFeatures);
            this.set("distance", defaults.distance);
            this.set("distanceUnits", defaults.distanceUnits);
            this.set("layerOptions", defaults.layerOptions);
            this.set("parentId", defaults.parentId);

            // widget node
            this.domNode = srcRefNode;
        },

        postMixInProperties: function () {
            var result = this.results.result,
                template = new PopupTemplate(this.layerInfo.popupInfo),
                layerName = this.layerInfo.layerName,
                layerItemId = this.results.id.replace(/ /g, '-'),
                titleTextSplit, indT = 0, layerNameEle;

            this.titleText = template.info.title.toString();
            this.titleField = [];

            // Check the title to see if it contains a field
            titleTextSplit = this.titleText.split('}');

            for (indT = 0; indT < titleTextSplit.length; indT++) {
                if (titleTextSplit[indT].indexOf('{') > -1) {
                    this.titleField.push(titleTextSplit[indT].substr(titleTextSplit[indT].indexOf('{') + 1));
                }
            }

            if (this.titleField.length === 0) {
                this.titleField.push(template.info.fieldInfos[0].fieldName);
            }

            // For each layer in the results add a row to the list
            layerNameEle = this.results.id.replace(/ /g, '-');

            // Remove any special characters that may cause element name errors
            layerNameEle = layerNameEle.replace(/[^\w\s-]/gi, '');

            // Add in item id
            layerNameEle = layerNameEle + "-" + layerItemId;

            this.set("layerName", layerName || this.results.id);
            this.set("layerId", layerNameEle);
            this.set("numberOfFeatures", result.length);

            if (this.layerOptions.display === "fixed") {
                this.set("expanded", true);
                this.set("expandedClass", "in");
                this.set("collapseClass", "");
                this.set("layerHref", "#/");
                this.set("fixedClass", "nearestLayer-fixed");
            }
            else {
                this.set("expanded", false);
                this.set("expandedClass", "");
                this.set("collapseClass", "collapse");
                this.set("layerHref", "#" + layerNameEle);
                this.set("fixedClass", "nearestLayer-expandable");
            }

            if (this.layerOptions.showCounters) {
                this.set("showCountersVisible", "block");
            }
            else {
                this.set("showCountersVisible","none");
            }

            if (this.numberOfFeatures === 0) {
                this.set("counterWording", i18n.noresults + " " + this._getDistance(this.distanceUnits, this.distance) + " " + this._getDistanceUnits(this.distanceUnits));
            }
            else {
                this.set("counterWording", i18n.showingclosest + " " + this.numberOfFeatures + " " + i18n.within + " " + this._getDistance(this.distanceUnits, this.distance) + " " + this._getDistanceUnits(this.distanceUnits));
            }

            this.inherited(arguments);
        },

        postCreate: function () {
            // summary:
            //    Overrides method of same name in dijit._Widget.
            // tags:
            //    private

            this._init();
            this.setupConnections();
            this.inherited(arguments);

        },

        // start widget. called by user
        startup: function () {

        },

        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function () {
            // call the superclass method of the same name.
            this.inherited(arguments);
        },

        setupConnections: function () {
            // summary:
            //    wire events, and such
            //
            var _this = this;

            // Fire event for clicking on layer name if not using fixed layout
            if (this.layerOptions.display !== "fixed") {
                on(this.showList, "click", function (evt) {
                    _this.expanded = !_this.expanded;
                    topic.publish("Nearest::show-layer", _this.results.result, _this.results.layerInfo, _this.expanded, _this);
                });
            }
        },

        /* ---------------- */
        /* Public Functions */
        /* ---------------- */

        /* ---------------- */
        /* Private Functions */
        /* ---------------- */

        _init: function () {
            // summary:
            //    If we have any results then display them
            //
            if (this.results.result) {
                this._createFeaturesList();
            }
        },

        _createFeaturesList: function () {
            // summary:
            //    Creates the list of items for this layer from the features list.
            //

            var attributes, item,
            featureInd = 0, fL = 0, feature, itemDiv,
            template = new PopupTemplate(this.layerInfo.popupInfo), g, rend;

            // For each feature and a sub row
            for (featureInd = 0, fL = this.results.result.length; featureInd < fL; featureInd++) {
                feature = this.results.result[featureInd];
                attributes = feature.feature.attributes;

                // Set the info template for the feature
                this.results.result[featureInd].feature.infoTemplate = template;
                g = new Graphic(this.results.result[featureInd].feature.geometry, this.results.layerInfo.renderer, feature.feature.attributes, template);

                rend = new PopupRenderer({ template: template, graphic: g });
                rend.startup();

                // layer node
                itemDiv = domConstruct.create("div", {});
                domConstruct.place(itemDiv, this._features, "last");

                item = new NearestItem({
                    feature: feature,
                    layerItemId: this.layerId,
                    distanceUnits: this.distanceUnits,
                    distance: this.results.result[featureInd].distance.toFixed(2),
                    titleText: this.titleText,
                    titleField: this.titleField,
                    featureNumber: 1 + parseInt(featureInd, 10),
                    description: rend.domNode.innerHTML,
                    renderer: this.results.layerInfo.renderer,
                    opacity: this.results.layerInfo.opacity,
                    layerOptions: this.layerOptions
                }, itemDiv);

                item.startup();

            }
        }
    });
});<commit_msg>Remove distance formatting<commit_after>/*global define, console*/

/*
 | Copyright 2015 ESRI (UK) Limited
 |
 | Licensed under the Apache License, Version 2.0 (the "License");
 | you may not use this file except in compliance with the License.
 | You may obtain a copy of the License at
 |
 |    http://www.apache.org/licenses/LICENSE-2.0
 |
 | Unless required by applicable law or agreed to in writing, software
 | distributed under the License is distributed on an "AS IS" BASIS,
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | See the License for the specific language governing permissions and
 | limitations under the License.
 */

define([
    'dojo/text!./templates/NearestLayer.html',
    'dojo/_base/declare',
    "dojo/_base/lang",
    'dijit/_Widget',
    'dijit/_TemplatedMixin',
    'dijit/_WidgetsInTemplateMixin',
    'dojo/dom-construct',
    './_NearestBase',
    './NearestItem',
    'esri/dijit/PopupTemplate',
    'dojo/topic',
    'dojo/on',
    'esri/dijit/PopupRenderer',
    'esri/graphic',
    'dojo/i18n!./nls/Nearest'
],
function (
    template, declare, lang, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, domConstruct, _NearestBase, NearestItem, PopupTemplate, topic, on, PopupRenderer, Graphic, i18n) {

    return declare([_Widget, _NearestBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
        // description:
        //    Find the nearest features around a point

        templateString: template,
        baseClass: 'nearestLayer',
        widgetsInTemplate: true,
        titleText: "",
        titleField: [],
        expanded: false,

        // Properties to be sent into constructor

        constructor: function (options, srcRefNode) {
            this.options = {
                results: null,
                layerInfo: null,
                maxFeatures: 5,
                distance: 0,
                distanceUnits: "m",
                layerOptions: null,
                parentId: ""
            };

            // mix in settings and defaults
            var defaults = lang.mixin({}, this.options, options);

            // Set properties
            this.set("results", defaults.results);
            this.set("layerInfo", defaults.layerInfo);
            this.set("maxFeatures", defaults.maxFeatures);
            this.set("distance", defaults.distance);
            this.set("distanceUnits", defaults.distanceUnits);
            this.set("layerOptions", defaults.layerOptions);
            this.set("parentId", defaults.parentId);

            // widget node
            this.domNode = srcRefNode;
        },

        postMixInProperties: function () {
            var result = this.results.result,
                template = new PopupTemplate(this.layerInfo.popupInfo),
                layerName = this.layerInfo.layerName,
                layerItemId = this.results.id.replace(/ /g, '-'),
                titleTextSplit, indT = 0, layerNameEle;

            this.titleText = template.info.title.toString();
            this.titleField = [];

            // Check the title to see if it contains a field
            titleTextSplit = this.titleText.split('}');

            for (indT = 0; indT < titleTextSplit.length; indT++) {
                if (titleTextSplit[indT].indexOf('{') > -1) {
                    this.titleField.push(titleTextSplit[indT].substr(titleTextSplit[indT].indexOf('{') + 1));
                }
            }

            if (this.titleField.length === 0) {
                this.titleField.push(template.info.fieldInfos[0].fieldName);
            }

            // For each layer in the results add a row to the list
            layerNameEle = this.results.id.replace(/ /g, '-');

            // Remove any special characters that may cause element name errors
            layerNameEle = layerNameEle.replace(/[^\w\s-]/gi, '');

            // Add in item id
            layerNameEle = layerNameEle + "-" + layerItemId;

            this.set("layerName", layerName || this.results.id);
            this.set("layerId", layerNameEle);
            this.set("numberOfFeatures", result.length);

            if (this.layerOptions.display === "fixed") {
                this.set("expanded", true);
                this.set("expandedClass", "in");
                this.set("collapseClass", "");
                this.set("layerHref", "#/");
                this.set("fixedClass", "nearestLayer-fixed");
            }
            else {
                this.set("expanded", false);
                this.set("expandedClass", "");
                this.set("collapseClass", "collapse");
                this.set("layerHref", "#" + layerNameEle);
                this.set("fixedClass", "nearestLayer-expandable");
            }

            if (this.layerOptions.showCounters) {
                this.set("showCountersVisible", "block");
            }
            else {
                this.set("showCountersVisible","none");
            }

            if (this.numberOfFeatures === 0) {
                this.set("counterWording", i18n.noresults + " " + this.distance + " " + this._getDistanceUnits(this.distanceUnits));
            }
            else {
                this.set("counterWording", i18n.showingclosest + " " + this.numberOfFeatures + " " + i18n.within + " " + this.distance + " " + this._getDistanceUnits(this.distanceUnits));
            }

            this.inherited(arguments);
        },

        postCreate: function () {
            // summary:
            //    Overrides method of same name in dijit._Widget.
            // tags:
            //    private

            this._init();
            this.setupConnections();
            this.inherited(arguments);

        },

        // start widget. called by user
        startup: function () {

        },

        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function () {
            // call the superclass method of the same name.
            this.inherited(arguments);
        },

        setupConnections: function () {
            // summary:
            //    wire events, and such
            //
            var _this = this;

            // Fire event for clicking on layer name if not using fixed layout
            if (this.layerOptions.display !== "fixed") {
                on(this.showList, "click", function (evt) {
                    _this.expanded = !_this.expanded;
                    topic.publish("Nearest::show-layer", _this.results.result, _this.results.layerInfo, _this.expanded, _this);
                });
            }
        },

        /* ---------------- */
        /* Public Functions */
        /* ---------------- */

        /* ---------------- */
        /* Private Functions */
        /* ---------------- */

        _init: function () {
            // summary:
            //    If we have any results then display them
            //
            if (this.results.result) {
                this._createFeaturesList();
            }
        },

        _createFeaturesList: function () {
            // summary:
            //    Creates the list of items for this layer from the features list.
            //

            var attributes, item,
            featureInd = 0, fL = 0, feature, itemDiv,
            template = new PopupTemplate(this.layerInfo.popupInfo), g, rend;

            // For each feature and a sub row
            for (featureInd = 0, fL = this.results.result.length; featureInd < fL; featureInd++) {
                feature = this.results.result[featureInd];
                attributes = feature.feature.attributes;

                // Set the info template for the feature
                this.results.result[featureInd].feature.infoTemplate = template;
                g = new Graphic(this.results.result[featureInd].feature.geometry, this.results.layerInfo.renderer, feature.feature.attributes, template);

                rend = new PopupRenderer({ template: template, graphic: g });
                rend.startup();

                // layer node
                itemDiv = domConstruct.create("div", {});
                domConstruct.place(itemDiv, this._features, "last");

                item = new NearestItem({
                    feature: feature,
                    layerItemId: this.layerId,
                    distanceUnits: this.distanceUnits,
                    distance: this.results.result[featureInd].distance.toFixed(2),
                    titleText: this.titleText,
                    titleField: this.titleField,
                    featureNumber: 1 + parseInt(featureInd, 10),
                    description: rend.domNode.innerHTML,
                    renderer: this.results.layerInfo.renderer,
                    opacity: this.results.layerInfo.opacity,
                    layerOptions: this.layerOptions
                }, itemDiv);

                item.startup();

            }
        }
    });
});<|endoftext|>