Modified the init script for Debian/Ubuntu to do a better job at detecting the presence of Upstart.
utils.py:  Re-enabled minifcation of JS and CSS via slimit and cssmin inside of `minify()`.
woff_info.py:  It now works properly in Python 3.
gateone.js:  Fixed a (very strange) bug in `GateOne.Utils.partial()` where it was memoizing the arguments passed to functions it created resulting in them always using the same values even when the arguments changed.
gateone.js:  Added `GateOne.Utils.keys()` which returns the keys (aka attributes) of a given object.
gateone.js:  Fixed a bug where `GateOne.Events.off()` wasn't working properly (due to the missing keys() function).
terminal.js:  Began work on a new feature that will let you persistently highlight whatever words you please.
gateone.py:  Fixed a bug where ApplicationWebSocket.base_url wasn't being constructed properly on ports other than 443.
utils.py:  Added some notes about the fact that the self-signed SSL certificate will utilize 4096-bit RSA encryption.
gateone.py:  Removed a leftover debugging statement from the last commit.
terminal.js:  Fixed a bug where `GateOne.Terminal.highlight()` would leave leftover/unused ``<span>`` elements everywhere after you called `GateOne.Terminal.unHighlight()`.
terminal_input.js:  Added an extra check to `GateOne.Terminal.Input.capture()` and `GateOne.Terminal.Input.disableCapture()` to prevent duplicate functions being added via `addEventLlistener()`.  I don't think it was a problem but it's more efficient this way (in case someone calls `capture()` more than once without ever calling `disableCapture()`).
Bookmarks plugin:  Adjusted/optimized the CSS a bit.
Bookmarks plugin:  Fixed a bug where you'd get an exception trying to import bookmarks when using Python 3.
Bookmarks plugin:  The initial bookmarks sync is now attached to the `go:js_loaded` event instead of the `go:user_login` event.  This should make it more reliable (since the `Bookmarks.init()` function could often be called *after* the `go:user_login` event had fired).
termio.py:  If you pass an `env` dict to `Multiplex.spawn()` that happens to have a `$TERM` value set it will be preseved when spawning the process.
termio.py:  A bit of code optimization/cleanup.
app_terminal.py:  Added support for adding "environment_vars" to your 50terminal.conf to set any default environment variables you want before terminal applications are spawned.  Also added a reasonable default (with a `$TERM` value) for when a new 50terminal.conf is generated (e.g. first-run situation).
gateone.py:  Fixed a mixup with the message log and the auth log in `ApplicationWebSocket.init()`.  This was why the 'WebSocket Closed' message was winding up in the message log instead of the auth log (no other log messages were impacted because both log handlers get re-initialized after the user authenticates to add extra metadata).
terminal.js:  Fixed a bug (that I created a commit or two ago) where the text highlight function wasn't working properly, creating broken spans all over the place in certain situations.
utils.py:  Added a little check to `utils.killall()` to ensure you don't get an exception if you run `gateone.py --kill` more than once.
gateone.py:  Added a new global logger:  `client_log`.  It will log messages to 'log/gateone-client.log'.  It also gets assigned to `ApplicationWebSocket.client_log()` inside of `ApplicationWebSocket.__init__()` and re-assigned inside of `ApplicationWebSocket.open()` (to add the client IP address metadata) as well as `ApplicationWebSocket.authenticate()` (to add the user's UPN to the metadata).
gateone.py:  Added a new WebSocket action: "go:log".  It is attached to a new function, `ApplicationWebSocket.log_message()` which will log incoming messages (sent via that WebSocket action) to 'logs/gateone-client.log'.
gateone.js:  Changed a few strings around here and there to improve clarity (and remove redunancy in some cases).  Also wrapped lots of strings (that could be localized) with the `GateOne.i18n.gettext()` function.  Still lots more string to wrap though.
gateone.js:  Added a docstring to `GateOne.Logging.init()`.
gateone.js:  Added `GateOne.Logging.logToServer()` and added it as a default log destination in `GateOne.Logging.destinations`.  This will ensure that client-side logs get recorded on the server in 'logs/gateone-client.log'.  I suspect this is going to be very useful in debugging!
gateone.js:  Added `GateOne.Net.onClose()`.  It replaces the closure function that gets assigned to the WebSocket's onclose function inside of `GateOne.Net.connect()`.  It fires the "go:disconnected" event.
gateone.js:  Added `GateOne.Net.disconnect()`.  It just closes the WebSocket and turns off any pings/keepalives/whatever that watch for connection problems.  It is primarily for embedded use.
gateone.js:  `GateOne.Visual.displayMessage()` will now strip HTML before logging messages.  Much easier to read the logs this way.
font.css:  Added an extra try/except block to catch the situation where a 'font_size' isn't provided to the template (e.g. when using `utils.combine_css()`).
logviewer.py:  Fixed a couple of bugs that prevented the '--html' option from working Python 3.
Convenience plugin:  All conveniences are now registered after all JavaScript has loaded (i.e. on the "go:js_loaded" event).
Convenience plugin:  Added checks to `GateOne.Convenience.registerIPConvenience()` and `GateOne.Convenience.registerLSConvenience()`to neglect adding features that depend on the SSH plugin if that plugin is disabled/missing.
Notice plugin:  Added a `self.notice_log` logger that logs to 'logs/gateone-notice.log'.  All notices will now be logged.
onoff.py:  Enhanced the try/except stuff with exception saving:  It will not raise the original exception (with traceback!) if all else fails at trying to call that darned callback.
app_terminal.py:  Added a `term_log` and `self.term_log` loggers (same thing but the second one gets extra user metadata) that logs to 'logs/gateone-terminal.log'.  Everything has been updated to use the new functions appropriately.
app_terminal.py:  The logging messages for terminals opening/closing/killed have been modified from 'debug' to 'info' since this information is useful all-around (not just for debugging).  Also added lots of extra metadata.
app_terminal.py:  The "command" (short version) is now stored in the `TerminalApplication.loc_terms` dict.
golog.py:  Added support to `JSONAdapter()` for including extra 'metadata' when logging messages.
gateone.js:  Removed a bit of redundance in terms of log messages when a connection error occurs.
gateone.js:  Modified `GateOne.Visual.newWorkspace()` to add the workspace metadata to the `GateOne.workspaces`.  Also, the "go:new_workspace" event now passes the workspace number instead of the workspace node as the only argument.
gateone.js:  `GateOne.Utils.getRowsAndColumns()` now takes an optional second argument, 'where' which works just like it does in `GateOne.Utils.getEmDimensions()`.
app_terminal.py:  Fixed a bug where you'd get an exception if the 'terminal:kill_terminal' WebSocket action was called for a terminal that was already dead.
terminal.css:  Fixed a bug where some of the classes were missing the ✈.
gatoene.js:  Changed the way Gate One works when disconnected:  Instaed of closing/removing everything it will simply display an overlay that indicates, "I am inactive".  The closing/removing stuff will now take place *after* the connection is re-established; just before everything gets re-created with fresh updated info from the server.
gateone.js:  The function that triggers "go:save_prefs" now calls `GateOne.Visual.updateDimensions()` whenever that happens.
gateone.py:  Everywhere:  Modified the way the file synchronization mechanism works so that it pretty much always sends a proper filename with each sync.  WTF?  JavaScript files always used the filename as their unique identifier but CSS files used a hash of the filename.  The reason for this was because the rendered filenames of CSS files included their original paths which would be an unnecessary information disclosure.  Now *all* files are identified by a hash of their filenames (when making API calls) but the client is also given the *original* file's (short) name.  I say, "original" because in the case of rendered CSS templates the original filename is different from the rendered filename.  The reason why I've made all these changes is so that it will be possible to list CSS files as dependencies of JavaScript and vice versa.
gateone.py:  `ApplicationWebSocket.send_message()` now uses the "go:user_message" WebSocket action instead of "go:notice".  For now it does the exact same thing but I will be modifying it in the future to include more useful metadata in the outgoing message.
terminal.js:  Added an extra sanity check to `GateOne.Terminal.sendDimensions()` to prevent the situation where we send broken dimensions to the server.
terminal.js:  Added some checks here and there to ensure that 'font.css' is loaded before we try to calculate the rows/cols of anything.
terminal.js:  Made some minor changes to reflect the new way of handling disconnection events.  Same stuff gets called just in different places/order.
terminal.js:  `GateOne.Terminal.newTerminal()` now sets `GateOne.Terminal.prevRows` and `GateOne.Terminal.prevCols` to the values that it ultimately ends up applying to the terminal.  `GateOne.Terminal.sendDimensions()` will use these values to determine if it needs to bother with sending a resize event to the server (if the detected rows/cols are the same as what are already set there's nothing to do).
golog.py:  Modified `go_logger()` to always return a `JSONAdapter` regardless of whether or not extra keyword arguments were supplied.
Rebuilt the docs to reflect the latest updates in the code.
app_terminal.py:  Added the current 'location' to the default log metadata.
Notice plugin:  Modified it to use the default log metadata.
gateone.py:  Added the current 'location' to the default log metadata (inside of `ApplicationWebSocket.authenticate()`).
terminal.js:  Fixed a bug where closed terminals weren't being removed from the DOM.
auth.py:  Fixed a bug where `require()` was using the old 'ws_connection' attribute instead of just 'ws' (when trying to send the client messages).
app_terminal.py:  Fixed a bug where `TerminalApplication.term_ended()` would raise a KeyError exception if a terminal was closed before it finished opening (e.g. policy denial).
gateone.js:  Fixed a bug where CSS element IDs could end up with dots in them under certain circumstances.
app_terminal.py:  Worked around a bug (which I'll have to fix next) where multiple dependencies for JS/CSS files are not working properly.  I simply changed terminal.js to only be dependent on 'terminal.css' instead of both 'terminal.css' *and* 'theme.css' for now.
app_terminal.py:  Modified `TerminalApplication.get_colors()` to use `ApplicationWebSocket.render_and_send_css()` insead of manipulating the file_cache and dealing with the file sync itself.
app_terminal.py:  Removed some of the garbage collection stuff from `TerminalApplication.debug_terminal()` since that stuff is now handled elsewhere (see below).
gateone.py:  `ApplicationWebSocket.open()` will now call `self.set_nodelay(True)` if it detects that you're running Tornado 3.1+.  This should reduce latency by a small amount.
gateone.py:  Added a simple `on_pong()` method (standard Tornado override) that logs the client's latency from the server's perspective.  It should be a little lower latency than the client-side ping (which is handled by `ApplicationWebSocket.pong()`) since JSON isn't involved.
gateone.py:  Fixed a bug in `ApplicationWebSocket.send_js_or_css()` where it wasn't sending the 'element_id'.  This didn't matter for most things (since it falls back to using the filename) but it broke the terminal text colors CSS.
gateone.py:  Added a little `debug()` function to `ApplicationWebSocket`.  Just prints out some useful memory utilization information at the moment and calls `gc.collect()`.
gateone.py:  Removed a leftover debugging print statement.
app_terminal.py:  Fixed a bug in `TerminalApplication.get_colors()` where it was providing unnecessary keyword arguments to `ApplicationWebSocket.render_and_send_css()`.
HUGE CPU REDUCTION IN THIS COMMIT!  See the note below about terminal.py...
app_terminal.py:  Cleaned up `TerminalApplication.get_colors()` a bit (still had some leftovers from before the change to using `render_and_send_css()`).
app_terminal.py:  Fixed a bug in `policy_char_handler()` where you could get a KeyError exception when an attempt was made to write to a terminal that was denied being opened by policy.  Really just a cosmetic issue (didn't hurt anything).
terminal.js:  Modified `GateOne.Terminal.loadTextColors()` so that it no longer bothers to send the 'container', 'prefix', and whatnot.
gateone.py:  The `ApplicationWebSocket.debug()` function now uses its own logger and stores useful information in gateone-debugging.log (at the INFO level).
gateone.py:  Changed the name of the default 'log_file_prefix' from 'webserver.log' to 'gateone.log' to match all the other logs in that directory.
gateone.py:  Added a new classmethod, `ApplicationWebSocket.load_prefs()`.  It just loads Gate One's preferences into `ApplicationWebSocket`.  The important part is that it gets attached to the file watching process (`ApplicationWebSocket.watch_file()`) and will automatically re-load all of Gate One's settings whenever they are changed.  So you won't need to restart gateone.py if you change things like policies (e.g. "max_terms"), API keys, origins, etc.  Changing things like listening address/port will obviously require a restart.
utils.py:  Wrote a new dict class:  `AutoExpireDict`.  It's kind of awesome (if I do say so myself!).  It's a `dict` that automaticaly expires (deleted) it's own keys after a specified *timeout*.  See the docstring for detailed examples of how it works.
utils.py:  Modified the `memoize` decorator to use the new `AutoExpireDict`.  Memoized data will auto-expire after five minutes by default.  This should keep things snappy while also being frugal with memory.
woff_info.py:  The `woff_info()` function is now using the new `memoize()` decorator with a built-in fallback (in case some other app wants to use woff_info.py).
onoff.py:  Added a missing sys import.
Terminal themes:  Minor tweak to make sure the terminal doesn't flip flop having scrollbars/not having scrollbars when you open a new one.
terminal.py:  Replaced the use of `prev_dump`, `prev_dump_rend`, and the `html_cache` with a single, global `HTML_CACHE` variable that not only caches the previous lines (by location) but *all* lines across *all* terminals.  So if a combination line/rendition was ever rendered before it will be served from the cache.  Won't that gobble up memory, you ask?  No!  Because the new `HTML_CACHE` is using my new `AutoExpireDict` (local copy--not from utils.py) which ensures that if a cached line hasn't been used in a while it will automatically remove itself, freeing up memory.  What's *really* great about this mechanism is that it is literally *twice as fast* as the old way.  Considering that the `_spanify_screen()` function is the most CPU-intensive in all of Gate One this should amount to a HUGE improvement overall.  Another bonus:  The `HTML_CACHE` will empty itself completely after a while (5 minutes) of inactivity so idle Gate One sessions won't be stuck eating an entire screen's worth of cached lines and renditions for every terminal that is open.
terminal.js:  Removed old leftover debug line that saved lastimage.img (last image captured by the terminal emulator) in your /tmp directory
ssh_connect.py:  Switched everything I could over to dynamic imports in order to reduce the initial memory footprint of this script.  On my system the initial memory footprint went from 5,508k down to 3,396k.  Quite a lot but I'm still looking at ways to reduce this further.
ssh_connect.py:  Added `GO_TERM` and `GO_SESSION` to the list of environment variables that get exported when an SSH connection is made.  Note that I *did* double-check that having the user's session ID will not be useful to an attacker (full code audit in regards to sessions)...  The session ID is only useful from the perspective of of a plugin trying to identify a user.  An attacker cannot impersonate a user just by having the session ID...  They'd also need to know the `cookie_secret` in order to encrypt it in such a way as to make the server accept it.
auth.py:  Fixed a minor issue with `require()` to make it more portable/universal.
utils.py:  Improved a few docstrings.
ssh_connect.py:  Added --logo-path option to allow specifying a custom path for the logo
ssh_connect.py:  Added --default-port option to specify the default connection port
ssh_connect.py:  Added --auth-only option to skip the connection info prompts and ask only for the credentials (user/password)
ssh_connect.py:  Added --default-host for consistency but kept old option --default_host for backwards compatibility
ssh_connect.py:  Added vim modeline comment at the end of the file to enforce code formatting