diff --git a/Dockerfile b/Dockerfile index ef68d2f..b6329f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:14.04.3 +FROM ubuntu:14.04 MAINTAINER Doro Wu ENV DEBIAN_FRONTEND noninteractive diff --git a/noVNC/.gitlastcommit b/noVNC/.gitlastcommit new file mode 100644 index 0000000..5c223b7 --- /dev/null +++ b/noVNC/.gitlastcommit @@ -0,0 +1 @@ +56d97524807b125d047730331031ddd00f9c61f diff --git a/noVNC/.gitmodules b/noVNC/.gitmodules deleted file mode 100644 index 45574ae..0000000 --- a/noVNC/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "include/web-socket-js-project"] - path = include/web-socket-js-project - url = https://github.com/gimite/web-socket-js.git diff --git a/noVNC/.npmignore b/noVNC/.npmignore new file mode 100644 index 0000000..b572f7a --- /dev/null +++ b/noVNC/.npmignore @@ -0,0 +1,20 @@ +app +core +.gitmodules +node_modules +.* +*~ +*.swp +*.swo +tests +.travis.yml +utils +docs/notes +docs/links +docs/release.txt +docs/rfb_notes +docs/*.pdf +vnc.html +vnc_auto.html +karma.conf.js +docs/flash_policy.txt diff --git a/noVNC/.travis.yml b/noVNC/.travis.yml index 8192252..a7fe423 100644 --- a/noVNC/.travis.yml +++ b/noVNC/.travis.yml @@ -1,15 +1,17 @@ language: node_js +sudo: false +cache: + directories: + - node_modules node_js: -- '0.11.13' +- '6.1' env: matrix: - TEST_BROWSER_NAME=PhantomJS - - TEST_BROWSER_NAME=chrome TEST_BROWSER_OS='Windows 7,Linux' - - TEST_BROWSER_NAME=firefox TEST_BROWSER_OS='Windows 7,Linux' TEST_BROWSER_VERSION='30,26' - - TEST_BROWSER_NAME='internet explorer' TEST_BROWSER_OS='Windows 7' TEST_BROWSER_VERSION=10 - - TEST_BROWSER_NAME='internet explorer' TEST_BROWSER_OS='Windows 8.1' TEST_BROWSER_VERSION=11 - - TEST_BROWSER_NAME=safari TEST_BROWSER_OS='OS X 10.8' TEST_BROWSER_VERSION=6 - - TEST_BROWSER_NAME=safari TEST_BROWSER_OS='OS X 10.9' TEST_BROWSER_VERSION=7 + - TEST_BROWSER_NAME=chrome TEST_BROWSER_OS='Windows 10,Linux,OS X 10.11' + - TEST_BROWSER_NAME=firefox TEST_BROWSER_OS='Windows 10,Linux,OS X 10.11' + - TEST_BROWSER_NAME='internet explorer' TEST_BROWSER_OS='Windows 10' + - TEST_BROWSER_NAME=safari TEST_BROWSER_OS='OS X 10.11' global: - secure: QE5GqGd2hrpQsIgd8dlv3oRUUHqZayomzzQjNXOB81VQi241uz/ru+3GtBZLB5WLZCq/Gj89vbLnR0LN4ixlmPaWv3/WJQGyDGuRD/vMnccVl+rBUP/Hh2zdYwiISIGcrywNAE+KLus/lyt/ahVgzbaRaDSzrM1HaZFT/rndGck= - secure: g75sdctEwj0hoLW0Y08Tdv8s5scNzplB6a9EtaJ2vJD9S/bK+AsPqbWesGv1UlrFPCWdbV7Vg61vkmoUjcmb5xhqFIjcM9TlYJoKWeOTsOmnQoSIkIq6gMF1k02+LmKInbPgIzrp3m3jluS1qaOs/EzFpDnJp9hWBiAfXa12Jxk= diff --git a/noVNC/LICENSE.txt b/noVNC/LICENSE.txt index e896efc..7b5de59 100644 --- a/noVNC/LICENSE.txt +++ b/noVNC/LICENSE.txt @@ -5,19 +5,19 @@ Public License 2.0). The noVNC core library is composed of the Javascript code necessary for full noVNC operation. This includes (but is not limited to): - include/base64.js - include/des.js - include/display.js - include/input.js - include/jsunzip.js - include/keysym.js - include/logo.js - include/playback.js - include/rfb.js - include/ui.js - include/util.js - include/websock.js - include/webutil.js + core/base64.js + core/des.js + core/display.js + core/input/devices.js + core/input/keysym.js + core/logo.js + core/playback.js + core/rfb.js + app/ui.js + core/util.js + core/websock.js + app/webutil.js + core/input/xtscancodes.js The HTML, CSS, font and images files that included with the noVNC source distibution (or repository) are not considered part of the @@ -29,12 +29,12 @@ The HTML, CSS, font and image files are licensed as follows: *.html : 2-Clause BSD license - include/*.css : 2-Clause BSD license + app/styles/*.css : 2-Clause BSD license - include/Orbitron* : SIL Open Font License 1.1 + app/styles/Orbitron* : SIL Open Font License 1.1 (Copyright 2009 Matt McInerney) - images/ : Creative Commons Attribution-ShareAlike + app/images/ : Creative Commons Attribution-ShareAlike http://creativecommons.org/licenses/by-sa/3.0/ Some portions of noVNC are copyright to their individual authors. @@ -45,20 +45,16 @@ The are several files and projects that have been incorporated into the noVNC core library. Here is a list of those files and the original licenses (all MPL 2.0 compatible): - include/base64.js : MPL 2.0 - - include/des.js : Various BSD style licenses + core/base64.js : MPL 2.0 - include/jsunzip.js : zlib/libpng license + core/des.js : Various BSD style licenses - include/web-socket-js/ : New BSD license (3-clause). Source code at - http://github.com/gimite/web-socket-js + utils/inflator.mod.js + include/inflator.js : MIT (for pako) - include/chrome-app/tcp-stream.js - : Apache 2.0 license - - utils/websockify - utils/websocket.py : LGPL 3 +Any other files not mentioned above are typically marked with +a copyright/license header at the top of the file. The default noVNC +license is MPL-2.0. The following license texts are included: @@ -70,6 +66,7 @@ The following license texts are included: docs/LICENSE.BSD-2-Clause (Simplified BSD / FreeBSD) docs/LICENSE.zlib docs/LICENSE.Apache-2.0 + docs/LICENSE.pako Or alternatively the license texts may be found here: diff --git a/noVNC/README.md b/noVNC/README.md index b5679cd..22755b8 100644 --- a/noVNC/README.md +++ b/noVNC/README.md @@ -1,45 +1,45 @@ ## noVNC: HTML5 VNC Client -[![Build Status](https://travis-ci.org/kanaka/noVNC.svg?branch=master)](https://travis-ci.org/kanaka/noVNC) +[![Build Status](https://travis-ci.org/novnc/noVNC.svg?branch=master)](https://travis-ci.org/novnc/noVNC) ### Description -noVNC is a HTML5 VNC client that runs well in any modern browser -including mobile browsers (iPhone/iPad and Android). +noVNC is a HTML5 VNC client that runs well in any modern browser including +mobile browsers (iOS and Android). -Many companies/projects have integrated noVNC including [Ganeti Web -Manager](http://code.osuosl.org/projects/ganeti-webmgr), +Many companies, projects and products have integrated noVNC including +[Ganeti Web Manager](http://code.osuosl.org/projects/ganeti-webmgr), [OpenStack](http://www.openstack.org), -[OpenNebula](http://opennebula.org/), and -[LibVNCServer](http://libvncserver.sourceforge.net). See [the Projects -and Companies wiki -page](https://github.com/kanaka/noVNC/wiki/ProjectsCompanies-using-noVNC) +[OpenNebula](http://opennebula.org/), +[LibVNCServer](http://libvncserver.sourceforge.net), and +[ThinLinc](https://cendio.com/thinlinc). See +[the Projects and Companies wiki page](https://github.com/novnc/noVNC/wiki/Projects-and-companies-using-noVNC) for a more complete list with additional info and links. ### News/help/contact Notable commits, announcements and news are posted to -@noVNC +@noVNC. -If you are a noVNC developer/integrator/user (or want to be) please -join the noVNC -discussion group +If you are a noVNC developer/integrator/user (or want to be) please join the + +noVNC discussion group. -Bugs and feature requests can be submitted via [github -issues](https://github.com/kanaka/noVNC/issues). If you are looking -for a place to start contributing to noVNC, a good place to start -would be the issues that are marked as -["patchwelcome"](https://github.com/kanaka/noVNC/issues?labels=patchwelcome). +Bugs and feature requests can be submitted via +[github issues](https://github.com/novnc/noVNC/issues). +If you are looking for a place to start contributing to noVNC, a good place to +start would be the issues that are marked as +["patchwelcome"](https://github.com/novnc/noVNC/issues?labels=patchwelcome). -If you want to show appreciation for noVNC you could donate to a great -non-profits such as: [Compassion -International](http://www.compassion.com/), [SIL](http://www.sil.org), -[Habitat for Humanity](http://www.habitat.org), [Electronic Frontier -Foundation](https://www.eff.org/), [Against Malaria -Foundation](http://www.againstmalaria.com/), [Nothing But -Nets](http://www.nothingbutnets.net/), etc. Please tweet @noVNC if you do. +If you want to show appreciation for noVNC you could donate to a great non- +profits such as: +[Compassion International](http://www.compassion.com/), +[SIL](http://www.sil.org), +[Habitat for Humanity](http://www.habitat.org), +[Electronic Frontier Foundation](https://www.eff.org/), +[Against Malaria Foundation](http://www.againstmalaria.com/), +[Nothing But Nets](http://www.nothingbutnets.net/), etc. +Please tweet @noVNC if you do. ### Features @@ -59,61 +59,72 @@ href="http://www.twitter.com/noVNC">@noVNC if you do. Running in Chrome before and after connecting: -  +  + -See more screenshots here. +See more screenshots +here. ### Browser Requirements -* HTML5 Canvas (with createImageData): Chrome, Firefox 3.6+, iOS - Safari, Opera 11+, Internet Explorer 9+, etc. +* Chrome 8, Firefox 4, Safari 6, Opera 12, IE 11, Edge 12, etc. -* HTML5 WebSockets: For browsers that do not have builtin - WebSockets support, the project includes - web-socket-js, - a WebSockets emulator using Adobe Flash. iOS 4.2+ has built-in - WebSocket support. +* HTML5 Canvas, WebSockets and Typed Arrays -* Fast Javascript Engine: this is not strictly a requirement, but - without a fast Javascript engine, noVNC might be painfully slow. +* Fast Javascript Engine: this is not strictly a requirement, but without a + fast Javascript engine, noVNC might be painfully slow. -* See the more detailed [browser compatibility wiki page](https://github.com/kanaka/noVNC/wiki/Browser-support). +* See the more detailed +[browser compatibility wiki page](https://github.com/novnc/noVNC/wiki/Browser-support). ### Server Requirements -Unless you are using a VNC server with support for WebSockets -connections (such as -[x11vnc/libvncserver](http://libvncserver.sourceforge.net/), +Unless you are using a VNC server with support for WebSockets connections (such +as [x11vnc/libvncserver](http://libvncserver.sourceforge.net/), [QEMU](http://www.qemu.org/), or -[PocketVNC](http://www.pocketvnc.com/blog/?page_id=866)), you need to -use a WebSockets to TCP socket proxy. There is a python proxy included +[MobileVNC](http://www.smartlab.at/mobilevnc/)), you need to use a +WebSockets to TCP socket proxy. There is a python proxy included ('websockify'). ### Quick Start -* Use the launch script to start a mini-webserver and the WebSockets - proxy (websockify). The `--vnc` option is used to specify the location of - a running VNC server: +* Use the launch script to start a mini-webserver and the WebSockets proxy + (websockify). The `--vnc` option is used to specify the location of a running + VNC server: `./utils/launch.sh --vnc localhost:5901` -* Point your browser to the cut-and-paste URL that is output by the - launch script. Enter a password if the VNC server has one - configured. Hit the Connect button and enjoy! +* Point your browser to the cut-and-paste URL that is output by the launch + script. Enter a password if the VNC server has one configured. Hit the + Connect button and enjoy! ### Other Pages -* [Encrypted Connections](https://github.com/kanaka/websockify/wiki/Encrypted-Connections). How to setup websockify so that you can use encrypted connections from noVNC. +* [Modules/API](https://github.com/novnc/noVNC/wiki/Modules-API) - The library + modules and their Javascript API. -* [Advanced Usage](https://github.com/kanaka/noVNC/wiki/Advanced-usage). Starting a VNC server, advanced websockify usage, etc. +* [Integration](https://github.com/novnc/noVNC/wiki/Integration) - Get noVNC + to work in existing projects. -* [Integrating noVNC](https://github.com/kanaka/noVNC/wiki/Integration) into existing projects. +* [Troubleshooting](https://github.com/novnc/noVNC/wiki/Troubleshooting) - How + to troubleshoot problems. -* [Troubleshooting noVNC](https://github.com/kanaka/noVNC/wiki/Troubleshooting) problems. +* [Encrypted Connections](https://github.com/novnc/websockify/wiki/Encrypted-Connections) - + Setup websockify so that you can use encrypted connections from noVNC. + +* [Advanced Usage](https://github.com/novnc/noVNC/wiki/Advanced-usage) - + Generating an SSL certificate, starting a VNC server, advanced websockify + usage, etc. + +* [Testing](https://github.com/novnc/noVNC/wiki/Testing) - Run and write + tests. + +* [Translations](https://github.com/novnc/noVNC/wiki/Translations) - Add and + modify localization for JavaScript and HTML. ### Authors/Contributors @@ -123,16 +134,17 @@ use a WebSockets to TCP socket proxy. There is a python proxy included * [Samuel Mannehed](https://github.com/samhed) (Cendio) * [Peter Åstrand](https://github.com/astrand) (Cendio) * [Solly Ross](https://github.com/DirectXMan12) (Red Hat / OpenStack) + * [Pierre Ossman](https://github.com/CendioOssman) (Cendio) * Notable contributions: - * UI and Icons : Chris Gordon + * UI and Icons : Pierre Ossman, Chris Gordon * Original Logo : Michael Sersen * tight encoding : Michael Tinglof (Mercuri.ca) * Included libraries: - * web-socket-js : Hiroshi Ichikawa (github.com/gimite/web-socket-js) * as3crypto : Henri Torgemane (code.google.com/p/as3crypto) * base64 : Martijn Pieters (Digital Creations 2), Samuel Sieb (sieb.net) - * jsunzip : Erik Moller (github.com/operasoftware/jsunzip), - * tinflate : Joergen Ibsen (ibsensoftware.com) * DES : Dave Zimmerman (Widget Workshop), Jef Poskanzer (ACME Labs) + * Pako : Vitaly Puzrin (https://github.com/nodeca/pako) + +* [Contribution guide](https://github.com/novnc/noVNC/wiki/Contributing) diff --git a/noVNC/app/images/alt.svg b/noVNC/app/images/alt.svg new file mode 100644 index 0000000..e5bb461 --- /dev/null +++ b/noVNC/app/images/alt.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/noVNC/app/images/clipboard.svg b/noVNC/app/images/clipboard.svg new file mode 100644 index 0000000..79af275 --- /dev/null +++ b/noVNC/app/images/clipboard.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/noVNC/app/images/connect.svg b/noVNC/app/images/connect.svg new file mode 100644 index 0000000..56cde41 --- /dev/null +++ b/noVNC/app/images/connect.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/noVNC/app/images/ctrl.svg b/noVNC/app/images/ctrl.svg new file mode 100644 index 0000000..856e939 --- /dev/null +++ b/noVNC/app/images/ctrl.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/noVNC/app/images/ctrlaltdel.svg b/noVNC/app/images/ctrlaltdel.svg new file mode 100644 index 0000000..d7744ea --- /dev/null +++ b/noVNC/app/images/ctrlaltdel.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/noVNC/app/images/disconnect.svg b/noVNC/app/images/disconnect.svg new file mode 100644 index 0000000..6be7d18 --- /dev/null +++ b/noVNC/app/images/disconnect.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/noVNC/app/images/drag.svg b/noVNC/app/images/drag.svg new file mode 100644 index 0000000..139caf9 --- /dev/null +++ b/noVNC/app/images/drag.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/noVNC/app/images/error.svg b/noVNC/app/images/error.svg new file mode 100644 index 0000000..8356d3f --- /dev/null +++ b/noVNC/app/images/error.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/noVNC/app/images/esc.svg b/noVNC/app/images/esc.svg new file mode 100644 index 0000000..830152b --- /dev/null +++ b/noVNC/app/images/esc.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/noVNC/app/images/expander.svg b/noVNC/app/images/expander.svg new file mode 100644 index 0000000..e163535 --- /dev/null +++ b/noVNC/app/images/expander.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/noVNC/app/images/fullscreen.svg b/noVNC/app/images/fullscreen.svg new file mode 100644 index 0000000..29bd05d --- /dev/null +++ b/noVNC/app/images/fullscreen.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/noVNC/app/images/handle.svg b/noVNC/app/images/handle.svg new file mode 100644 index 0000000..4a7a126 --- /dev/null +++ b/noVNC/app/images/handle.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/noVNC/app/images/handle_bg.svg b/noVNC/app/images/handle_bg.svg new file mode 100644 index 0000000..7579c42 --- /dev/null +++ b/noVNC/app/images/handle_bg.svg @@ -0,0 +1,172 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/noVNC/app/images/icons/Makefile b/noVNC/app/images/icons/Makefile new file mode 100644 index 0000000..be564b4 --- /dev/null +++ b/noVNC/app/images/icons/Makefile @@ -0,0 +1,42 @@ +ICONS := \ + novnc-16x16.png \ + novnc-24x24.png \ + novnc-32x32.png \ + novnc-48x48.png \ + novnc-64x64.png + +ANDROID_LAUNCHER := \ + novnc-48x48.png \ + novnc-72x72.png \ + novnc-96x96.png \ + novnc-144x144.png \ + novnc-192x192.png + +IPHONE_LAUNCHER := \ + novnc-60x60.png \ + novnc-120x120.png + +IPAD_LAUNCHER := \ + novnc-76x76.png \ + novnc-152x152.png + +ALL_ICONS := $(ICONS) $(ANDROID_LAUNCHER) $(IPHONE_LAUNCHER) $(IPAD_LAUNCHER) + +all: $(ALL_ICONS) + +novnc-16x16.png: novnc-icon-sm.svg + convert -density 90 \ + -background transparent "$<" "$@" +novnc-24x24.png: novnc-icon-sm.svg + convert -density 135 \ + -background transparent "$<" "$@" +novnc-32x32.png: novnc-icon-sm.svg + convert -density 180 \ + -background transparent "$<" "$@" + +novnc-%.png: novnc-icon.svg + convert -density $$[`echo $* | cut -d x -f 1` * 90 / 48] \ + -background transparent "$<" "$@" + +clean: + rm -f *.png diff --git a/noVNC/app/images/icons/novnc-120x120.png b/noVNC/app/images/icons/novnc-120x120.png new file mode 100644 index 0000000..40823ef Binary files /dev/null and b/noVNC/app/images/icons/novnc-120x120.png differ diff --git a/noVNC/app/images/icons/novnc-144x144.png b/noVNC/app/images/icons/novnc-144x144.png new file mode 100644 index 0000000..eee71f1 Binary files /dev/null and b/noVNC/app/images/icons/novnc-144x144.png differ diff --git a/noVNC/app/images/icons/novnc-152x152.png b/noVNC/app/images/icons/novnc-152x152.png new file mode 100644 index 0000000..0694b2d Binary files /dev/null and b/noVNC/app/images/icons/novnc-152x152.png differ diff --git a/noVNC/app/images/icons/novnc-16x16.png b/noVNC/app/images/icons/novnc-16x16.png new file mode 100644 index 0000000..42108f4 Binary files /dev/null and b/noVNC/app/images/icons/novnc-16x16.png differ diff --git a/noVNC/app/images/icons/novnc-192x192.png b/noVNC/app/images/icons/novnc-192x192.png new file mode 100644 index 0000000..ef9201f Binary files /dev/null and b/noVNC/app/images/icons/novnc-192x192.png differ diff --git a/noVNC/app/images/icons/novnc-24x24.png b/noVNC/app/images/icons/novnc-24x24.png new file mode 100644 index 0000000..1106135 Binary files /dev/null and b/noVNC/app/images/icons/novnc-24x24.png differ diff --git a/noVNC/app/images/icons/novnc-32x32.png b/noVNC/app/images/icons/novnc-32x32.png new file mode 100644 index 0000000..ff00dc3 Binary files /dev/null and b/noVNC/app/images/icons/novnc-32x32.png differ diff --git a/noVNC/app/images/icons/novnc-48x48.png b/noVNC/app/images/icons/novnc-48x48.png new file mode 100644 index 0000000..f24cd6c Binary files /dev/null and b/noVNC/app/images/icons/novnc-48x48.png differ diff --git a/noVNC/app/images/icons/novnc-60x60.png b/noVNC/app/images/icons/novnc-60x60.png new file mode 100644 index 0000000..06b0d60 Binary files /dev/null and b/noVNC/app/images/icons/novnc-60x60.png differ diff --git a/noVNC/app/images/icons/novnc-64x64.png b/noVNC/app/images/icons/novnc-64x64.png new file mode 100644 index 0000000..6d0fb34 Binary files /dev/null and b/noVNC/app/images/icons/novnc-64x64.png differ diff --git a/noVNC/app/images/icons/novnc-72x72.png b/noVNC/app/images/icons/novnc-72x72.png new file mode 100644 index 0000000..23163a2 Binary files /dev/null and b/noVNC/app/images/icons/novnc-72x72.png differ diff --git a/noVNC/app/images/icons/novnc-76x76.png b/noVNC/app/images/icons/novnc-76x76.png new file mode 100644 index 0000000..aef61c4 Binary files /dev/null and b/noVNC/app/images/icons/novnc-76x76.png differ diff --git a/noVNC/app/images/icons/novnc-96x96.png b/noVNC/app/images/icons/novnc-96x96.png new file mode 100644 index 0000000..1a77c53 Binary files /dev/null and b/noVNC/app/images/icons/novnc-96x96.png differ diff --git a/noVNC/app/images/icons/novnc-icon-sm.svg b/noVNC/app/images/icons/novnc-icon-sm.svg new file mode 100644 index 0000000..aa1c6f1 --- /dev/null +++ b/noVNC/app/images/icons/novnc-icon-sm.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/noVNC/app/images/icons/novnc-icon.svg b/noVNC/app/images/icons/novnc-icon.svg new file mode 100644 index 0000000..1efff91 --- /dev/null +++ b/noVNC/app/images/icons/novnc-icon.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/noVNC/app/images/info.svg b/noVNC/app/images/info.svg new file mode 100644 index 0000000..557b772 --- /dev/null +++ b/noVNC/app/images/info.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/noVNC/app/images/keyboard.svg b/noVNC/app/images/keyboard.svg new file mode 100644 index 0000000..137b350 --- /dev/null +++ b/noVNC/app/images/keyboard.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/noVNC/app/images/mouse_left.svg b/noVNC/app/images/mouse_left.svg new file mode 100644 index 0000000..ce4cca4 --- /dev/null +++ b/noVNC/app/images/mouse_left.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/noVNC/app/images/mouse_middle.svg b/noVNC/app/images/mouse_middle.svg new file mode 100644 index 0000000..6603425 --- /dev/null +++ b/noVNC/app/images/mouse_middle.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/noVNC/app/images/mouse_none.svg b/noVNC/app/images/mouse_none.svg new file mode 100644 index 0000000..3e0f838 --- /dev/null +++ b/noVNC/app/images/mouse_none.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/noVNC/app/images/mouse_right.svg b/noVNC/app/images/mouse_right.svg new file mode 100644 index 0000000..f4bad76 --- /dev/null +++ b/noVNC/app/images/mouse_right.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/noVNC/app/images/power.svg b/noVNC/app/images/power.svg new file mode 100644 index 0000000..4925d3e --- /dev/null +++ b/noVNC/app/images/power.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/noVNC/app/images/settings.svg b/noVNC/app/images/settings.svg new file mode 100644 index 0000000..dbb2e80 --- /dev/null +++ b/noVNC/app/images/settings.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/noVNC/app/images/tab.svg b/noVNC/app/images/tab.svg new file mode 100644 index 0000000..1ccb322 --- /dev/null +++ b/noVNC/app/images/tab.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/noVNC/app/images/toggleextrakeys.svg b/noVNC/app/images/toggleextrakeys.svg new file mode 100644 index 0000000..b578c0d --- /dev/null +++ b/noVNC/app/images/toggleextrakeys.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/noVNC/app/images/warning.svg b/noVNC/app/images/warning.svg new file mode 100644 index 0000000..7114f9b --- /dev/null +++ b/noVNC/app/images/warning.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/noVNC/app/locale/de.js b/noVNC/app/locale/de.js new file mode 100644 index 0000000..6819c48 --- /dev/null +++ b/noVNC/app/locale/de.js @@ -0,0 +1,18 @@ +/* + * Translations for de + * + * This file was autotomatically generated from de.po + * DO NOT EDIT! + */ + +Language = { + "Connecting...": "Verbunden...", + "Connected (encrypted) to ": "Verbunden mit (verschlüsselt) ", + "Connected (unencrypted) to ": "Verbunden mit (unverschlüsselt) ", + "Disconnecting...": "Verbindung trennen...", + "Disconnected": "Verbindung zum Server getrennt", + "Must set host and port": "Richten Sie Host und Port ein", + "Password is required": "Passwort ist erforderlich", + "Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "'Clipping-Modus' aktiviert, Scrollbalken in 'IE-Vollbildmodus' werden nicht unterstützt", + "Disconnect timeout": "Timeout beim trennen", +}; diff --git a/noVNC/app/locale/el.js b/noVNC/app/locale/el.js new file mode 100644 index 0000000..3ce6c38 --- /dev/null +++ b/noVNC/app/locale/el.js @@ -0,0 +1,74 @@ +/* + * Translations for el + * + * This file was autotomatically generated from el.po + * DO NOT EDIT! + */ + +Language = { + "Connecting...": "Συνδέεται...", + "Connected (encrypted) to ": "Συνδέθηκε (κρυπτογραφημένα) με το ", + "Connected (unencrypted) to ": "Συνδέθηκε (μη κρυπτογραφημένα) με το ", + "Disconnecting...": "Aποσυνδέεται...", + "Disconnected": "Αποσυνδέθηκε", + "Must set host and port": "Πρέπει να οριστεί το όνομα και η πόρτα του διακομιστή", + "Password is required": "Απαιτείται ο κωδικός πρόσβασης", + "Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "Εφαρμογή λειτουργίας αποκοπής αφού δεν υποστηρίζονται οι λωρίδες κύλισης σε πλήρη οθόνη στον IE", + "Disconnect timeout": "Παρέλευση χρονικού ορίου αποσύνδεσης", + "noVNC encountered an error:": "το noVNC αντιμετώπισε ένα σφάλμα", + "Hide/Show the control bar": "Απόκρυψη/Εμφάνιση γραμμής ελέγχου", + "Move/Drag Viewport": "Μετακίνηση/Σύρσιμο Θεατού πεδίου", + "viewport drag": "σύρσιμο θεατού πεδίου", + "Active Mouse Button": "Ενεργό Πλήκτρο Ποντικιού", + "No mousebutton": "Χωρίς Πλήκτρο Ποντικιού", + "Left mousebutton": "Αριστερό Πλήκτρο Ποντικιού", + "Middle mousebutton": "Μεσαίο Πλήκτρο Ποντικιού", + "Right mousebutton": "Δεξί Πλήκτρο Ποντικιού", + "Keyboard": "Πληκτρολόγιο", + "Show Keyboard": "Εμφάνιση Πληκτρολογίου", + "Extra keys": "Επιπλέον πλήκτρα", + "Show Extra Keys": "Εμφάνιση Επιπλέον Πλήκτρων", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Εναλλαγή Ctrl", + "Alt": "Alt", + "Toggle Alt": "Εναλλαγή Alt", + "Send Tab": "Αποστολή Tab", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Αποστολή Escape", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Αποστολή Ctrl-Alt-Del", + "Shutdown/Reboot": "Κλείσιμο/Επανεκκίνηση", + "Shutdown/Reboot...": "Κλείσιμο/Επανεκκίνηση...", + "Power": "Απενεργοποίηση", + "Shutdown": "Κλείσιμο", + "Reboot": "Επανεκκίνηση", + "Reset": "Επαναφορά", + "Clipboard": "Πρόχειρο", + "Clear": "Καθάρισμα", + "Fullscreen": "Πλήρης Οθόνη", + "Settings": "Ρυθμίσεις", + "Encrypt": "Κρυπτογράφηση", + "True Color": "Πραγματικά Χρώματα", + "Local Cursor": "Τοπικός Δρομέας", + "Clip to Window": "Αποκοπή στο όριο του Παράθυρου", + "Shared Mode": "Κοινόχρηστη Λειτουργία", + "View Only": "Μόνο Θέαση", + "Path:": "Διαδρομή:", + "Scaling Mode:": "Λειτουργία Κλιμάκωσης:", + "None": "Καμία", + "Local Scaling": "Τοπική Κλιμάκωση", + "Local Downscaling": "Τοπική Συρρίκνωση", + "Remote Resizing": "Απομακρυσμένη Αλλαγή μεγέθους", + "Repeater ID:": "Repeater ID:", + "Style:": "Στυλ:", + "default": "προεπιλεγμένο", + "Logging:": "Καταγραφή:", + "Apply": "Εφαρμογή", + "Host:": "Όνομα διακομιστή:", + "Port:": "Πόρτα διακομιστή:", + "Password:": "Κωδικός Πρόσβασης:", + "Token:": "Διακριτικό:", + "Send Password": "Αποστολή Κωδικού Πρόσβασης", + "Canvas not supported.": "Δεν υποστηρίζεται το στοιχείο Canvas", +}; diff --git a/noVNC/app/locale/nl.js b/noVNC/app/locale/nl.js new file mode 100644 index 0000000..cacab30 --- /dev/null +++ b/noVNC/app/locale/nl.js @@ -0,0 +1,18 @@ +/* + * Translations for nl + * + * This file was autotomatically generated from nl.po + * DO NOT EDIT! + */ + +Language = { + "Connecting...": "Verbinden...", + "Connected (encrypted) to ": "Verbonden (versleuteld) met ", + "Connected (unencrypted) to ": "Verbonden (onversleuteld) met ", + "Disconnecting...": "Verbinding verbreken...", + "Disconnected": "Verbinding verbroken", + "Must set host and port": "Host en poort moeten worden ingesteld", + "Password is required": "Wachtwoord is vereist", + "Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "''Clipping mode' ingeschakeld, omdat schuifbalken in volledige-scherm-modus in IE niet worden ondersteund", + "Disconnect timeout": "Timeout tijdens verbreken van verbinding", +}; diff --git a/noVNC/app/locale/sv.js b/noVNC/app/locale/sv.js new file mode 100644 index 0000000..b7f4c1f --- /dev/null +++ b/noVNC/app/locale/sv.js @@ -0,0 +1,77 @@ +/* + * Translations for sv + * + * This file was autotomatically generated from sv.po + * DO NOT EDIT! + */ + +Language = { + "Connecting...": "Ansluter...", + "Connected (encrypted) to ": "Ansluten (krypterat) till ", + "Connected (unencrypted) to ": "Ansluten (okrypterat) till ", + "Disconnecting...": "Kopplar ner...", + "Disconnected": "Frånkopplad", + "Must set host and port": "Du måste specifiera en host och port", + "Password is required": "Lösenord krävs", + "Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "Tvingar 'Clipping mode' eftersom skrollning inte stödjs av IE i fullskärm", + "Disconnect timeout": "Det tog för lång tid att koppla ner", + "noVNC encountered an error:": "noVNC stötte på ett problem:", + "Hide/Show the control bar": "Göm/Visa kontrollbaren", + "Move/Drag Viewport": "Flytta/Dra Vyn", + "viewport drag": "dra vy", + "Active Mouse Button": "Aktiv musknapp", + "No mousebutton": "Ingen musknapp", + "Left mousebutton": "Vänster musknapp", + "Middle mousebutton": "Mitten-musknapp", + "Right mousebutton": "Höger musknapp", + "Keyboard": "Tangentbord", + "Show Keyboard": "Visa Tangentbord", + "Extra keys": "Extraknappar", + "Show Extra Keys": "Visa Extraknappar", + "Ctrl": "Ctrl", + "Toggle Ctrl": "Växla Ctrl", + "Alt": "Alt", + "Toggle Alt": "Växla Alt", + "Send Tab": "Skicka Tab", + "Tab": "Tab", + "Esc": "Esc", + "Send Escape": "Skicka Escape", + "Ctrl+Alt+Del": "Ctrl+Alt+Del", + "Send Ctrl-Alt-Del": "Skicka Ctrl-Alt-Del", + "Shutdown/Reboot": "Stäng av/Boota om", + "Shutdown/Reboot...": "Stäng av/Boota om...", + "Power": "Ström", + "Shutdown": "Stäng av", + "Reboot": "Boota om", + "Reset": "Återställ", + "Clipboard": "Urklipp", + "Clear": "Rensa", + "Fullscreen": "Fullskärm", + "Settings": "Inställningar", + "Encrypt": "Kryptera", + "True Color": "Fullfärg", + "Local Cursor": "Lokal Muspekare", + "Clip to Window": "Begränsa till Fönster", + "Shared Mode": "Delat Läge", + "View Only": "Endast Visning", + "Path:": "Sökväg:", + "Scaling Mode:": "Skalningsläge:", + "None": "Ingen", + "Local Scaling": "Lokal Skalning", + "Local Downscaling": "Lokal Nedskalning", + "Remote Resizing": "Ändra Storlek", + "Repeater ID:": "Repeater-ID:", + "Style:": "Stil:", + "default": "standard", + "Logging:": "Loggning:", + "Apply": "Verkställ", + "Connect": "Anslut", + "Disconnect": "Koppla från", + "Connection": "Uppkoppling", + "Host:": "Värd:", + "Port:": "Port:", + "Password:": "Lösenord:", + "Token:": "Token:", + "Send Password": "Skicka Lösenord", + "Canvas not supported.": "Canvas stöds ej", +}; diff --git a/noVNC/app/sounds/CREDITS b/noVNC/app/sounds/CREDITS new file mode 100644 index 0000000..ec1fb55 --- /dev/null +++ b/noVNC/app/sounds/CREDITS @@ -0,0 +1,4 @@ +bell + Copyright: Dr. Richard Boulanger et al + URL: http://www.archive.org/details/Berklee44v12 + License: CC-BY Attribution 3.0 Unported diff --git a/noVNC/app/sounds/bell.mp3 b/noVNC/app/sounds/bell.mp3 new file mode 100644 index 0000000..fdbf149 Binary files /dev/null and b/noVNC/app/sounds/bell.mp3 differ diff --git a/noVNC/app/sounds/bell.oga b/noVNC/app/sounds/bell.oga new file mode 100644 index 0000000..144d2b3 Binary files /dev/null and b/noVNC/app/sounds/bell.oga differ diff --git a/noVNC/include/Orbitron700.ttf b/noVNC/app/styles/Orbitron700.ttf similarity index 100% rename from noVNC/include/Orbitron700.ttf rename to noVNC/app/styles/Orbitron700.ttf diff --git a/noVNC/include/Orbitron700.woff b/noVNC/app/styles/Orbitron700.woff similarity index 100% rename from noVNC/include/Orbitron700.woff rename to noVNC/app/styles/Orbitron700.woff diff --git a/noVNC/app/styles/auto.css b/noVNC/app/styles/auto.css new file mode 100644 index 0000000..50f9a82 --- /dev/null +++ b/noVNC/app/styles/auto.css @@ -0,0 +1,89 @@ +/* + * noVNC auto CSS + * Copyright (C) 2012 Joel Martin + * Copyright (C) 2016 Samuel Mannehed for Cendio AB + * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) + * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). + */ + +body { + margin:0; + padding:0; + font-family: Helvetica; + /*Background image with light grey curve.*/ + background-color:#494949; + background-repeat:no-repeat; + background-position:right bottom; + height:100%; +} + +html { + height:100%; +} + +#noVNC_container { + display: table; + width:100%; + height:100%; + background-color:#313131; + border-bottom-right-radius: 800px 600px; + /*border-top-left-radius: 800px 600px;*/ +} + +#noVNC_status { + font-size: 12px; + padding-top: 4px; + height:32px; + text-align: center; + font-weight: bold; + color: #fff; + z-index: 0; + position: absolute; + width: 100%; + margin-left: 0px; +} + +.noVNC_status_normal { + background: #b2bdcd; /* Old browsers */ + background: -moz-linear-gradient(top, #b2bdcd 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b2bdcd), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */ + background: -ms-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */ + background: linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */ +} + +.noVNC_status_error { + background: #f04040; /* Old browsers */ + background: -moz-linear-gradient(top, #f04040 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f04040), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */ + background: -ms-linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */ + background: linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */ +} + +.noVNC_status_warn { + background: #f0f040; /* Old browsers */ + background: -moz-linear-gradient(top, #f0f040 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f0f040), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */ + background: -ms-linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */ + background: linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */ +} + +#noVNC_buttons { + white-space: nowrap; +} + +/* Do not set width/height for VNC_canvas or incorrect + * scaling will occur. Canvas size depends on remote VNC + * settings and noVNC settings. */ +#noVNC_canvas { + position: absolute; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; +} diff --git a/noVNC/app/styles/base.css b/noVNC/app/styles/base.css new file mode 100644 index 0000000..6bb23a4 --- /dev/null +++ b/noVNC/app/styles/base.css @@ -0,0 +1,876 @@ +/* + * noVNC base CSS + * Copyright (C) 2012 Joel Martin + * Copyright (C) 2016 Samuel Mannehed for Cendio AB + * Copyright (C) 2016 Pierre Ossman for Cendio AB + * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) + * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). + */ + +/* + * Z index layers: + * + * 0: Main screen + * 10: Control bar + * 50: Transition blocker + * 60: Connection popups + * 100: Status bar + * ... + * 1000: Javascript crash + * ... + * 10000: Max (used for polyfills) + */ + +body { + margin:0; + padding:0; + font-family: Helvetica; + /*Background image with light grey curve.*/ + background-color:#494949; + background-repeat:no-repeat; + background-position:right bottom; + height:100%; + touch-action: none; +} + +html { + height:100%; +} + +.noVNC_only_touch.noVNC_hidden { + display: none; +} + +.noVNC_disabled { + color: rgb(128, 128, 128); +} + +/* ---------------------------------------- + * Spinner + * ---------------------------------------- + */ + +.noVNC_spinner { + position: relative; +} +.noVNC_spinner, .noVNC_spinner::before, .noVNC_spinner::after { + width: 10px; + height: 10px; + border-radius: 2px; + animation: noVNC_spinner 1.0s linear infinite; +} +.noVNC_spinner::before { + content: ""; + position: absolute; + left: 0px; + top: 0px; + animation-delay: -0.1s; +} +.noVNC_spinner::after { + content: ""; + position: absolute; + top: 0px; + left: 0px; + animation-delay: 0.1s; +} +@keyframes noVNC_spinner { + 0% { box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); width: 20px; } + 25% { box-shadow: 20px 10px 0 rgba(255, 255, 255, 1); width: 10px; } + 50% { box-shadow: 60px 10px 0 rgba(255, 255, 255, 0); width: 10px; } +} + +/* ---------------------------------------- + * Input Elements + * ---------------------------------------- + */ + +input[type=input], input[type=password], input[type=number], +input:not([type]), textarea { + /* Disable default rendering */ + -webkit-appearance: none; + -moz-appearance: none; + background: none; + + margin: 2px; + padding: 2px; + border: 1px solid rgb(192, 192, 192); + border-radius: 5px; + color: black; + background: linear-gradient(to top, rgb(255, 255, 255) 80%, rgb(240, 240, 240)); +} + +input[type=button], input[type=submit], select { + /* Disable default rendering */ + -webkit-appearance: none; + -moz-appearance: none; + background: none; + + margin: 2px; + padding: 2px; + border: 1px solid rgb(192, 192, 192); + border-bottom-width: 2px; + border-radius: 5px; + color: black; + background: linear-gradient(to top, rgb(255, 255, 255), rgb(240, 240, 240)); + + /* This avoids it jumping around when :active */ + vertical-align: middle; +} + +input[type=button], input[type=submit] { + padding-left: 20px; + padding-right: 20px; +} + +option { + color: black; + background: white; +} + +input[type=input]:focus, input[type=password]:focus, +input:not([type]):focus, input[type=button]:focus, +input[type=submit]:focus, +textarea:focus, select:focus { + box-shadow: 0px 0px 3px rgba(74, 144, 217, 0.5); + border-color: rgb(74, 144, 217); + outline: none; +} + +input[type=button]::-moz-focus-inner, +input[type=submit]::-moz-focus-inner { + border: none; +} + +input[type=input]:disabled, input[type=password]:disabled, +input:not([type]):disabled, input[type=button]:disabled, +input[type=submit]:disabled, input[type=number]:disabled, +textarea:disabled, select:disabled { + color: rgb(128, 128, 128); + background: rgb(240, 240, 240); +} + +input[type=button]:active, input[type=submit]:active, +select:active { + border-bottom-width: 1px; + margin-top: 3px; +} + +:root:not(.noVNC_touch) input[type=button]:hover:not(:disabled), +:root:not(.noVNC_touch) input[type=submit]:hover:not(:disabled), +:root:not(.noVNC_touch) select:hover:not(:disabled) { + background: linear-gradient(to top, rgb(255, 255, 255), rgb(250, 250, 250)); +} + +/* ---------------------------------------- + * WebKit centering hacks + * ---------------------------------------- + */ + +.noVNC_center { + /* + * This is a workaround because webkit misrenders transforms and + * uses non-integer coordinates, resulting in blurry content. + * Ideally we'd use "top: 50%; transform: translateY(-50%);" on + * the objects instead. + */ + display: flex; + align-items: center; + justify-content: center; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; +} +.noVNC_center > * { + pointer-events: auto; +} +.noVNC_vcenter { + display: flex; + flex-direction: column; + justify-content: center; + position: fixed; + top: 0; + left: 0; + height: 100%; + pointer-events: none; +} +.noVNC_vcenter > * { + pointer-events: auto; +} + +/* ---------------------------------------- + * Layering + * ---------------------------------------- + */ + +.noVNC_connect_layer { + z-index: 60; +} + +/* ---------------------------------------- + * Fallback error + * ---------------------------------------- + */ + +#noVNC_fallback_error { + position: fixed; + z-index: 1000; + left: 50%; + transform: translate(-50%, -50px); + transition: 0.5s ease-in-out; + + visibility: hidden; + opacity: 0; + + top: 60px; + padding: 15px; + width: auto; + + text-align: center; + font-weight: bold; + word-wrap: break-word; + color: #fff; + + border-radius: 10px; + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); + background: rgba(200,55,55,0.8); +} +#noVNC_fallback_error.noVNC_open { + transform: translate(-50%, 0); + visibility: visible; + opacity: 1; +} + +#noVNC_fallback_errormsg { + font-weight: normal; +} + +#noVNC_fallback_error .noVNC_location { + font-style: italic; + font-size: 0.8em; + color: rgba(255, 255, 255, 0.8); +} + +#noVNC_fallback_error .noVNC_stack { + padding: 10px; + margin: 10px; + font-size: 0.8em; + text-align: left; + white-space: pre; + border: 1px solid rgba(0, 0, 0, 0.5); + background: rgba(0, 0, 0, 0.2); +} + +/* ---------------------------------------- + * Control Bar + * ---------------------------------------- + */ + +#noVNC_control_bar_anchor { + /* The anchor is needed to get z-stacking to work */ + position: fixed; + z-index: 10; + + transition: 0.5s ease-in-out; + + /* Edge misrenders animations wihthout this */ + transform: translateX(0); +} +:root.noVNC_connected #noVNC_control_bar_anchor.noVNC_idle { + opacity: 0.8; +} +#noVNC_control_bar_anchor.noVNC_right { + left: auto; + right: 0; +} + +#noVNC_control_bar { + position: relative; + left: -100%; + + transition: 0.5s ease-in-out; + + background-color: rgb(110, 132, 163); + border-radius: 0 10px 10px 0; + +} +#noVNC_control_bar.noVNC_open { + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); + left: 0; +} +#noVNC_control_bar::before { + /* This extra element is to get a proper shadow */ + content: ""; + position: absolute; + z-index: -1; + height: 100%; + width: 30px; + left: -30px; + transition: box-shadow 0.5s ease-in-out; +} +#noVNC_control_bar.noVNC_open::before { + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); +} +.noVNC_right #noVNC_control_bar { + left: 100%; + border-radius: 10px 0 0 10px; +} +.noVNC_right #noVNC_control_bar.noVNC_open { + left: 0; +} +.noVNC_right #noVNC_control_bar::before { + visibility: hidden; +} + +#noVNC_control_bar_handle { + position: absolute; + left: -15px; + top: 0; + transform: translateY(35px); + width: calc(100% + 30px); + height: 50px; + z-index: -1; + cursor: pointer; + border-radius: 5px; + background-color: rgb(83, 99, 122); + background-image: url("../images/handle_bg.svg"); + background-repeat: no-repeat; + background-position: right; + box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.5); +} +#noVNC_control_bar_handle:after { + content: ""; + transition: transform 0.5s ease-in-out; + background: url("../images/handle.svg"); + position: absolute; + top: 22px; /* (50px-6px)/2 */ + right: 5px; + width: 5px; + height: 6px; +} +#noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after { + transform: translateX(1px) rotate(180deg); +} +:root:not(.noVNC_connected) #noVNC_control_bar_handle { + display: none; +} +.noVNC_right #noVNC_control_bar_handle { + background-position: left; +} +.noVNC_right #noVNC_control_bar_handle:after { + left: 5px; + right: 0; + transform: translateX(1px) rotate(180deg); +} +.noVNC_right #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after { + transform: none; +} +#noVNC_control_bar_handle div { + position: absolute; + right: -35px; + top: 0; + width: 50px; + height: 50px; +} +:root:not(.noVNC_touch) #noVNC_control_bar_handle div { + display: none; +} +.noVNC_right #noVNC_control_bar_handle div { + left: -35px; + right: auto; +} + +#noVNC_control_bar .noVNC_scroll { + max-height: 100vh; /* Chrome is buggy with 100% */ + overflow-x: hidden; + overflow-y: auto; + padding: 0 10px 0 5px; +} +.noVNC_right #noVNC_control_bar .noVNC_scroll { + padding: 0 5px 0 10px; +} + +/* General button style */ +.noVNC_button { + display: block; + padding: 4px 4px; + margin: 10px 0; + vertical-align: middle; + border:1px solid rgba(255, 255, 255, 0.2); + border-radius: 6px; +} +.noVNC_button.noVNC_selected { + border-color: rgba(0, 0, 0, 0.8); + background: rgba(0, 0, 0, 0.5); +} +.noVNC_button:disabled { + opacity: 0.4; +} +.noVNC_button:focus { + outline: none; +} +.noVNC_button:active { + padding-top: 5px; + padding-bottom: 3px; +} +:root:not(.noVNC_touch) .noVNC_button.noVNC_selected:hover { + border-color: rgba(0, 0, 0, 0.4); + background: rgba(0, 0, 0, 0.2); +} +:root:not(.noVNC_touch) .noVNC_button:hover { + background: rgba(255, 255, 255, 0.2); +} +.noVNC_button.noVNC_hidden { + display: none; +} + +/* Panels */ +.noVNC_panel { + transform: translateX(25px); + + transition: 0.5s ease-in-out; + + max-height: 100vh; /* Chrome is buggy with 100% */ + overflow-x: hidden; + overflow-y: auto; + + visibility: hidden; + opacity: 0; + + padding: 15px; + + background: #fff; + border-radius: 10px; + color: #000; + border: 2px solid #E0E0E0; + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); +} +.noVNC_panel.noVNC_open { + visibility: visible; + opacity: 1; + transform: translateX(75px); +} +.noVNC_right .noVNC_vcenter { + left: auto; + right: 0; +} +.noVNC_right .noVNC_panel { + transform: translateX(-25px); +} +.noVNC_right .noVNC_panel.noVNC_open { + transform: translateX(-75px); +} + +.noVNC_panel hr { + border: none; + border-top: 1px solid rgb(192, 192, 192); +} + +.noVNC_panel label { + display: block; + white-space: nowrap; +} + +.noVNC_panel .noVNC_heading { + background-color: rgb(110, 132, 163); + border-radius: 5px; + padding: 5px; + /* Compensate for padding in image */ + padding-right: 8px; + color: white; + font-size: 20px; + margin-bottom: 10px; + white-space: nowrap; +} +.noVNC_panel .noVNC_heading img { + vertical-align: bottom; +} + +.noVNC_submit { + float: right; +} + +/* Expanders */ +.noVNC_expander { + cursor: pointer; +} +.noVNC_expander::before { + content: url("../images/expander.svg"); + display: inline-block; + margin-right: 5px; + transition: 0.2s ease-in-out; +} +.noVNC_expander.noVNC_open::before { + transform: rotateZ(90deg); +} +.noVNC_expander ~ * { + margin: 5px; + margin-left: 10px; + padding: 5px; + background: rgba(0, 0, 0, 0.05); + border-radius: 5px; +} +.noVNC_expander:not(.noVNC_open) ~ * { + display: none; +} + +/* Control bar content */ + +#noVNC_control_bar .noVNC_logo { + font-size: 13px; +} + +:root:not(.noVNC_connected) #noVNC_view_drag_button { + display: none; +} + +/* noVNC Touch Device only buttons */ +:root:not(.noVNC_connected) #noVNC_mobile_buttons { + display: none; +} +:root:not(.noVNC_touch) #noVNC_mobile_buttons { + display: none; +} + +/* Extra manual keys */ +:root:not(.noVNC_connected) #noVNC_extra_keys { + display: none; +} + +#noVNC_modifiers { + background-color: rgb(92, 92, 92); + border: none; + padding: 0 10px; +} + +/* XVP Shutdown/Reboot */ +:root:not(.noVNC_connected) #noVNC_xvp_button { + display: none; +} +#noVNC_xvp { +} +#noVNC_xvp_buttons { + display: none; +} + +#noVNC_xvp input[type=button] { + width: 100%; +} + +/* Clipboard */ +:root:not(.noVNC_connected) #noVNC_clipboard_button { + display: none; +} +#noVNC_clipboard { + /* Full screen, minus padding and left and right margins */ + max-width: calc(100vw - 2*15px - 75px - 25px); +} +#noVNC_clipboard_text { + width: 500px; + max-width: 100%; +} + +/* Settings */ +#noVNC_settings { +} +#noVNC_settings ul { + list-style: none; + margin: 0px; + padding: 0px; +} +#noVNC_setting_port { + width: 80px; +} +#noVNC_setting_path { + width: 100px; +} + +/* Connection Controls */ +:root:not(.noVNC_connected) #noVNC_disconnect_button { + display: none; +} + +/* ---------------------------------------- + * Status Dialog + * ---------------------------------------- + */ + +#noVNC_status { + position: fixed; + top: 0; + left: 0; + width: 100%; + z-index: 100; + transform: translateY(-100%); + + cursor: pointer; + + transition: 0.5s ease-in-out; + + visibility: hidden; + opacity: 0; + + padding: 5px; + + display: flex; + flex-direction: row; + justify-content: center; + align-content: center; + + line-height: 25px; + word-wrap: break-word; + color: #fff; + + border-bottom: 1px solid rgba(0, 0, 0, 0.9); +} +#noVNC_status.noVNC_open { + transform: translateY(0); + visibility: visible; + opacity: 1; +} + +#noVNC_status::before { + content: ""; + display: inline-block; + width: 25px; + height: 25px; + margin-right: 5px; +} + +#noVNC_status.noVNC_status_normal { + background: rgba(128,128,128,0.9); +} +#noVNC_status.noVNC_status_normal::before { + content: url("../images/info.svg") " "; +} +#noVNC_status.noVNC_status_error { + background: rgba(200,55,55,0.9); +} +#noVNC_status.noVNC_status_error::before { + content: url("../images/error.svg") " "; +} +#noVNC_status.noVNC_status_warn { + background: rgba(180,180,30,0.9); +} +#noVNC_status.noVNC_status_warn::before { + content: url("../images/warning.svg") " "; +} + +/* ---------------------------------------- + * Connect Dialog + * ---------------------------------------- + */ + +#noVNC_connect_dlg { + transition: 0.5s ease-in-out; + + transform: scale(0, 0); + visibility: hidden; + opacity: 0; +} +#noVNC_connect_dlg.noVNC_open { + transform: scale(1, 1); + visibility: visible; + opacity: 1; +} +#noVNC_connect_dlg .noVNC_logo { + transition: 0.5s ease-in-out; + padding: 10px; + margin-bottom: 10px; + + font-size: 80px; + text-align: center; + + border-radius: 5px; +} +@media (max-width: 440px) { + #noVNC_connect_dlg { + max-width: calc(100vw - 100px); + } + #noVNC_connect_dlg .noVNC_logo { + font-size: calc(25vw - 30px); + } +} +#noVNC_connect_button { + cursor: pointer; + + padding: 10px; + + color: white; + background-color: rgb(110, 132, 163); + border-radius: 12px; + + text-align: center; + font-size: 20px; + + box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); +} +#noVNC_connect_button div { + margin: 2px; + padding: 5px 30px; + border: 1px solid rgb(83, 99, 122); + border-bottom-width: 2px; + border-radius: 5px; + background: linear-gradient(to top, rgb(110, 132, 163), rgb(99, 119, 147)); + + /* This avoids it jumping around when :active */ + vertical-align: middle; +} +#noVNC_connect_button div:active { + border-bottom-width: 1px; + margin-top: 3px; +} +:root:not(.noVNC_touch) #noVNC_connect_button div:hover { + background: linear-gradient(to top, rgb(110, 132, 163), rgb(105, 125, 155)); +} + +#noVNC_connect_button img { + vertical-align: bottom; + height: 1.3em; +} + +/* ---------------------------------------- + * Password Dialog + * ---------------------------------------- + */ + +#noVNC_password_dlg { + position: relative; + + transform: translateY(-50px); +} +#noVNC_password_dlg.noVNC_open { + transform: translateY(0); +} +#noVNC_password_dlg ul { + list-style: none; + margin: 0px; + padding: 0px; +} + +/* ---------------------------------------- + * Main Area + * ---------------------------------------- + */ + +/* Transition screen */ +#noVNC_transition { + display: none; + + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + + color: white; + background: rgba(0, 0, 0, 0.5); + z-index: 50; + + /*display: flex;*/ + align-items: center; + justify-content: center; + flex-direction: column; +} +:root.noVNC_connecting #noVNC_transition, +:root.noVNC_disconnecting #noVNC_transition, +:root.noVNC_reconnecting #noVNC_transition { + display: flex; +} +:root:not(.noVNC_reconnecting) #noVNC_cancel_reconnect_button { + display: none; +} +#noVNC_transition_text { + font-size: 1.5em; +} + +/* Main container */ +#noVNC_container { + width: 100%; + height: 100%; + background-color: #313131; + border-bottom-right-radius: 800px 600px; + /*border-top-left-radius: 800px 600px;*/ +} + +#noVNC_keyboardinput { + width: 1px; + height: 1px; + background-color: #fff; + color: #fff; + border: 0; + position: absolute; + left: -40px; + z-index: -1; + ime-mode: disabled; +} + +/* HTML5 Canvas */ +#noVNC_screen { + display: flex; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgb(40, 40, 40); +} +:root:not(.noVNC_connected) #noVNC_screen { + display: none; +} + +/* Do not set width/height for VNC_canvas or incorrect + * scaling will occur. Canvas size depends on remote VNC + * settings and noVNC settings. */ +#noVNC_canvas { + margin: auto; + /* IE miscalculates width without this :( */ + flex-shrink: 0; +} + +/*Default noVNC logo.*/ +/* From: http://fonts.googleapis.com/css?family=Orbitron:700 */ +@font-face { + font-family: 'Orbitron'; + font-style: normal; + font-weight: 700; + src: local('?'), url('Orbitron700.woff') format('woff'), + url('Orbitron700.ttf') format('truetype'); +} + +.noVNC_logo { + color:yellow; + font-family: 'Orbitron', 'OrbitronTTF', sans-serif; + line-height:90%; + text-shadow: 0.1em 0.1em 0 black; +} +.noVNC_logo span{ + color:green; +} + +#noVNC_bell { + display: none; +} + +/* ---------------------------------------- + * Media sizing + * ---------------------------------------- + */ + +@media screen and (max-width: 640px){ + #noVNC_logo { + font-size: 150px; + } +} + +@media screen and (min-width: 321px) and (max-width: 480px) { + #noVNC_logo { + font-size: 110px; + } +} + +@media screen and (max-width: 320px) { + #noVNC_logo { + font-size: 90px; + } +} diff --git a/noVNC/app/ui.js b/noVNC/app/ui.js new file mode 100644 index 0000000..33cd1d4 --- /dev/null +++ b/noVNC/app/ui.js @@ -0,0 +1,1761 @@ +/* + * noVNC: HTML5 VNC client + * Copyright (C) 2012 Joel Martin + * Copyright (C) 2016 Samuel Mannehed for Cendio AB + * Copyright (C) 2016 Pierre Ossman for Cendio AB + * Licensed under MPL 2.0 (see LICENSE.txt) + * + * See README.md for usage and integration instructions. + */ + +/* jslint white: false, browser: true */ +/* global window, document.getElementById, Util, WebUtil, RFB, Display */ + +/* [module] + * import Util from "../core/util"; + * import KeyTable from "../core/input/keysym"; + * import keysyms from "./keysymdef"; + * import RFB from "../core/rfb"; + * import Display from "../core/display"; + * import WebUtil from "./webutil"; + */ + +var UI; + +(function () { + "use strict"; + + // Fallback for all uncought errors + window.addEventListener('error', function(event) { + try { + var msg, div, text; + + msg = document.getElementById('noVNC_fallback_errormsg'); + + // Only show the initial error + if (msg.hasChildNodes()) { + return false; + } + + div = document.createElement("div"); + div.appendChild(document.createTextNode(event.message)); + msg.appendChild(div); + + div = document.createElement("div"); + div.className = 'noVNC_location'; + text = event.filename + ":" + event.lineno + ":" + event.colno; + div.appendChild(document.createTextNode(text)); + msg.appendChild(div); + + if ((event.error !== undefined) && + (event.error.stack !== undefined)) { + div = document.createElement("div"); + div.className = 'noVNC_stack'; + div.appendChild(document.createTextNode(event.error.stack)); + msg.appendChild(div); + } + + document.getElementById('noVNC_fallback_error') + .classList.add("noVNC_open"); + } catch (exc) { + document.write("noVNC encountered an error."); + } + // Don't return true since this would prevent the error + // from being printed to the browser console. + return false; + }); + + // Set up translations + var LINGUAS = ["de", "el", "nl", "sv"]; + Util.Localisation.setup(LINGUAS); + if (Util.Localisation.language !== "en") { + WebUtil.load_scripts( + {'app': ["locale/" + Util.Localisation.language + ".js"]}); + } + + /* [begin skip-as-module] */ + // Load supporting scripts + WebUtil.load_scripts( + {'core': ["base64.js", "websock.js", "des.js", "input/keysymdef.js", + "input/xtscancodes.js", "input/util.js", "input/devices.js", + "display.js", "inflator.js", "rfb.js", "input/keysym.js"]}); + + window.onscriptsload = function () { UI.load(); }; + /* [end skip-as-module] */ + + var _ = Util.Localisation.get; + + UI = { + + connected: false, + desktopName: "", + + resizeTimeout: null, + statusTimeout: null, + hideKeyboardTimeout: null, + idleControlbarTimeout: null, + closeControlbarTimeout: null, + + controlbarGrabbed: false, + controlbarDrag: false, + controlbarMouseDownClientY: 0, + controlbarMouseDownOffsetY: 0, + + isSafari: false, + rememberedClipSetting: null, + lastKeyboardinput: null, + defaultKeyboardinputLen: 100, + + inhibit_reconnect: true, + reconnect_callback: null, + reconnect_password: null, + + // Setup rfb object, load settings from browser storage, then call + // UI.init to setup the UI/menus + load: function(callback) { + WebUtil.initSettings(UI.start, callback); + }, + + // Render default UI and initialize settings menu + start: function(callback) { + + // Setup global variables first + UI.isSafari = (navigator.userAgent.indexOf('Safari') !== -1 && + navigator.userAgent.indexOf('Chrome') === -1); + + UI.initSettings(); + + // Translate the DOM + Util.Localisation.translateDOM(); + + // Adapt the interface for touch screen devices + if (Util.isTouchDevice) { + document.documentElement.classList.add("noVNC_touch"); + // Remove the address bar + setTimeout(function() { window.scrollTo(0, 1); }, 100); + } + + // Restore control bar position + if (WebUtil.readSetting('controlbar_pos') === 'right') { + UI.toggleControlbarSide(); + } + + UI.initFullscreen(); + + // Setup event handlers + UI.addResizeHandlers(); + UI.addControlbarHandlers(); + UI.addTouchSpecificHandlers(); + UI.addExtraKeysHandlers(); + UI.addXvpHandlers(); + UI.addConnectionControlHandlers(); + UI.addClipboardHandlers(); + UI.addSettingsHandlers(); + document.getElementById("noVNC_status") + .addEventListener('click', UI.hideStatus); + + UI.openControlbar(); + + // Show the connect panel on first load unless autoconnecting + if (!autoconnect) { + UI.openConnectPanel(); + } + + UI.updateViewClip(); + + UI.updateVisualState(); + + document.getElementById('noVNC_setting_host').focus(); + + var autoconnect = WebUtil.getConfigVar('autoconnect', false); + if (autoconnect === 'true' || autoconnect == '1') { + autoconnect = true; + UI.connect(); + } else { + autoconnect = false; + } + + if (typeof callback === "function") { + callback(UI.rfb); + } + }, + + initFullscreen: function() { + // Only show the button if fullscreen is properly supported + // * Safari doesn't support alphanumerical input while in fullscreen + if (!UI.isSafari && + (document.documentElement.requestFullscreen || + document.documentElement.mozRequestFullScreen || + document.documentElement.webkitRequestFullscreen || + document.body.msRequestFullscreen)) { + document.getElementById('noVNC_fullscreen_button') + .classList.remove("noVNC_hidden"); + UI.addFullscreenHandlers(); + } + }, + + initSettings: function() { + var i; + + // Logging selection dropdown + var llevels = ['error', 'warn', 'info', 'debug']; + for (i = 0; i < llevels.length; i += 1) { + UI.addOption(document.getElementById('noVNC_setting_logging'),llevels[i], llevels[i]); + } + + // Settings with immediate effects + UI.initSetting('logging', 'warn'); + UI.updateLogging(); + + // if port == 80 (or 443) then it won't be present and should be + // set manually + var port = window.location.port; + if (!port) { + if (window.location.protocol.substring(0,5) == 'https') { + port = 443; + } + else if (window.location.protocol.substring(0,4) == 'http') { + port = 80; + } + } + + /* Populate the controls if defaults are provided in the URL */ + UI.initSetting('host', window.location.hostname); + UI.initSetting('port', port); + UI.initSetting('encrypt', (window.location.protocol === "https:")); + UI.initSetting('true_color', true); + UI.initSetting('cursor', !Util.isTouchDevice); + UI.initSetting('clip', false); + UI.initSetting('resize', 'off'); + UI.initSetting('shared', true); + UI.initSetting('view_only', false); + UI.initSetting('path', 'websockify'); + UI.initSetting('repeaterID', ''); + UI.initSetting('reconnect', false); + UI.initSetting('reconnect_delay', 5000); + + UI.setupSettingLabels(); + }, + + // Adds a link to the label elements on the corresponding input elements + setupSettingLabels: function() { + var labels = document.getElementsByTagName('LABEL'); + for (var i = 0; i < labels.length; i++) { + var htmlFor = labels[i].htmlFor; + if (htmlFor != '') { + var elem = document.getElementById(htmlFor); + if (elem) elem.label = labels[i]; + } else { + // If 'for' isn't set, use the first input element child + var children = labels[i].children; + for (var j = 0; j < children.length; j++) { + if (children[j].form !== undefined) { + children[j].label = labels[i]; + break; + } + } + } + } + }, + + initRFB: function() { + try { + UI.rfb = new RFB({'target': document.getElementById('noVNC_canvas'), + 'onNotification': UI.notification, + 'onUpdateState': UI.updateState, + 'onDisconnected': UI.disconnectFinished, + 'onPasswordRequired': UI.passwordRequired, + 'onXvpInit': UI.updateXvpButton, + 'onClipboard': UI.clipboardReceive, + 'onBell': UI.bell, + 'onFBUComplete': UI.initialResize, + 'onFBResize': UI.updateSessionSize, + 'onDesktopName': UI.updateDesktopName}); + return true; + } catch (exc) { + var msg = "Unable to create RFB client -- " + exc; + Util.Error(msg); + UI.showStatus(msg, 'error'); + return false; + } + }, + +/* ------^------- + * /INIT + * ============== + * EVENT HANDLERS + * ------v------*/ + + addResizeHandlers: function() { + window.addEventListener('resize', UI.applyResizeMode); + window.addEventListener('resize', UI.updateViewClip); + }, + + addControlbarHandlers: function() { + document.getElementById("noVNC_control_bar") + .addEventListener('mousemove', UI.activateControlbar); + document.getElementById("noVNC_control_bar") + .addEventListener('mouseup', UI.activateControlbar); + document.getElementById("noVNC_control_bar") + .addEventListener('mousedown', UI.activateControlbar); + document.getElementById("noVNC_control_bar") + .addEventListener('keypress', UI.activateControlbar); + + document.getElementById("noVNC_control_bar") + .addEventListener('mousedown', UI.keepControlbar); + document.getElementById("noVNC_control_bar") + .addEventListener('keypress', UI.keepControlbar); + + document.getElementById("noVNC_view_drag_button") + .addEventListener('click', UI.toggleViewDrag); + + document.getElementById("noVNC_control_bar_handle") + .addEventListener('mousedown', UI.controlbarHandleMouseDown); + document.getElementById("noVNC_control_bar_handle") + .addEventListener('mouseup', UI.controlbarHandleMouseUp); + document.getElementById("noVNC_control_bar_handle") + .addEventListener('mousemove', UI.dragControlbarHandle); + // resize events aren't available for elements + window.addEventListener('resize', UI.updateControlbarHandle); + + var exps = document.getElementsByClassName("noVNC_expander"); + for (var i = 0;i < exps.length;i++) { + exps[i].addEventListener('click', UI.toggleExpander); + } + }, + + addTouchSpecificHandlers: function() { + document.getElementById("noVNC_mouse_button0") + .addEventListener('click', function () { UI.setMouseButton(1); }); + document.getElementById("noVNC_mouse_button1") + .addEventListener('click', function () { UI.setMouseButton(2); }); + document.getElementById("noVNC_mouse_button2") + .addEventListener('click', function () { UI.setMouseButton(4); }); + document.getElementById("noVNC_mouse_button4") + .addEventListener('click', function () { UI.setMouseButton(0); }); + document.getElementById("noVNC_keyboard_button") + .addEventListener('click', UI.toggleVirtualKeyboard); + + document.getElementById("noVNC_keyboardinput") + .addEventListener('input', UI.keyInput); + document.getElementById("noVNC_keyboardinput") + .addEventListener('focus', UI.onfocusVirtualKeyboard); + document.getElementById("noVNC_keyboardinput") + .addEventListener('blur', UI.onblurVirtualKeyboard); + document.getElementById("noVNC_keyboardinput") + .addEventListener('submit', function () { return false; }); + + document.documentElement + .addEventListener('mousedown', UI.keepVirtualKeyboard, true); + + document.getElementById("noVNC_control_bar") + .addEventListener('touchstart', UI.activateControlbar); + document.getElementById("noVNC_control_bar") + .addEventListener('touchmove', UI.activateControlbar); + document.getElementById("noVNC_control_bar") + .addEventListener('touchend', UI.activateControlbar); + document.getElementById("noVNC_control_bar") + .addEventListener('input', UI.activateControlbar); + + document.getElementById("noVNC_control_bar") + .addEventListener('touchstart', UI.keepControlbar); + document.getElementById("noVNC_control_bar") + .addEventListener('input', UI.keepControlbar); + + document.getElementById("noVNC_control_bar_handle") + .addEventListener('touchstart', UI.controlbarHandleMouseDown); + document.getElementById("noVNC_control_bar_handle") + .addEventListener('touchend', UI.controlbarHandleMouseUp); + document.getElementById("noVNC_control_bar_handle") + .addEventListener('touchmove', UI.dragControlbarHandle); + + window.addEventListener('load', UI.keyboardinputReset); + }, + + addExtraKeysHandlers: function() { + document.getElementById("noVNC_toggle_extra_keys_button") + .addEventListener('click', UI.toggleExtraKeys); + document.getElementById("noVNC_toggle_ctrl_button") + .addEventListener('click', UI.toggleCtrl); + document.getElementById("noVNC_toggle_alt_button") + .addEventListener('click', UI.toggleAlt); + document.getElementById("noVNC_send_tab_button") + .addEventListener('click', UI.sendTab); + document.getElementById("noVNC_send_esc_button") + .addEventListener('click', UI.sendEsc); + document.getElementById("noVNC_send_ctrl_alt_del_button") + .addEventListener('click', UI.sendCtrlAltDel); + }, + + addXvpHandlers: function() { + document.getElementById("noVNC_xvp_shutdown_button") + .addEventListener('click', function() { UI.rfb.xvpShutdown(); }); + document.getElementById("noVNC_xvp_reboot_button") + .addEventListener('click', function() { UI.rfb.xvpReboot(); }); + document.getElementById("noVNC_xvp_reset_button") + .addEventListener('click', function() { UI.rfb.xvpReset(); }); + document.getElementById("noVNC_xvp_button") + .addEventListener('click', UI.toggleXvpPanel); + }, + + addConnectionControlHandlers: function() { + document.getElementById("noVNC_disconnect_button") + .addEventListener('click', UI.disconnect); + document.getElementById("noVNC_connect_button") + .addEventListener('click', UI.connect); + document.getElementById("noVNC_cancel_reconnect_button") + .addEventListener('click', UI.cancelReconnect); + + document.getElementById("noVNC_password_button") + .addEventListener('click', UI.setPassword); + }, + + addClipboardHandlers: function() { + document.getElementById("noVNC_clipboard_button") + .addEventListener('click', UI.toggleClipboardPanel); + document.getElementById("noVNC_clipboard_text") + .addEventListener('focus', UI.displayBlur); + document.getElementById("noVNC_clipboard_text") + .addEventListener('blur', UI.displayFocus); + document.getElementById("noVNC_clipboard_text") + .addEventListener('change', UI.clipboardSend); + document.getElementById("noVNC_clipboard_clear_button") + .addEventListener('click', UI.clipboardClear); + }, + + // Add a call to save settings when the element changes, + // unless the optional parameter changeFunc is used instead. + addSettingChangeHandler: function(name, changeFunc) { + var settingElem = document.getElementById("noVNC_setting_" + name); + if (changeFunc === undefined) { + changeFunc = function () { UI.saveSetting(name); }; + } + settingElem.addEventListener('change', changeFunc); + }, + + addSettingsHandlers: function() { + document.getElementById("noVNC_settings_button") + .addEventListener('click', UI.toggleSettingsPanel); + + UI.addSettingChangeHandler('encrypt'); + UI.addSettingChangeHandler('true_color'); + UI.addSettingChangeHandler('cursor'); + UI.addSettingChangeHandler('cursor', UI.updateLocalCursor); + UI.addSettingChangeHandler('resize'); + UI.addSettingChangeHandler('resize', UI.enableDisableViewClip); + UI.addSettingChangeHandler('resize', UI.applyResizeMode); + UI.addSettingChangeHandler('clip'); + UI.addSettingChangeHandler('clip', UI.updateViewClip); + UI.addSettingChangeHandler('shared'); + UI.addSettingChangeHandler('view_only'); + UI.addSettingChangeHandler('view_only', UI.updateViewOnly); + UI.addSettingChangeHandler('host'); + UI.addSettingChangeHandler('port'); + UI.addSettingChangeHandler('path'); + UI.addSettingChangeHandler('repeaterID'); + UI.addSettingChangeHandler('logging'); + UI.addSettingChangeHandler('logging', UI.updateLogging); + UI.addSettingChangeHandler('reconnect'); + UI.addSettingChangeHandler('reconnect_delay'); + }, + + addFullscreenHandlers: function() { + document.getElementById("noVNC_fullscreen_button") + .addEventListener('click', UI.toggleFullscreen); + + window.addEventListener('fullscreenchange', UI.updateFullscreenButton); + window.addEventListener('mozfullscreenchange', UI.updateFullscreenButton); + window.addEventListener('webkitfullscreenchange', UI.updateFullscreenButton); + window.addEventListener('msfullscreenchange', UI.updateFullscreenButton); + }, + +/* ------^------- + * /EVENT HANDLERS + * ============== + * VISUAL + * ------v------*/ + + updateState: function(rfb, state, oldstate) { + var msg; + + document.documentElement.classList.remove("noVNC_connecting"); + document.documentElement.classList.remove("noVNC_connected"); + document.documentElement.classList.remove("noVNC_disconnecting"); + document.documentElement.classList.remove("noVNC_reconnecting"); + + switch (state) { + case 'connecting': + document.getElementById("noVNC_transition_text").textContent = _("Connecting..."); + document.documentElement.classList.add("noVNC_connecting"); + break; + case 'connected': + UI.connected = true; + UI.inhibit_reconnect = false; + document.documentElement.classList.add("noVNC_connected"); + if (rfb && rfb.get_encrypt()) { + msg = _("Connected (encrypted) to ") + UI.desktopName; + } else { + msg = _("Connected (unencrypted) to ") + UI.desktopName; + } + UI.showStatus(msg); + break; + case 'disconnecting': + UI.connected = false; + document.getElementById("noVNC_transition_text").textContent = _("Disconnecting..."); + document.documentElement.classList.add("noVNC_disconnecting"); + break; + case 'disconnected': + UI.showStatus(_("Disconnected")); + break; + default: + msg = "Invalid UI state"; + Util.Error(msg); + UI.showStatus(msg, 'error'); + break; + } + + UI.updateVisualState(); + }, + + // Disable/enable controls depending on connection state + updateVisualState: function() { + //Util.Debug(">> updateVisualState"); + + UI.enableDisableViewClip(); + + if (Util.browserSupportsCursorURIs() && !Util.isTouchDevice) { + UI.enableSetting('cursor'); + } else { + UI.disableSetting('cursor'); + } + + if (UI.connected) { + UI.disableSetting('encrypt'); + UI.disableSetting('true_color'); + UI.disableSetting('shared'); + UI.disableSetting('host'); + UI.disableSetting('port'); + UI.disableSetting('path'); + UI.disableSetting('repeaterID'); + UI.updateViewClip(); + UI.setMouseButton(1); + + // Hide the controlbar after 2 seconds + UI.closeControlbarTimeout = setTimeout(UI.closeControlbar, 2000); + } else { + UI.enableSetting('encrypt'); + UI.enableSetting('true_color'); + UI.enableSetting('shared'); + UI.enableSetting('host'); + UI.enableSetting('port'); + UI.enableSetting('path'); + UI.enableSetting('repeaterID'); + UI.updateXvpButton(0); + UI.keepControlbar(); + } + + // Hide input related buttons in view only mode + if (UI.rfb && UI.rfb.get_view_only()) { + document.getElementById('noVNC_keyboard_button') + .classList.add('noVNC_hidden'); + document.getElementById('noVNC_toggle_extra_keys_button') + .classList.add('noVNC_hidden'); + } else { + document.getElementById('noVNC_keyboard_button') + .classList.remove('noVNC_hidden'); + document.getElementById('noVNC_toggle_extra_keys_button') + .classList.remove('noVNC_hidden'); + } + + // State change disables viewport dragging. + // It is enabled (toggled) by direct click on the button + UI.setViewDrag(false); + + // State change also closes the password dialog + document.getElementById('noVNC_password_dlg') + .classList.remove('noVNC_open'); + + //Util.Debug("<< updateVisualState"); + }, + + showStatus: function(text, status_type, time) { + var statusElem = document.getElementById('noVNC_status'); + + clearTimeout(UI.statusTimeout); + + if (typeof status_type === 'undefined') { + status_type = 'normal'; + } + + statusElem.classList.remove("noVNC_status_normal"); + statusElem.classList.remove("noVNC_status_warn"); + statusElem.classList.remove("noVNC_status_error"); + + switch (status_type) { + case 'warning': + case 'warn': + statusElem.classList.add("noVNC_status_warn"); + break; + case 'error': + statusElem.classList.add("noVNC_status_error"); + break; + case 'normal': + case 'info': + default: + statusElem.classList.add("noVNC_status_normal"); + break; + } + + statusElem.textContent = text; + statusElem.classList.add("noVNC_open"); + + // If no time was specified, show the status for 1.5 seconds + if (typeof time === 'undefined') { + time = 1500; + } + + // Error messages do not timeout + if (status_type !== 'error') { + UI.statusTimeout = window.setTimeout(UI.hideStatus, time); + } + }, + + hideStatus: function() { + clearTimeout(UI.statusTimeout); + document.getElementById('noVNC_status').classList.remove("noVNC_open"); + }, + + notification: function (rfb, msg, level, options) { + UI.showStatus(msg, level); + }, + + activateControlbar: function(event) { + clearTimeout(UI.idleControlbarTimeout); + // We manipulate the anchor instead of the actual control + // bar in order to avoid creating new a stacking group + document.getElementById('noVNC_control_bar_anchor') + .classList.remove("noVNC_idle"); + UI.idleControlbarTimeout = window.setTimeout(UI.idleControlbar, 2000); + }, + + idleControlbar: function() { + document.getElementById('noVNC_control_bar_anchor') + .classList.add("noVNC_idle"); + }, + + keepControlbar: function() { + clearTimeout(UI.closeControlbarTimeout); + }, + + openControlbar: function() { + document.getElementById('noVNC_control_bar') + .classList.add("noVNC_open"); + }, + + closeControlbar: function() { + UI.closeAllPanels(); + document.getElementById('noVNC_control_bar') + .classList.remove("noVNC_open"); + }, + + toggleControlbar: function() { + if (document.getElementById('noVNC_control_bar') + .classList.contains("noVNC_open")) { + UI.closeControlbar(); + } else { + UI.openControlbar(); + } + }, + + toggleControlbarSide: function () { + // Temporarily disable animation to avoid weird movement + var bar = document.getElementById('noVNC_control_bar'); + bar.style.transitionDuration = '0s'; + bar.addEventListener('transitionend', function () { this.style.transitionDuration = ""; }); + + var anchor = document.getElementById('noVNC_control_bar_anchor'); + if (anchor.classList.contains("noVNC_right")) { + WebUtil.writeSetting('controlbar_pos', 'left'); + anchor.classList.remove("noVNC_right"); + } else { + WebUtil.writeSetting('controlbar_pos', 'right'); + anchor.classList.add("noVNC_right"); + } + + // Consider this a movement of the handle + UI.controlbarDrag = true; + }, + + dragControlbarHandle: function (e) { + if (!UI.controlbarGrabbed) return; + + var ptr = Util.getPointerEvent(e); + + var anchor = document.getElementById('noVNC_control_bar_anchor'); + if (ptr.clientX < (window.innerWidth * 0.1)) { + if (anchor.classList.contains("noVNC_right")) { + UI.toggleControlbarSide(); + } + } else if (ptr.clientX > (window.innerWidth * 0.9)) { + if (!anchor.classList.contains("noVNC_right")) { + UI.toggleControlbarSide(); + } + } + + if (!UI.controlbarDrag) { + // The goal is to trigger on a certain physical width, the + // devicePixelRatio brings us a bit closer but is not optimal. + var dragThreshold = 10 * (window.devicePixelRatio || 1); + var dragDistance = Math.abs(ptr.clientY - UI.controlbarMouseDownClientY); + + if (dragDistance < dragThreshold) return; + + UI.controlbarDrag = true; + } + + var eventY = ptr.clientY - UI.controlbarMouseDownOffsetY; + + UI.moveControlbarHandle(eventY); + + e.preventDefault(); + e.stopPropagation(); + UI.keepControlbar(); + UI.activateControlbar(); + }, + + // Move the handle but don't allow any position outside the bounds + moveControlbarHandle: function (viewportRelativeY) { + var handle = document.getElementById("noVNC_control_bar_handle"); + var handleHeight = handle.getBoundingClientRect().height; + var controlbarBounds = document.getElementById("noVNC_control_bar") + .getBoundingClientRect(); + var margin = 10; + + // These heights need to be non-zero for the below logic to work + if (handleHeight === 0 || controlbarBounds.height === 0) { + return; + } + + var newY = viewportRelativeY; + + // Check if the coordinates are outside the control bar + if (newY < controlbarBounds.top + margin) { + // Force coordinates to be below the top of the control bar + newY = controlbarBounds.top + margin; + + } else if (newY > controlbarBounds.top + + controlbarBounds.height - handleHeight - margin) { + // Force coordinates to be above the bottom of the control bar + newY = controlbarBounds.top + + controlbarBounds.height - handleHeight - margin; + } + + // Corner case: control bar too small for stable position + if (controlbarBounds.height < (handleHeight + margin * 2)) { + newY = controlbarBounds.top + + (controlbarBounds.height - handleHeight) / 2; + } + + // The transform needs coordinates that are relative to the parent + var parentRelativeY = newY - controlbarBounds.top; + handle.style.transform = "translateY(" + parentRelativeY + "px)"; + }, + + updateControlbarHandle: function () { + // Since the control bar is fixed on the viewport and not the page, + // the move function expects coordinates relative the the viewport. + var handle = document.getElementById("noVNC_control_bar_handle"); + var handleBounds = handle.getBoundingClientRect(); + UI.moveControlbarHandle(handleBounds.top); + }, + + controlbarHandleMouseUp: function(e) { + if ((e.type == "mouseup") && (e.button != 0)) return; + + // mouseup and mousedown on the same place toggles the controlbar + if (UI.controlbarGrabbed && !UI.controlbarDrag) { + UI.toggleControlbar(); + e.preventDefault(); + e.stopPropagation(); + UI.keepControlbar(); + UI.activateControlbar(); + } + UI.controlbarGrabbed = false; + }, + + controlbarHandleMouseDown: function(e) { + if ((e.type == "mousedown") && (e.button != 0)) return; + + var ptr = Util.getPointerEvent(e); + + var handle = document.getElementById("noVNC_control_bar_handle"); + var bounds = handle.getBoundingClientRect(); + + Util.setCapture(handle); + UI.controlbarGrabbed = true; + UI.controlbarDrag = false; + + UI.controlbarMouseDownClientY = ptr.clientY; + UI.controlbarMouseDownOffsetY = ptr.clientY - bounds.top; + e.preventDefault(); + e.stopPropagation(); + UI.keepControlbar(); + UI.activateControlbar(); + }, + + toggleExpander: function(e) { + if (this.classList.contains("noVNC_open")) { + this.classList.remove("noVNC_open"); + } else { + this.classList.add("noVNC_open"); + } + }, + +/* ------^------- + * /VISUAL + * ============== + * SETTINGS + * ------v------*/ + + // Initial page load read/initialization of settings + initSetting: function(name, defVal) { + // Check Query string followed by cookie + var val = WebUtil.getConfigVar(name); + if (val === null) { + val = WebUtil.readSetting(name, defVal); + } + UI.updateSetting(name, val); + return val; + }, + + // Update cookie and form control setting. If value is not set, then + // updates from control to current cookie setting. + updateSetting: function(name, value) { + + // Save the cookie for this session + if (typeof value !== 'undefined') { + WebUtil.writeSetting(name, value); + } + + // Update the settings control + value = UI.getSetting(name); + + var ctrl = document.getElementById('noVNC_setting_' + name); + if (ctrl.type === 'checkbox') { + ctrl.checked = value; + + } else if (typeof ctrl.options !== 'undefined') { + for (var i = 0; i < ctrl.options.length; i += 1) { + if (ctrl.options[i].value === value) { + ctrl.selectedIndex = i; + break; + } + } + } else { + /*Weird IE9 error leads to 'null' appearring + in textboxes instead of ''.*/ + if (value === null) { + value = ""; + } + ctrl.value = value; + } + }, + + // Save control setting to cookie + saveSetting: function(name) { + var val, ctrl = document.getElementById('noVNC_setting_' + name); + if (ctrl.type === 'checkbox') { + val = ctrl.checked; + } else if (typeof ctrl.options !== 'undefined') { + val = ctrl.options[ctrl.selectedIndex].value; + } else { + val = ctrl.value; + } + WebUtil.writeSetting(name, val); + //Util.Debug("Setting saved '" + name + "=" + val + "'"); + return val; + }, + + // Read form control compatible setting from cookie + getSetting: function(name) { + var ctrl = document.getElementById('noVNC_setting_' + name); + var val = WebUtil.readSetting(name); + if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') { + if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) { + val = false; + } else { + val = true; + } + } + return val; + }, + + // These helpers compensate for the lack of parent-selectors and + // previous-sibling-selectors in CSS which are needed when we want to + // disable the labels that belong to disabled input elements. + disableSetting: function(name) { + var ctrl = document.getElementById('noVNC_setting_' + name); + ctrl.disabled = true; + ctrl.label.classList.add('noVNC_disabled'); + }, + + enableSetting: function(name) { + var ctrl = document.getElementById('noVNC_setting_' + name); + ctrl.disabled = false; + ctrl.label.classList.remove('noVNC_disabled'); + }, + +/* ------^------- + * /SETTINGS + * ============== + * PANELS + * ------v------*/ + + closeAllPanels: function() { + UI.closeSettingsPanel(); + UI.closeXvpPanel(); + UI.closeClipboardPanel(); + UI.closeExtraKeys(); + }, + +/* ------^------- + * /PANELS + * ============== + * SETTINGS (panel) + * ------v------*/ + + openSettingsPanel: function() { + UI.closeAllPanels(); + UI.openControlbar(); + + // Refresh UI elements from saved cookies + UI.updateSetting('encrypt'); + UI.updateSetting('true_color'); + if (Util.browserSupportsCursorURIs()) { + UI.updateSetting('cursor'); + } else { + UI.updateSetting('cursor', !Util.isTouchDevice); + UI.disableSetting('cursor'); + } + UI.updateSetting('clip'); + UI.updateSetting('resize'); + UI.updateSetting('shared'); + UI.updateSetting('view_only'); + UI.updateSetting('path'); + UI.updateSetting('repeaterID'); + UI.updateSetting('logging'); + UI.updateSetting('reconnect'); + UI.updateSetting('reconnect_delay'); + + document.getElementById('noVNC_settings') + .classList.add("noVNC_open"); + document.getElementById('noVNC_settings_button') + .classList.add("noVNC_selected"); + }, + + closeSettingsPanel: function() { + document.getElementById('noVNC_settings') + .classList.remove("noVNC_open"); + document.getElementById('noVNC_settings_button') + .classList.remove("noVNC_selected"); + }, + + toggleSettingsPanel: function() { + if (document.getElementById('noVNC_settings') + .classList.contains("noVNC_open")) { + UI.closeSettingsPanel(); + } else { + UI.openSettingsPanel(); + } + }, + +/* ------^------- + * /SETTINGS + * ============== + * XVP + * ------v------*/ + + openXvpPanel: function() { + UI.closeAllPanels(); + UI.openControlbar(); + + document.getElementById('noVNC_xvp') + .classList.add("noVNC_open"); + document.getElementById('noVNC_xvp_button') + .classList.add("noVNC_selected"); + }, + + closeXvpPanel: function() { + document.getElementById('noVNC_xvp') + .classList.remove("noVNC_open"); + document.getElementById('noVNC_xvp_button') + .classList.remove("noVNC_selected"); + }, + + toggleXvpPanel: function() { + if (document.getElementById('noVNC_xvp') + .classList.contains("noVNC_open")) { + UI.closeXvpPanel(); + } else { + UI.openXvpPanel(); + } + }, + + // Disable/enable XVP button + updateXvpButton: function(ver) { + if (ver >= 1 && !UI.rfb.get_view_only()) { + document.getElementById('noVNC_xvp_button') + .classList.remove("noVNC_hidden"); + } else { + document.getElementById('noVNC_xvp_button') + .classList.add("noVNC_hidden"); + // Close XVP panel if open + UI.closeXvpPanel(); + } + }, + +/* ------^------- + * /XVP + * ============== + * CLIPBOARD + * ------v------*/ + + openClipboardPanel: function() { + UI.closeAllPanels(); + UI.openControlbar(); + + document.getElementById('noVNC_clipboard') + .classList.add("noVNC_open"); + document.getElementById('noVNC_clipboard_button') + .classList.add("noVNC_selected"); + }, + + closeClipboardPanel: function() { + document.getElementById('noVNC_clipboard') + .classList.remove("noVNC_open"); + document.getElementById('noVNC_clipboard_button') + .classList.remove("noVNC_selected"); + }, + + toggleClipboardPanel: function() { + if (document.getElementById('noVNC_clipboard') + .classList.contains("noVNC_open")) { + UI.closeClipboardPanel(); + } else { + UI.openClipboardPanel(); + } + }, + + clipboardReceive: function(rfb, text) { + Util.Debug(">> UI.clipboardReceive: " + text.substr(0,40) + "..."); + document.getElementById('noVNC_clipboard_text').value = text; + Util.Debug("<< UI.clipboardReceive"); + }, + + clipboardClear: function() { + document.getElementById('noVNC_clipboard_text').value = ""; + UI.rfb.clipboardPasteFrom(""); + }, + + clipboardSend: function() { + var text = document.getElementById('noVNC_clipboard_text').value; + Util.Debug(">> UI.clipboardSend: " + text.substr(0,40) + "..."); + UI.rfb.clipboardPasteFrom(text); + Util.Debug("<< UI.clipboardSend"); + }, + +/* ------^------- + * /CLIPBOARD + * ============== + * CONNECTION + * ------v------*/ + + openConnectPanel: function() { + document.getElementById('noVNC_connect_dlg') + .classList.add("noVNC_open"); + }, + + closeConnectPanel: function() { + document.getElementById('noVNC_connect_dlg') + .classList.remove("noVNC_open"); + }, + + connect: function(event, password) { + var host = UI.getSetting('host'); + var port = UI.getSetting('port'); + var path = UI.getSetting('path'); + + if (typeof password === 'undefined') { + password = WebUtil.getConfigVar('password'); + } + + if (password === null) { + password = undefined; + } + + if ((!host) || (!port)) { + var msg = _("Must set host and port"); + Util.Error(msg); + UI.showStatus(msg, 'error'); + return; + } + + if (!UI.initRFB()) return; + + UI.closeAllPanels(); + UI.closeConnectPanel(); + + UI.rfb.set_encrypt(UI.getSetting('encrypt')); + UI.rfb.set_true_color(UI.getSetting('true_color')); + UI.rfb.set_shared(UI.getSetting('shared')); + UI.rfb.set_repeaterID(UI.getSetting('repeaterID')); + + UI.updateLocalCursor(); + UI.updateViewOnly(); + + UI.rfb.connect(host, port, password, path); + }, + + disconnect: function() { + UI.closeAllPanels(); + UI.rfb.disconnect(); + + // Disable automatic reconnecting + UI.inhibit_reconnect = true; + + // Restore the callback used for initial resize + UI.rfb.set_onFBUComplete(UI.initialResize); + + // Don't display the connection settings until we're actually disconnected + }, + + reconnect: function() { + UI.reconnect_callback = null; + + // if reconnect has been disabled in the meantime, do nothing. + if (UI.inhibit_reconnect) { + return; + } + + UI.connect(null, UI.reconnect_password); + }, + + disconnectFinished: function (rfb, reason) { + if (typeof reason !== 'undefined') { + UI.showStatus(reason, 'error'); + } else if (UI.getSetting('reconnect', false) === true && !UI.inhibit_reconnect) { + document.getElementById("noVNC_transition_text").textContent = _("Reconnecting..."); + document.documentElement.classList.add("noVNC_reconnecting"); + + var delay = parseInt(UI.getSetting('reconnect_delay')); + UI.reconnect_callback = setTimeout(UI.reconnect, delay); + return; + } + + UI.openControlbar(); + UI.openConnectPanel(); + }, + + cancelReconnect: function() { + if (UI.reconnect_callback !== null) { + clearTimeout(UI.reconnect_callback); + UI.reconnect_callback = null; + } + + document.documentElement.classList.remove("noVNC_reconnecting"); + UI.openControlbar(); + UI.openConnectPanel(); + }, + +/* ------^------- + * /CONNECTION + * ============== + * PASSWORD + * ------v------*/ + + passwordRequired: function(rfb, msg) { + + document.getElementById('noVNC_password_dlg') + .classList.add('noVNC_open'); + + setTimeout(function () { + document.getElementById('noVNC_password_input').focus(); + }, 100); + + if (typeof msg === 'undefined') { + msg = _("Password is required"); + } + Util.Warn(msg); + UI.showStatus(msg, "warning"); + }, + + setPassword: function(e) { + var password = document.getElementById('noVNC_password_input').value; + UI.rfb.sendPassword(password); + UI.reconnect_password = password; + document.getElementById('noVNC_password_dlg') + .classList.remove('noVNC_open'); + // Prevent actually submitting the form + e.preventDefault(); + }, + +/* ------^------- + * /PASSWORD + * ============== + * FULLSCREEN + * ------v------*/ + + toggleFullscreen: function() { + if (document.fullscreenElement || // alternative standard method + document.mozFullScreenElement || // currently working methods + document.webkitFullscreenElement || + document.msFullscreenElement) { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen(); + } else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } + } else { + if (document.documentElement.requestFullscreen) { + document.documentElement.requestFullscreen(); + } else if (document.documentElement.mozRequestFullScreen) { + document.documentElement.mozRequestFullScreen(); + } else if (document.documentElement.webkitRequestFullscreen) { + document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); + } else if (document.body.msRequestFullscreen) { + document.body.msRequestFullscreen(); + } + } + UI.enableDisableViewClip(); + UI.updateFullscreenButton(); + }, + + updateFullscreenButton: function() { + if (document.fullscreenElement || // alternative standard method + document.mozFullScreenElement || // currently working methods + document.webkitFullscreenElement || + document.msFullscreenElement ) { + document.getElementById('noVNC_fullscreen_button') + .classList.add("noVNC_selected"); + } else { + document.getElementById('noVNC_fullscreen_button') + .classList.remove("noVNC_selected"); + } + }, + +/* ------^------- + * /FULLSCREEN + * ============== + * RESIZE + * ------v------*/ + + // Apply remote resizing or local scaling + applyResizeMode: function() { + if (!UI.rfb) return; + + var screen = UI.screenSize(); + + if (screen && UI.connected && UI.rfb.get_display()) { + + var display = UI.rfb.get_display(); + var resizeMode = UI.getSetting('resize'); + display.set_scale(1); + + // Make sure the viewport is adjusted first + UI.updateViewClip(); + + if (resizeMode === 'remote') { + + // Request changing the resolution of the remote display to + // the size of the local browser viewport. + + // In order to not send multiple requests before the browser-resize + // is finished we wait 0.5 seconds before sending the request. + clearTimeout(UI.resizeTimeout); + UI.resizeTimeout = setTimeout(function(){ + // Request a remote size covering the viewport + if (UI.rfb.requestDesktopSize(screen.w, screen.h)) { + Util.Debug('Requested new desktop size: ' + + screen.w + 'x' + screen.h); + } + }, 500); + + } else if (resizeMode === 'scale' || resizeMode === 'downscale') { + var downscaleOnly = resizeMode === 'downscale'; + display.autoscale(screen.w, screen.h, downscaleOnly); + UI.fixScrollbars(); + } + } + }, + + // Gets the the size of the available viewport in the browser window + screenSize: function() { + var screen = document.getElementById('noVNC_screen'); + return {w: screen.offsetWidth, h: screen.offsetHeight}; + }, + + // Normally we only apply the current resize mode after a window resize + // event. This means that when a new connection is opened, there is no + // resize mode active. + // We have to wait until the first FBU because this is where the client + // will find the supported encodings of the server. Some calls later in + // the chain is dependant on knowing the server-capabilities. + initialResize: function(rfb, fbu) { + UI.applyResizeMode(); + // After doing this once, we remove the callback. + UI.rfb.set_onFBUComplete(function() { }); + }, + +/* ------^------- + * /RESIZE + * ============== + * CLIPPING + * ------v------*/ + + // Set and configure viewport clipping + setViewClip: function(clip) { + UI.updateSetting('clip', clip); + UI.updateViewClip(); + }, + + // Update parameters that depend on the clip setting + updateViewClip: function() { + if (!UI.rfb) return; + + var display = UI.rfb.get_display(); + var cur_clip = display.get_viewport(); + var new_clip = UI.getSetting('clip'); + + var resizeSetting = UI.getSetting('resize'); + if (resizeSetting === 'downscale' || resizeSetting === 'scale') { + // Disable clipping if we are scaling + new_clip = false; + } else if (Util.isTouchDevice) { + // Touch devices usually have shit scrollbars + new_clip = true; + } + + if (cur_clip !== new_clip) { + display.set_viewport(new_clip); + } + + var size = UI.screenSize(); + + if (new_clip && size) { + // When clipping is enabled, the screen is limited to + // the size of the browser window. + display.viewportChangeSize(size.w, size.h); + UI.fixScrollbars(); + } + + // Changing the viewport may change the state of + // the dragging button + UI.updateViewDrag(); + }, + + // Handle special cases where clipping is forced on/off or locked + enableDisableViewClip: function() { + var resizeSetting = UI.getSetting('resize'); + // Disable clipping if we are scaling, connected or on touch + if (resizeSetting === 'downscale' || resizeSetting === 'scale' || + Util.isTouchDevice) { + UI.disableSetting('clip'); + } else { + UI.enableSetting('clip'); + } + }, + +/* ------^------- + * /CLIPPING + * ============== + * VIEWDRAG + * ------v------*/ + + toggleViewDrag: function() { + if (!UI.rfb) return; + + var drag = UI.rfb.get_viewportDrag(); + UI.setViewDrag(!drag); + }, + + // Set the view drag mode which moves the viewport on mouse drags + setViewDrag: function(drag) { + if (!UI.rfb) return; + + UI.rfb.set_viewportDrag(drag); + + UI.updateViewDrag(); + }, + + updateViewDrag: function() { + var clipping = false; + + if (!UI.connected) return; + + // Check if viewport drag is possible. It is only possible + // if the remote display is clipping the client display. + if (UI.rfb.get_display().get_viewport() && + UI.rfb.get_display().clippingDisplay()) { + clipping = true; + } + + var viewDragButton = document.getElementById('noVNC_view_drag_button'); + + if (!clipping && + UI.rfb.get_viewportDrag()) { + // The size of the remote display is the same or smaller + // than the client display. Make sure viewport drag isn't + // active when it can't be used. + UI.rfb.set_viewportDrag(false); + } + + if (UI.rfb.get_viewportDrag()) { + viewDragButton.classList.add("noVNC_selected"); + } else { + viewDragButton.classList.remove("noVNC_selected"); + } + + // Different behaviour for touch vs non-touch + // The button is disabled instead of hidden on touch devices + if (Util.isTouchDevice) { + viewDragButton.classList.remove("noVNC_hidden"); + + if (clipping) { + viewDragButton.disabled = false; + } else { + viewDragButton.disabled = true; + } + } else { + viewDragButton.disabled = false; + + if (clipping) { + viewDragButton.classList.remove("noVNC_hidden"); + } else { + viewDragButton.classList.add("noVNC_hidden"); + } + } + }, + +/* ------^------- + * /VIEWDRAG + * ============== + * KEYBOARD + * ------v------*/ + + showVirtualKeyboard: function() { + if (!Util.isTouchDevice) return; + + var input = document.getElementById('noVNC_keyboardinput'); + + if (document.activeElement == input) return; + + input.focus(); + + try { + var l = input.value.length; + // Move the caret to the end + input.setSelectionRange(l, l); + } catch (err) {} // setSelectionRange is undefined in Google Chrome + }, + + hideVirtualKeyboard: function() { + if (!Util.isTouchDevice) return; + + var input = document.getElementById('noVNC_keyboardinput'); + + if (document.activeElement != input) return; + + input.blur(); + }, + + toggleVirtualKeyboard: function () { + if (document.getElementById('noVNC_keyboard_button') + .classList.contains("noVNC_selected")) { + UI.hideVirtualKeyboard(); + } else { + UI.showVirtualKeyboard(); + } + }, + + onfocusVirtualKeyboard: function(event) { + document.getElementById('noVNC_keyboard_button') + .classList.add("noVNC_selected"); + }, + + onblurVirtualKeyboard: function(event) { + document.getElementById('noVNC_keyboard_button') + .classList.remove("noVNC_selected"); + }, + + keepVirtualKeyboard: function(event) { + var input = document.getElementById('noVNC_keyboardinput'); + + // Only prevent focus change if the virtual keyboard is active + if (document.activeElement != input) { + return; + } + + // Only allow focus to move to other elements that need + // focus to function properly + if (event.target.form !== undefined) { + switch (event.target.type) { + case 'text': + case 'email': + case 'search': + case 'password': + case 'tel': + case 'url': + case 'textarea': + case 'select-one': + case 'select-multiple': + return; + } + } + + event.preventDefault(); + }, + + keyboardinputReset: function() { + var kbi = document.getElementById('noVNC_keyboardinput'); + kbi.value = new Array(UI.defaultKeyboardinputLen).join("_"); + UI.lastKeyboardinput = kbi.value; + }, + + // When normal keyboard events are left uncought, use the input events from + // the keyboardinput element instead and generate the corresponding key events. + // This code is required since some browsers on Android are inconsistent in + // sending keyCodes in the normal keyboard events when using on screen keyboards. + keyInput: function(event) { + + if (!UI.rfb) return; + + var newValue = event.target.value; + + if (!UI.lastKeyboardinput) { + UI.keyboardinputReset(); + } + var oldValue = UI.lastKeyboardinput; + + var newLen; + try { + // Try to check caret position since whitespace at the end + // will not be considered by value.length in some browsers + newLen = Math.max(event.target.selectionStart, newValue.length); + } catch (err) { + // selectionStart is undefined in Google Chrome + newLen = newValue.length; + } + var oldLen = oldValue.length; + + var backspaces; + var inputs = newLen - oldLen; + if (inputs < 0) { + backspaces = -inputs; + } else { + backspaces = 0; + } + + // Compare the old string with the new to account for + // text-corrections or other input that modify existing text + var i; + for (i = 0; i < Math.min(oldLen, newLen); i++) { + if (newValue.charAt(i) != oldValue.charAt(i)) { + inputs = newLen - i; + backspaces = oldLen - i; + break; + } + } + + // Send the key events + for (i = 0; i < backspaces; i++) { + UI.rfb.sendKey(KeyTable.XK_BackSpace); + } + for (i = newLen - inputs; i < newLen; i++) { + UI.rfb.sendKey(keysyms.fromUnicode(newValue.charCodeAt(i)).keysym); + } + + // Control the text content length in the keyboardinput element + if (newLen > 2 * UI.defaultKeyboardinputLen) { + UI.keyboardinputReset(); + } else if (newLen < 1) { + // There always have to be some text in the keyboardinput + // element with which backspace can interact. + UI.keyboardinputReset(); + // This sometimes causes the keyboard to disappear for a second + // but it is required for the android keyboard to recognize that + // text has been added to the field + event.target.blur(); + // This has to be ran outside of the input handler in order to work + setTimeout(event.target.focus.bind(event.target), 0); + } else { + UI.lastKeyboardinput = newValue; + } + }, + +/* ------^------- + * /KEYBOARD + * ============== + * EXTRA KEYS + * ------v------*/ + + openExtraKeys: function() { + UI.closeAllPanels(); + UI.openControlbar(); + + document.getElementById('noVNC_modifiers') + .classList.add("noVNC_open"); + document.getElementById('noVNC_toggle_extra_keys_button') + .classList.add("noVNC_selected"); + }, + + closeExtraKeys: function() { + document.getElementById('noVNC_modifiers') + .classList.remove("noVNC_open"); + document.getElementById('noVNC_toggle_extra_keys_button') + .classList.remove("noVNC_selected"); + }, + + toggleExtraKeys: function() { + if(document.getElementById('noVNC_modifiers') + .classList.contains("noVNC_open")) { + UI.closeExtraKeys(); + } else { + UI.openExtraKeys(); + } + }, + + sendEsc: function() { + UI.rfb.sendKey(KeyTable.XK_Escape); + }, + + sendTab: function() { + UI.rfb.sendKey(KeyTable.XK_Tab); + }, + + toggleCtrl: function() { + var btn = document.getElementById('noVNC_toggle_ctrl_button'); + if (btn.classList.contains("noVNC_selected")) { + UI.rfb.sendKey(KeyTable.XK_Control_L, false); + btn.classList.remove("noVNC_selected"); + } else { + UI.rfb.sendKey(KeyTable.XK_Control_L, true); + btn.classList.add("noVNC_selected"); + } + }, + + toggleAlt: function() { + var btn = document.getElementById('noVNC_toggle_alt_button'); + if (btn.classList.contains("noVNC_selected")) { + UI.rfb.sendKey(KeyTable.XK_Alt_L, false); + btn.classList.remove("noVNC_selected"); + } else { + UI.rfb.sendKey(KeyTable.XK_Alt_L, true); + btn.classList.add("noVNC_selected"); + } + }, + + sendCtrlAltDel: function() { + UI.rfb.sendCtrlAltDel(); + }, + +/* ------^------- + * /EXTRA KEYS + * ============== + * MISC + * ------v------*/ + + setMouseButton: function(num) { + var view_only = UI.rfb.get_view_only(); + if (UI.rfb && !view_only) { + UI.rfb.get_mouse().set_touchButton(num); + } + + var blist = [0, 1,2,4]; + for (var b = 0; b < blist.length; b++) { + var button = document.getElementById('noVNC_mouse_button' + + blist[b]); + if (blist[b] === num && !view_only) { + button.classList.remove("noVNC_hidden"); + } else { + button.classList.add("noVNC_hidden"); + } + } + }, + + displayBlur: function() { + if (UI.rfb && !UI.rfb.get_view_only()) { + UI.rfb.get_keyboard().set_focused(false); + UI.rfb.get_mouse().set_focused(false); + } + }, + + displayFocus: function() { + if (UI.rfb && !UI.rfb.get_view_only()) { + UI.rfb.get_keyboard().set_focused(true); + UI.rfb.get_mouse().set_focused(true); + } + }, + + updateLocalCursor: function() { + UI.rfb.set_local_cursor(UI.getSetting('cursor')); + }, + + updateViewOnly: function() { + UI.rfb.set_view_only(UI.getSetting('view_only')); + }, + + updateLogging: function() { + WebUtil.init_logging(UI.getSetting('logging')); + }, + + updateSessionSize: function(rfb, width, height) { + UI.updateViewClip(); + UI.fixScrollbars(); + }, + + fixScrollbars: function() { + // This is a hack because Chrome screws up the calculation + // for when scrollbars are needed. So to fix it we temporarily + // toggle them off and on. + var screen = document.getElementById('noVNC_screen'); + screen.style.overflow = 'hidden'; + // Force Chrome to recalculate the layout by asking for + // an element's dimensions + screen.getBoundingClientRect(); + screen.style.overflow = null; + }, + + updateDesktopName: function(rfb, name) { + UI.desktopName = name; + // Display the desktop name in the document title + document.title = name + " - noVNC"; + }, + + bell: function(rfb) { + if (WebUtil.getConfigVar('bell', 'on') === 'on') { + document.getElementById('noVNC_bell').play(); + } + }, + + //Helper to add options to dropdown. + addOption: function(selectbox, text, value) { + var optn = document.createElement("OPTION"); + optn.text = text; + optn.value = value; + selectbox.options.add(optn); + }, + +/* ------^------- + * /MISC + * ============== + */ + }; + + /* [module] UI.load(); */ +})(); + +/* [module] export default UI; */ diff --git a/noVNC/include/webutil.js b/noVNC/app/webutil.js similarity index 53% rename from noVNC/include/webutil.js rename to noVNC/app/webutil.js index e674bf9..e6e6afb 100644 --- a/noVNC/include/webutil.js +++ b/noVNC/app/webutil.js @@ -10,25 +10,12 @@ /*jslint bitwise: false, white: false, browser: true, devel: true */ /*global Util, window, document */ -// Globals defined here -var WebUtil = {}, $D; - -/* - * Simple DOM selector by ID +/* [module] + * import Util from "../core/util"; */ -if (!window.$D) { - window.$D = function (id) { - if (document.getElementById) { - return document.getElementById(id); - } else if (document.all) { - return document.all[id]; - } else if (document.layers) { - return document.layers[id]; - } - return undefined; - }; -} +// Globals defined here +var WebUtil = {}; /* * ------------------------------------------------------ @@ -90,6 +77,29 @@ WebUtil.getQueryVar = function (name, defVal) { } }; +// Read a hash fragment variable +WebUtil.getHashVar = function (name, defVal) { + "use strict"; + var re = new RegExp('.*[&#]' + name + '=([^&]*)'), + match = document.location.hash.match(re); + if (typeof defVal === 'undefined') { defVal = null; } + if (match) { + return decodeURIComponent(match[1]); + } else { + return defVal; + } +}; + +// Read a variable from the fragment or the query string +// Fragment takes precedence +WebUtil.getConfigVar = function (name, defVal) { + "use strict"; + var val = WebUtil.getHashVar(name); + if (val === null) { + val = WebUtil.getQueryVar(name, defVal); + } + return val; +}; /* * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html @@ -199,41 +209,103 @@ WebUtil.eraseSetting = function (name) { } }; -/* - * Alternate stylesheet selection - */ -WebUtil.getStylesheets = function () { - "use strict"; - var links = document.getElementsByTagName("link"); - var sheets = []; +WebUtil.injectParamIfMissing = function (path, param, value) { + // force pretend that we're dealing with a relative path + // (assume that we wanted an extra if we pass one in) + path = "/" + path; - for (var i = 0; i < links.length; i += 1) { - if (links[i].title && - links[i].rel.toUpperCase().indexOf("STYLESHEET") > -1) { - sheets.push(links[i]); - } + var elem = document.createElement('a'); + elem.href = path; + + var param_eq = encodeURIComponent(param) + "="; + var query; + if (elem.search) { + query = elem.search.slice(1).split('&'); + } else { + query = []; + } + + if (!query.some(function (v) { return v.startsWith(param_eq); })) { + query.push(param_eq + encodeURIComponent(value)); + elem.search = "?" + query.join("&"); + } + + // some browsers (e.g. IE11) may occasionally omit the leading slash + // in the elem.pathname string. Handle that case gracefully. + if (elem.pathname.charAt(0) == "/") { + return elem.pathname.slice(1) + elem.search + elem.hash; + } else { + return elem.pathname + elem.search + elem.hash; } - return sheets; }; -// No sheet means try and use value from cookie, null sheet used to -// clear all alternates. -WebUtil.selectStylesheet = function (sheet) { +// Dynamically load scripts without using document.write() +// Reference: http://unixpapa.com/js/dyna.html +// +// Handles the case where load_scripts is invoked from a script that +// itself is loaded via load_scripts. Once all scripts are loaded the +// window.onscriptsloaded handler is called (if set). +WebUtil.get_include_uri = function (root_dir) { + return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI + root_dir + '/' : root_dir + '/'; +}; +WebUtil._loading_scripts = []; +WebUtil._pending_scripts = []; +WebUtil.load_scripts = function (files_by_dir) { "use strict"; - if (typeof sheet === 'undefined') { - sheet = 'default'; - } + var head = document.getElementsByTagName('head')[0], script, + ls = WebUtil._loading_scripts, ps = WebUtil._pending_scripts; - var sheets = WebUtil.getStylesheets(); - for (var i = 0; i < sheets.length; i += 1) { - var link = sheets[i]; - if (link.title === sheet) { - Util.Debug("Using stylesheet " + sheet); - link.disabled = false; - } else { - //Util.Debug("Skipping stylesheet " + link.title); - link.disabled = true; + var loadFunc = function (e) { + while (ls.length > 0 && (ls[0].readyState === 'loaded' || + ls[0].readyState === 'complete')) { + // For IE, append the script to trigger execution + var s = ls.shift(); + //console.log("loaded script: " + s.src); + head.appendChild(s); + } + if (!this.readyState || + (Util.Engine.presto && this.readyState === 'loaded') || + this.readyState === 'complete') { + if (ps.indexOf(this) >= 0) { + this.onload = this.onreadystatechange = null; + //console.log("completed script: " + this.src); + ps.splice(ps.indexOf(this), 1); + + // Call window.onscriptsload after last script loads + if (ps.length === 0 && window.onscriptsload) { + window.onscriptsload(); + } + } + } + }; + + var root_dirs = Object.keys(files_by_dir); + + for (var d = 0; d < root_dirs.length; d++) { + var root_dir = root_dirs[d]; + var files = files_by_dir[root_dir]; + + for (var f = 0; f < files.length; f++) { + script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = WebUtil.get_include_uri(root_dir) + files[f]; + //console.log("loading script: " + script.src); + script.onload = script.onreadystatechange = loadFunc; + // In-order script execution tricks + if (Util.Engine.trident) { + // For IE wait until readyState is 'loaded' before + // appending it which will trigger execution + // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order + ls.push(script); + } else { + // For webkit and firefox set async=false and append now + // https://developer.mozilla.org/en-US/docs/HTML/Element/script + script.async = false; + head.appendChild(script); + } + ps.push(script); } } - return sheet; }; + +/* [module] export default WebUtil; */ diff --git a/noVNC/include/base64.js b/noVNC/core/base64.js similarity index 99% rename from noVNC/include/base64.js rename to noVNC/core/base64.js index 651fbad..2b4f948 100644 --- a/noVNC/include/base64.js +++ b/noVNC/core/base64.js @@ -85,7 +85,7 @@ var Base64 = { console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i); continue; } - + // Collect data into leftdata, update bitcount leftdata = (leftdata << 6) | c; leftbits += 6; @@ -111,3 +111,5 @@ var Base64 = { return result; } }; /* End of Base64 namespace */ + +/* [module] export default Base64; */ diff --git a/noVNC/include/des.js b/noVNC/core/des.js similarity index 99% rename from noVNC/include/des.js rename to noVNC/core/des.js index ecbc819..c9a4753 100644 --- a/noVNC/include/des.js +++ b/noVNC/core/des.js @@ -25,16 +25,16 @@ * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and - * without fee is hereby granted, provided that this copyright notice is kept - * intact. - * + * without fee is hereby granted, provided that this copyright notice is kept + * intact. + * * WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. - * + * * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT @@ -77,7 +77,7 @@ /* jslint white: false */ -function DES(passwd) { +/* [module] export default */ function DES(passwd) { "use strict"; // Tables, permutations, S-boxes, etc. @@ -273,4 +273,4 @@ function DES(passwd) { setKeys(passwd); // Setup keys return {'encrypt': encrypt}; // Public interface -} // function DES +}; // function DES diff --git a/noVNC/core/display.js b/noVNC/core/display.js new file mode 100644 index 0000000..f7c437b --- /dev/null +++ b/noVNC/core/display.js @@ -0,0 +1,872 @@ +/* + * noVNC: HTML5 VNC client + * Copyright (C) 2012 Joel Martin + * Copyright (C) 2015 Samuel Mannehed for Cendio AB + * Licensed under MPL 2.0 (see LICENSE.txt) + * + * See README.md for usage and integration instructions. + */ + +/*jslint browser: true, white: false */ +/*global Util, Base64, changeCursor */ + +/* [module] + * import Util from "./util"; + * import Base64 from "./base64"; + */ + +/* [module] export default */ function Display(defaults) { + this._drawCtx = null; + this._c_forceCanvas = false; + + this._renderQ = []; // queue drawing actions for in-oder rendering + this._flushing = false; + + // the full frame buffer (logical canvas) size + this._fb_width = 0; + this._fb_height = 0; + + this._prevDrawStyle = ""; + this._tile = null; + this._tile16x16 = null; + this._tile_x = 0; + this._tile_y = 0; + + Util.set_defaults(this, defaults, { + 'true_color': true, + 'colourMap': [], + 'scale': 1.0, + 'viewport': false, + 'render_mode': '', + "onFlush": function () {}, + }); + + Util.Debug(">> Display.constructor"); + + // The visible canvas + if (!this._target) { + throw new Error("Target must be set"); + } + + if (typeof this._target === 'string') { + throw new Error('target must be a DOM element'); + } + + if (!this._target.getContext) { + throw new Error("no getContext method"); + } + + this._targetCtx = this._target.getContext('2d'); + + // the visible canvas viewport (i.e. what actually gets seen) + this._viewportLoc = { 'x': 0, 'y': 0, 'w': this._target.width, 'h': this._target.height }; + + // The hidden canvas, where we do the actual rendering + this._backbuffer = document.createElement('canvas'); + this._drawCtx = this._backbuffer.getContext('2d'); + + this._damageBounds = { left:0, top:0, + right: this._backbuffer.width, + bottom: this._backbuffer.height }; + + Util.Debug("User Agent: " + navigator.userAgent); + if (Util.Engine.gecko) { Util.Debug("Browser: gecko " + Util.Engine.gecko); } + if (Util.Engine.webkit) { Util.Debug("Browser: webkit " + Util.Engine.webkit); } + if (Util.Engine.trident) { Util.Debug("Browser: trident " + Util.Engine.trident); } + if (Util.Engine.presto) { Util.Debug("Browser: presto " + Util.Engine.presto); } + + this.clear(); + + // Check canvas features + if ('createImageData' in this._drawCtx) { + this._render_mode = 'canvas rendering'; + } else { + throw new Error("Canvas does not support createImageData"); + } + + if (this._prefer_js === null) { + Util.Info("Prefering javascript operations"); + this._prefer_js = true; + } + + // Determine browser support for setting the cursor via data URI scheme + if (this._cursor_uri || this._cursor_uri === null || + this._cursor_uri === undefined) { + this._cursor_uri = Util.browserSupportsCursorURIs(); + } + + Util.Debug("<< Display.constructor"); +}; + +(function () { + "use strict"; + + var SUPPORTS_IMAGEDATA_CONSTRUCTOR = false; + try { + new ImageData(new Uint8ClampedArray(4), 1, 1); + SUPPORTS_IMAGEDATA_CONSTRUCTOR = true; + } catch (ex) { + // ignore failure + } + + + Display.prototype = { + // Public methods + viewportChangePos: function (deltaX, deltaY) { + var vp = this._viewportLoc; + deltaX = Math.floor(deltaX); + deltaY = Math.floor(deltaY); + + if (!this._viewport) { + deltaX = -vp.w; // clamped later of out of bounds + deltaY = -vp.h; + } + + var vx2 = vp.x + vp.w - 1; + var vy2 = vp.y + vp.h - 1; + + // Position change + + if (deltaX < 0 && vp.x + deltaX < 0) { + deltaX = -vp.x; + } + if (vx2 + deltaX >= this._fb_width) { + deltaX -= vx2 + deltaX - this._fb_width + 1; + } + + if (vp.y + deltaY < 0) { + deltaY = -vp.y; + } + if (vy2 + deltaY >= this._fb_height) { + deltaY -= (vy2 + deltaY - this._fb_height + 1); + } + + if (deltaX === 0 && deltaY === 0) { + return; + } + Util.Debug("viewportChange deltaX: " + deltaX + ", deltaY: " + deltaY); + + vp.x += deltaX; + vp.y += deltaY; + + this._damage(vp.x, vp.y, vp.w, vp.h); + + this.flip(); + }, + + viewportChangeSize: function(width, height) { + + if (!this._viewport || + typeof(width) === "undefined" || + typeof(height) === "undefined") { + + Util.Debug("Setting viewport to full display region"); + width = this._fb_width; + height = this._fb_height; + } + + if (width > this._fb_width) { + width = this._fb_width; + } + if (height > this._fb_height) { + height = this._fb_height; + } + + var vp = this._viewportLoc; + if (vp.w !== width || vp.h !== height) { + vp.w = width; + vp.h = height; + + var canvas = this._target; + canvas.width = width; + canvas.height = height; + + // The position might need to be updated if we've grown + this.viewportChangePos(0, 0); + + this._damage(vp.x, vp.y, vp.w, vp.h); + this.flip(); + + // Update the visible size of the target canvas + this._rescale(this._scale); + } + }, + + absX: function (x) { + return x / this._scale + this._viewportLoc.x; + }, + + absY: function (y) { + return y / this._scale + this._viewportLoc.y; + }, + + resize: function (width, height) { + this._prevDrawStyle = ""; + + this._fb_width = width; + this._fb_height = height; + + var canvas = this._backbuffer; + if (canvas.width !== width || canvas.height !== height) { + + // We have to save the canvas data since changing the size will clear it + var saveImg = null; + if (canvas.width > 0 && canvas.height > 0) { + saveImg = this._drawCtx.getImageData(0, 0, canvas.width, canvas.height); + } + + if (canvas.width !== width) { + canvas.width = width; + } + if (canvas.height !== height) { + canvas.height = height; + } + + if (saveImg) { + this._drawCtx.putImageData(saveImg, 0, 0); + } + } + + // Readjust the viewport as it may be incorrectly sized + // and positioned + var vp = this._viewportLoc; + this.viewportChangeSize(vp.w, vp.h); + this.viewportChangePos(0, 0); + }, + + // Track what parts of the visible canvas that need updating + _damage: function(x, y, w, h) { + if (x < this._damageBounds.left) { + this._damageBounds.left = x; + } + if (y < this._damageBounds.top) { + this._damageBounds.top = y; + } + if ((x + w) > this._damageBounds.right) { + this._damageBounds.right = x + w; + } + if ((y + h) > this._damageBounds.bottom) { + this._damageBounds.bottom = y + h; + } + }, + + // Update the visible canvas with the contents of the + // rendering canvas + flip: function(from_queue) { + if (this._renderQ.length !== 0 && !from_queue) { + this._renderQ_push({ + 'type': 'flip' + }); + } else { + var x, y, vx, vy, w, h; + + x = this._damageBounds.left; + y = this._damageBounds.top; + w = this._damageBounds.right - x; + h = this._damageBounds.bottom - y; + + vx = x - this._viewportLoc.x; + vy = y - this._viewportLoc.y; + + if (vx < 0) { + w += vx; + x -= vx; + vx = 0; + } + if (vy < 0) { + h += vy; + y -= vy; + vy = 0; + } + + if ((vx + w) > this._viewportLoc.w) { + w = this._viewportLoc.w - vx; + } + if ((vy + h) > this._viewportLoc.h) { + h = this._viewportLoc.h - vy; + } + + if ((w > 0) && (h > 0)) { + // FIXME: We may need to disable image smoothing here + // as well (see copyImage()), but we haven't + // noticed any problem yet. + this._targetCtx.drawImage(this._backbuffer, + x, y, w, h, + vx, vy, w, h); + } + + this._damageBounds.left = this._damageBounds.top = 65535; + this._damageBounds.right = this._damageBounds.bottom = 0; + } + }, + + clear: function () { + if (this._logo) { + this.resize(this._logo.width, this._logo.height); + this.imageRect(0, 0, this._logo.type, this._logo.data); + } else { + this.resize(240, 20); + this._drawCtx.clearRect(0, 0, this._fb_width, this._fb_height); + } + this.flip(); + }, + + pending: function() { + return this._renderQ.length > 0; + }, + + flush: function() { + if (this._renderQ.length === 0) { + this._onFlush(); + } else { + this._flushing = true; + } + }, + + fillRect: function (x, y, width, height, color, from_queue) { + if (this._renderQ.length !== 0 && !from_queue) { + this._renderQ_push({ + 'type': 'fill', + 'x': x, + 'y': y, + 'width': width, + 'height': height, + 'color': color + }); + } else { + this._setFillColor(color); + this._drawCtx.fillRect(x, y, width, height); + this._damage(x, y, width, height); + } + }, + + copyImage: function (old_x, old_y, new_x, new_y, w, h, from_queue) { + if (this._renderQ.length !== 0 && !from_queue) { + this._renderQ_push({ + 'type': 'copy', + 'old_x': old_x, + 'old_y': old_y, + 'x': new_x, + 'y': new_y, + 'width': w, + 'height': h, + }); + } else { + // Due to this bug among others [1] we need to disable the image-smoothing to + // avoid getting a blur effect when copying data. + // + // 1. https://bugzilla.mozilla.org/show_bug.cgi?id=1194719 + // + // We need to set these every time since all properties are reset + // when the the size is changed + this._drawCtx.mozImageSmoothingEnabled = false; + this._drawCtx.webkitImageSmoothingEnabled = false; + this._drawCtx.msImageSmoothingEnabled = false; + this._drawCtx.imageSmoothingEnabled = false; + + this._drawCtx.drawImage(this._backbuffer, + old_x, old_y, w, h, + new_x, new_y, w, h); + this._damage(new_x, new_y, w, h); + } + }, + + imageRect: function(x, y, mime, arr) { + var img = new Image(); + img.src = "data: " + mime + ";base64," + Base64.encode(arr); + this._renderQ_push({ + 'type': 'img', + 'img': img, + 'x': x, + 'y': y + }); + }, + + // start updating a tile + startTile: function (x, y, width, height, color) { + this._tile_x = x; + this._tile_y = y; + if (width === 16 && height === 16) { + this._tile = this._tile16x16; + } else { + this._tile = this._drawCtx.createImageData(width, height); + } + + if (this._prefer_js) { + var bgr; + if (this._true_color) { + bgr = color; + } else { + bgr = this._colourMap[color[0]]; + } + var red = bgr[2]; + var green = bgr[1]; + var blue = bgr[0]; + + var data = this._tile.data; + for (var i = 0; i < width * height * 4; i += 4) { + data[i] = red; + data[i + 1] = green; + data[i + 2] = blue; + data[i + 3] = 255; + } + } else { + this.fillRect(x, y, width, height, color, true); + } + }, + + // update sub-rectangle of the current tile + subTile: function (x, y, w, h, color) { + if (this._prefer_js) { + var bgr; + if (this._true_color) { + bgr = color; + } else { + bgr = this._colourMap[color[0]]; + } + var red = bgr[2]; + var green = bgr[1]; + var blue = bgr[0]; + var xend = x + w; + var yend = y + h; + + var data = this._tile.data; + var width = this._tile.width; + for (var j = y; j < yend; j++) { + for (var i = x; i < xend; i++) { + var p = (i + (j * width)) * 4; + data[p] = red; + data[p + 1] = green; + data[p + 2] = blue; + data[p + 3] = 255; + } + } + } else { + this.fillRect(this._tile_x + x, this._tile_y + y, w, h, color, true); + } + }, + + // draw the current tile to the screen + finishTile: function () { + if (this._prefer_js) { + this._drawCtx.putImageData(this._tile, this._tile_x, this._tile_y); + this._damage(this._tile_x, this._tile_y, + this._tile.width, this._tile.height); + } + // else: No-op -- already done by setSubTile + }, + + blitImage: function (x, y, width, height, arr, offset, from_queue) { + if (this._renderQ.length !== 0 && !from_queue) { + // NB(directxman12): it's technically more performant here to use preallocated arrays, + // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue, + // this probably isn't getting called *nearly* as much + var new_arr = new Uint8Array(width * height * 4); + new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length)); + this._renderQ_push({ + 'type': 'blit', + 'data': new_arr, + 'x': x, + 'y': y, + 'width': width, + 'height': height, + }); + } else if (this._true_color) { + this._bgrxImageData(x, y, width, height, arr, offset); + } else { + this._cmapImageData(x, y, width, height, arr, offset); + } + }, + + blitRgbImage: function (x, y , width, height, arr, offset, from_queue) { + if (this._renderQ.length !== 0 && !from_queue) { + // NB(directxman12): it's technically more performant here to use preallocated arrays, + // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue, + // this probably isn't getting called *nearly* as much + var new_arr = new Uint8Array(width * height * 3); + new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length)); + this._renderQ_push({ + 'type': 'blitRgb', + 'data': new_arr, + 'x': x, + 'y': y, + 'width': width, + 'height': height, + }); + } else if (this._true_color) { + this._rgbImageData(x, y, width, height, arr, offset); + } else { + // probably wrong? + this._cmapImageData(x, y, width, height, arr, offset); + } + }, + + blitRgbxImage: function (x, y, width, height, arr, offset, from_queue) { + if (this._renderQ.length !== 0 && !from_queue) { + // NB(directxman12): it's technically more performant here to use preallocated arrays, + // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue, + // this probably isn't getting called *nearly* as much + var new_arr = new Uint8Array(width * height * 4); + new_arr.set(new Uint8Array(arr.buffer, 0, new_arr.length)); + this._renderQ_push({ + 'type': 'blitRgbx', + 'data': new_arr, + 'x': x, + 'y': y, + 'width': width, + 'height': height, + }); + } else { + this._rgbxImageData(x, y, width, height, arr, offset); + } + }, + + drawImage: function (img, x, y) { + this._drawCtx.drawImage(img, x, y); + this._damage(x, y, img.width, img.height); + }, + + changeCursor: function (pixels, mask, hotx, hoty, w, h) { + if (this._cursor_uri === false) { + Util.Warn("changeCursor called but no cursor data URI support"); + return; + } + + if (this._true_color) { + Display.changeCursor(this._target, pixels, mask, hotx, hoty, w, h); + } else { + Display.changeCursor(this._target, pixels, mask, hotx, hoty, w, h, this._colourMap); + } + }, + + defaultCursor: function () { + this._target.style.cursor = "default"; + }, + + disableLocalCursor: function () { + this._target.style.cursor = "none"; + }, + + clippingDisplay: function () { + var vp = this._viewportLoc; + return this._fb_width > vp.w || this._fb_height > vp.h; + }, + + // Overridden getters/setters + set_scale: function (scale) { + this._rescale(scale); + }, + + set_viewport: function (viewport) { + this._viewport = viewport; + // May need to readjust the viewport dimensions + var vp = this._viewportLoc; + this.viewportChangeSize(vp.w, vp.h); + this.viewportChangePos(0, 0); + }, + + get_width: function () { + return this._fb_width; + }, + get_height: function () { + return this._fb_height; + }, + + autoscale: function (containerWidth, containerHeight, downscaleOnly) { + var vp = this._viewportLoc; + var targetAspectRatio = containerWidth / containerHeight; + var fbAspectRatio = vp.w / vp.h; + + var scaleRatio; + if (fbAspectRatio >= targetAspectRatio) { + scaleRatio = containerWidth / vp.w; + } else { + scaleRatio = containerHeight / vp.h; + } + + if (scaleRatio > 1.0 && downscaleOnly) { + scaleRatio = 1.0; + } + + this._rescale(scaleRatio); + }, + + // Private Methods + _rescale: function (factor) { + this._scale = factor; + var vp = this._viewportLoc; + + // NB(directxman12): If you set the width directly, or set the + // style width to a number, the canvas is cleared. + // However, if you set the style width to a string + // ('NNNpx'), the canvas is scaled without clearing. + var width = Math.round(factor * vp.w) + 'px'; + var height = Math.round(factor * vp.h) + 'px'; + + if ((this._target.style.width !== width) || + (this._target.style.height !== height)) { + this._target.style.width = width; + this._target.style.height = height; + } + }, + + _setFillColor: function (color) { + var bgr; + if (this._true_color) { + bgr = color; + } else { + bgr = this._colourMap[color]; + } + + var newStyle = 'rgb(' + bgr[2] + ',' + bgr[1] + ',' + bgr[0] + ')'; + if (newStyle !== this._prevDrawStyle) { + this._drawCtx.fillStyle = newStyle; + this._prevDrawStyle = newStyle; + } + }, + + _rgbImageData: function (x, y, width, height, arr, offset) { + var img = this._drawCtx.createImageData(width, height); + var data = img.data; + for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 3) { + data[i] = arr[j]; + data[i + 1] = arr[j + 1]; + data[i + 2] = arr[j + 2]; + data[i + 3] = 255; // Alpha + } + this._drawCtx.putImageData(img, x, y); + this._damage(x, y, img.width, img.height); + }, + + _bgrxImageData: function (x, y, width, height, arr, offset) { + var img = this._drawCtx.createImageData(width, height); + var data = img.data; + for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 4) { + data[i] = arr[j + 2]; + data[i + 1] = arr[j + 1]; + data[i + 2] = arr[j]; + data[i + 3] = 255; // Alpha + } + this._drawCtx.putImageData(img, x, y); + this._damage(x, y, img.width, img.height); + }, + + _rgbxImageData: function (x, y, width, height, arr, offset) { + // NB(directxman12): arr must be an Type Array view + var img; + if (SUPPORTS_IMAGEDATA_CONSTRUCTOR) { + img = new ImageData(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4), width, height); + } else { + img = this._drawCtx.createImageData(width, height); + img.data.set(new Uint8ClampedArray(arr.buffer, arr.byteOffset, width * height * 4)); + } + this._drawCtx.putImageData(img, x, y); + this._damage(x, y, img.width, img.height); + }, + + _cmapImageData: function (x, y, width, height, arr, offset) { + var img = this._drawCtx.createImageData(width, height); + var data = img.data; + var cmap = this._colourMap; + for (var i = 0, j = offset; i < width * height * 4; i += 4, j++) { + var bgr = cmap[arr[j]]; + data[i] = bgr[2]; + data[i + 1] = bgr[1]; + data[i + 2] = bgr[0]; + data[i + 3] = 255; // Alpha + } + this._drawCtx.putImageData(img, x, y); + this._damage(x, y, img.width, img.height); + }, + + _renderQ_push: function (action) { + this._renderQ.push(action); + if (this._renderQ.length === 1) { + // If this can be rendered immediately it will be, otherwise + // the scanner will wait for the relevant event + this._scan_renderQ(); + } + }, + + _resume_renderQ: function() { + // "this" is the object that is ready, not the + // display object + this.removeEventListener('load', this._noVNC_display._resume_renderQ); + this._noVNC_display._scan_renderQ(); + }, + + _scan_renderQ: function () { + var ready = true; + while (ready && this._renderQ.length > 0) { + var a = this._renderQ[0]; + switch (a.type) { + case 'flip': + this.flip(true); + break; + case 'copy': + this.copyImage(a.old_x, a.old_y, a.x, a.y, a.width, a.height, true); + break; + case 'fill': + this.fillRect(a.x, a.y, a.width, a.height, a.color, true); + break; + case 'blit': + this.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true); + break; + case 'blitRgb': + this.blitRgbImage(a.x, a.y, a.width, a.height, a.data, 0, true); + break; + case 'blitRgbx': + this.blitRgbxImage(a.x, a.y, a.width, a.height, a.data, 0, true); + break; + case 'img': + if (a.img.complete) { + this.drawImage(a.img, a.x, a.y); + } else { + a.img._noVNC_display = this; + a.img.addEventListener('load', this._resume_renderQ); + // We need to wait for this image to 'load' + // to keep things in-order + ready = false; + } + break; + } + + if (ready) { + this._renderQ.shift(); + } + } + + if (this._renderQ.length === 0 && this._flushing) { + this._flushing = false; + this._onFlush(); + } + }, + }; + + Util.make_properties(Display, [ + ['target', 'wo', 'dom'], // Canvas element for rendering + ['context', 'ro', 'raw'], // Canvas 2D context for rendering (read-only) + ['logo', 'rw', 'raw'], // Logo to display when cleared: {"width": w, "height": h, "type": mime-type, "data": data} + ['true_color', 'rw', 'bool'], // Use true-color pixel data + ['colourMap', 'rw', 'arr'], // Colour map array (when not true-color) + ['scale', 'rw', 'float'], // Display area scale factor 0.0 - 1.0 + ['viewport', 'rw', 'bool'], // Use viewport clipping + ['width', 'ro', 'int'], // Display area width + ['height', 'ro', 'int'], // Display area height + + ['render_mode', 'ro', 'str'], // Canvas rendering mode (read-only) + + ['prefer_js', 'rw', 'str'], // Prefer Javascript over canvas methods + ['cursor_uri', 'rw', 'raw'], // Can we render cursor using data URI + + ['onFlush', 'rw', 'func'], // onFlush(): A flush request has finished + ]); + + // Class Methods + Display.changeCursor = function (target, pixels, mask, hotx, hoty, w0, h0, cmap) { + var w = w0; + var h = h0; + if (h < w) { + h = w; // increase h to make it square + } else { + w = h; // increase w to make it square + } + + var cur = []; + + // Push multi-byte little-endian values + cur.push16le = function (num) { + this.push(num & 0xFF, (num >> 8) & 0xFF); + }; + cur.push32le = function (num) { + this.push(num & 0xFF, + (num >> 8) & 0xFF, + (num >> 16) & 0xFF, + (num >> 24) & 0xFF); + }; + + var IHDRsz = 40; + var RGBsz = w * h * 4; + var XORsz = Math.ceil((w * h) / 8.0); + var ANDsz = Math.ceil((w * h) / 8.0); + + cur.push16le(0); // 0: Reserved + cur.push16le(2); // 2: .CUR type + cur.push16le(1); // 4: Number of images, 1 for non-animated ico + + // Cursor #1 header (ICONDIRENTRY) + cur.push(w); // 6: width + cur.push(h); // 7: height + cur.push(0); // 8: colors, 0 -> true-color + cur.push(0); // 9: reserved + cur.push16le(hotx); // 10: hotspot x coordinate + cur.push16le(hoty); // 12: hotspot y coordinate + cur.push32le(IHDRsz + RGBsz + XORsz + ANDsz); + // 14: cursor data byte size + cur.push32le(22); // 18: offset of cursor data in the file + + // Cursor #1 InfoHeader (ICONIMAGE/BITMAPINFO) + cur.push32le(IHDRsz); // 22: InfoHeader size + cur.push32le(w); // 26: Cursor width + cur.push32le(h * 2); // 30: XOR+AND height + cur.push16le(1); // 34: number of planes + cur.push16le(32); // 36: bits per pixel + cur.push32le(0); // 38: Type of compression + + cur.push32le(XORsz + ANDsz); + // 42: Size of Image + cur.push32le(0); // 46: reserved + cur.push32le(0); // 50: reserved + cur.push32le(0); // 54: reserved + cur.push32le(0); // 58: reserved + + // 62: color data (RGBQUAD icColors[]) + var y, x; + for (y = h - 1; y >= 0; y--) { + for (x = 0; x < w; x++) { + if (x >= w0 || y >= h0) { + cur.push(0); // blue + cur.push(0); // green + cur.push(0); // red + cur.push(0); // alpha + } else { + var idx = y * Math.ceil(w0 / 8) + Math.floor(x / 8); + var alpha = (mask[idx] << (x % 8)) & 0x80 ? 255 : 0; + if (cmap) { + idx = (w0 * y) + x; + var rgb = cmap[pixels[idx]]; + cur.push(rgb[2]); // blue + cur.push(rgb[1]); // green + cur.push(rgb[0]); // red + cur.push(alpha); // alpha + } else { + idx = ((w0 * y) + x) * 4; + cur.push(pixels[idx]); // blue + cur.push(pixels[idx + 1]); // green + cur.push(pixels[idx + 2]); // red + cur.push(alpha); // alpha + } + } + } + } + + // XOR/bitmask data (BYTE icXOR[]) + // (ignored, just needs to be the right size) + for (y = 0; y < h; y++) { + for (x = 0; x < Math.ceil(w / 8); x++) { + cur.push(0); + } + } + + // AND/bitmask data (BYTE icAND[]) + // (ignored, just needs to be the right size) + for (y = 0; y < h; y++) { + for (x = 0; x < Math.ceil(w / 8); x++) { + cur.push(0); + } + } + + var url = 'data:image/x-icon;base64,' + Base64.encode(cur); + target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default'; + }; +})(); diff --git a/noVNC/core/inflator.js b/noVNC/core/inflator.js new file mode 100644 index 0000000..973836d --- /dev/null +++ b/noVNC/core/inflator.js @@ -0,0 +1,2453 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Inflator = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o this.chunkSize) { + this.chunkSize = expected; + this.strm.output = new Uint8Array(this.chunkSize); + } + + this.strm.avail_out = this.chunkSize; + + zlib.inflate(this.strm, flush); + + return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); + }, + + reset: function () { + zlib.inflateReset(this.strm); + } +}; + +module.exports = { Inflate: Inflate }; + +},{"pako/lib/zlib/inflate.js":6,"pako/lib/zlib/zstream.js":8}],2:[function(require,module,exports){ +'use strict'; + + +var TYPED_OK = (typeof Uint8Array !== 'undefined') && + (typeof Uint16Array !== 'undefined') && + (typeof Int32Array !== 'undefined'); + + +exports.assign = function (obj /*from1, from2, from3, ...*/) { + var sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + var source = sources.shift(); + if (!source) { continue; } + + if (typeof source !== 'object') { + throw new TypeError(source + 'must be non-object'); + } + + for (var p in source) { + if (source.hasOwnProperty(p)) { + obj[p] = source[p]; + } + } + } + + return obj; +}; + + +// reduce buffer size, avoiding mem copy +exports.shrinkBuf = function (buf, size) { + if (buf.length === size) { return buf; } + if (buf.subarray) { return buf.subarray(0, size); } + buf.length = size; + return buf; +}; + + +var fnTyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + if (src.subarray && dest.subarray) { + dest.set(src.subarray(src_offs, src_offs + len), dest_offs); + return; + } + // Fallback to ordinary array + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function (chunks) { + var i, l, len, pos, chunk, result; + + // calculate data length + len = 0; + for (i = 0, l = chunks.length; i < l; i++) { + len += chunks[i].length; + } + + // join chunks + result = new Uint8Array(len); + pos = 0; + for (i = 0, l = chunks.length; i < l; i++) { + chunk = chunks[i]; + result.set(chunk, pos); + pos += chunk.length; + } + + return result; + } +}; + +var fnUntyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function (chunks) { + return [].concat.apply([], chunks); + } +}; + + +// Enable/Disable typed arrays use, for testing +// +exports.setTyped = function (on) { + if (on) { + exports.Buf8 = Uint8Array; + exports.Buf16 = Uint16Array; + exports.Buf32 = Int32Array; + exports.assign(exports, fnTyped); + } else { + exports.Buf8 = Array; + exports.Buf16 = Array; + exports.Buf32 = Array; + exports.assign(exports, fnUntyped); + } +}; + +exports.setTyped(TYPED_OK); + +},{}],3:[function(require,module,exports){ +'use strict'; + +// Note: adler32 takes 12% for level 0 and 2% for level 6. +// It doesn't worth to make additional optimizationa as in original. +// Small size is preferable. + +function adler32(adler, buf, len, pos) { + var s1 = (adler & 0xffff) |0, + s2 = ((adler >>> 16) & 0xffff) |0, + n = 0; + + while (len !== 0) { + // Set limit ~ twice less than 5552, to keep + // s2 in 31-bits, because we force signed ints. + // in other case %= will fail. + n = len > 2000 ? 2000 : len; + len -= n; + + do { + s1 = (s1 + buf[pos++]) |0; + s2 = (s2 + s1) |0; + } while (--n); + + s1 %= 65521; + s2 %= 65521; + } + + return (s1 | (s2 << 16)) |0; +} + + +module.exports = adler32; + +},{}],4:[function(require,module,exports){ +'use strict'; + +// Note: we can't get significant speed boost here. +// So write code to minimize size - no pregenerated tables +// and array tools dependencies. + + +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; + + for (var n = 0; n < 256; n++) { + c = n; + for (var k = 0; k < 8; k++) { + c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; + } + + return table; +} + +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); + + +function crc32(crc, buf, len, pos) { + var t = crcTable, + end = pos + len; + + crc ^= -1; + + for (var i = pos; i < end; i++) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + + +module.exports = crc32; + +},{}],5:[function(require,module,exports){ +'use strict'; + +// See state defs from inflate.js +var BAD = 30; /* got a data error -- remain here until reset */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state.mode === LEN + strm.avail_in >= 6 + strm.avail_out >= 258 + start >= strm.avail_out + state.bits < 8 + + On return, state.mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm.avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm.avail_out >= 258 for each loop to avoid checking for + output space. + */ +module.exports = function inflate_fast(strm, start) { + var state; + var _in; /* local strm.input */ + var last; /* have enough input while in < last */ + var _out; /* local strm.output */ + var beg; /* inflate()'s initial strm.output */ + var end; /* while out < end, enough space available */ +//#ifdef INFLATE_STRICT + var dmax; /* maximum distance from zlib header */ +//#endif + var wsize; /* window size or zero if not using window */ + var whave; /* valid bytes in the window */ + var wnext; /* window write index */ + // Use `s_window` instead `window`, avoid conflict with instrumentation tools + var s_window; /* allocated sliding window, if wsize != 0 */ + var hold; /* local strm.hold */ + var bits; /* local strm.bits */ + var lcode; /* local strm.lencode */ + var dcode; /* local strm.distcode */ + var lmask; /* mask for first level of length codes */ + var dmask; /* mask for first level of distance codes */ + var here; /* retrieved table entry */ + var op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + var len; /* match length, unused bytes */ + var dist; /* match distance */ + var from; /* where to copy match from */ + var from_source; + + + var input, output; // JS specific, because we have no pointers + + /* copy state to local variables */ + state = strm.state; + //here = state.here; + _in = strm.next_in; + input = strm.input; + last = _in + (strm.avail_in - 5); + _out = strm.next_out; + output = strm.output; + beg = _out - (start - strm.avail_out); + end = _out + (strm.avail_out - 257); +//#ifdef INFLATE_STRICT + dmax = state.dmax; +//#endif + wsize = state.wsize; + whave = state.whave; + wnext = state.wnext; + s_window = state.window; + hold = state.hold; + bits = state.bits; + lcode = state.lencode; + dcode = state.distcode; + lmask = (1 << state.lenbits) - 1; + dmask = (1 << state.distbits) - 1; + + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + top: + do { + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + + here = lcode[hold & lmask]; + + dolen: + for (;;) { // Goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + if (op === 0) { /* literal */ + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + output[_out++] = here & 0xffff/*here.val*/; + } + else if (op & 16) { /* length base */ + len = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + len += hold & ((1 << op) - 1); + hold >>>= op; + bits -= op; + } + //Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = dcode[hold & dmask]; + + dodist: + for (;;) { // goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + + if (op & 16) { /* distance base */ + dist = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + } + dist += hold & ((1 << op) - 1); +//#ifdef INFLATE_STRICT + if (dist > dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } +//#endif + hold >>>= op; + bits -= op; + //Tracevv((stderr, "inflate: distance %u\n", dist)); + op = _out - beg; /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// if (len <= op - whave) { +// do { +// output[_out++] = 0; +// } while (--len); +// continue top; +// } +// len -= op - whave; +// do { +// output[_out++] = 0; +// } while (--op > whave); +// if (op === 0) { +// from = _out - dist; +// do { +// output[_out++] = output[from++]; +// } while (--len); +// continue top; +// } +//#endif + } + from = 0; // window index + from_source = s_window; + if (wnext === 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = 0; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + while (len > 2) { + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + len -= 3; + } + if (len) { + output[_out++] = from_source[from++]; + if (len > 1) { + output[_out++] = from_source[from++]; + } + } + } + else { + from = _out - dist; /* copy direct from output */ + do { /* minimum length is three */ + output[_out++] = output[from++]; + output[_out++] = output[from++]; + output[_out++] = output[from++]; + len -= 3; + } while (len > 2); + if (len) { + output[_out++] = output[from++]; + if (len > 1) { + output[_out++] = output[from++]; + } + } + } + } + else if ((op & 64) === 0) { /* 2nd level distance code */ + here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dodist; + } + else { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } + else if ((op & 64) === 0) { /* 2nd level length code */ + here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dolen; + } + else if (op & 32) { /* end-of-block */ + //Tracevv((stderr, "inflate: end of block\n")); + state.mode = TYPE; + break top; + } + else { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } while (_in < last && _out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + _in -= len; + bits -= len << 3; + hold &= (1 << bits) - 1; + + /* update state and return */ + strm.next_in = _in; + strm.next_out = _out; + strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); + strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); + state.hold = hold; + state.bits = bits; + return; +}; + +},{}],6:[function(require,module,exports){ +'use strict'; + + +var utils = require('../utils/common'); +var adler32 = require('./adler32'); +var crc32 = require('./crc32'); +var inflate_fast = require('./inffast'); +var inflate_table = require('./inftrees'); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +//var Z_NO_FLUSH = 0; +//var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +//var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + +/* The deflate compression method */ +var Z_DEFLATED = 8; + + +/* STATES ====================================================================*/ +/* ===========================================================================*/ + + +var HEAD = 1; /* i: waiting for magic header */ +var FLAGS = 2; /* i: waiting for method and flags (gzip) */ +var TIME = 3; /* i: waiting for modification time (gzip) */ +var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ +var EXLEN = 5; /* i: waiting for extra length (gzip) */ +var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ +var NAME = 7; /* i: waiting for end of file name (gzip) */ +var COMMENT = 8; /* i: waiting for end of comment (gzip) */ +var HCRC = 9; /* i: waiting for header crc (gzip) */ +var DICTID = 10; /* i: waiting for dictionary check value */ +var DICT = 11; /* waiting for inflateSetDictionary() call */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ +var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ +var STORED = 14; /* i: waiting for stored size (length and complement) */ +var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ +var COPY = 16; /* i/o: waiting for input or output to copy stored block */ +var TABLE = 17; /* i: waiting for dynamic block table lengths */ +var LENLENS = 18; /* i: waiting for code length code lengths */ +var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ +var LEN_ = 20; /* i: same as LEN below, but only first time in */ +var LEN = 21; /* i: waiting for length/lit/eob code */ +var LENEXT = 22; /* i: waiting for length extra bits */ +var DIST = 23; /* i: waiting for distance code */ +var DISTEXT = 24; /* i: waiting for distance extra bits */ +var MATCH = 25; /* o: waiting for output space to copy string */ +var LIT = 26; /* o: waiting for output space to write literal */ +var CHECK = 27; /* i: waiting for 32-bit check value */ +var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ +var DONE = 29; /* finished check, done -- remain here until reset */ +var BAD = 30; /* got a data error -- remain here until reset */ +var MEM = 31; /* got an inflate() memory error -- remain here until reset */ +var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ + +/* ===========================================================================*/ + + + +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_WBITS = MAX_WBITS; + + +function zswap32(q) { + return (((q >>> 24) & 0xff) + + ((q >>> 8) & 0xff00) + + ((q & 0xff00) << 8) + + ((q & 0xff) << 24)); +} + + +function InflateState() { + this.mode = 0; /* current inflate mode */ + this.last = false; /* true if processing last block */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.havedict = false; /* true if dictionary provided */ + this.flags = 0; /* gzip header method and flags (0 if zlib) */ + this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ + this.check = 0; /* protected copy of check value */ + this.total = 0; /* protected copy of output count */ + // TODO: may be {} + this.head = null; /* where to save gzip header information */ + + /* sliding window */ + this.wbits = 0; /* log base 2 of requested window size */ + this.wsize = 0; /* window size or zero if not using window */ + this.whave = 0; /* valid bytes in the window */ + this.wnext = 0; /* window write index */ + this.window = null; /* allocated sliding window, if needed */ + + /* bit accumulator */ + this.hold = 0; /* input bit accumulator */ + this.bits = 0; /* number of bits in "in" */ + + /* for string and stored block copying */ + this.length = 0; /* literal or length of data to copy */ + this.offset = 0; /* distance back to copy string from */ + + /* for table and code decoding */ + this.extra = 0; /* extra bits needed */ + + /* fixed and dynamic code tables */ + this.lencode = null; /* starting table for length/literal codes */ + this.distcode = null; /* starting table for distance codes */ + this.lenbits = 0; /* index bits for lencode */ + this.distbits = 0; /* index bits for distcode */ + + /* dynamic table building */ + this.ncode = 0; /* number of code length code lengths */ + this.nlen = 0; /* number of length code lengths */ + this.ndist = 0; /* number of distance code lengths */ + this.have = 0; /* number of code lengths in lens[] */ + this.next = null; /* next available space in codes[] */ + + this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ + this.work = new utils.Buf16(288); /* work area for code table building */ + + /* + because we don't have pointers in js, we use lencode and distcode directly + as buffers so we don't need codes + */ + //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ + this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ + this.distdyn = null; /* dynamic table for distance codes (JS specific) */ + this.sane = 0; /* if false, allow invalid distance too far */ + this.back = 0; /* bits back of last unprocessed length/lit */ + this.was = 0; /* initial length of match */ +} + +function inflateResetKeep(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + strm.total_in = strm.total_out = state.total = 0; + strm.msg = ''; /*Z_NULL*/ + if (state.wrap) { /* to support ill-conceived Java test suite */ + strm.adler = state.wrap & 1; + } + state.mode = HEAD; + state.last = 0; + state.havedict = 0; + state.dmax = 32768; + state.head = null/*Z_NULL*/; + state.hold = 0; + state.bits = 0; + //state.lencode = state.distcode = state.next = state.codes; + state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); + state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); + + state.sane = 1; + state.back = -1; + //Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +function inflateReset(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + state.wsize = 0; + state.whave = 0; + state.wnext = 0; + return inflateResetKeep(strm); + +} + +function inflateReset2(strm, windowBits) { + var wrap; + var state; + + /* get the state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; + if (windowBits < 48) { + windowBits &= 15; + } + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) { + return Z_STREAM_ERROR; + } + if (state.window !== null && state.wbits !== windowBits) { + state.window = null; + } + + /* update state and reset the rest of it */ + state.wrap = wrap; + state.wbits = windowBits; + return inflateReset(strm); +} + +function inflateInit2(strm, windowBits) { + var ret; + var state; + + if (!strm) { return Z_STREAM_ERROR; } + //strm.msg = Z_NULL; /* in case we return an error */ + + state = new InflateState(); + + //if (state === Z_NULL) return Z_MEM_ERROR; + //Tracev((stderr, "inflate: allocated\n")); + strm.state = state; + state.window = null/*Z_NULL*/; + ret = inflateReset2(strm, windowBits); + if (ret !== Z_OK) { + strm.state = null/*Z_NULL*/; + } + return ret; +} + +function inflateInit(strm) { + return inflateInit2(strm, DEF_WBITS); +} + + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +var virgin = true; + +var lenfix, distfix; // We have no pointers in JS, so keep tables separate + +function fixedtables(state) { + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + var sym; + + lenfix = new utils.Buf32(512); + distfix = new utils.Buf32(32); + + /* literal/length table */ + sym = 0; + while (sym < 144) { state.lens[sym++] = 8; } + while (sym < 256) { state.lens[sym++] = 9; } + while (sym < 280) { state.lens[sym++] = 7; } + while (sym < 288) { state.lens[sym++] = 8; } + + inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); + + /* distance table */ + sym = 0; + while (sym < 32) { state.lens[sym++] = 5; } + + inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); + + /* do this just once */ + virgin = false; + } + + state.lencode = lenfix; + state.lenbits = 9; + state.distcode = distfix; + state.distbits = 5; +} + + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +function updatewindow(strm, src, end, copy) { + var dist; + var state = strm.state; + + /* if it hasn't been done already, allocate space for the window */ + if (state.window === null) { + state.wsize = 1 << state.wbits; + state.wnext = 0; + state.whave = 0; + + state.window = new utils.Buf8(state.wsize); + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state.wsize) { + utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0); + state.wnext = 0; + state.whave = state.wsize; + } + else { + dist = state.wsize - state.wnext; + if (dist > copy) { + dist = copy; + } + //zmemcpy(state->window + state->wnext, end - copy, dist); + utils.arraySet(state.window, src, end - copy, dist, state.wnext); + copy -= dist; + if (copy) { + //zmemcpy(state->window, end - copy, copy); + utils.arraySet(state.window, src, end - copy, copy, 0); + state.wnext = copy; + state.whave = state.wsize; + } + else { + state.wnext += dist; + if (state.wnext === state.wsize) { state.wnext = 0; } + if (state.whave < state.wsize) { state.whave += dist; } + } + } + return 0; +} + +function inflate(strm, flush) { + var state; + var input, output; // input/output buffers + var next; /* next input INDEX */ + var put; /* next output INDEX */ + var have, left; /* available input and output */ + var hold; /* bit buffer */ + var bits; /* bits in bit buffer */ + var _in, _out; /* save starting available input and output */ + var copy; /* number of stored or match bytes to copy */ + var from; /* where to copy match bytes from */ + var from_source; + var here = 0; /* current decoding table entry */ + var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) + //var last; /* parent table entry */ + var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) + var len; /* length to copy for repeats, bits to drop */ + var ret; /* return code */ + var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ + var opts; + + var n; // temporary var for NEED_BITS + + var order = /* permutation of code lengths */ + [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; + + + if (!strm || !strm.state || !strm.output || + (!strm.input && strm.avail_in !== 0)) { + return Z_STREAM_ERROR; + } + + state = strm.state; + if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ + + + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + _in = have; + _out = left; + ret = Z_OK; + + inf_leave: // goto emulation + for (;;) { + switch (state.mode) { + case HEAD: + if (state.wrap === 0) { + state.mode = TYPEDO; + break; + } + //=== NEEDBITS(16); + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ + state.check = 0/*crc32(0L, Z_NULL, 0)*/; + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = FLAGS; + break; + } + state.flags = 0; /* expect zlib header */ + if (state.head) { + state.head.done = false; + } + if (!(state.wrap & 1) || /* check if zlib header allowed */ + (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { + strm.msg = 'incorrect header check'; + state.mode = BAD; + break; + } + if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// + len = (hold & 0x0f)/*BITS(4)*/ + 8; + if (state.wbits === 0) { + state.wbits = len; + } + else if (len > state.wbits) { + strm.msg = 'invalid window size'; + state.mode = BAD; + break; + } + state.dmax = 1 << len; + //Tracev((stderr, "inflate: zlib header ok\n")); + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = hold & 0x200 ? DICTID : TYPE; + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + break; + case FLAGS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.flags = hold; + if ((state.flags & 0xff) !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + if (state.flags & 0xe000) { + strm.msg = 'unknown header flags set'; + state.mode = BAD; + break; + } + if (state.head) { + state.head.text = ((hold >> 8) & 1); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = TIME; + /* falls through */ + case TIME: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.time = hold; + } + if (state.flags & 0x0200) { + //=== CRC4(state.check, hold) + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + hbuf[2] = (hold >>> 16) & 0xff; + hbuf[3] = (hold >>> 24) & 0xff; + state.check = crc32(state.check, hbuf, 4, 0); + //=== + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = OS; + /* falls through */ + case OS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.xflags = (hold & 0xff); + state.head.os = (hold >> 8); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = EXLEN; + /* falls through */ + case EXLEN: + if (state.flags & 0x0400) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length = hold; + if (state.head) { + state.head.extra_len = hold; + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + else if (state.head) { + state.head.extra = null/*Z_NULL*/; + } + state.mode = EXTRA; + /* falls through */ + case EXTRA: + if (state.flags & 0x0400) { + copy = state.length; + if (copy > have) { copy = have; } + if (copy) { + if (state.head) { + len = state.head.extra_len - state.length; + if (!state.head.extra) { + // Use untyped array for more conveniend processing later + state.head.extra = new Array(state.head.extra_len); + } + utils.arraySet( + state.head.extra, + input, + next, + // extra field is limited to 65536 bytes + // - no need for additional size check + copy, + /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ + len + ); + //zmemcpy(state.head.extra + len, next, + // len + copy > state.head.extra_max ? + // state.head.extra_max - len : copy); + } + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + state.length -= copy; + } + if (state.length) { break inf_leave; } + } + state.length = 0; + state.mode = NAME; + /* falls through */ + case NAME: + if (state.flags & 0x0800) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + // TODO: 2 or 1 bytes? + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.name_max*/)) { + state.head.name += String.fromCharCode(len); + } + } while (len && copy < have); + + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.name = null; + } + state.length = 0; + state.mode = COMMENT; + /* falls through */ + case COMMENT: + if (state.flags & 0x1000) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.comm_max*/)) { + state.head.comment += String.fromCharCode(len); + } + } while (len && copy < have); + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.comment = null; + } + state.mode = HCRC; + /* falls through */ + case HCRC: + if (state.flags & 0x0200) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.check & 0xffff)) { + strm.msg = 'header crc mismatch'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + if (state.head) { + state.head.hcrc = ((state.flags >> 9) & 1); + state.head.done = true; + } + strm.adler = state.check = 0; + state.mode = TYPE; + break; + case DICTID: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + strm.adler = state.check = zswap32(hold); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = DICT; + /* falls through */ + case DICT: + if (state.havedict === 0) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + return Z_NEED_DICT; + } + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + /* falls through */ + case TYPE: + if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } + /* falls through */ + case TYPEDO: + if (state.last) { + //--- BYTEBITS() ---// + hold >>>= bits & 7; + bits -= bits & 7; + //---// + state.mode = CHECK; + break; + } + //=== NEEDBITS(3); */ + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.last = (hold & 0x01)/*BITS(1)*/; + //--- DROPBITS(1) ---// + hold >>>= 1; + bits -= 1; + //---// + + switch ((hold & 0x03)/*BITS(2)*/) { + case 0: /* stored block */ + //Tracev((stderr, "inflate: stored block%s\n", + // state.last ? " (last)" : "")); + state.mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + //Tracev((stderr, "inflate: fixed codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = LEN_; /* decode codes */ + if (flush === Z_TREES) { + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break inf_leave; + } + break; + case 2: /* dynamic block */ + //Tracev((stderr, "inflate: dynamic codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = TABLE; + break; + case 3: + strm.msg = 'invalid block type'; + state.mode = BAD; + } + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break; + case STORED: + //--- BYTEBITS() ---// /* go to byte boundary */ + hold >>>= bits & 7; + bits -= bits & 7; + //---// + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { + strm.msg = 'invalid stored block lengths'; + state.mode = BAD; + break; + } + state.length = hold & 0xffff; + //Tracev((stderr, "inflate: stored length %u\n", + // state.length)); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = COPY_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case COPY_: + state.mode = COPY; + /* falls through */ + case COPY: + copy = state.length; + if (copy) { + if (copy > have) { copy = have; } + if (copy > left) { copy = left; } + if (copy === 0) { break inf_leave; } + //--- zmemcpy(put, next, copy); --- + utils.arraySet(output, input, next, copy, put); + //---// + have -= copy; + next += copy; + left -= copy; + put += copy; + state.length -= copy; + break; + } + //Tracev((stderr, "inflate: stored end\n")); + state.mode = TYPE; + break; + case TABLE: + //=== NEEDBITS(14); */ + while (bits < 14) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// +//#ifndef PKZIP_BUG_WORKAROUND + if (state.nlen > 286 || state.ndist > 30) { + strm.msg = 'too many length or distance symbols'; + state.mode = BAD; + break; + } +//#endif + //Tracev((stderr, "inflate: table sizes ok\n")); + state.have = 0; + state.mode = LENLENS; + /* falls through */ + case LENLENS: + while (state.have < state.ncode) { + //=== NEEDBITS(3); + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + while (state.have < 19) { + state.lens[order[state.have++]] = 0; + } + // We have separate tables & no pointers. 2 commented lines below not needed. + //state.next = state.codes; + //state.lencode = state.next; + // Switch to use dynamic table + state.lencode = state.lendyn; + state.lenbits = 7; + + opts = { bits: state.lenbits }; + ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); + state.lenbits = opts.bits; + + if (ret) { + strm.msg = 'invalid code lengths set'; + state.mode = BAD; + break; + } + //Tracev((stderr, "inflate: code lengths ok\n")); + state.have = 0; + state.mode = CODELENS; + /* falls through */ + case CODELENS: + while (state.have < state.nlen + state.ndist) { + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_val < 16) { + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.lens[state.have++] = here_val; + } + else { + if (here_val === 16) { + //=== NEEDBITS(here.bits + 2); + n = here_bits + 2; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + if (state.have === 0) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + len = state.lens[state.have - 1]; + copy = 3 + (hold & 0x03);//BITS(2); + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + } + else if (here_val === 17) { + //=== NEEDBITS(here.bits + 3); + n = here_bits + 3; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 3 + (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + else { + //=== NEEDBITS(here.bits + 7); + n = here_bits + 7; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 11 + (hold & 0x7f);//BITS(7); + //--- DROPBITS(7) ---// + hold >>>= 7; + bits -= 7; + //---// + } + if (state.have + copy > state.nlen + state.ndist) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + while (copy--) { + state.lens[state.have++] = len; + } + } + } + + /* handle error breaks in while */ + if (state.mode === BAD) { break; } + + /* check for end-of-block code (better have one) */ + if (state.lens[256] === 0) { + strm.msg = 'invalid code -- missing end-of-block'; + state.mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state.lenbits = 9; + + opts = { bits: state.lenbits }; + ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.lenbits = opts.bits; + // state.lencode = state.next; + + if (ret) { + strm.msg = 'invalid literal/lengths set'; + state.mode = BAD; + break; + } + + state.distbits = 6; + //state.distcode.copy(state.codes); + // Switch to use dynamic table + state.distcode = state.distdyn; + opts = { bits: state.distbits }; + ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.distbits = opts.bits; + // state.distcode = state.next; + + if (ret) { + strm.msg = 'invalid distances set'; + state.mode = BAD; + break; + } + //Tracev((stderr, 'inflate: codes ok\n')); + state.mode = LEN_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case LEN_: + state.mode = LEN; + /* falls through */ + case LEN: + if (have >= 6 && left >= 258) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + inflate_fast(strm, _out); + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + if (state.mode === TYPE) { + state.back = -1; + } + break; + } + state.back = 0; + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_op && (here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.lencode[last_val + + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + state.length = here_val; + if (here_op === 0) { + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + state.mode = LIT; + break; + } + if (here_op & 32) { + //Tracevv((stderr, "inflate: end of block\n")); + state.back = -1; + state.mode = TYPE; + break; + } + if (here_op & 64) { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break; + } + state.extra = here_op & 15; + state.mode = LENEXT; + /* falls through */ + case LENEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } + //Tracevv((stderr, "inflate: length %u\n", state.length)); + state.was = state.length; + state.mode = DIST; + /* falls through */ + case DIST: + for (;;) { + here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if ((here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.distcode[last_val + + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + if (here_op & 64) { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break; + } + state.offset = here_val; + state.extra = (here_op) & 15; + state.mode = DISTEXT; + /* falls through */ + case DISTEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } +//#ifdef INFLATE_STRICT + if (state.offset > state.dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +//#endif + //Tracevv((stderr, "inflate: distance %u\n", state.offset)); + state.mode = MATCH; + /* falls through */ + case MATCH: + if (left === 0) { break inf_leave; } + copy = _out - left; + if (state.offset > copy) { /* copy from window */ + copy = state.offset - copy; + if (copy > state.whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// Trace((stderr, "inflate.c too far\n")); +// copy -= state.whave; +// if (copy > state.length) { copy = state.length; } +// if (copy > left) { copy = left; } +// left -= copy; +// state.length -= copy; +// do { +// output[put++] = 0; +// } while (--copy); +// if (state.length === 0) { state.mode = LEN; } +// break; +//#endif + } + if (copy > state.wnext) { + copy -= state.wnext; + from = state.wsize - copy; + } + else { + from = state.wnext - copy; + } + if (copy > state.length) { copy = state.length; } + from_source = state.window; + } + else { /* copy from output */ + from_source = output; + from = put - state.offset; + copy = state.length; + } + if (copy > left) { copy = left; } + left -= copy; + state.length -= copy; + do { + output[put++] = from_source[from++]; + } while (--copy); + if (state.length === 0) { state.mode = LEN; } + break; + case LIT: + if (left === 0) { break inf_leave; } + output[put++] = state.length; + left--; + state.mode = LEN; + break; + case CHECK: + if (state.wrap) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + // Use '|' insdead of '+' to make sure that result is signed + hold |= input[next++] << bits; + bits += 8; + } + //===// + _out -= left; + strm.total_out += _out; + state.total += _out; + if (_out) { + strm.adler = state.check = + /*UPDATE(state.check, put - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); + + } + _out = left; + // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too + if ((state.flags ? hold : zswap32(hold)) !== state.check) { + strm.msg = 'incorrect data check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: check matches trailer\n")); + } + state.mode = LENGTH; + /* falls through */ + case LENGTH: + if (state.wrap && state.flags) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.total & 0xffffffff)) { + strm.msg = 'incorrect length check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: length matches trailer\n")); + } + state.mode = DONE; + /* falls through */ + case DONE: + ret = Z_STREAM_END; + break inf_leave; + case BAD: + ret = Z_DATA_ERROR; + break inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* falls through */ + default: + return Z_STREAM_ERROR; + } + } + + // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + + if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && + (state.mode < CHECK || flush !== Z_FINISH))) { + if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { + state.mode = MEM; + return Z_MEM_ERROR; + } + } + _in -= strm.avail_in; + _out -= strm.avail_out; + strm.total_in += _in; + strm.total_out += _out; + state.total += _out; + if (state.wrap && _out) { + strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); + } + strm.data_type = state.bits + (state.last ? 64 : 0) + + (state.mode === TYPE ? 128 : 0) + + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); + if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { + ret = Z_BUF_ERROR; + } + return ret; +} + +function inflateEnd(strm) { + + if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { + return Z_STREAM_ERROR; + } + + var state = strm.state; + if (state.window) { + state.window = null; + } + strm.state = null; + return Z_OK; +} + +function inflateGetHeader(strm, head) { + var state; + + /* check state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } + + /* save header structure */ + state.head = head; + head.done = false; + return Z_OK; +} + +function inflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; + + var state; + var dictid; + var ret; + + /* check state */ + if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; } + state = strm.state; + + if (state.wrap !== 0 && state.mode !== DICT) { + return Z_STREAM_ERROR; + } + + /* check for correct dictionary identifier */ + if (state.mode === DICT) { + dictid = 1; /* adler32(0, null, 0)*/ + /* dictid = adler32(dictid, dictionary, dictLength); */ + dictid = adler32(dictid, dictionary, dictLength, 0); + if (dictid !== state.check) { + return Z_DATA_ERROR; + } + } + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary, dictLength, dictLength); + if (ret) { + state.mode = MEM; + return Z_MEM_ERROR; + } + state.havedict = 1; + // Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +exports.inflateReset = inflateReset; +exports.inflateReset2 = inflateReset2; +exports.inflateResetKeep = inflateResetKeep; +exports.inflateInit = inflateInit; +exports.inflateInit2 = inflateInit2; +exports.inflate = inflate; +exports.inflateEnd = inflateEnd; +exports.inflateGetHeader = inflateGetHeader; +exports.inflateSetDictionary = inflateSetDictionary; +exports.inflateInfo = 'pako inflate (from Nodeca project)'; + +/* Not implemented +exports.inflateCopy = inflateCopy; +exports.inflateGetDictionary = inflateGetDictionary; +exports.inflateMark = inflateMark; +exports.inflatePrime = inflatePrime; +exports.inflateSync = inflateSync; +exports.inflateSyncPoint = inflateSyncPoint; +exports.inflateUndermine = inflateUndermine; +*/ + +},{"../utils/common":2,"./adler32":3,"./crc32":4,"./inffast":5,"./inftrees":7}],7:[function(require,module,exports){ +'use strict'; + + +var utils = require('../utils/common'); + +var MAXBITS = 15; +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +var lbase = [ /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 +]; + +var lext = [ /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 +]; + +var dbase = [ /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0 +]; + +var dext = [ /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64 +]; + +module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) +{ + var bits = opts.bits; + //here = opts.here; /* table entry for duplication */ + + var len = 0; /* a code's length in bits */ + var sym = 0; /* index of code symbols */ + var min = 0, max = 0; /* minimum and maximum code lengths */ + var root = 0; /* number of index bits for root table */ + var curr = 0; /* number of index bits for current table */ + var drop = 0; /* code bits to drop for sub-table */ + var left = 0; /* number of prefix codes available */ + var used = 0; /* code entries in table used */ + var huff = 0; /* Huffman code */ + var incr; /* for incrementing code, index */ + var fill; /* index for replicating entries */ + var low; /* low bits for current root entry */ + var mask; /* mask for low root bits */ + var next; /* next available space in table */ + var base = null; /* base value table to use */ + var base_index = 0; +// var shoextra; /* extra bits table to use */ + var end; /* use base and extra for symbol > end */ + var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ + var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ + var extra = null; + var extra_index = 0; + + var here_bits, here_op, here_val; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) { + count[len] = 0; + } + for (sym = 0; sym < codes; sym++) { + count[lens[lens_index + sym]]++; + } + + /* bound code lengths, force root to be within code lengths */ + root = bits; + for (max = MAXBITS; max >= 1; max--) { + if (count[max] !== 0) { break; } + } + if (root > max) { + root = max; + } + if (max === 0) { /* no symbols to code at all */ + //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ + //table.bits[opts.table_index] = 1; //here.bits = (var char)1; + //table.val[opts.table_index++] = 0; //here.val = (var short)0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + + //table.op[opts.table_index] = 64; + //table.bits[opts.table_index] = 1; + //table.val[opts.table_index++] = 0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + opts.bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) { + if (count[min] !== 0) { break; } + } + if (root < min) { + root = min; + } + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) { + return -1; + } /* over-subscribed */ + } + if (left > 0 && (type === CODES || max !== 1)) { + return -1; /* incomplete set */ + } + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) { + offs[len + 1] = offs[len] + count[len]; + } + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) { + if (lens[lens_index + sym] !== 0) { + work[offs[lens[lens_index + sym]]++] = sym; + } + } + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + // poor man optimization - use if-else instead of switch, + // to avoid deopts in old v8 + if (type === CODES) { + base = extra = work; /* dummy value--not used */ + end = 19; + + } else if (type === LENS) { + base = lbase; + base_index -= 257; + extra = lext; + extra_index -= 257; + end = 256; + + } else { /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize opts for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = table_index; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = -1; /* trigger new sub-table when len > root */ + used = 1 << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + var i = 0; + /* process all codes and make table entries */ + for (;;) { + i++; + /* create table entry */ + here_bits = len - drop; + if (work[sym] < end) { + here_op = 0; + here_val = work[sym]; + } + else if (work[sym] > end) { + here_op = extra[extra_index + work[sym]]; + here_val = base[base_index + work[sym]]; + } + else { + here_op = 32 + 64; /* end of block */ + here_val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1 << (len - drop); + fill = 1 << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; + } while (fill !== 0); + + /* backwards increment the len-bit code huff */ + incr = 1 << (len - 1); + while (huff & incr) { + incr >>= 1; + } + if (incr !== 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--count[len] === 0) { + if (len === max) { break; } + len = lens[lens_index + work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) !== low) { + /* if first time, transition to sub-tables */ + if (drop === 0) { + drop = root; + } + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = 1 << curr; + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) { break; } + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1 << curr; + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + /* point entry in root table to sub-table */ + low = huff & mask; + /*table.op[low] = curr; + table.bits[low] = root; + table.val[low] = next - opts.table_index;*/ + table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff !== 0) { + //table.op[next + huff] = 64; /* invalid code marker */ + //table.bits[next + huff] = len - drop; + //table.val[next + huff] = 0; + table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; + } + + /* set return parameters */ + //opts.table_index += used; + opts.bits = root; + return 0; +}; + +},{"../utils/common":2}],8:[function(require,module,exports){ +'use strict'; + + +function ZStream() { + /* next input byte */ + this.input = null; // JS specific, because we have no pointers + this.next_in = 0; + /* number of bytes available at input */ + this.avail_in = 0; + /* total number of input bytes read so far */ + this.total_in = 0; + /* next output byte should be put there */ + this.output = null; // JS specific, because we have no pointers + this.next_out = 0; + /* remaining free space at output */ + this.avail_out = 0; + /* total number of bytes output so far */ + this.total_out = 0; + /* last error message, NULL if no error */ + this.msg = ''/*Z_NULL*/; + /* not visible by applications */ + this.state = null; + /* best guess about the data type: binary or text */ + this.data_type = 2/*Z_UNKNOWN*/; + /* adler32 value of the uncompressed data */ + this.adler = 0; +} + +module.exports = ZStream; + +},{}]},{},[1])(1) +}); \ No newline at end of file diff --git a/noVNC/core/inflator.mod.js b/noVNC/core/inflator.mod.js new file mode 100644 index 0000000..26e6441 --- /dev/null +++ b/noVNC/core/inflator.mod.js @@ -0,0 +1,40 @@ +var zlib = require('pako/lib/zlib/inflate.js'); +var ZStream = require('pako/lib/zlib/zstream.js'); + +function Inflate() { + this.strm = new ZStream(); + this.chunkSize = 1024 * 10 * 10; + this.strm.output = new Uint8Array(this.chunkSize); + this.windowBits = 5; + + zlib.inflateInit(this.strm, this.windowBits); +}; + +Inflate.prototype = { + inflate: function (data, flush, expected) { + this.strm.input = data; + this.strm.avail_in = this.strm.input.length; + this.strm.next_in = 0; + this.strm.next_out = 0; + + // resize our output buffer if it's too small + // (we could just use multiple chunks, but that would cause an extra + // allocation each time to flatten the chunks) + if (expected > this.chunkSize) { + this.chunkSize = expected; + this.strm.output = new Uint8Array(this.chunkSize); + } + + this.strm.avail_out = this.chunkSize; + + zlib.inflate(this.strm, flush); + + return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); + }, + + reset: function () { + zlib.inflateReset(this.strm); + } +}; + +module.exports = { Inflate: Inflate }; diff --git a/noVNC/include/input.js b/noVNC/core/input/devices.js similarity index 57% rename from noVNC/include/input.js rename to noVNC/core/input/devices.js index 5d9e209..2e41122 100644 --- a/noVNC/include/input.js +++ b/noVNC/core/input/devices.js @@ -8,7 +8,12 @@ /*jslint browser: true, white: false */ /*global window, Util */ -var Keyboard, Mouse; +/* [module] + * import Util from "../util"; + * import KeyboardUtil from "./util"; + */ + +/* [module] export */ var Keyboard; (function () { "use strict"; @@ -27,10 +32,10 @@ var Keyboard, Mouse; }); // create the keyboard handler - this._handler = new KeyEventDecoder(kbdUtil.ModifierSync(), - VerifyCharModifier( /* jshint newcap: false */ - TrackKeyState( - EscapeModifiers(this._handleRfbEvent.bind(this)) + this._handler = new KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), + KeyboardUtil.VerifyCharModifier( /* jshint newcap: false */ + KeyboardUtil.TrackKeyState( + KeyboardUtil.EscapeModifiers(this._handleRfbEvent.bind(this)) ) ) ); /* jshint newcap: true */ @@ -51,49 +56,45 @@ var Keyboard, Mouse; if (this._onKeyPress) { Util.Debug("onKeyPress " + (e.type == 'keydown' ? "down" : "up") + ", keysym: " + e.keysym.keysym + "(" + e.keysym.keyname + ")"); - this._onKeyPress(e.keysym.keysym, e.type == 'keydown'); + this._onKeyPress(e); } }, + setQEMUVNCKeyboardHandler: function () { + this._handler = new KeyboardUtil.QEMUKeyEventDecoder(KeyboardUtil.ModifierSync(), + KeyboardUtil.TrackQEMUKeyState( + this._handleRfbEvent.bind(this) + ) + ); + }, + _handleKeyDown: function (e) { - if (!this._focused) { return true; } + if (!this._focused) { return; } if (this._handler.keydown(e)) { // Suppress bubbling/default actions Util.stopEvent(e); - return false; } else { // Allow the event to bubble and become a keyPress event which // will have the character code translated - return true; } }, _handleKeyPress: function (e) { - if (!this._focused) { return true; } + if (!this._focused) { return; } if (this._handler.keypress(e)) { // Suppress bubbling/default actions Util.stopEvent(e); - return false; - } else { - // Allow the event to bubble and become a keyPress event which - // will have the character code translated - return true; } }, _handleKeyUp: function (e) { - if (!this._focused) { return true; } + if (!this._focused) { return; } if (this._handler.keyup(e)) { // Suppress bubbling/default actions Util.stopEvent(e); - return false; - } else { - // Allow the event to bubble and become a keyPress event which - // will have the character code translated - return true; } }, @@ -109,12 +110,12 @@ var Keyboard, Mouse; //Util.Debug(">> Keyboard.grab"); var c = this._target; - Util.addEvent(c, 'keydown', this._eventHandlers.keydown); - Util.addEvent(c, 'keyup', this._eventHandlers.keyup); - Util.addEvent(c, 'keypress', this._eventHandlers.keypress); + c.addEventListener('keydown', this._eventHandlers.keydown); + c.addEventListener('keyup', this._eventHandlers.keyup); + c.addEventListener('keypress', this._eventHandlers.keypress); // Release (key up) if window loses focus - Util.addEvent(window, 'blur', this._eventHandlers.blur); + window.addEventListener('blur', this._eventHandlers.blur); //Util.Debug("<< Keyboard.grab"); }, @@ -123,10 +124,10 @@ var Keyboard, Mouse; //Util.Debug(">> Keyboard.ungrab"); var c = this._target; - Util.removeEvent(c, 'keydown', this._eventHandlers.keydown); - Util.removeEvent(c, 'keyup', this._eventHandlers.keyup); - Util.removeEvent(c, 'keypress', this._eventHandlers.keypress); - Util.removeEvent(window, 'blur', this._eventHandlers.blur); + c.removeEventListener('keydown', this._eventHandlers.keydown); + c.removeEventListener('keyup', this._eventHandlers.keyup); + c.removeEventListener('keypress', this._eventHandlers.keypress); + window.removeEventListener('blur', this._eventHandlers.blur); // Release (key up) all keys that are in a down state this._allKeysUp(); @@ -145,11 +146,11 @@ var Keyboard, Mouse; ['onKeyPress', 'rw', 'func'] // Handler for key press/release ]); +})(); - // - // Mouse event handler - // +/* [module] export */ var Mouse; +(function () { Mouse = function (defaults) { this._mouseCaptured = false; @@ -160,7 +161,6 @@ var Keyboard, Mouse; Util.set_defaults(this, defaults, { 'target': document, 'focused': true, - 'scale': 1.0, 'touchButton': 1 }); @@ -177,9 +177,7 @@ var Keyboard, Mouse; // private methods _captureMouse: function () { // capturing the mouse ensures we get the mouseup event - if (this._target.setCapture) { - this._target.setCapture(); - } + Util.setCapture(this._target); // some browsers give us mouseup events regardless, // so if we never captured the mouse, we can disregard the event @@ -187,9 +185,7 @@ var Keyboard, Mouse; }, _releaseMouse: function () { - if (this._target.releaseCapture) { - this._target.releaseCapture(); - } + Util.releaseCapture(); this._mouseCaptured = false; }, @@ -198,21 +194,20 @@ var Keyboard, Mouse; }, _handleMouseButton: function (e, down) { - if (!this._focused) { return true; } + if (!this._focused) { return; } if (this._notify) { this._notify(e); } - var evt = (e ? e : window.event); - var pos = Util.getEventPosition(e, this._target, this._scale); + var pos = this._getMousePosition(e); var bmask; if (e.touches || e.changedTouches) { // Touch device // When two touches occur within 500 ms of each other and are - // closer than 20 pixels together a double click is triggered. + // close enough together a double click is triggered. if (down == 1) { if (this._doubleClickTimer === null) { this._lastTouchPos = pos; @@ -229,7 +224,8 @@ var Keyboard, Mouse; // The goal is to trigger on a certain physical width, the // devicePixelRatio brings us a bit closer but is not optimal. - if (d < 20 * window.devicePixelRatio) { + var threshold = 20 * (window.devicePixelRatio || 1); + if (d < threshold) { pos = this._lastTouchPos; } } @@ -237,14 +233,14 @@ var Keyboard, Mouse; } bmask = this._touchButton; // If bmask is set - } else if (evt.which) { + } else if (e.which) { /* everything except IE */ - bmask = 1 << evt.button; + bmask = 1 << e.button; } else { /* IE including 9 */ - bmask = (evt.button & 0x1) + // Left - (evt.button & 0x2) * 2 + // Right - (evt.button & 0x4) / 2; // Middle + bmask = (e.button & 0x1) + // Left + (e.button & 0x2) * 2 + // Right + (e.button & 0x4) / 2; // Middle } if (this._onMouseButton) { @@ -253,7 +249,6 @@ var Keyboard, Mouse; this._onMouseButton(pos.x, pos.y, down, bmask); } Util.stopEvent(e); - return false; }, _handleMouseDown: function (e) { @@ -269,62 +264,85 @@ var Keyboard, Mouse; }, _handleMouseWheel: function (e) { - if (!this._focused) { return true; } + if (!this._focused) { return; } if (this._notify) { this._notify(e); } - var evt = (e ? e : window.event); - var pos = Util.getEventPosition(e, this._target, this._scale); - var wheelData = evt.detail ? evt.detail * -1 : evt.wheelDelta / 40; - var bmask; - if (wheelData > 0) { - bmask = 1 << 3; - } else { - bmask = 1 << 4; - } + var pos = this._getMousePosition(e); if (this._onMouseButton) { - this._onMouseButton(pos.x, pos.y, 1, bmask); - this._onMouseButton(pos.x, pos.y, 0, bmask); + if (e.deltaX < 0) { + this._onMouseButton(pos.x, pos.y, 1, 1 << 5); + this._onMouseButton(pos.x, pos.y, 0, 1 << 5); + } else if (e.deltaX > 0) { + this._onMouseButton(pos.x, pos.y, 1, 1 << 6); + this._onMouseButton(pos.x, pos.y, 0, 1 << 6); + } + + if (e.deltaY < 0) { + this._onMouseButton(pos.x, pos.y, 1, 1 << 3); + this._onMouseButton(pos.x, pos.y, 0, 1 << 3); + } else if (e.deltaY > 0) { + this._onMouseButton(pos.x, pos.y, 1, 1 << 4); + this._onMouseButton(pos.x, pos.y, 0, 1 << 4); + } } + Util.stopEvent(e); - return false; }, _handleMouseMove: function (e) { - if (! this._focused) { return true; } + if (! this._focused) { return; } if (this._notify) { this._notify(e); } - var evt = (e ? e : window.event); - var pos = Util.getEventPosition(e, this._target, this._scale); + var pos = this._getMousePosition(e); if (this._onMouseMove) { this._onMouseMove(pos.x, pos.y); } Util.stopEvent(e); - return false; }, _handleMouseDisable: function (e) { - if (!this._focused) { return true; } + if (!this._focused) { return; } - var evt = (e ? e : window.event); - var pos = Util.getEventPosition(e, this._target, this._scale); - - /* Stop propagation if inside canvas area */ - if ((pos.realx >= 0) && (pos.realy >= 0) && - (pos.realx < this._target.offsetWidth) && - (pos.realy < this._target.offsetHeight)) { + /* + * Stop propagation if inside canvas area + * Note: This is only needed for the 'click' event as it fails + * to fire properly for the target element so we have + * to listen on the document element instead. + */ + if (e.target == this._target) { //Util.Debug("mouse event disabled"); Util.stopEvent(e); - return false; } + }, - return true; + // Return coordinates relative to target + _getMousePosition: function(e) { + e = Util.getPointerEvent(e); + var bounds = this._target.getBoundingClientRect(); + var x, y; + // Clip to target bounds + if (e.clientX < bounds.left) { + x = 0; + } else if (e.clientX >= bounds.right) { + x = bounds.width - 1; + } else { + x = e.clientX - bounds.left; + } + if (e.clientY < bounds.top) { + y = 0; + } else if (e.clientY >= bounds.bottom) { + y = bounds.height - 1; + } else { + y = e.clientY - bounds.top; + } + return {x:x, y:y}; }, @@ -332,46 +350,44 @@ var Keyboard, Mouse; grab: function () { var c = this._target; - if ('ontouchstart' in document.documentElement) { - Util.addEvent(c, 'touchstart', this._eventHandlers.mousedown); - Util.addEvent(window, 'touchend', this._eventHandlers.mouseup); - Util.addEvent(c, 'touchend', this._eventHandlers.mouseup); - Util.addEvent(c, 'touchmove', this._eventHandlers.mousemove); - } else { - Util.addEvent(c, 'mousedown', this._eventHandlers.mousedown); - Util.addEvent(window, 'mouseup', this._eventHandlers.mouseup); - Util.addEvent(c, 'mouseup', this._eventHandlers.mouseup); - Util.addEvent(c, 'mousemove', this._eventHandlers.mousemove); - Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', - this._eventHandlers.mousewheel); + if (Util.isTouchDevice) { + c.addEventListener('touchstart', this._eventHandlers.mousedown); + window.addEventListener('touchend', this._eventHandlers.mouseup); + c.addEventListener('touchend', this._eventHandlers.mouseup); + c.addEventListener('touchmove', this._eventHandlers.mousemove); } + c.addEventListener('mousedown', this._eventHandlers.mousedown); + window.addEventListener('mouseup', this._eventHandlers.mouseup); + c.addEventListener('mouseup', this._eventHandlers.mouseup); + c.addEventListener('mousemove', this._eventHandlers.mousemove); + c.addEventListener('wheel', this._eventHandlers.mousewheel); - /* Work around right and middle click browser behaviors */ - Util.addEvent(document, 'click', this._eventHandlers.mousedisable); - Util.addEvent(document.body, 'contextmenu', this._eventHandlers.mousedisable); + /* Prevent middle-click pasting (see above for why we bind to document) */ + document.addEventListener('click', this._eventHandlers.mousedisable); + + /* preventDefault() on mousedown doesn't stop this event for some + reason so we have to explicitly block it */ + c.addEventListener('contextmenu', this._eventHandlers.mousedisable); }, ungrab: function () { var c = this._target; - if ('ontouchstart' in document.documentElement) { - Util.removeEvent(c, 'touchstart', this._eventHandlers.mousedown); - Util.removeEvent(window, 'touchend', this._eventHandlers.mouseup); - Util.removeEvent(c, 'touchend', this._eventHandlers.mouseup); - Util.removeEvent(c, 'touchmove', this._eventHandlers.mousemove); - } else { - Util.removeEvent(c, 'mousedown', this._eventHandlers.mousedown); - Util.removeEvent(window, 'mouseup', this._eventHandlers.mouseup); - Util.removeEvent(c, 'mouseup', this._eventHandlers.mouseup); - Util.removeEvent(c, 'mousemove', this._eventHandlers.mousemove); - Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', - this._eventHandlers.mousewheel); + if (Util.isTouchDevice) { + c.removeEventListener('touchstart', this._eventHandlers.mousedown); + window.removeEventListener('touchend', this._eventHandlers.mouseup); + c.removeEventListener('touchend', this._eventHandlers.mouseup); + c.removeEventListener('touchmove', this._eventHandlers.mousemove); } + c.removeEventListener('mousedown', this._eventHandlers.mousedown); + window.removeEventListener('mouseup', this._eventHandlers.mouseup); + c.removeEventListener('mouseup', this._eventHandlers.mouseup); + c.removeEventListener('mousemove', this._eventHandlers.mousemove); + c.removeEventListener('wheel', this._eventHandlers.mousewheel); - /* Work around right and middle click browser behaviors */ - Util.removeEvent(document, 'click', this._eventHandlers.mousedisable); - Util.removeEvent(document.body, 'contextmenu', this._eventHandlers.mousedisable); + document.removeEventListener('click', this._eventHandlers.mousedisable); + c.removeEventListener('contextmenu', this._eventHandlers.mousedisable); } }; @@ -379,7 +395,6 @@ var Keyboard, Mouse; ['target', 'ro', 'dom'], // DOM element that captures mouse input ['notify', 'ro', 'func'], // Function to call to notify whenever a mouse event is received ['focused', 'rw', 'bool'], // Capture and send mouse clicks/movement - ['scale', 'rw', 'float'], // Viewport scale factor 0.0 - 1.0 ['onMouseButton', 'rw', 'func'], // Handler for mouse button click/release ['onMouseMove', 'rw', 'func'], // Handler for mouse movement diff --git a/noVNC/core/input/keysym.js b/noVNC/core/input/keysym.js new file mode 100644 index 0000000..5983c38 --- /dev/null +++ b/noVNC/core/input/keysym.js @@ -0,0 +1,382 @@ +var KeyTable = { + XK_VoidSymbol: 0xffffff, /* Void symbol */ + + XK_BackSpace: 0xff08, /* Back space, back char */ + XK_Tab: 0xff09, + XK_Linefeed: 0xff0a, /* Linefeed, LF */ + XK_Clear: 0xff0b, + XK_Return: 0xff0d, /* Return, enter */ + XK_Pause: 0xff13, /* Pause, hold */ + XK_Scroll_Lock: 0xff14, + XK_Sys_Req: 0xff15, + XK_Escape: 0xff1b, + XK_Delete: 0xffff, /* Delete, rubout */ + + /* Cursor control & motion */ + + XK_Home: 0xff50, + XK_Left: 0xff51, /* Move left, left arrow */ + XK_Up: 0xff52, /* Move up, up arrow */ + XK_Right: 0xff53, /* Move right, right arrow */ + XK_Down: 0xff54, /* Move down, down arrow */ + XK_Prior: 0xff55, /* Prior, previous */ + XK_Page_Up: 0xff55, + XK_Next: 0xff56, /* Next */ + XK_Page_Down: 0xff56, + XK_End: 0xff57, /* EOL */ + XK_Begin: 0xff58, /* BOL */ + + + /* Misc functions */ + + XK_Select: 0xff60, /* Select, mark */ + XK_Print: 0xff61, + XK_Execute: 0xff62, /* Execute, run, do */ + XK_Insert: 0xff63, /* Insert, insert here */ + XK_Undo: 0xff65, + XK_Redo: 0xff66, /* Redo, again */ + XK_Menu: 0xff67, + XK_Find: 0xff68, /* Find, search */ + XK_Cancel: 0xff69, /* Cancel, stop, abort, exit */ + XK_Help: 0xff6a, /* Help */ + XK_Break: 0xff6b, + XK_Mode_switch: 0xff7e, /* Character set switch */ + XK_script_switch: 0xff7e, /* Alias for mode_switch */ + XK_Num_Lock: 0xff7f, + + /* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ + + XK_KP_Space: 0xff80, /* Space */ + XK_KP_Tab: 0xff89, + XK_KP_Enter: 0xff8d, /* Enter */ + XK_KP_F1: 0xff91, /* PF1, KP_A, ... */ + XK_KP_F2: 0xff92, + XK_KP_F3: 0xff93, + XK_KP_F4: 0xff94, + XK_KP_Home: 0xff95, + XK_KP_Left: 0xff96, + XK_KP_Up: 0xff97, + XK_KP_Right: 0xff98, + XK_KP_Down: 0xff99, + XK_KP_Prior: 0xff9a, + XK_KP_Page_Up: 0xff9a, + XK_KP_Next: 0xff9b, + XK_KP_Page_Down: 0xff9b, + XK_KP_End: 0xff9c, + XK_KP_Begin: 0xff9d, + XK_KP_Insert: 0xff9e, + XK_KP_Delete: 0xff9f, + XK_KP_Equal: 0xffbd, /* Equals */ + XK_KP_Multiply: 0xffaa, + XK_KP_Add: 0xffab, + XK_KP_Separator: 0xffac, /* Separator, often comma */ + XK_KP_Subtract: 0xffad, + XK_KP_Decimal: 0xffae, + XK_KP_Divide: 0xffaf, + + XK_KP_0: 0xffb0, + XK_KP_1: 0xffb1, + XK_KP_2: 0xffb2, + XK_KP_3: 0xffb3, + XK_KP_4: 0xffb4, + XK_KP_5: 0xffb5, + XK_KP_6: 0xffb6, + XK_KP_7: 0xffb7, + XK_KP_8: 0xffb8, + XK_KP_9: 0xffb9, + + /* + * Auxiliary functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufacturers have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + + XK_F1: 0xffbe, + XK_F2: 0xffbf, + XK_F3: 0xffc0, + XK_F4: 0xffc1, + XK_F5: 0xffc2, + XK_F6: 0xffc3, + XK_F7: 0xffc4, + XK_F8: 0xffc5, + XK_F9: 0xffc6, + XK_F10: 0xffc7, + XK_F11: 0xffc8, + XK_L1: 0xffc8, + XK_F12: 0xffc9, + XK_L2: 0xffc9, + XK_F13: 0xffca, + XK_L3: 0xffca, + XK_F14: 0xffcb, + XK_L4: 0xffcb, + XK_F15: 0xffcc, + XK_L5: 0xffcc, + XK_F16: 0xffcd, + XK_L6: 0xffcd, + XK_F17: 0xffce, + XK_L7: 0xffce, + XK_F18: 0xffcf, + XK_L8: 0xffcf, + XK_F19: 0xffd0, + XK_L9: 0xffd0, + XK_F20: 0xffd1, + XK_L10: 0xffd1, + XK_F21: 0xffd2, + XK_R1: 0xffd2, + XK_F22: 0xffd3, + XK_R2: 0xffd3, + XK_F23: 0xffd4, + XK_R3: 0xffd4, + XK_F24: 0xffd5, + XK_R4: 0xffd5, + XK_F25: 0xffd6, + XK_R5: 0xffd6, + XK_F26: 0xffd7, + XK_R6: 0xffd7, + XK_F27: 0xffd8, + XK_R7: 0xffd8, + XK_F28: 0xffd9, + XK_R8: 0xffd9, + XK_F29: 0xffda, + XK_R9: 0xffda, + XK_F30: 0xffdb, + XK_R10: 0xffdb, + XK_F31: 0xffdc, + XK_R11: 0xffdc, + XK_F32: 0xffdd, + XK_R12: 0xffdd, + XK_F33: 0xffde, + XK_R13: 0xffde, + XK_F34: 0xffdf, + XK_R14: 0xffdf, + XK_F35: 0xffe0, + XK_R15: 0xffe0, + + /* Modifiers */ + + XK_Shift_L: 0xffe1, /* Left shift */ + XK_Shift_R: 0xffe2, /* Right shift */ + XK_Control_L: 0xffe3, /* Left control */ + XK_Control_R: 0xffe4, /* Right control */ + XK_Caps_Lock: 0xffe5, /* Caps lock */ + XK_Shift_Lock: 0xffe6, /* Shift lock */ + + XK_Meta_L: 0xffe7, /* Left meta */ + XK_Meta_R: 0xffe8, /* Right meta */ + XK_Alt_L: 0xffe9, /* Left alt */ + XK_Alt_R: 0xffea, /* Right alt */ + XK_Super_L: 0xffeb, /* Left super */ + XK_Super_R: 0xffec, /* Right super */ + XK_Hyper_L: 0xffed, /* Left hyper */ + XK_Hyper_R: 0xffee, /* Right hyper */ + + XK_ISO_Level3_Shift: 0xfe03, /* AltGr */ + + /* + * Latin 1 + * (ISO/IEC 8859-1: Unicode U+0020..U+00FF) + * Byte 3: 0 + */ + + XK_space: 0x0020, /* U+0020 SPACE */ + XK_exclam: 0x0021, /* U+0021 EXCLAMATION MARK */ + XK_quotedbl: 0x0022, /* U+0022 QUOTATION MARK */ + XK_numbersign: 0x0023, /* U+0023 NUMBER SIGN */ + XK_dollar: 0x0024, /* U+0024 DOLLAR SIGN */ + XK_percent: 0x0025, /* U+0025 PERCENT SIGN */ + XK_ampersand: 0x0026, /* U+0026 AMPERSAND */ + XK_apostrophe: 0x0027, /* U+0027 APOSTROPHE */ + XK_quoteright: 0x0027, /* deprecated */ + XK_parenleft: 0x0028, /* U+0028 LEFT PARENTHESIS */ + XK_parenright: 0x0029, /* U+0029 RIGHT PARENTHESIS */ + XK_asterisk: 0x002a, /* U+002A ASTERISK */ + XK_plus: 0x002b, /* U+002B PLUS SIGN */ + XK_comma: 0x002c, /* U+002C COMMA */ + XK_minus: 0x002d, /* U+002D HYPHEN-MINUS */ + XK_period: 0x002e, /* U+002E FULL STOP */ + XK_slash: 0x002f, /* U+002F SOLIDUS */ + XK_0: 0x0030, /* U+0030 DIGIT ZERO */ + XK_1: 0x0031, /* U+0031 DIGIT ONE */ + XK_2: 0x0032, /* U+0032 DIGIT TWO */ + XK_3: 0x0033, /* U+0033 DIGIT THREE */ + XK_4: 0x0034, /* U+0034 DIGIT FOUR */ + XK_5: 0x0035, /* U+0035 DIGIT FIVE */ + XK_6: 0x0036, /* U+0036 DIGIT SIX */ + XK_7: 0x0037, /* U+0037 DIGIT SEVEN */ + XK_8: 0x0038, /* U+0038 DIGIT EIGHT */ + XK_9: 0x0039, /* U+0039 DIGIT NINE */ + XK_colon: 0x003a, /* U+003A COLON */ + XK_semicolon: 0x003b, /* U+003B SEMICOLON */ + XK_less: 0x003c, /* U+003C LESS-THAN SIGN */ + XK_equal: 0x003d, /* U+003D EQUALS SIGN */ + XK_greater: 0x003e, /* U+003E GREATER-THAN SIGN */ + XK_question: 0x003f, /* U+003F QUESTION MARK */ + XK_at: 0x0040, /* U+0040 COMMERCIAL AT */ + XK_A: 0x0041, /* U+0041 LATIN CAPITAL LETTER A */ + XK_B: 0x0042, /* U+0042 LATIN CAPITAL LETTER B */ + XK_C: 0x0043, /* U+0043 LATIN CAPITAL LETTER C */ + XK_D: 0x0044, /* U+0044 LATIN CAPITAL LETTER D */ + XK_E: 0x0045, /* U+0045 LATIN CAPITAL LETTER E */ + XK_F: 0x0046, /* U+0046 LATIN CAPITAL LETTER F */ + XK_G: 0x0047, /* U+0047 LATIN CAPITAL LETTER G */ + XK_H: 0x0048, /* U+0048 LATIN CAPITAL LETTER H */ + XK_I: 0x0049, /* U+0049 LATIN CAPITAL LETTER I */ + XK_J: 0x004a, /* U+004A LATIN CAPITAL LETTER J */ + XK_K: 0x004b, /* U+004B LATIN CAPITAL LETTER K */ + XK_L: 0x004c, /* U+004C LATIN CAPITAL LETTER L */ + XK_M: 0x004d, /* U+004D LATIN CAPITAL LETTER M */ + XK_N: 0x004e, /* U+004E LATIN CAPITAL LETTER N */ + XK_O: 0x004f, /* U+004F LATIN CAPITAL LETTER O */ + XK_P: 0x0050, /* U+0050 LATIN CAPITAL LETTER P */ + XK_Q: 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */ + XK_R: 0x0052, /* U+0052 LATIN CAPITAL LETTER R */ + XK_S: 0x0053, /* U+0053 LATIN CAPITAL LETTER S */ + XK_T: 0x0054, /* U+0054 LATIN CAPITAL LETTER T */ + XK_U: 0x0055, /* U+0055 LATIN CAPITAL LETTER U */ + XK_V: 0x0056, /* U+0056 LATIN CAPITAL LETTER V */ + XK_W: 0x0057, /* U+0057 LATIN CAPITAL LETTER W */ + XK_X: 0x0058, /* U+0058 LATIN CAPITAL LETTER X */ + XK_Y: 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */ + XK_Z: 0x005a, /* U+005A LATIN CAPITAL LETTER Z */ + XK_bracketleft: 0x005b, /* U+005B LEFT SQUARE BRACKET */ + XK_backslash: 0x005c, /* U+005C REVERSE SOLIDUS */ + XK_bracketright: 0x005d, /* U+005D RIGHT SQUARE BRACKET */ + XK_asciicircum: 0x005e, /* U+005E CIRCUMFLEX ACCENT */ + XK_underscore: 0x005f, /* U+005F LOW LINE */ + XK_grave: 0x0060, /* U+0060 GRAVE ACCENT */ + XK_quoteleft: 0x0060, /* deprecated */ + XK_a: 0x0061, /* U+0061 LATIN SMALL LETTER A */ + XK_b: 0x0062, /* U+0062 LATIN SMALL LETTER B */ + XK_c: 0x0063, /* U+0063 LATIN SMALL LETTER C */ + XK_d: 0x0064, /* U+0064 LATIN SMALL LETTER D */ + XK_e: 0x0065, /* U+0065 LATIN SMALL LETTER E */ + XK_f: 0x0066, /* U+0066 LATIN SMALL LETTER F */ + XK_g: 0x0067, /* U+0067 LATIN SMALL LETTER G */ + XK_h: 0x0068, /* U+0068 LATIN SMALL LETTER H */ + XK_i: 0x0069, /* U+0069 LATIN SMALL LETTER I */ + XK_j: 0x006a, /* U+006A LATIN SMALL LETTER J */ + XK_k: 0x006b, /* U+006B LATIN SMALL LETTER K */ + XK_l: 0x006c, /* U+006C LATIN SMALL LETTER L */ + XK_m: 0x006d, /* U+006D LATIN SMALL LETTER M */ + XK_n: 0x006e, /* U+006E LATIN SMALL LETTER N */ + XK_o: 0x006f, /* U+006F LATIN SMALL LETTER O */ + XK_p: 0x0070, /* U+0070 LATIN SMALL LETTER P */ + XK_q: 0x0071, /* U+0071 LATIN SMALL LETTER Q */ + XK_r: 0x0072, /* U+0072 LATIN SMALL LETTER R */ + XK_s: 0x0073, /* U+0073 LATIN SMALL LETTER S */ + XK_t: 0x0074, /* U+0074 LATIN SMALL LETTER T */ + XK_u: 0x0075, /* U+0075 LATIN SMALL LETTER U */ + XK_v: 0x0076, /* U+0076 LATIN SMALL LETTER V */ + XK_w: 0x0077, /* U+0077 LATIN SMALL LETTER W */ + XK_x: 0x0078, /* U+0078 LATIN SMALL LETTER X */ + XK_y: 0x0079, /* U+0079 LATIN SMALL LETTER Y */ + XK_z: 0x007a, /* U+007A LATIN SMALL LETTER Z */ + XK_braceleft: 0x007b, /* U+007B LEFT CURLY BRACKET */ + XK_bar: 0x007c, /* U+007C VERTICAL LINE */ + XK_braceright: 0x007d, /* U+007D RIGHT CURLY BRACKET */ + XK_asciitilde: 0x007e, /* U+007E TILDE */ + + XK_nobreakspace: 0x00a0, /* U+00A0 NO-BREAK SPACE */ + XK_exclamdown: 0x00a1, /* U+00A1 INVERTED EXCLAMATION MARK */ + XK_cent: 0x00a2, /* U+00A2 CENT SIGN */ + XK_sterling: 0x00a3, /* U+00A3 POUND SIGN */ + XK_currency: 0x00a4, /* U+00A4 CURRENCY SIGN */ + XK_yen: 0x00a5, /* U+00A5 YEN SIGN */ + XK_brokenbar: 0x00a6, /* U+00A6 BROKEN BAR */ + XK_section: 0x00a7, /* U+00A7 SECTION SIGN */ + XK_diaeresis: 0x00a8, /* U+00A8 DIAERESIS */ + XK_copyright: 0x00a9, /* U+00A9 COPYRIGHT SIGN */ + XK_ordfeminine: 0x00aa, /* U+00AA FEMININE ORDINAL INDICATOR */ + XK_guillemotleft: 0x00ab, /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ + XK_notsign: 0x00ac, /* U+00AC NOT SIGN */ + XK_hyphen: 0x00ad, /* U+00AD SOFT HYPHEN */ + XK_registered: 0x00ae, /* U+00AE REGISTERED SIGN */ + XK_macron: 0x00af, /* U+00AF MACRON */ + XK_degree: 0x00b0, /* U+00B0 DEGREE SIGN */ + XK_plusminus: 0x00b1, /* U+00B1 PLUS-MINUS SIGN */ + XK_twosuperior: 0x00b2, /* U+00B2 SUPERSCRIPT TWO */ + XK_threesuperior: 0x00b3, /* U+00B3 SUPERSCRIPT THREE */ + XK_acute: 0x00b4, /* U+00B4 ACUTE ACCENT */ + XK_mu: 0x00b5, /* U+00B5 MICRO SIGN */ + XK_paragraph: 0x00b6, /* U+00B6 PILCROW SIGN */ + XK_periodcentered: 0x00b7, /* U+00B7 MIDDLE DOT */ + XK_cedilla: 0x00b8, /* U+00B8 CEDILLA */ + XK_onesuperior: 0x00b9, /* U+00B9 SUPERSCRIPT ONE */ + XK_masculine: 0x00ba, /* U+00BA MASCULINE ORDINAL INDICATOR */ + XK_guillemotright: 0x00bb, /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ + XK_onequarter: 0x00bc, /* U+00BC VULGAR FRACTION ONE QUARTER */ + XK_onehalf: 0x00bd, /* U+00BD VULGAR FRACTION ONE HALF */ + XK_threequarters: 0x00be, /* U+00BE VULGAR FRACTION THREE QUARTERS */ + XK_questiondown: 0x00bf, /* U+00BF INVERTED QUESTION MARK */ + XK_Agrave: 0x00c0, /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ + XK_Aacute: 0x00c1, /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ + XK_Acircumflex: 0x00c2, /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ + XK_Atilde: 0x00c3, /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ + XK_Adiaeresis: 0x00c4, /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ + XK_Aring: 0x00c5, /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ + XK_AE: 0x00c6, /* U+00C6 LATIN CAPITAL LETTER AE */ + XK_Ccedilla: 0x00c7, /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ + XK_Egrave: 0x00c8, /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ + XK_Eacute: 0x00c9, /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ + XK_Ecircumflex: 0x00ca, /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ + XK_Ediaeresis: 0x00cb, /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ + XK_Igrave: 0x00cc, /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ + XK_Iacute: 0x00cd, /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ + XK_Icircumflex: 0x00ce, /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ + XK_Idiaeresis: 0x00cf, /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ + XK_ETH: 0x00d0, /* U+00D0 LATIN CAPITAL LETTER ETH */ + XK_Eth: 0x00d0, /* deprecated */ + XK_Ntilde: 0x00d1, /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ + XK_Ograve: 0x00d2, /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ + XK_Oacute: 0x00d3, /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ + XK_Ocircumflex: 0x00d4, /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ + XK_Otilde: 0x00d5, /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ + XK_Odiaeresis: 0x00d6, /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ + XK_multiply: 0x00d7, /* U+00D7 MULTIPLICATION SIGN */ + XK_Oslash: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ + XK_Ooblique: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ + XK_Ugrave: 0x00d9, /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ + XK_Uacute: 0x00da, /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ + XK_Ucircumflex: 0x00db, /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ + XK_Udiaeresis: 0x00dc, /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ + XK_Yacute: 0x00dd, /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ + XK_THORN: 0x00de, /* U+00DE LATIN CAPITAL LETTER THORN */ + XK_Thorn: 0x00de, /* deprecated */ + XK_ssharp: 0x00df, /* U+00DF LATIN SMALL LETTER SHARP S */ + XK_agrave: 0x00e0, /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ + XK_aacute: 0x00e1, /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ + XK_acircumflex: 0x00e2, /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ + XK_atilde: 0x00e3, /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ + XK_adiaeresis: 0x00e4, /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ + XK_aring: 0x00e5, /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ + XK_ae: 0x00e6, /* U+00E6 LATIN SMALL LETTER AE */ + XK_ccedilla: 0x00e7, /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ + XK_egrave: 0x00e8, /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ + XK_eacute: 0x00e9, /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ + XK_ecircumflex: 0x00ea, /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ + XK_ediaeresis: 0x00eb, /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ + XK_igrave: 0x00ec, /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ + XK_iacute: 0x00ed, /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ + XK_icircumflex: 0x00ee, /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ + XK_idiaeresis: 0x00ef, /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ + XK_eth: 0x00f0, /* U+00F0 LATIN SMALL LETTER ETH */ + XK_ntilde: 0x00f1, /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ + XK_ograve: 0x00f2, /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ + XK_oacute: 0x00f3, /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ + XK_ocircumflex: 0x00f4, /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ + XK_otilde: 0x00f5, /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ + XK_odiaeresis: 0x00f6, /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ + XK_division: 0x00f7, /* U+00F7 DIVISION SIGN */ + XK_oslash: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ + XK_ooblique: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ + XK_ugrave: 0x00f9, /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ + XK_uacute: 0x00fa, /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ + XK_ucircumflex: 0x00fb, /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ + XK_udiaeresis: 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ + XK_yacute: 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ + XK_thorn: 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */ + XK_ydiaeresis: 0x00ff, /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ +}; + +/* [module] export default KeyTable; */ diff --git a/noVNC/include/keysymdef.js b/noVNC/core/input/keysymdef.js similarity index 98% rename from noVNC/include/keysymdef.js rename to noVNC/core/input/keysymdef.js index f94445c..c4d0ace 100644 --- a/noVNC/include/keysymdef.js +++ b/noVNC/core/input/keysymdef.js @@ -2,6 +2,7 @@ // (and optionally, key names) expected by the RFB protocol // How this file was generated: // node /Users/jalf/dev/mi/novnc/utils/parse.js /opt/X11/include/X11/keysymdef.h + var keysyms = (function(){ "use strict"; var keynames = null; @@ -9,7 +10,15 @@ var keysyms = (function(){ function lookup(k) { return k ? {keysym: k, keyname: keynames ? keynames[k] : k} : undefined; } return { - fromUnicode : function(u) { return lookup(codepoints[u]); }, + fromUnicode : function(u) { + var keysym = codepoints[u]; + if (keysym === undefined) { + keysym = 0x01000000 | u; + } + return lookup(keysym); + }, lookup : lookup }; })(); + +/* [module] export default keysyms */ diff --git a/noVNC/include/keyboard.js b/noVNC/core/input/util.js similarity index 66% rename from noVNC/include/keyboard.js rename to noVNC/core/input/util.js index 8667031..52b3128 100644 --- a/noVNC/include/keyboard.js +++ b/noVNC/core/input/util.js @@ -1,4 +1,11 @@ -var kbdUtil = (function() { +/* [module] + * import KeyTable from "./keysym"; + * import keysyms from "./keysymdef"; + */ + +var KeyboardUtil = {}; + +(function() { "use strict"; function substituteCodepoint(cp) { @@ -31,7 +38,7 @@ var kbdUtil = (function() { function hasShortcutModifier(charModifier, currentModifiers) { var mods = {}; for (var key in currentModifiers) { - if (parseInt(key) !== XK_Shift_L) { + if (parseInt(key) !== KeyTable.XK_Shift_L) { mods[key] = currentModifiers[key]; } } @@ -68,15 +75,15 @@ var kbdUtil = (function() { if (!charModifier) { if (isMac()) { // on Mac, Option (AKA Alt) is used as a char modifier - charModifier = [XK_Alt_L]; + charModifier = [KeyTable.XK_Alt_L]; } else if (isWindows()) { // on Windows, Ctrl+Alt is used as a char modifier - charModifier = [XK_Alt_L, XK_Control_L]; + charModifier = [KeyTable.XK_Alt_L, KeyTable.XK_Control_L]; } else if (isLinux()) { // on Linux, ISO Level 3 Shift (AltGr) is used as a char modifier - charModifier = [XK_ISO_Level3_Shift]; + charModifier = [KeyTable.XK_ISO_Level3_Shift]; } else { charModifier = []; @@ -84,11 +91,11 @@ var kbdUtil = (function() { } var state = {}; - state[XK_Control_L] = false; - state[XK_Alt_L] = false; - state[XK_ISO_Level3_Shift] = false; - state[XK_Shift_L] = false; - state[XK_Meta_L] = false; + state[KeyTable.XK_Control_L] = false; + state[KeyTable.XK_Alt_L] = false; + state[KeyTable.XK_ISO_Level3_Shift] = false; + state[KeyTable.XK_Shift_L] = false; + state[KeyTable.XK_Meta_L] = false; function sync(evt, keysym) { var result = []; @@ -97,29 +104,29 @@ var kbdUtil = (function() { } if (evt.ctrlKey !== undefined && - evt.ctrlKey !== state[XK_Control_L] && keysym !== XK_Control_L) { - state[XK_Control_L] = evt.ctrlKey; - result.push(syncKey(XK_Control_L)); + evt.ctrlKey !== state[KeyTable.XK_Control_L] && keysym !== KeyTable.XK_Control_L) { + state[KeyTable.XK_Control_L] = evt.ctrlKey; + result.push(syncKey(KeyTable.XK_Control_L)); } if (evt.altKey !== undefined && - evt.altKey !== state[XK_Alt_L] && keysym !== XK_Alt_L) { - state[XK_Alt_L] = evt.altKey; - result.push(syncKey(XK_Alt_L)); + evt.altKey !== state[KeyTable.XK_Alt_L] && keysym !== KeyTable.XK_Alt_L) { + state[KeyTable.XK_Alt_L] = evt.altKey; + result.push(syncKey(KeyTable.XK_Alt_L)); } if (evt.altGraphKey !== undefined && - evt.altGraphKey !== state[XK_ISO_Level3_Shift] && keysym !== XK_ISO_Level3_Shift) { - state[XK_ISO_Level3_Shift] = evt.altGraphKey; - result.push(syncKey(XK_ISO_Level3_Shift)); + evt.altGraphKey !== state[KeyTable.XK_ISO_Level3_Shift] && keysym !== KeyTable.XK_ISO_Level3_Shift) { + state[KeyTable.XK_ISO_Level3_Shift] = evt.altGraphKey; + result.push(syncKey(KeyTable.XK_ISO_Level3_Shift)); } if (evt.shiftKey !== undefined && - evt.shiftKey !== state[XK_Shift_L] && keysym !== XK_Shift_L) { - state[XK_Shift_L] = evt.shiftKey; - result.push(syncKey(XK_Shift_L)); + evt.shiftKey !== state[KeyTable.XK_Shift_L] && keysym !== KeyTable.XK_Shift_L) { + state[KeyTable.XK_Shift_L] = evt.shiftKey; + result.push(syncKey(KeyTable.XK_Shift_L)); } if (evt.metaKey !== undefined && - evt.metaKey !== state[XK_Meta_L] && keysym !== XK_Meta_L) { - state[XK_Meta_L] = evt.metaKey; - result.push(syncKey(XK_Meta_L)); + evt.metaKey !== state[KeyTable.XK_Meta_L] && keysym !== KeyTable.XK_Meta_L) { + state[KeyTable.XK_Meta_L] = evt.metaKey; + result.push(syncKey(KeyTable.XK_Meta_L)); } return result; } @@ -177,10 +184,7 @@ var kbdUtil = (function() { codepoint = evt.keyCode; } if (codepoint) { - var res = keysyms.fromUnicode(substituteCodepoint(codepoint)); - if (res) { - return res; - } + return keysyms.fromUnicode(substituteCodepoint(codepoint)); } // we could check evt.key here. // Legal values are defined in http://www.w3.org/TR/DOM-Level-3-Events/#key-values-list, @@ -210,21 +214,21 @@ var kbdUtil = (function() { return shiftPressed ? keycode : keycode + 32; // A-Z } if (keycode >= 0x60 && keycode <= 0x69) { - return XK_KP_0 + (keycode - 0x60); // numpad 0-9 + return KeyTable.XK_KP_0 + (keycode - 0x60); // numpad 0-9 } switch(keycode) { - case 0x20: return XK_space; - case 0x6a: return XK_KP_Multiply; - case 0x6b: return XK_KP_Add; - case 0x6c: return XK_KP_Separator; - case 0x6d: return XK_KP_Subtract; - case 0x6e: return XK_KP_Decimal; - case 0x6f: return XK_KP_Divide; - case 0xbb: return XK_plus; - case 0xbc: return XK_comma; - case 0xbd: return XK_minus; - case 0xbe: return XK_period; + case 0x20: return KeyTable.XK_space; + case 0x6a: return KeyTable.XK_KP_Multiply; + case 0x6b: return KeyTable.XK_KP_Add; + case 0x6c: return KeyTable.XK_KP_Separator; + case 0x6d: return KeyTable.XK_KP_Subtract; + case 0x6e: return KeyTable.XK_KP_Decimal; + case 0x6f: return KeyTable.XK_KP_Divide; + case 0xbb: return KeyTable.XK_plus; + case 0xbc: return KeyTable.XK_comma; + case 0xbd: return KeyTable.XK_minus; + case 0xbe: return KeyTable.XK_period; } return nonCharacterKey({keyCode: keycode}); @@ -238,53 +242,183 @@ var kbdUtil = (function() { var keycode = evt.keyCode; if (keycode >= 0x70 && keycode <= 0x87) { - return XK_F1 + keycode - 0x70; // F1-F24 + return KeyTable.XK_F1 + keycode - 0x70; // F1-F24 } switch (keycode) { - case 8 : return XK_BackSpace; - case 13 : return XK_Return; + case 8 : return KeyTable.XK_BackSpace; + case 13 : return KeyTable.XK_Return; - case 9 : return XK_Tab; + case 9 : return KeyTable.XK_Tab; - case 27 : return XK_Escape; - case 46 : return XK_Delete; + case 27 : return KeyTable.XK_Escape; + case 46 : return KeyTable.XK_Delete; - case 36 : return XK_Home; - case 35 : return XK_End; - case 33 : return XK_Page_Up; - case 34 : return XK_Page_Down; - case 45 : return XK_Insert; + case 36 : return KeyTable.XK_Home; + case 35 : return KeyTable.XK_End; + case 33 : return KeyTable.XK_Page_Up; + case 34 : return KeyTable.XK_Page_Down; + case 45 : return KeyTable.XK_Insert; - case 37 : return XK_Left; - case 38 : return XK_Up; - case 39 : return XK_Right; - case 40 : return XK_Down; + case 37 : return KeyTable.XK_Left; + case 38 : return KeyTable.XK_Up; + case 39 : return KeyTable.XK_Right; + case 40 : return KeyTable.XK_Down; - case 16 : return XK_Shift_L; - case 17 : return XK_Control_L; - case 18 : return XK_Alt_L; // also: Option-key on Mac + case 16 : return KeyTable.XK_Shift_L; + case 17 : return KeyTable.XK_Control_L; + case 18 : return KeyTable.XK_Alt_L; // also: Option-key on Mac - case 224 : return XK_Meta_L; - case 225 : return XK_ISO_Level3_Shift; // AltGr - case 91 : return XK_Super_L; // also: Windows-key - case 92 : return XK_Super_R; // also: Windows-key - case 93 : return XK_Menu; // also: Windows-Menu, Command on Mac + case 224 : return KeyTable.XK_Meta_L; + case 225 : return KeyTable.XK_ISO_Level3_Shift; // AltGr + case 91 : return KeyTable.XK_Super_L; // also: Windows-key + case 92 : return KeyTable.XK_Super_R; // also: Windows-key + case 93 : return KeyTable.XK_Menu; // also: Windows-Menu, Command on Mac default: return null; } } - return { - hasShortcutModifier : hasShortcutModifier, - hasCharModifier : hasCharModifier, - ModifierSync : ModifierSync, - getKey : getKey, - getKeysym : getKeysym, - keysymFromKeyCode : keysymFromKeyCode, - nonCharacterKey : nonCharacterKey, - substituteCodepoint : substituteCodepoint - }; + + KeyboardUtil.hasShortcutModifier = hasShortcutModifier; + KeyboardUtil.hasCharModifier = hasCharModifier; + KeyboardUtil.ModifierSync = ModifierSync; + KeyboardUtil.getKey = getKey; + KeyboardUtil.getKeysym = getKeysym; + KeyboardUtil.keysymFromKeyCode = keysymFromKeyCode; + KeyboardUtil.nonCharacterKey = nonCharacterKey; + KeyboardUtil.substituteCodepoint = substituteCodepoint; })(); +KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) { + "use strict"; + + function sendAll(evts) { + for (var i = 0; i < evts.length; ++i) { + next(evts[i]); + } + } + + var numPadCodes = ["Numpad0", "Numpad1", "Numpad2", + "Numpad3", "Numpad4", "Numpad5", "Numpad6", + "Numpad7", "Numpad8", "Numpad9", "NumpadDecimal"]; + + var numLockOnKeySyms = { + "Numpad0": 0xffb0, "Numpad1": 0xffb1, "Numpad2": 0xffb2, + "Numpad3": 0xffb3, "Numpad4": 0xffb4, "Numpad5": 0xffb5, + "Numpad6": 0xffb6, "Numpad7": 0xffb7, "Numpad8": 0xffb8, + "Numpad9": 0xffb9, "NumpadDecimal": 0xffac + }; + + var numLockOnKeyCodes = [96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 108, 110]; + + function isNumPadMultiKey(evt) { + return (numPadCodes.indexOf(evt.code) !== -1); + } + + function getNumPadKeySym(evt) { + if (numLockOnKeyCodes.indexOf(evt.keyCode) !== -1) { + return numLockOnKeySyms[evt.code]; + } + return 0; + } + + function process(evt, type) { + var result = {type: type}; + result.code = evt.code; + result.keysym = 0; + + if (isNumPadMultiKey(evt)) { + result.keysym = getNumPadKeySym(evt); + } + + var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier(); + var isShift = evt.keyCode === 0x10 || evt.key === 'Shift'; + + var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!KeyboardUtil.nonCharacterKey(evt)); + + next(result); + return suppress; + } + return { + keydown: function(evt) { + sendAll(modifierState.keydown(evt)); + return process(evt, 'keydown'); + }, + keypress: function(evt) { + return true; + }, + keyup: function(evt) { + sendAll(modifierState.keyup(evt)); + return process(evt, 'keyup'); + }, + syncModifiers: function(evt) { + sendAll(modifierState.syncAny(evt)); + }, + releaseAll: function() { next({type: 'releaseall'}); } + }; +}; + +KeyboardUtil.TrackQEMUKeyState = function(next) { + "use strict"; + var state = []; + + return function (evt) { + var last = state.length !== 0 ? state[state.length-1] : null; + + switch (evt.type) { + case 'keydown': + + if (!last || last.code !== evt.code) { + last = {code: evt.code}; + + if (state.length > 0 && state[state.length-1].code == 'ControlLeft') { + if (evt.code !== 'AltRight') { + next({code: 'ControlLeft', type: 'keydown', keysym: 0}); + } else { + state.pop(); + } + } + state.push(last); + } + if (evt.code !== 'ControlLeft') { + next(evt); + } + break; + + case 'keyup': + if (state.length === 0) { + return; + } + var idx = null; + // do we have a matching key tracked as being down? + for (var i = 0; i !== state.length; ++i) { + if (state[i].code === evt.code) { + idx = i; + break; + } + } + // if we couldn't find a match (it happens), assume it was the last key pressed + if (idx === null) { + if (evt.code === 'ControlLeft') { + return; + } + idx = state.length - 1; + } + + state.splice(idx, 1); + next(evt); + break; + case 'releaseall': + /* jshint shadow: true */ + for (var i = 0; i < state.length; ++i) { + next({code: state[i].code, keysym: 0, type: 'keyup'}); + } + /* jshint shadow: false */ + state = []; + } + }; +}; + // Takes a DOM keyboard event and: // - determines which keysym it represents // - determines a keyId identifying the key that was pressed (corresponding to the key/keyCode properties on the DOM event) @@ -292,7 +426,7 @@ var kbdUtil = (function() { // - marks each event with an 'escape' property if a modifier was down which should be "escaped" // - generates a "stall" event in cases where it might be necessary to wait and see if a keypress event follows a keydown // This information is collected into an object which is passed to the next() function. (one call per event) -function KeyEventDecoder(modifierState, next) { +KeyboardUtil.KeyEventDecoder = function(modifierState, next) { "use strict"; function sendAll(evts) { for (var i = 0; i < evts.length; ++i) { @@ -301,18 +435,18 @@ function KeyEventDecoder(modifierState, next) { } function process(evt, type) { var result = {type: type}; - var keyId = kbdUtil.getKey(evt); + var keyId = KeyboardUtil.getKey(evt); if (keyId) { result.keyId = keyId; } - var keysym = kbdUtil.getKeysym(evt); + var keysym = KeyboardUtil.getKeysym(evt); var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier(); // Is this a case where we have to decide on the keysym right away, rather than waiting for the keypress? // "special" keys like enter, tab or backspace don't send keypress events, // and some browsers don't send keypresses at all if a modifier is down - if (keysym && (type !== 'keydown' || kbdUtil.nonCharacterKey(evt) || hasModifier)) { + if (keysym && (type !== 'keydown' || KeyboardUtil.nonCharacterKey(evt) || hasModifier)) { result.keysym = keysym; } @@ -321,11 +455,11 @@ function KeyEventDecoder(modifierState, next) { // Should we prevent the browser from handling the event? // Doing so on a keydown (in most browsers) prevents keypress from being generated // so only do that if we have to. - var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!kbdUtil.nonCharacterKey(evt)); + var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!KeyboardUtil.nonCharacterKey(evt)); // If a char modifier is down on a keydown, we need to insert a stall, // so VerifyCharModifier knows to wait and see if a keypress is comnig - var stall = type === 'keydown' && modifierState.activeCharModifier() && !kbdUtil.nonCharacterKey(evt); + var stall = type === 'keydown' && modifierState.activeCharModifier() && !KeyboardUtil.nonCharacterKey(evt); // if a char modifier is pressed, get the keys it consists of (on Windows, AltGr is equivalent to Ctrl+Alt) var active = modifierState.activeCharModifier(); @@ -371,7 +505,7 @@ function KeyEventDecoder(modifierState, next) { }, releaseAll: function() { next({type: 'releaseall'}); } }; -} +}; // Combines keydown and keypress events where necessary to handle char modifiers. // On some OS'es, a char modifier is sometimes used as a shortcut modifier. @@ -379,7 +513,7 @@ function KeyEventDecoder(modifierState, next) { // so when used with the '2' key, Ctrl-Alt counts as a char modifier (and should be escaped), but when used with 'D', it does not. // The only way we can distinguish these cases is to wait and see if a keypress event arrives // When we receive a "stall" event, wait a few ms before processing the next keydown. If a keypress has also arrived, merge the two -function VerifyCharModifier(next) { +KeyboardUtil.VerifyCharModifier = function(next) { "use strict"; var queue = []; var timer = null; @@ -429,14 +563,14 @@ function VerifyCharModifier(next) { queue.push(evt); process(); }; -} +}; // Keeps track of which keys we (and the server) believe are down // When a keyup is received, match it against this list, to determine the corresponding keysym(s) // in some cases, a single key may produce multiple keysyms, so the corresponding keyup event must release all of these chars // key repeat events should be merged into a single entry. // Because we can't always identify which entry a keydown or keyup event corresponds to, we sometimes have to guess -function TrackKeyState(next) { +KeyboardUtil.TrackKeyState = function(next) { "use strict"; var state = []; @@ -516,11 +650,11 @@ function TrackKeyState(next) { state = []; } }; -} +}; // Handles "escaping" of modifiers: if a char modifier is used to produce a keysym (such as AltGr-2 to generate an @), // then the modifier must be "undone" before sending the @, and "redone" afterwards. -function EscapeModifiers(next) { +KeyboardUtil.EscapeModifiers = function(next) { "use strict"; return function(evt) { if (evt.type !== 'keydown' || evt.escape === undefined) { @@ -540,4 +674,6 @@ function EscapeModifiers(next) { } /* jshint shadow: false */ }; -} +}; + +/* [module] export default KeyboardUtil; */ diff --git a/noVNC/core/input/xtscancodes.js b/noVNC/core/input/xtscancodes.js new file mode 100644 index 0000000..542bcf7 --- /dev/null +++ b/noVNC/core/input/xtscancodes.js @@ -0,0 +1,151 @@ +var XtScancode = { + "Escape": 0x0001, + "Digit1": 0x0002, + "Digit2": 0x0003, + "Digit3": 0x0004, + "Digit4": 0x0005, + "Digit5": 0x0006, + "Digit6": 0x0007, + "Digit7": 0x0008, + "Digit8": 0x0009, + "Digit9": 0x000A, + "Digit0": 0x000B, + "Minus": 0x000C, + "Equal": 0x000D, + "Backspace": 0x000E, + "Tab": 0x000F, + "KeyQ": 0x0010, + "KeyW": 0x0011, + "KeyE": 0x0012, + "KeyR": 0x0013, + "KeyT": 0x0014, + "KeyY": 0x0015, + "KeyU": 0x0016, + "KeyI": 0x0017, + "KeyO": 0x0018, + "KeyP": 0x0019, + "BracketLeft": 0x001A, + "BracketRight": 0x001B, + "Enter": 0x001C, + "ControlLeft": 0x001D, + "KeyA": 0x001E, + "KeyS": 0x001F, + "KeyD": 0x0020, + "KeyF": 0x0021, + "KeyG": 0x0022, + "KeyH": 0x0023, + "KeyJ": 0x0024, + "KeyK": 0x0025, + "KeyL": 0x0026, + "Semicolon": 0x0027, + "Quote": 0x0028, + "Backquote": 0x0029, + "ShiftLeft": 0x002A, + "Backslash": 0x002B, + "KeyZ": 0x002C, + "KeyX": 0x002D, + "KeyC": 0x002E, + "KeyV": 0x002F, + "KeyB": 0x0030, + "KeyN": 0x0031, + "KeyM": 0x0032, + "Comma": 0x0033, + "Period": 0x0034, + "Slash": 0x0035, + "ShiftRight": 0x0036, + "NumpadMultiply": 0x0037, + "AltLeft": 0x0038, + "Space": 0x0039, + "CapsLock": 0x003A, + "F1": 0x003B, + "F2": 0x003C, + "F3": 0x003D, + "F4": 0x003E, + "F5": 0x003F, + "F6": 0x0040, + "F7": 0x0041, + "F8": 0x0042, + "F9": 0x0043, + "F10": 0x0044, + "Pause": 0xE045, + "ScrollLock": 0x0046, + "Numpad7": 0x0047, + "Numpad8": 0x0048, + "Numpad9": 0x0049, + "NumpadSubtract": 0x004A, + "Numpad4": 0x004B, + "Numpad5": 0x004C, + "Numpad6": 0x004D, + "NumpadAdd": 0x004E, + "Numpad1": 0x004F, + "Numpad2": 0x0050, + "Numpad3": 0x0051, + "Numpad0": 0x0052, + "NumpadDecimal": 0x0053, + "IntlBackslash": 0x0056, + "F11": 0x0057, + "F12": 0x0058, + "IntlYen": 0x007D, + "MediaTrackPrevious": 0xE010, + "MediaTrackNext": 0xE019, + "NumpadEnter": 0xE01C, + "ControlRight": 0xE01D, + "VolumeMute": 0xE020, + "MediaPlayPause": 0xE022, + "MediaStop": 0xE024, + "VolumeDown": 0xE02E, + "VolumeUp": 0xE030, + "BrowserHome": 0xE032, + "NumpadDivide": 0xE035, + "PrintScreen": 0xE037, + "AltRight": 0xE038, + "NumLock": 0x0045, + "Home": 0xE047, + "ArrowUp": 0xE048, + "PageUp": 0xE049, + "ArrowLeft": 0xE04B, + "ArrowRight": 0xE04D, + "End": 0xE04F, + "ArrowDown": 0xE050, + "PageDown": 0xE051, + "Insert": 0xE052, + "Delete": 0xE053, + "MetaLeft": 0xE05B, + "MetaRight": 0xE05C, + "OSLeft": 0xE05B, // OSLeft and OSRight are kept for compatability since + "OSRight": 0xE05C, // Firefox haven't updated to MetaLeft and MetaRight yet + "ContextMenu": 0xE05D, + "BrowserSearch": 0xE065, + "BrowserFavorites": 0xE066, + "BrowserRefresh": 0xE067, + "BrowserStop": 0xE068, + "BrowserForward": 0xE069, + "BrowserBack": 0xE06A, + "NumpadComma": 0x007E, + "NumpadEqual": 0x0059, + "F13": 0x0064, + "F14": 0x0065, + "F15": 0x0066, + "F16": 0x0067, + "F17": 0x0068, + "F18": 0x0069, + "F19": 0x006A, + "F20": 0x006B, + "F21": 0x006C, + "F22": 0x006D, + "F23": 0x006E, + "F24": 0x0076, + "KanaMode": 0x0070, + "Lang2": 0x0071, + "Lang1": 0x0072, + "IntlRo": 0x0073, + "Convert": 0x0079, + "NonConvert": 0x007B, + "LaunchApp2": 0xE021, + "Power": 0xE05E, + "LaunchApp1": 0xE06B, + "LaunchMail": 0xE06C, + "MediaSelect": 0xE06D, +}; + +/* [module] export default XtScancode */ diff --git a/noVNC/include/rfb.js b/noVNC/core/rfb.js similarity index 51% rename from noVNC/include/rfb.js rename to noVNC/core/rfb.js index e030b09..baf5f3c 100644 --- a/noVNC/include/rfb.js +++ b/noVNC/core/rfb.js @@ -1,7 +1,7 @@ /* * noVNC: HTML5 VNC client * Copyright (C) 2012 Joel Martin - * Copyright (C) 2013 Samuel Mannehed for Cendio AB + * Copyright (C) 2016 Samuel Mannehed for Cendio AB * Licensed under MPL 2.0 (see LICENSE.txt) * * See README.md for usage and integration instructions. @@ -10,252 +10,261 @@ * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca) */ +/* [module] + * import Util from "./util"; + * import Display from "./display"; + * import { Keyboard, Mouse } from "./input/devices" + * import Websock from "./websock" + * import Base64 from "./base64"; + * import DES from "./des"; + * import KeyTable from "./input/keysym"; + * import XtScancode from "./input/xtscancodes"; + * import Inflator from "./inflator.mod"; + */ /*jslint white: false, browser: true */ -/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES */ +/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, KeyTable, Inflator, XtScancode */ -var RFB; - -(function () { +/* [module] export default */ function RFB(defaults) { "use strict"; - RFB = function (defaults) { - if (!defaults) { - defaults = {}; - } + if (!defaults) { + defaults = {}; + } - this._rfb_host = ''; - this._rfb_port = 5900; - this._rfb_password = ''; - this._rfb_path = ''; + this._rfb_host = ''; + this._rfb_port = 5900; + this._rfb_password = ''; + this._rfb_path = ''; - this._rfb_state = 'disconnected'; - this._rfb_version = 0; - this._rfb_max_version = 3.8; - this._rfb_auth_scheme = ''; + this._rfb_connection_state = ''; + this._rfb_init_state = ''; + this._rfb_version = 0; + this._rfb_max_version = 3.8; + this._rfb_auth_scheme = ''; + this._rfb_disconnect_reason = ""; - this._rfb_tightvnc = false; - this._rfb_xvp_ver = 0; + this._rfb_tightvnc = false; + this._rfb_xvp_ver = 0; - this._encHandlers = {}; - this._encNames = {}; - this._encStats = {}; + // In preference order + this._encodings = [ + ['COPYRECT', 0x01 ], + ['TIGHT', 0x07 ], + ['TIGHT_PNG', -260 ], + ['HEXTILE', 0x05 ], + ['RRE', 0x02 ], + ['RAW', 0x00 ], - this._sock = null; // Websock object - this._display = null; // Display object - this._keyboard = null; // Keyboard input handler object - this._mouse = null; // Mouse input handler object - this._sendTimer = null; // Send Queue check timer - this._disconnTimer = null; // disconnection timer - this._msgTimer = null; // queued handle_msg timer + // Psuedo-encoding settings - // Frame buffer update state - this._FBU = { - rects: 0, - subrects: 0, // RRE - lines: 0, // RAW - tiles: 0, // HEXTILE - bytes: 0, - x: 0, - y: 0, - width: 0, - height: 0, - encoding: 0, - subencoding: -1, - background: null, - zlib: [] // TIGHT zlib streams - }; + //['JPEG_quality_lo', -32 ], + ['JPEG_quality_med', -26 ], + //['JPEG_quality_hi', -23 ], + //['compress_lo', -255 ], + ['compress_hi', -247 ], - this._fb_Bpp = 4; - this._fb_depth = 3; - this._fb_width = 0; - this._fb_height = 0; - this._fb_name = ""; + ['DesktopSize', -223 ], + ['last_rect', -224 ], + ['Cursor', -239 ], + ['QEMUExtendedKeyEvent', -258 ], + ['ExtendedDesktopSize', -308 ], + ['xvp', -309 ], + ['Fence', -312 ], + ['ContinuousUpdates', -313 ] + ]; - this._rre_chunk_sz = 100; + this._encHandlers = {}; + this._encNames = {}; + this._encStats = {}; - this._timing = { - last_fbu: 0, - fbu_total: 0, - fbu_total_cnt: 0, - full_fbu_total: 0, - full_fbu_cnt: 0, + this._sock = null; // Websock object + this._display = null; // Display object + this._flushing = false; // Display flushing state + this._keyboard = null; // Keyboard input handler object + this._mouse = null; // Mouse input handler object + this._disconnTimer = null; // disconnection timer - fbu_rt_start: 0, - fbu_rt_total: 0, - fbu_rt_cnt: 0, - pixels: 0 - }; + this._supportsFence = false; - this._supportsSetDesktopSize = false; - this._screen_id = 0; - this._screen_flags = 0; + this._supportsContinuousUpdates = false; + this._enabledContinuousUpdates = false; - // Mouse state - this._mouse_buttonMask = 0; - this._mouse_arr = []; - this._viewportDragging = false; - this._viewportDragPos = {}; - - // set the default value on user-facing properties - Util.set_defaults(this, defaults, { - 'target': 'null', // VNC display rendering Canvas object - 'focusContainer': document, // DOM element that captures keyboard input - 'encrypt': false, // Use TLS/SSL/wss encryption - 'true_color': true, // Request true color pixel data - 'local_cursor': false, // Request locally rendered cursor - 'shared': true, // Request shared mode - 'view_only': false, // Disable client mouse/keyboard - 'xvp_password_sep': '@', // Separator for XVP password fields - 'disconnectTimeout': 3, // Time (s) to wait for disconnection - 'wsProtocols': ['binary', 'base64'], // Protocols to use in the WebSocket connection - 'repeaterID': '', // [UltraVNC] RepeaterID to connect to - 'viewportDrag': false, // Move the viewport on mouse drags - // Callback functions - 'onUpdateState': function () { }, // onUpdateState(rfb, state, oldstate, statusMsg): state update/change - 'onPasswordRequired': function () { }, // onPasswordRequired(rfb): VNC password is required - 'onClipboard': function () { }, // onClipboard(rfb, text): RFB clipboard contents received - 'onBell': function () { }, // onBell(rfb): RFB Bell message received - 'onFBUReceive': function () { }, // onFBUReceive(rfb, fbu): RFB FBU received but not yet processed - 'onFBUComplete': function () { }, // onFBUComplete(rfb, fbu): RFB FBU received and processed - 'onFBResize': function () { }, // onFBResize(rfb, width, height): frame buffer resized - 'onDesktopName': function () { }, // onDesktopName(rfb, name): desktop name received - 'onXvpInit': function () { }, // onXvpInit(version): XVP extensions active for this connection - }); - - try{ - // Use my custom 'jpeg_quality'. - this._encodings = [ - // ['COPYRECT', 0x01 ], - ['TIGHT', 0x07 ], - ['TIGHT_PNG', -260 ], - ['HEXTILE', 0x05 ], - ['RRE', 0x02 ], - ['RAW', 0x00 ], - ['DesktopSize', -223 ], - ['Cursor', -239 ], - - // Psuedo-encoding settings - ['JPEG_quality_lo', -32 + jpeg_quality ], - // ['JPEG_quality_med', -28 ], - // ['JPEG_quality_hi', -23 ], - // ['compress_lo', -255 ], - ['compress_hi', -247 ], - ['last_rect', -224 ], - ['xvp', -309 ], - ['ExtendedDesktopSize', -308 ] - ]; - } - catch(e){ - // If my custom 'jpeg_quality' is not defined, just use default setting. - this._encodings = [ - ['COPYRECT', 0x01 ], - ['TIGHT', 0x07 ], - ['TIGHT_PNG', -260 ], - ['HEXTILE', 0x05 ], - ['RRE', 0x02 ], - ['RAW', 0x00 ], - ['DesktopSize', -223 ], - ['Cursor', -239 ], - - // Psuedo-encoding settings - //['JPEG_quality_lo', -32 ], - ['JPEG_quality_med', -26 ], - //['JPEG_quality_hi', -23 ], - //['compress_lo', -255 ], - ['compress_hi', -247 ], - ['last_rect', -224 ], - ['xvp', -309 ], - ['ExtendedDesktopSize', -308 ] - ]; - } - - // main setup - Util.Debug(">> RFB.constructor"); - - // populate encHandlers with bound versions - Object.keys(RFB.encodingHandlers).forEach(function (encName) { - this._encHandlers[encName] = RFB.encodingHandlers[encName].bind(this); - }.bind(this)); - - // Create lookup tables based on encoding number - for (var i = 0; i < this._encodings.length; i++) { - this._encHandlers[this._encodings[i][1]] = this._encHandlers[this._encodings[i][0]]; - this._encNames[this._encodings[i][1]] = this._encodings[i][0]; - this._encStats[this._encodings[i][1]] = [0, 0]; - } - - // NB: nothing that needs explicit teardown should be done - // before this point, since this can throw an exception - try { - this._display = new Display({target: this._target}); - } catch (exc) { - Util.Error("Display exception: " + exc); - throw exc; - } - - this._keyboard = new Keyboard({target: this._focusContainer, - onKeyPress: this._handleKeyPress.bind(this)}); - - this._mouse = new Mouse({target: this._target, - onMouseButton: this._handleMouseButton.bind(this), - onMouseMove: this._handleMouseMove.bind(this), - notify: this._keyboard.sync.bind(this._keyboard)}); - - this._sock = new Websock(); - this._sock.on('message', this._handle_message.bind(this)); - this._sock.on('open', function () { - if (this._rfb_state === 'connect') { - this._updateState('ProtocolVersion', "Starting VNC handshake"); - } else { - this._fail("Got unexpected WebSocket connection"); - } - }.bind(this)); - this._sock.on('close', function (e) { - Util.Warn("WebSocket on-close event"); - var msg = ""; - if (e.code) { - msg = " (code: " + e.code; - if (e.reason) { - msg += ", reason: " + e.reason; - } - msg += ")"; - } - if (this._rfb_state === 'disconnect') { - this._updateState('disconnected', 'VNC disconnected' + msg); - } else if (this._rfb_state === 'ProtocolVersion') { - this._fail('Failed to connect to server' + msg); - } else if (this._rfb_state in {'failed': 1, 'disconnected': 1}) { - Util.Error("Received onclose while disconnected" + msg); - } else { - this._fail("Server disconnected" + msg); - } - this._sock.off('close'); - }.bind(this)); - this._sock.on('error', function (e) { - Util.Warn("WebSocket on-error event"); - }); - - this._init_vars(); - - var rmode = this._display.get_render_mode(); - if (Websock_native) { - Util.Info("Using native WebSockets"); - this._updateState('loaded', 'noVNC ready: native WebSockets, ' + rmode); - } else { - Util.Warn("Using web-socket-js bridge. Flash version: " + Util.Flash.version); - if (!Util.Flash || Util.Flash.version < 9) { - this._cleanupSocket('fatal'); - throw new Exception("WebSockets or Adobe Flash is required"); - } else if (document.location.href.substr(0, 7) === 'file://') { - this._cleanupSocket('fatal'); - throw new Exception("'file://' URL is incompatible with Adobe Flash"); - } else { - this._updateState('loaded', 'noVNC ready: WebSockets emulation, ' + rmode); - } - } - - Util.Debug("<< RFB.constructor"); + // Frame buffer update state + this._FBU = { + rects: 0, + subrects: 0, // RRE + lines: 0, // RAW + tiles: 0, // HEXTILE + bytes: 0, + x: 0, + y: 0, + width: 0, + height: 0, + encoding: 0, + subencoding: -1, + background: null, + zlib: [] // TIGHT zlib streams }; + this._fb_Bpp = 4; + this._fb_depth = 3; + this._fb_width = 0; + this._fb_height = 0; + this._fb_name = ""; + + this._destBuff = null; + this._paletteBuff = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel) + + this._rre_chunk_sz = 100; + + this._timing = { + last_fbu: 0, + fbu_total: 0, + fbu_total_cnt: 0, + full_fbu_total: 0, + full_fbu_cnt: 0, + + fbu_rt_start: 0, + fbu_rt_total: 0, + fbu_rt_cnt: 0, + pixels: 0 + }; + + this._supportsSetDesktopSize = false; + this._screen_id = 0; + this._screen_flags = 0; + + // Mouse state + this._mouse_buttonMask = 0; + this._mouse_arr = []; + this._viewportDragging = false; + this._viewportDragPos = {}; + this._viewportHasMoved = false; + + // QEMU Extended Key Event support - default to false + this._qemuExtKeyEventSupported = false; + + // set the default value on user-facing properties + Util.set_defaults(this, defaults, { + 'target': 'null', // VNC display rendering Canvas object + 'focusContainer': document, // DOM element that captures keyboard input + 'encrypt': false, // Use TLS/SSL/wss encryption + 'true_color': true, // Request true color pixel data + 'local_cursor': false, // Request locally rendered cursor + 'shared': true, // Request shared mode + 'view_only': false, // Disable client mouse/keyboard + 'xvp_password_sep': '@', // Separator for XVP password fields + 'disconnectTimeout': 3, // Time (s) to wait for disconnection + 'wsProtocols': ['binary'], // Protocols to use in the WebSocket connection + 'repeaterID': '', // [UltraVNC] RepeaterID to connect to + 'viewportDrag': false, // Move the viewport on mouse drags + + // Callback functions + 'onUpdateState': function () { }, // onUpdateState(rfb, state, oldstate): connection state change + 'onNotification': function () { }, // onNotification(rfb, msg, level, options): notification for UI + 'onDisconnected': function () { }, // onDisconnected(rfb, reason): disconnection finished + 'onPasswordRequired': function () { }, // onPasswordRequired(rfb, msg): VNC password is required + 'onClipboard': function () { }, // onClipboard(rfb, text): RFB clipboard contents received + 'onBell': function () { }, // onBell(rfb): RFB Bell message received + 'onFBUReceive': function () { }, // onFBUReceive(rfb, fbu): RFB FBU received but not yet processed + 'onFBUComplete': function () { }, // onFBUComplete(rfb, fbu): RFB FBU received and processed + 'onFBResize': function () { }, // onFBResize(rfb, width, height): frame buffer resized + 'onDesktopName': function () { }, // onDesktopName(rfb, name): desktop name received + 'onXvpInit': function () { } // onXvpInit(version): XVP extensions active for this connection + }); + + // main setup + Util.Debug(">> RFB.constructor"); + + // populate encHandlers with bound versions + Object.keys(RFB.encodingHandlers).forEach(function (encName) { + this._encHandlers[encName] = RFB.encodingHandlers[encName].bind(this); + }.bind(this)); + + // Create lookup tables based on encoding number + for (var i = 0; i < this._encodings.length; i++) { + this._encHandlers[this._encodings[i][1]] = this._encHandlers[this._encodings[i][0]]; + this._encNames[this._encodings[i][1]] = this._encodings[i][0]; + this._encStats[this._encodings[i][1]] = [0, 0]; + } + + // NB: nothing that needs explicit teardown should be done + // before this point, since this can throw an exception + try { + this._display = new Display({target: this._target, + onFlush: this._onFlush.bind(this)}); + } catch (exc) { + Util.Error("Display exception: " + exc); + throw exc; + } + + this._keyboard = new Keyboard({target: this._focusContainer, + onKeyPress: this._handleKeyPress.bind(this)}); + + this._mouse = new Mouse({target: this._target, + onMouseButton: this._handleMouseButton.bind(this), + onMouseMove: this._handleMouseMove.bind(this), + notify: this._keyboard.sync.bind(this._keyboard)}); + + this._sock = new Websock(); + this._sock.on('message', this._handle_message.bind(this)); + this._sock.on('open', function () { + if ((this._rfb_connection_state === 'connecting') && + (this._rfb_init_state === '')) { + this._rfb_init_state = 'ProtocolVersion'; + Util.Debug("Starting VNC handshake"); + } else { + this._fail("Unexpected server connection"); + } + }.bind(this)); + this._sock.on('close', function (e) { + Util.Warn("WebSocket on-close event"); + var msg = ""; + if (e.code) { + msg = " (code: " + e.code; + if (e.reason) { + msg += ", reason: " + e.reason; + } + msg += ")"; + } + switch (this._rfb_connection_state) { + case 'disconnecting': + this._updateConnectionState('disconnected'); + break; + case 'connecting': + this._fail('Failed to connect to server', msg); + break; + case 'connected': + // Handle disconnects that were initiated server-side + this._updateConnectionState('disconnecting'); + this._updateConnectionState('disconnected'); + break; + case 'disconnected': + this._fail("Unexpected server disconnect", + "Already disconnected: " + msg); + break; + default: + this._fail("Unexpected server disconnect", + "Not in any state yet: " + msg); + break; + } + this._sock.off('close'); + }.bind(this)); + this._sock.on('error', function (e) { + Util.Warn("WebSocket on-error event"); + }); + + this._init_vars(); + this._cleanup(); + + var rmode = this._display.get_render_mode(); + Util.Info("Using native WebSockets, render mode: " + rmode); + + Util.Debug("<< RFB.constructor"); +}; + +(function() { + var _ = Util.Localisation.get; + RFB.prototype = { // Public methods connect: function (host, port, password, path) { @@ -265,14 +274,17 @@ var RFB; this._rfb_path = (path !== undefined) ? path : ""; if (!this._rfb_host || !this._rfb_port) { - return this._fail("Must set host and port"); + return this._fail( + _("Must set host and port")); } - this._updateState('connect'); + this._rfb_init_state = ''; + this._updateConnectionState('connecting'); + return true; }, disconnect: function () { - this._updateState('disconnect', 'Disconnecting'); + this._updateConnectionState('disconnecting'); this._sock.off('error'); this._sock.off('message'); this._sock.off('open'); @@ -280,22 +292,20 @@ var RFB; sendPassword: function (passwd) { this._rfb_password = passwd; - this._rfb_state = 'Authentication'; - setTimeout(this._init_msg.bind(this), 1); + setTimeout(this._init_msg.bind(this), 0); }, sendCtrlAltDel: function () { - if (this._rfb_state !== 'normal' || this._view_only) { return false; } + if (this._rfb_connection_state !== 'connected' || this._view_only) { return false; } Util.Info("Sending Ctrl-Alt-Del"); - var arr = []; - arr = arr.concat(RFB.messages.keyEvent(XK_Control_L, 1)); - arr = arr.concat(RFB.messages.keyEvent(XK_Alt_L, 1)); - arr = arr.concat(RFB.messages.keyEvent(XK_Delete, 1)); - arr = arr.concat(RFB.messages.keyEvent(XK_Delete, 0)); - arr = arr.concat(RFB.messages.keyEvent(XK_Alt_L, 0)); - arr = arr.concat(RFB.messages.keyEvent(XK_Control_L, 0)); - this._sock.send(arr); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Control_L, 1); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Alt_L, 1); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Delete, 1); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Delete, 0); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Alt_L, 0); + RFB.messages.keyEvent(this._sock, KeyTable.XK_Control_L, 0); + return true; }, xvpOp: function (ver, op) { @@ -319,47 +329,41 @@ var RFB; // Send a key press. If 'down' is not specified then send a down key // followed by an up key. - sendKey: function (code, down) { - if (this._rfb_state !== "normal" || this._view_only) { return false; } - var arr = []; + sendKey: function (keysym, down) { + if (this._rfb_connection_state !== 'connected' || this._view_only) { return false; } if (typeof down !== 'undefined') { - Util.Info("Sending key code (" + (down ? "down" : "up") + "): " + code); - arr = arr.concat(RFB.messages.keyEvent(code, down ? 1 : 0)); + Util.Info("Sending keysym (" + (down ? "down" : "up") + "): " + keysym); + RFB.messages.keyEvent(this._sock, keysym, down ? 1 : 0); } else { - Util.Info("Sending key code (down + up): " + code); - arr = arr.concat(RFB.messages.keyEvent(code, 1)); - arr = arr.concat(RFB.messages.keyEvent(code, 0)); + Util.Info("Sending keysym (down + up): " + keysym); + RFB.messages.keyEvent(this._sock, keysym, 1); + RFB.messages.keyEvent(this._sock, keysym, 0); } - this._sock.send(arr); + return true; }, clipboardPasteFrom: function (text) { - if (this._rfb_state !== 'normal') { return; } - this._sock.send(RFB.messages.clientCutText(text)); + if (this._rfb_connection_state !== 'connected' || this._view_only) { + return; + } + RFB.messages.clientCutText(this._sock, text); }, - setDesktopSize: function (width, height) { - if (this._rfb_state !== "normal") { return; } + // Requests a change of remote desktop size. This message is an extension + // and may only be sent if we have received an ExtendedDesktopSize message + requestDesktopSize: function (width, height) { + if (this._rfb_connection_state !== 'connected' || + this._view_only) { + return false; + } if (this._supportsSetDesktopSize) { - - var arr = [251]; // msg-type - arr.push8(0); // padding - arr.push16(width); // width - arr.push16(height); // height - - arr.push8(1); // number-of-screens - arr.push8(0); // padding - - // screen array - arr.push32(this._screen_id); // id - arr.push16(0); // x-position - arr.push16(0); // y-position - arr.push16(width); // width - arr.push16(height); // height - arr.push32(this._screen_flags); // flags - - this._sock.send(arr); + RFB.messages.setDesktopSize(this._sock, width, height, + this._screen_id, this._screen_flags); + this._sock.flush(); + return true; + } else { + return false; } }, @@ -368,6 +372,7 @@ var RFB; _connect: function () { Util.Debug(">> RFB.connect"); + this._init_vars(); var uri; if (typeof UsingSocketIO !== 'undefined') { @@ -379,15 +384,30 @@ var RFB; uri += '://' + this._rfb_host + ':' + this._rfb_port + '/' + this._rfb_path; Util.Info("connecting to " + uri); - this._sock.open(uri, this._wsProtocols); + try { + // WebSocket.onopen transitions to the RFB init states + this._sock.open(uri, this._wsProtocols); + } catch (e) { + if (e.name === 'SyntaxError') { + this._fail("Invalid host or port value given", e); + } else { + this._fail("Error while connecting", e); + } + } Util.Debug("<< RFB.connect"); }, + _disconnect: function () { + Util.Debug(">> RFB.disconnect"); + this._cleanup(); + this._sock.close(); + this._print_stats(); + Util.Debug("<< RFB.disconnect"); + }, + _init_vars: function () { // reset state - this._sock.init(); - this._FBU.rects = 0; this._FBU.subrects = 0; // RRE and HEXTILE this._FBU.lines = 0; // RAW @@ -404,8 +424,7 @@ var RFB; } for (i = 0; i < 4; i++) { - this._FBU.zlibs[i] = new TINF(); - this._FBU.zlibs[i].init(); + this._FBU.zlibs[i] = new Inflator.Inflate(); } }, @@ -426,173 +445,201 @@ var RFB; } }, - _cleanupSocket: function (state) { - if (this._sendTimer) { - clearInterval(this._sendTimer); - this._sendTimer = null; + _cleanup: function () { + if (!this._view_only) { this._keyboard.ungrab(); } + if (!this._view_only) { this._mouse.ungrab(); } + this._display.defaultCursor(); + if (Util.get_logging() !== 'debug') { + // Show noVNC logo on load and when disconnected, unless in + // debug mode + this._display.clear(); } - - if (this._msgTimer) { - clearInterval(this._msgTimer); - this._msgTimer = null; - } - - if (this._display && this._display.get_context()) { - this._keyboard.ungrab(); - this._mouse.ungrab(); - if (state !== 'connect' && state !== 'loaded') { - this._display.defaultCursor(); - } - if (Util.get_logging() !== 'debug' || state === 'loaded') { - // Show noVNC logo on load and when disconnected, unless in - // debug mode - this._display.clear(); - } - } - - this._sock.close(); }, /* - * Page states: - * loaded - page load, equivalent to disconnected - * disconnected - idle state - * connect - starting to connect (to ProtocolVersion) - * normal - connected - * disconnect - starting to disconnect - * failed - abnormal disconnect - * fatal - failed to load page, or fatal error - * - * RFB protocol initialization states: - * ProtocolVersion - * Security - * Authentication - * password - waiting for password, not part of RFB - * SecurityResult - * ClientInitialization - not triggered by server message - * ServerInitialization (to normal) + * Connection states: + * connecting + * connected + * disconnecting + * disconnected - permanent state */ - _updateState: function (state, statusMsg) { - var oldstate = this._rfb_state; + _updateConnectionState: function (state) { + var oldstate = this._rfb_connection_state; if (state === oldstate) { - // Already here, ignore Util.Debug("Already in state '" + state + "', ignoring"); + return; } - /* - * These are disconnected states. A previous connect may - * asynchronously cause a connection so make sure we are closed. - */ - if (state in {'disconnected': 1, 'loaded': 1, 'connect': 1, - 'disconnect': 1, 'failed': 1, 'fatal': 1}) { - this._cleanupSocket(state); - } - - if (oldstate === 'fatal') { - Util.Error('Fatal error, cannot continue'); - } - - var cmsg = typeof(statusMsg) !== 'undefined' ? (" Msg: " + statusMsg) : ""; - var fullmsg = "New state '" + state + "', was '" + oldstate + "'." + cmsg; - if (state === 'failed' || state === 'fatal') { - Util.Error(cmsg); - } else { - Util.Warn(cmsg); - } - - if (oldstate === 'failed' && state === 'disconnected') { - // do disconnect action, but stay in failed state - this._rfb_state = 'failed'; - } else { - this._rfb_state = state; - } - - if (this._disconnTimer && this._rfb_state !== 'disconnect') { - Util.Debug("Clearing disconnect timer"); - clearTimeout(this._disconnTimer); - this._disconnTimer = null; - this._sock.off('close'); // make sure we don't get a double event + // The 'disconnected' state is permanent for each RFB object + if (oldstate === 'disconnected') { + Util.Error("Tried changing state of a disconnected RFB object"); + return; } + // Ensure proper transitions before doing anything switch (state) { - case 'normal': - if (oldstate === 'disconnected' || oldstate === 'failed') { - Util.Error("Invalid transition from 'disconnected' or 'failed' to 'normal'"); + case 'connected': + if (oldstate !== 'connecting') { + Util.Error("Bad transition to connected state, " + + "previous connection state: " + oldstate); + return; } break; - case 'connect': - this._init_vars(); - this._connect(); - // WebSocket.onopen transitions to 'ProtocolVersion' - break; - - case 'disconnect': - this._disconnTimer = setTimeout(function () { - this._fail("Disconnect timeout"); - }.bind(this), this._disconnectTimeout * 1000); - - this._print_stats(); - - // WebSocket.onclose transitions to 'disconnected' - break; - - case 'failed': - if (oldstate === 'disconnected') { - Util.Error("Invalid transition from 'disconnected' to 'failed'"); - } else if (oldstate === 'normal') { - Util.Error("Error while connected."); - } else if (oldstate === 'init') { - Util.Error("Error while initializing."); + case 'disconnected': + if (oldstate !== 'disconnecting') { + Util.Error("Bad transition to disconnected state, " + + "previous connection state: " + oldstate); + return; } + break; - // Make sure we transition to disconnected - setTimeout(function () { - this._updateState('disconnected'); - }.bind(this), 50); + case 'connecting': + if (oldstate !== '') { + Util.Error("Bad transition to connecting state, " + + "previous connection state: " + oldstate); + return; + } + break; + case 'disconnecting': + if (oldstate !== 'connected' && oldstate !== 'connecting') { + Util.Error("Bad transition to disconnecting state, " + + "previous connection state: " + oldstate); + return; + } break; default: - // No state change action to take + Util.Error("Unknown connection state: " + state); + return; } - if (oldstate === 'failed' && state === 'disconnected') { - this._onUpdateState(this, state, oldstate); - } else { - this._onUpdateState(this, state, oldstate, statusMsg); + // State change actions + + this._rfb_connection_state = state; + this._onUpdateState(this, state, oldstate); + + var smsg = "New state '" + state + "', was '" + oldstate + "'."; + Util.Debug(smsg); + + if (this._disconnTimer && state !== 'disconnecting') { + Util.Debug("Clearing disconnect timer"); + clearTimeout(this._disconnTimer); + this._disconnTimer = null; + + // make sure we don't get a double event + this._sock.off('close'); + } + + switch (state) { + case 'disconnected': + // Call onDisconnected callback after onUpdateState since + // we don't know if the UI only displays the latest message + if (this._rfb_disconnect_reason !== "") { + this._onDisconnected(this, this._rfb_disconnect_reason); + } else { + // No reason means clean disconnect + this._onDisconnected(this); + } + break; + + case 'connecting': + this._connect(); + break; + + case 'disconnecting': + this._disconnect(); + + this._disconnTimer = setTimeout(function () { + this._rfb_disconnect_reason = _("Disconnect timeout"); + this._updateConnectionState('disconnected'); + }.bind(this), this._disconnectTimeout * 1000); + break; } }, - _fail: function (msg) { - this._updateState('failed', msg); + /* Print errors and disconnect + * + * The optional parameter 'details' is used for information that + * should be logged but not sent to the user interface. + */ + _fail: function (msg, details) { + var fullmsg = msg; + if (typeof details !== 'undefined') { + fullmsg = msg + " (" + details + ")"; + } + switch (this._rfb_connection_state) { + case 'disconnecting': + Util.Error("Failed when disconnecting: " + fullmsg); + break; + case 'connected': + Util.Error("Failed while connected: " + fullmsg); + break; + case 'connecting': + Util.Error("Failed when connecting: " + fullmsg); + break; + default: + Util.Error("RFB failure: " + fullmsg); + break; + } + this._rfb_disconnect_reason = msg; //This is sent to the UI + + // Transition to disconnected without waiting for socket to close + this._updateConnectionState('disconnecting'); + this._updateConnectionState('disconnected'); + return false; }, + /* + * Send a notification to the UI. Valid levels are: + * 'normal'|'warn'|'error' + * + * NOTE: Options could be added in the future. + * NOTE: If this function is called multiple times, remember that the + * interface could be only showing the latest notification. + */ + _notification: function(msg, level, options) { + switch (level) { + case 'normal': + case 'warn': + case 'error': + Util.Debug("Notification[" + level + "]:" + msg); + break; + default: + Util.Error("Invalid notification level: " + level); + return; + } + + if (options) { + this._onNotification(this, msg, level, options); + } else { + this._onNotification(this, msg, level); + } + }, + _handle_message: function () { if (this._sock.rQlen() === 0) { Util.Warn("handle_message called on an empty receive queue"); return; } - switch (this._rfb_state) { + switch (this._rfb_connection_state) { case 'disconnected': - case 'failed': Util.Error("Got data while disconnected"); break; - case 'normal': - if (this._normal_msg() && this._sock.rQlen() > 0) { - // true means we can continue processing - // Give other events a chance to run - if (this._msgTimer === null) { - Util.Debug("More data to process, creating timer"); - this._msgTimer = setTimeout(function () { - this._msgTimer = null; - this._handle_message(); - }.bind(this), 10); - } else { - Util.Debug("More data to process, existing timer"); + case 'connected': + while (true) { + if (this._flushing) { + break; + } + if (!this._normal_msg()) { + break; + } + if (this._sock.rQlen() === 0) { + break; } } break; @@ -602,16 +649,22 @@ var RFB; } }, - _checkEvents: function () { - if (this._rfb_state === 'normal' && !this._viewportDragging && this._mouse_arr.length > 0) { - this._sock.send(this._mouse_arr); - this._mouse_arr = []; - } - }, - - _handleKeyPress: function (keysym, down) { + _handleKeyPress: function (keyevent) { if (this._view_only) { return; } // View only, skip keyboard, events - this._sock.send(RFB.messages.keyEvent(keysym, down)); + + var down = (keyevent.type == 'keydown'); + if (this._qemuExtKeyEventSupported) { + var scancode = XtScancode[keyevent.code]; + if (scancode) { + var keysym = keyevent.keysym; + RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode); + } else { + Util.Error('Unable to find a xt scancode for code = ' + keyevent.code); + } + } else { + keysym = keyevent.keysym.keysym; + RFB.messages.keyEvent(this._sock, keysym, down); + } }, _handleMouseButton: function (x, y, down, bmask) { @@ -630,24 +683,38 @@ var RFB; return; } else { this._viewportDragging = false; + + // If the viewport didn't actually move, then treat as a mouse click event + // Send the button down event here, as the button up event is sent at the end of this function + if (!this._viewportHasMoved && !this._view_only) { + RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), bmask); + } + this._viewportHasMoved = false; } } if (this._view_only) { return; } // View only, skip mouse events - this._mouse_arr = this._mouse_arr.concat( - RFB.messages.pointerEvent(this._display.absX(x), this._display.absY(y), this._mouse_buttonMask)); - this._sock.send(this._mouse_arr); - this._mouse_arr = []; + if (this._rfb_connection_state !== 'connected') { return; } + RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask); }, _handleMouseMove: function (x, y) { if (this._viewportDragging) { var deltaX = this._viewportDragPos.x - x; var deltaY = this._viewportDragPos.y - y; - this._viewportDragPos = {'x': x, 'y': y}; - this._display.viewportChangePos(deltaX, deltaY); + // The goal is to trigger on a certain physical width, the + // devicePixelRatio brings us a bit closer but is not optimal. + var dragThreshold = 10 * (window.devicePixelRatio || 1); + + if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold || + Math.abs(deltaY) > dragThreshold)) { + this._viewportHasMoved = true; + + this._viewportDragPos = {'x': x, 'y': y}; + this._display.viewportChangePos(deltaX, deltaY); + } // Skip sending mouse events return; @@ -655,17 +722,16 @@ var RFB; if (this._view_only) { return; } // View only, skip mouse events - this._mouse_arr = this._mouse_arr.concat( - RFB.messages.pointerEvent(this._display.absX(x), this._display.absY(y), this._mouse_buttonMask)); - - this._checkEvents(); + if (this._rfb_connection_state !== 'connected') { return; } + RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask); }, // Message Handlers _negotiate_protocol_version: function () { if (this._sock.rQlen() < 12) { - return this._fail("Incomplete protocol version"); + return this._fail("Error while negotiating with server", + "Incomplete protocol version"); } var sversion = this._sock.rQshiftStr(12).substr(4, 7); @@ -686,10 +752,12 @@ var RFB; case "003.008": case "004.000": // Intel AMT KVM case "004.001": // RealVNC 4.6 + case "005.000": // RealVNC 5.3 this._rfb_version = 3.8; break; default: - return this._fail("Invalid server version " + sversion); + return this._fail("Unsupported server", + "Invalid server version: " + sversion); } if (is_repeater) { @@ -705,14 +773,12 @@ var RFB; this._rfb_version = this._rfb_max_version; } - // Send updates either at a rate of 1 update per 50ms, or - // whatever slower rate the network can handle - this._sendTimer = setInterval(this._sock.flush.bind(this._sock), 50); - var cversion = "00" + parseInt(this._rfb_version, 10) + ".00" + ((this._rfb_version * 10) % 10); this._sock.send_string("RFB " + cversion + "\n"); - this._updateState('Security', 'Sent ProtocolVersion: ' + cversion); + Util.Debug('Sent ProtocolVersion: ' + cversion); + + this._rfb_init_state = 'Security'; }, _negotiate_security: function () { @@ -724,20 +790,37 @@ var RFB; if (num_types === 0) { var strlen = this._sock.rQshift32(); var reason = this._sock.rQshiftStr(strlen); - return this._fail("Security failure: " + reason); + return this._fail("Error while negotiating with server", + "Security failure: " + reason); } - this._rfb_auth_scheme = 0; var types = this._sock.rQshiftBytes(num_types); Util.Debug("Server security types: " + types); - for (var i = 0; i < types.length; i++) { - if (types[i] > this._rfb_auth_scheme && (types[i] <= 16 || types[i] == 22)) { - this._rfb_auth_scheme = types[i]; + + // Polyfill since IE and PhantomJS doesn't have + // TypedArray.includes() + function includes(item, array) { + for (var i = 0; i < array.length; i++) { + if (array[i] === item) { + return true; + } } + return false; } - if (this._rfb_auth_scheme === 0) { - return this._fail("Unsupported security types: " + types); + // Look for each auth in preferred order + this._rfb_auth_scheme = 0; + if (includes(1, types)) { + this._rfb_auth_scheme = 1; // None + } else if (includes(22, types)) { + this._rfb_auth_scheme = 22; // XVP + } else if (includes(16, types)) { + this._rfb_auth_scheme = 16; // Tight + } else if (includes(2, types)) { + this._rfb_auth_scheme = 2; // VNC Auth + } else { + return this._fail("Unsupported server", + "Unsupported security types: " + types); } this._sock.send([this._rfb_auth_scheme]); @@ -747,7 +830,9 @@ var RFB; this._rfb_auth_scheme = this._sock.rQshift32(); } - this._updateState('Authentication', 'Authenticating using scheme: ' + this._rfb_auth_scheme); + this._rfb_init_state = 'Authentication'; + Util.Debug('Authenticating using scheme: ' + this._rfb_auth_scheme); + return this._init_msg(); // jump to authentication }, @@ -756,9 +841,9 @@ var RFB; var xvp_sep = this._xvp_password_sep; var xvp_auth = this._rfb_password.split(xvp_sep); if (xvp_auth.length < 3) { - this._updateState('password', 'XVP credentials required (user' + xvp_sep + - 'target' + xvp_sep + 'password) -- got only ' + this._rfb_password); - this._onPasswordRequired(this); + var msg = 'XVP credentials required (user' + xvp_sep + + 'target' + xvp_sep + 'password) -- got only ' + this._rfb_password; + this._onPasswordRequired(this, msg); return false; } @@ -774,18 +859,17 @@ var RFB; _negotiate_std_vnc_auth: function () { if (this._rfb_password.length === 0) { - // Notify via both callbacks since it's kind of - // an RFB state change and a UI interface issue - this._updateState('password', "Password Required"); this._onPasswordRequired(this); + return false; } if (this._sock.rQwait("auth challenge", 16)) { return false; } - var challenge = this._sock.rQshiftBytes(16); + // TODO(directxman12): make genDES not require an Array + var challenge = Array.prototype.slice.call(this._sock.rQshiftBytes(16)); var response = RFB.genDES(this._rfb_password, challenge); this._sock.send(response); - this._updateState("SecurityResult"); + this._rfb_init_state = "SecurityResult"; return true; }, @@ -806,12 +890,16 @@ var RFB; if (serverSupportedTunnelTypes[0]) { if (serverSupportedTunnelTypes[0].vendor != clientSupportedTunnelTypes[0].vendor || serverSupportedTunnelTypes[0].signature != clientSupportedTunnelTypes[0].signature) { - return this._fail("Client's tunnel type had the incorrect vendor or signature"); + return this._fail("Unsupported server", + "Client's tunnel type had the incorrect " + + "vendor or signature"); } this._sock.send([0, 0, 0, 0]); // use NOTUNNEL return false; // wait until we receive the sub auth count to continue } else { - return this._fail("Server wanted tunnels, but doesn't support the notunnel type"); + return this._fail("Unsupported server", + "Server wanted tunnels, but doesn't support " + + "the notunnel type"); } }, @@ -832,6 +920,11 @@ var RFB; // second pass, do the sub-auth negotiation if (this._sock.rQwait("sub auth count", 4)) { return false; } var subAuthCount = this._sock.rQshift32(); + if (subAuthCount === 0) { // empty sub-auth list received means 'no auth' subtype selected + this._rfb_init_state = 'SecurityResult'; + return true; + } + if (this._sock.rQwait("sub auth capabilities", 16 * subAuthCount, 4)) { return false; } var clientSupportedTypes = { @@ -853,18 +946,21 @@ var RFB; switch (authType) { case 'STDVNOAUTH__': // no auth - this._updateState('SecurityResult'); + this._rfb_init_state = 'SecurityResult'; return true; case 'STDVVNCAUTH_': // VNC auth this._rfb_auth_scheme = 2; return this._init_msg(); default: - return this._fail("Unsupported tiny auth scheme: " + authType); + return this._fail("Unsupported server", + "Unsupported tiny auth scheme: " + + authType); } } } - this._fail("No supported sub-auth types!"); + return this._fail("Unsupported server", + "No supported sub-auth types!"); }, _negotiate_authentication: function () { @@ -873,14 +969,14 @@ var RFB; if (this._sock.rQwait("auth reason", 4)) { return false; } var strlen = this._sock.rQshift32(); var reason = this._sock.rQshiftStr(strlen); - return this._fail("Auth failure: " + reason); + return this._fail("Authentication failure", reason); case 1: // no auth if (this._rfb_version >= 3.8) { - this._updateState('SecurityResult'); + this._rfb_init_state = 'SecurityResult'; return true; } - this._updateState('ClientInitialisation', "No auth required"); + this._rfb_init_state = 'ClientInitialisation'; return this._init_msg(); case 22: // XVP auth @@ -893,7 +989,9 @@ var RFB; return this._negotiate_tight_auth(); default: - return this._fail("Unsupported auth scheme: " + this._rfb_auth_scheme); + return this._fail("Unsupported server", + "Unsupported auth scheme: " + + this._rfb_auth_scheme); } }, @@ -901,20 +999,24 @@ var RFB; if (this._sock.rQwait('VNC auth response ', 4)) { return false; } switch (this._sock.rQshift32()) { case 0: // OK - this._updateState('ClientInitialisation', 'Authentication OK'); + this._rfb_init_state = 'ClientInitialisation'; + Util.Debug('Authentication OK'); return this._init_msg(); case 1: // failed if (this._rfb_version >= 3.8) { var length = this._sock.rQshift32(); if (this._sock.rQwait("SecurityResult reason", length, 8)) { return false; } var reason = this._sock.rQshiftStr(length); - return this._fail(reason); + return this._fail("Authentication failure", reason); } else { return this._fail("Authentication failure"); } return false; case 2: - return this._fail("Too many auth attempts"); + return this._fail("Too many authentication attempts"); + default: + return this._fail("Unsupported server", + "Unknown SecurityResult"); } }, @@ -924,6 +1026,7 @@ var RFB; /* Screen size */ this._fb_width = this._sock.rQshift16(); this._fb_height = this._sock.rQshift16(); + this._destBuff = new Uint8Array(this._fb_width * this._fb_height * 4); /* PIXEL_FORMAT */ var bpp = this._sock.rQshift8(); @@ -958,18 +1061,17 @@ var RFB; var totalMessagesLength = (numServerMessages + numClientMessages + numEncodings) * 16; if (this._sock.rQwait('TightVNC extended server init header', totalMessagesLength, 32 + name_length)) { return false; } - var i; - for (i = 0; i < numServerMessages; i++) { - var srvMsg = this._sock.rQshiftStr(16); - } + // we don't actually do anything with the capability information that TIGHT sends, + // so we just skip the all of this. - for (i = 0; i < numClientMessages; i++) { - var clientMsg = this._sock.rQshiftStr(16); - } + // TIGHT server message capabilities + this._sock.rQskipBytes(16 * numServerMessages); - for (i = 0; i < numEncodings; i++) { - var encoding = this._sock.rQshiftStr(16); - } + // TIGHT client message capabilities + this._sock.rQskipBytes(16 * numClientMessages); + + // TIGHT encoding capabilities + this._sock.rQskipBytes(16 * numEncodings); } // NB(directxman12): these are down here so that we don't run them multiple times @@ -1008,8 +1110,9 @@ var RFB; this._display.set_true_color(this._true_color); this._display.resize(this._fb_width, this._fb_height); this._onFBResize(this, this._fb_width, this._fb_height); - this._keyboard.grab(); - this._mouse.grab(); + + if (!this._view_only) { this._keyboard.grab(); } + if (!this._view_only) { this._mouse.grab(); } if (this._true_color) { this._fb_Bpp = 4; @@ -1019,28 +1122,27 @@ var RFB; this._fb_depth = 1; } - var response = RFB.messages.pixelFormat(this._fb_Bpp, this._fb_depth, this._true_color); - response = response.concat( - RFB.messages.clientEncodings(this._encodings, this._local_cursor, this._true_color)); - response = response.concat( - RFB.messages.fbUpdateRequests(this._display.getCleanDirtyReset(), - this._fb_width, this._fb_height)); + RFB.messages.pixelFormat(this._sock, this._fb_Bpp, this._fb_depth, this._true_color); + RFB.messages.clientEncodings(this._sock, this._encodings, this._local_cursor, this._true_color); + RFB.messages.fbUpdateRequest(this._sock, false, 0, 0, this._fb_width, this._fb_height); this._timing.fbu_rt_start = (new Date()).getTime(); this._timing.pixels = 0; - this._sock.send(response); - this._checkEvents(); - - if (this._encrypt) { - this._updateState('normal', 'Connected (encrypted) to: ' + this._fb_name); - } else { - this._updateState('normal', 'Connected (unencrypted) to: ' + this._fb_name); - } + this._updateConnectionState('connected'); + return true; }, + /* RFB protocol initialization states: + * ProtocolVersion + * Security + * Authentication + * SecurityResult + * ClientInitialization - not triggered by server message + * ServerInitialization + */ _init_msg: function () { - switch (this._rfb_state) { + switch (this._rfb_init_state) { case 'ProtocolVersion': return this._negotiate_protocol_version(); @@ -1055,11 +1157,15 @@ var RFB; case 'ClientInitialisation': this._sock.send([this._shared ? 1 : 0]); // ClientInitialisation - this._updateState('ServerInitialisation', "Authentication OK"); + this._rfb_init_state = 'ServerInitialisation'; return true; case 'ServerInitialisation': return this._negotiate_server_init(); + + default: + return this._fail("Internal error", "Unknown init state: " + + this._rfb_init_state); } }, @@ -1085,6 +1191,8 @@ var RFB; _handle_server_cut_text: function () { Util.Debug("ServerCutText"); + if (this._view_only) { return true; } + if (this._sock.rQwait("ServerCutText header", 7, 1)) { return false; } this._sock.rQskipBytes(3); // Padding var length = this._sock.rQshift32(); @@ -1096,6 +1204,49 @@ var RFB; return true; }, + _handle_server_fence_msg: function() { + if (this._sock.rQwait("ServerFence header", 8, 1)) { return false; } + this._sock.rQskipBytes(3); // Padding + var flags = this._sock.rQshift32(); + var length = this._sock.rQshift8(); + + if (this._sock.rQwait("ServerFence payload", length, 9)) { return false; } + + if (length > 64) { + Util.Warn("Bad payload length (" + length + ") in fence response"); + length = 64; + } + + var payload = this._sock.rQshiftStr(length); + + this._supportsFence = true; + + /* + * Fence flags + * + * (1<<0) - BlockBefore + * (1<<1) - BlockAfter + * (1<<2) - SyncNext + * (1<<31) - Request + */ + + if (!(flags & (1<<31))) { + return this._fail("Internal error", + "Unexpected fence response"); + } + + // Filter out unsupported flags + // FIXME: support syncNext + flags &= (1<<0) | (1<<1); + + // BlockBefore and BlockAfter are automatically handled by + // the fact that we process each incoming message + // synchronuosly. + RFB.messages.clientFence(this._sock, flags, payload); + + return true; + }, + _handle_xvp_msg: function () { if (this._sock.rQwait("XVP version and message", 3, 1)) { return false; } this._sock.rQskip8(); // Padding @@ -1104,7 +1255,8 @@ var RFB; switch (xvp_msg) { case 0: // XVP_FAIL - this._updateState(this._rfb_state, "Operation Failed"); + Util.Error("Operation Failed"); + this._notification("XVP Operation Failed", 'error'); break; case 1: // XVP_INIT this._rfb_xvp_ver = xvp_ver; @@ -1112,7 +1264,8 @@ var RFB; this._onXvpInit(this._rfb_xvp_ver); break; default: - this._fail("Disconnected: illegal server XVP message " + xvp_msg); + this._fail("Unexpected server message", + "Illegal server XVP message " + xvp_msg); break; } @@ -1131,9 +1284,9 @@ var RFB; switch (msg_type) { case 0: // FramebufferUpdate var ret = this._framebufferUpdate(); - if (ret) { - this._sock.send(RFB.messages.fbUpdateRequests(this._display.getCleanDirtyReset(), - this._fb_width, this._fb_height)); + if (ret && !this._enabledContinuousUpdates) { + RFB.messages.fbUpdateRequest(this._sock, true, 0, 0, + this._fb_width, this._fb_height); } return ret; @@ -1148,16 +1301,41 @@ var RFB; case 3: // ServerCutText return this._handle_server_cut_text(); + case 150: // EndOfContinuousUpdates + var first = !(this._supportsContinuousUpdates); + this._supportsContinuousUpdates = true; + this._enabledContinuousUpdates = false; + if (first) { + this._enabledContinuousUpdates = true; + this._updateContinuousUpdates(); + Util.Info("Enabling continuous updates."); + } else { + // FIXME: We need to send a framebufferupdaterequest here + // if we add support for turning off continuous updates + } + return true; + + case 248: // ServerFence + return this._handle_server_fence_msg(); + case 250: // XVP return this._handle_xvp_msg(); default: - this._fail("Disconnected: illegal server message type " + msg_type); + this._fail("Unexpected server message", "Type:" + msg_type); Util.Debug("sock.rQslice(0, 30): " + this._sock.rQslice(0, 30)); return true; } }, + _onFlush: function() { + this._flushing = false; + // Resume processing + if (this._sock.rQlen() > 0) { + this._handle_message(); + } + }, + _framebufferUpdate: function () { var ret = true; var now; @@ -1172,10 +1350,18 @@ var RFB; now = (new Date()).getTime(); Util.Info("First FBU latency: " + (now - this._timing.fbu_rt_start)); } + + // Make sure the previous frame is fully rendered first + // to avoid building up an excessive queue + if (this._display.pending()) { + this._flushing = true; + this._display.flush(); + return false; + } } while (this._FBU.rects > 0) { - if (this._rfb_state !== "normal") { return false; } + if (this._rfb_connection_state !== 'connected') { return false; } if (this._sock.rQwait("FBU", this._FBU.bytes)) { return false; } if (this._FBU.bytes === 0) { @@ -1197,7 +1383,8 @@ var RFB; 'encodingName': this._encNames[this._FBU.encoding]}); if (!this._encNames[this._FBU.encoding]) { - this._fail("Disconnected: unsupported encoding " + + this._fail("Unexpected server message", + "Unsupported encoding " + this._FBU.encoding); return false; } @@ -1244,6 +1431,8 @@ var RFB; if (!ret) { return ret; } // need more data } + this._display.flip(); + this._onFBUComplete(this, {'x': this._FBU.x, 'y': this._FBU.y, 'width': this._FBU.width, 'height': this._FBU.height, @@ -1252,6 +1441,13 @@ var RFB; return true; // We finished this FBU }, + + _updateContinuousUpdates: function() { + if (!this._enabledContinuousUpdates) { return; } + + RFB.messages.enableContinuousUpdates(this._sock, true, 0, 0, + this._fb_width, this._fb_height); + } }; Util.make_properties(RFB, [ @@ -1269,15 +1465,17 @@ var RFB; ['viewportDrag', 'rw', 'bool'], // Move the viewport on mouse drags // Callback functions - ['onUpdateState', 'rw', 'func'], // onUpdateState(rfb, state, oldstate, statusMsg): RFB state update/change - ['onPasswordRequired', 'rw', 'func'], // onPasswordRequired(rfb): VNC password is required + ['onUpdateState', 'rw', 'func'], // onUpdateState(rfb, state, oldstate): connection state change + ['onNotification', 'rw', 'func'], // onNotification(rfb, msg, level, options): notification for the UI + ['onDisconnected', 'rw', 'func'], // onDisconnected(rfb, reason): disconnection finished + ['onPasswordRequired', 'rw', 'func'], // onPasswordRequired(rfb, msg): VNC password is required ['onClipboard', 'rw', 'func'], // onClipboard(rfb, text): RFB clipboard contents received ['onBell', 'rw', 'func'], // onBell(rfb): RFB Bell message received ['onFBUReceive', 'rw', 'func'], // onFBUReceive(rfb, fbu): RFB FBU received but not yet processed ['onFBUComplete', 'rw', 'func'], // onFBUComplete(rfb, fbu): RFB FBU received and processed ['onFBResize', 'rw', 'func'], // onFBResize(rfb, width, height): frame buffer resized ['onDesktopName', 'rw', 'func'], // onDesktopName(rfb, name): desktop name received - ['onXvpInit', 'rw', 'func'], // onXvpInit(version): XVP extensions active for this connection + ['onXvpInit', 'rw', 'func'] // onXvpInit(version): XVP extensions active for this connection ]); RFB.prototype.set_local_cursor = function (cursor) { @@ -1292,6 +1490,27 @@ var RFB; this._display.disableLocalCursor(); } } + + // Need to send an updated list of encodings if we are connected + if (this._rfb_connection_state === "connected") { + RFB.messages.clientEncodings(this._sock, this._encodings, cursor, + this._true_color); + } + }; + + RFB.prototype.set_view_only = function (view_only) { + this._view_only = view_only; + + if (this._rfb_connection_state === "connecting" || + this._rfb_connection_state === "connected") { + if (view_only) { + this._keyboard.ungrab(); + this._mouse.ungrab(); + } else { + this._keyboard.grab(); + this._mouse.grab(); + } + } }; RFB.prototype.get_display = function () { return this._display; }; @@ -1300,64 +1519,234 @@ var RFB; // Class Methods RFB.messages = { - keyEvent: function (keysym, down) { - var arr = [4]; - arr.push8(down); - arr.push16(0); - arr.push32(keysym); - return arr; + keyEvent: function (sock, keysym, down) { + var buff = sock._sQ; + var offset = sock._sQlen; + + buff[offset] = 4; // msg-type + buff[offset + 1] = down; + + buff[offset + 2] = 0; + buff[offset + 3] = 0; + + buff[offset + 4] = (keysym >> 24); + buff[offset + 5] = (keysym >> 16); + buff[offset + 6] = (keysym >> 8); + buff[offset + 7] = keysym; + + sock._sQlen += 8; + sock.flush(); }, - pointerEvent: function (x, y, mask) { - var arr = [5]; // msg-type - arr.push8(mask); - arr.push16(x); - arr.push16(y); - return arr; + QEMUExtendedKeyEvent: function (sock, keysym, down, keycode) { + function getRFBkeycode(xt_scancode) { + var upperByte = (keycode >> 8); + var lowerByte = (keycode & 0x00ff); + if (upperByte === 0xe0 && lowerByte < 0x7f) { + lowerByte = lowerByte | 0x80; + return lowerByte; + } + return xt_scancode; + } + + var buff = sock._sQ; + var offset = sock._sQlen; + + buff[offset] = 255; // msg-type + buff[offset + 1] = 0; // sub msg-type + + buff[offset + 2] = (down >> 8); + buff[offset + 3] = down; + + buff[offset + 4] = (keysym >> 24); + buff[offset + 5] = (keysym >> 16); + buff[offset + 6] = (keysym >> 8); + buff[offset + 7] = keysym; + + var RFBkeycode = getRFBkeycode(keycode); + + buff[offset + 8] = (RFBkeycode >> 24); + buff[offset + 9] = (RFBkeycode >> 16); + buff[offset + 10] = (RFBkeycode >> 8); + buff[offset + 11] = RFBkeycode; + + sock._sQlen += 12; + sock.flush(); + }, + + pointerEvent: function (sock, x, y, mask) { + var buff = sock._sQ; + var offset = sock._sQlen; + + buff[offset] = 5; // msg-type + + buff[offset + 1] = mask; + + buff[offset + 2] = x >> 8; + buff[offset + 3] = x; + + buff[offset + 4] = y >> 8; + buff[offset + 5] = y; + + sock._sQlen += 6; + sock.flush(); }, // TODO(directxman12): make this unicode compatible? - clientCutText: function (text) { - var arr = [6]; // msg-type - arr.push8(0); // padding - arr.push8(0); // padding - arr.push8(0); // padding - arr.push32(text.length); + clientCutText: function (sock, text) { + var buff = sock._sQ; + var offset = sock._sQlen; + + buff[offset] = 6; // msg-type + + buff[offset + 1] = 0; // padding + buff[offset + 2] = 0; // padding + buff[offset + 3] = 0; // padding + var n = text.length; + + buff[offset + 4] = n >> 24; + buff[offset + 5] = n >> 16; + buff[offset + 6] = n >> 8; + buff[offset + 7] = n; + for (var i = 0; i < n; i++) { - arr.push(text.charCodeAt(i)); + buff[offset + 8 + i] = text.charCodeAt(i); } - return arr; + sock._sQlen += 8 + n; + sock.flush(); }, - pixelFormat: function (bpp, depth, true_color) { - var arr = [0]; // msg-type - arr.push8(0); // padding - arr.push8(0); // padding - arr.push8(0); // padding + setDesktopSize: function (sock, width, height, id, flags) { + var buff = sock._sQ; + var offset = sock._sQlen; - arr.push8(bpp * 8); // bits-per-pixel - arr.push8(depth * 8); // depth - arr.push8(0); // little-endian - arr.push8(true_color ? 1 : 0); // true-color + buff[offset] = 251; // msg-type + buff[offset + 1] = 0; // padding + buff[offset + 2] = width >> 8; // width + buff[offset + 3] = width; + buff[offset + 4] = height >> 8; // height + buff[offset + 5] = height; - arr.push16(255); // red-max - arr.push16(255); // green-max - arr.push16(255); // blue-max - arr.push8(16); // red-shift - arr.push8(8); // green-shift - arr.push8(0); // blue-shift + buff[offset + 6] = 1; // number-of-screens + buff[offset + 7] = 0; // padding - arr.push8(0); // padding - arr.push8(0); // padding - arr.push8(0); // padding - return arr; + // screen array + buff[offset + 8] = id >> 24; // id + buff[offset + 9] = id >> 16; + buff[offset + 10] = id >> 8; + buff[offset + 11] = id; + buff[offset + 12] = 0; // x-position + buff[offset + 13] = 0; + buff[offset + 14] = 0; // y-position + buff[offset + 15] = 0; + buff[offset + 16] = width >> 8; // width + buff[offset + 17] = width; + buff[offset + 18] = height >> 8; // height + buff[offset + 19] = height; + buff[offset + 20] = flags >> 24; // flags + buff[offset + 21] = flags >> 16; + buff[offset + 22] = flags >> 8; + buff[offset + 23] = flags; + + sock._sQlen += 24; + sock.flush(); }, - clientEncodings: function (encodings, local_cursor, true_color) { - var i, encList = []; + clientFence: function (sock, flags, payload) { + var buff = sock._sQ; + var offset = sock._sQlen; + buff[offset] = 248; // msg-type + + buff[offset + 1] = 0; // padding + buff[offset + 2] = 0; // padding + buff[offset + 3] = 0; // padding + + buff[offset + 4] = flags >> 24; // flags + buff[offset + 5] = flags >> 16; + buff[offset + 6] = flags >> 8; + buff[offset + 7] = flags; + + var n = payload.length; + + buff[offset + 8] = n; // length + + for (var i = 0; i < n; i++) { + buff[offset + 9 + i] = payload.charCodeAt(i); + } + + sock._sQlen += 9 + n; + sock.flush(); + }, + + enableContinuousUpdates: function (sock, enable, x, y, width, height) { + var buff = sock._sQ; + var offset = sock._sQlen; + + buff[offset] = 150; // msg-type + buff[offset + 1] = enable; // enable-flag + + buff[offset + 2] = x >> 8; // x + buff[offset + 3] = x; + buff[offset + 4] = y >> 8; // y + buff[offset + 5] = y; + buff[offset + 6] = width >> 8; // width + buff[offset + 7] = width; + buff[offset + 8] = height >> 8; // height + buff[offset + 9] = height; + + sock._sQlen += 10; + sock.flush(); + }, + + pixelFormat: function (sock, bpp, depth, true_color) { + var buff = sock._sQ; + var offset = sock._sQlen; + + buff[offset] = 0; // msg-type + + buff[offset + 1] = 0; // padding + buff[offset + 2] = 0; // padding + buff[offset + 3] = 0; // padding + + buff[offset + 4] = bpp * 8; // bits-per-pixel + buff[offset + 5] = depth * 8; // depth + buff[offset + 6] = 0; // little-endian + buff[offset + 7] = true_color ? 1 : 0; // true-color + + buff[offset + 8] = 0; // red-max + buff[offset + 9] = 255; // red-max + + buff[offset + 10] = 0; // green-max + buff[offset + 11] = 255; // green-max + + buff[offset + 12] = 0; // blue-max + buff[offset + 13] = 255; // blue-max + + buff[offset + 14] = 16; // red-shift + buff[offset + 15] = 8; // green-shift + buff[offset + 16] = 0; // blue-shift + + buff[offset + 17] = 0; // padding + buff[offset + 18] = 0; // padding + buff[offset + 19] = 0; // padding + + sock._sQlen += 20; + sock.flush(); + }, + + clientEncodings: function (sock, encodings, local_cursor, true_color) { + var buff = sock._sQ; + var offset = sock._sQlen; + + buff[offset] = 2; // msg-type + buff[offset + 1] = 0; // padding + + // offset + 2 and offset + 3 are encoding count + + var i, j = offset + 4, cnt = 0; for (i = 0; i < encodings.length; i++) { if (encodings[i][0] === "Cursor" && !local_cursor) { Util.Debug("Skipping Cursor pseudo-encoding"); @@ -1365,56 +1754,48 @@ var RFB; // TODO: remove this when we have tight+non-true-color Util.Warn("Skipping tight as it is only supported with true color"); } else { - encList.push(encodings[i][1]); + var enc = encodings[i][1]; + buff[j] = enc >> 24; + buff[j + 1] = enc >> 16; + buff[j + 2] = enc >> 8; + buff[j + 3] = enc; + + j += 4; + cnt++; } } - var arr = [2]; // msg-type - arr.push8(0); // padding + buff[offset + 2] = cnt >> 8; + buff[offset + 3] = cnt; - arr.push16(encList.length); // encoding count - for (i = 0; i < encList.length; i++) { - arr.push32(encList[i]); - } - - return arr; + sock._sQlen += j - offset; + sock.flush(); }, - fbUpdateRequests: function (cleanDirty, fb_width, fb_height) { - var arr = []; + fbUpdateRequest: function (sock, incremental, x, y, w, h) { + var buff = sock._sQ; + var offset = sock._sQlen; - var cb = cleanDirty.cleanBox; - var w, h; - if (cb.w > 0 && cb.h > 0) { - w = typeof cb.w === "undefined" ? fb_width : cb.w; - h = typeof cb.h === "undefined" ? fb_height : cb.h; - // Request incremental for clean box - arr = arr.concat(RFB.messages.fbUpdateRequest(1, cb.x, cb.y, w, h)); - } - - for (var i = 0; i < cleanDirty.dirtyBoxes.length; i++) { - var db = cleanDirty.dirtyBoxes[i]; - // Force all (non-incremental) for dirty box - w = typeof db.w === "undefined" ? fb_width : db.w; - h = typeof db.h === "undefined" ? fb_height : db.h; - arr = arr.concat(RFB.messages.fbUpdateRequest(0, db.x, db.y, w, h)); - } - - return arr; - }, - - fbUpdateRequest: function (incremental, x, y, w, h) { if (typeof(x) === "undefined") { x = 0; } if (typeof(y) === "undefined") { y = 0; } - var arr = [3]; // msg-type - arr.push8(incremental); - arr.push16(x); - arr.push16(y); - arr.push16(w); - arr.push16(h); + buff[offset] = 3; // msg-type + buff[offset + 1] = incremental ? 1 : 0; - return arr; + buff[offset + 2] = (x >> 8) & 0xFF; + buff[offset + 3] = x & 0xFF; + + buff[offset + 4] = (y >> 8) & 0xFF; + buff[offset + 5] = y & 0xFF; + + buff[offset + 6] = (w >> 8) & 0xFF; + buff[offset + 7] = w & 0xFF; + + buff[offset + 8] = (h >> 8) & 0xFF; + buff[offset + 9] = h & 0xFF; + + sock._sQlen += 10; + sock.flush(); } }; @@ -1426,10 +1807,6 @@ var RFB; return (new DES(passwd)).encrypt(challenge); }; - RFB.extract_data_uri = function (arr) { - return ";base64," + Base64.encode(arr); - }; - RFB.encodingHandlers = { RAW: function () { if (this._FBU.lines === 0) { @@ -1460,15 +1837,10 @@ var RFB; COPYRECT: function () { this._FBU.bytes = 4; if (this._sock.rQwait("COPYRECT", 4)) { return false; } - this._display.renderQ_push({ - 'type': 'copy', - 'old_x': this._sock.rQshift16(), - 'old_y': this._sock.rQshift16(), - 'x': this._FBU.x, - 'y': this._FBU.y, - 'width': this._FBU.width, - 'height': this._FBU.height - }); + this._display.copyImage(this._sock.rQshift16(), this._sock.rQshift16(), + this._FBU.x, this._FBU.y, this._FBU.width, + this._FBU.height); + this._FBU.rects--; this._FBU.bytes = 0; return true; @@ -1521,7 +1893,8 @@ var RFB; if (this._sock.rQwait("HEXTILE subencoding", this._FBU.bytes)) { return false; } var subencoding = rQ[rQi]; // Peek if (subencoding > 30) { // Raw - this._fail("Disconnected: illegal hextile subencoding " + subencoding); + this._fail("Unexpected server message", + "Illegal hextile subencoding: " + subencoding); return false; } @@ -1573,11 +1946,21 @@ var RFB; rQi += this._FBU.bytes - 1; } else { if (this._FBU.subencoding & 0x02) { // Background - this._FBU.background = rQ.slice(rQi, rQi + this._fb_Bpp); + if (this._fb_Bpp == 1) { + this._FBU.background = rQ[rQi]; + } else { + // fb_Bpp is 4 + this._FBU.background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; + } rQi += this._fb_Bpp; } if (this._FBU.subencoding & 0x04) { // Foreground - this._FBU.foreground = rQ.slice(rQi, rQi + this._fb_Bpp); + if (this._fb_Bpp == 1) { + this._FBU.foreground = rQ[rQi]; + } else { + // this._fb_Bpp is 4 + this._FBU.foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; + } rQi += this._fb_Bpp; } @@ -1589,7 +1972,12 @@ var RFB; for (var s = 0; s < subrects; s++) { var color; if (this._FBU.subencoding & 0x10) { // SubrectsColoured - color = rQ.slice(rQi, rQi + this._fb_Bpp); + if (this._fb_Bpp === 1) { + color = rQ[rQi]; + } else { + // _fb_Bpp is 4 + color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; + } rQi += this._fb_Bpp; } else { color = this._FBU.foreground; @@ -1638,7 +2026,9 @@ var RFB; display_tight: function (isTightPNG) { if (this._fb_depth === 1) { - this._fail("Tight protocol handler only implements true color mode"); + this._fail("Internal error", + "Tight protocol handler only implements " + + "true color mode"); } this._FBU.bytes = 1; // compression-control byte @@ -1655,7 +2045,7 @@ var RFB; var resetStreams = 0; var streamId = -1; - var decompress = function (data) { + var decompress = function (data, expected) { for (var i = 0; i < 4; i++) { if ((resetStreams >> i) & 1) { this._FBU.zlibs[i].reset(); @@ -1663,61 +2053,96 @@ var RFB; } } - var uncompressed = this._FBU.zlibs[streamId].uncompress(data, 0); - if (uncompressed.status !== 0) { + //var uncompressed = this._FBU.zlibs[streamId].uncompress(data, 0); + var uncompressed = this._FBU.zlibs[streamId].inflate(data, true, expected); + /*if (uncompressed.status !== 0) { Util.Error("Invalid data in zlib stream"); - } + }*/ - return uncompressed.data; + //return uncompressed.data; + return uncompressed; }.bind(this); - var indexedToRGB = function (data, numColors, palette, width, height) { + var indexedToRGBX2Color = function (data, palette, width, height) { // Convert indexed (palette based) image data to RGB // TODO: reduce number of calculations inside loop - var dest = []; - var x, y, dp, sp; - if (numColors === 2) { - var w = Math.floor((width + 7) / 8); - var w1 = Math.floor(width / 8); + var dest = this._destBuff; + var w = Math.floor((width + 7) / 8); + var w1 = Math.floor(width / 8); - for (y = 0; y < height; y++) { - var b; - for (x = 0; x < w1; x++) { - for (b = 7; b >= 0; b--) { - dp = (y * width + x * 8 + 7 - b) * 3; - sp = (data[y * w + x] >> b & 1) * 3; - dest[dp] = palette[sp]; - dest[dp + 1] = palette[sp + 1]; - dest[dp + 2] = palette[sp + 2]; - } - } - - for (b = 7; b >= 8 - width % 8; b--) { - dp = (y * width + x * 8 + 7 - b) * 3; - sp = (data[y * w + x] >> b & 1) * 3; + /*for (var y = 0; y < height; y++) { + var b, x, dp, sp; + var yoffset = y * width; + var ybitoffset = y * w; + var xoffset, targetbyte; + for (x = 0; x < w1; x++) { + xoffset = yoffset + x * 8; + targetbyte = data[ybitoffset + x]; + for (b = 7; b >= 0; b--) { + dp = (xoffset + 7 - b) * 3; + sp = (targetbyte >> b & 1) * 3; dest[dp] = palette[sp]; dest[dp + 1] = palette[sp + 1]; dest[dp + 2] = palette[sp + 2]; } } - } else { - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - dp = (y * width + x) * 3; - sp = data[y * width + x] * 3; + + xoffset = yoffset + x * 8; + targetbyte = data[ybitoffset + x]; + for (b = 7; b >= 8 - width % 8; b--) { + dp = (xoffset + 7 - b) * 3; + sp = (targetbyte >> b & 1) * 3; + dest[dp] = palette[sp]; + dest[dp + 1] = palette[sp + 1]; + dest[dp + 2] = palette[sp + 2]; + } + }*/ + + for (var y = 0; y < height; y++) { + var b, x, dp, sp; + for (x = 0; x < w1; x++) { + for (b = 7; b >= 0; b--) { + dp = (y * width + x * 8 + 7 - b) * 4; + sp = (data[y * w + x] >> b & 1) * 3; dest[dp] = palette[sp]; dest[dp + 1] = palette[sp + 1]; dest[dp + 2] = palette[sp + 2]; + dest[dp + 3] = 255; } } + + for (b = 7; b >= 8 - width % 8; b--) { + dp = (y * width + x * 8 + 7 - b) * 4; + sp = (data[y * w + x] >> b & 1) * 3; + dest[dp] = palette[sp]; + dest[dp + 1] = palette[sp + 1]; + dest[dp + 2] = palette[sp + 2]; + dest[dp + 3] = 255; + } + } + + return dest; + }.bind(this); + + var indexedToRGBX = function (data, palette, width, height) { + // Convert indexed (palette based) image data to RGB + var dest = this._destBuff; + var total = width * height * 4; + for (var i = 0, j = 0; i < total; i += 4, j++) { + var sp = data[j] * 3; + dest[i] = palette[sp]; + dest[i + 1] = palette[sp + 1]; + dest[i + 2] = palette[sp + 2]; + dest[i + 3] = 255; } return dest; }.bind(this); - var rQ = this._sock.get_rQ(); var rQi = this._sock.get_rQi(); - var cmode, clength, data; + var rQ = this._sock.rQwhole(); + var cmode, data; + var cl_header, cl_data; var handlePalette = function () { var numColors = rQ[rQi + 2] + 1; @@ -1730,37 +2155,51 @@ var RFB; var raw = false; if (rowSize * this._FBU.height < 12) { raw = true; - clength = [0, rowSize * this._FBU.height]; + cl_header = 0; + cl_data = rowSize * this._FBU.height; + //clength = [0, rowSize * this._FBU.height]; } else { - clength = RFB.encodingHandlers.getTightCLength(this._sock.rQslice(3 + paletteSize, - 3 + paletteSize + 3)); + // begin inline getTightCLength (returning two-item arrays is bad for performance with GC) + var cl_offset = rQi + 3 + paletteSize; + cl_header = 1; + cl_data = 0; + cl_data += rQ[cl_offset] & 0x7f; + if (rQ[cl_offset] & 0x80) { + cl_header++; + cl_data += (rQ[cl_offset + 1] & 0x7f) << 7; + if (rQ[cl_offset + 1] & 0x80) { + cl_header++; + cl_data += rQ[cl_offset + 2] << 14; + } + } + // end inline getTightCLength } - this._FBU.bytes += clength[0] + clength[1]; + this._FBU.bytes += cl_header + cl_data; if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) { return false; } // Shift ctl, filter id, num colors, palette entries, and clength off this._sock.rQskipBytes(3); - var palette = this._sock.rQshiftBytes(paletteSize); - this._sock.rQskipBytes(clength[0]); + //var palette = this._sock.rQshiftBytes(paletteSize); + this._sock.rQshiftTo(this._paletteBuff, paletteSize); + this._sock.rQskipBytes(cl_header); if (raw) { - data = this._sock.rQshiftBytes(clength[1]); + data = this._sock.rQshiftBytes(cl_data); } else { - data = decompress(this._sock.rQshiftBytes(clength[1])); + data = decompress(this._sock.rQshiftBytes(cl_data), rowSize * this._FBU.height); } // Convert indexed (palette based) image data to RGB - var rgb = indexedToRGB(data, numColors, palette, this._FBU.width, this._FBU.height); + var rgbx; + if (numColors == 2) { + rgbx = indexedToRGBX2Color(data, this._paletteBuff, this._FBU.width, this._FBU.height); + this._display.blitRgbxImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, rgbx, 0, false); + } else { + rgbx = indexedToRGBX(data, this._paletteBuff, this._FBU.width, this._FBU.height); + this._display.blitRgbxImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, rgbx, 0, false); + } - this._display.renderQ_push({ - 'type': 'blitRgb', - 'data': rgb, - 'x': this._FBU.x, - 'y': this._FBU.y, - 'width': this._FBU.width, - 'height': this._FBU.height - }); return true; }.bind(this); @@ -1770,30 +2209,37 @@ var RFB; var uncompressedSize = this._FBU.width * this._FBU.height * this._fb_depth; if (uncompressedSize < 12) { raw = true; - clength = [0, uncompressedSize]; + cl_header = 0; + cl_data = uncompressedSize; } else { - clength = RFB.encodingHandlers.getTightCLength(this._sock.rQslice(1, 4)); + // begin inline getTightCLength (returning two-item arrays is for peformance with GC) + var cl_offset = rQi + 1; + cl_header = 1; + cl_data = 0; + cl_data += rQ[cl_offset] & 0x7f; + if (rQ[cl_offset] & 0x80) { + cl_header++; + cl_data += (rQ[cl_offset + 1] & 0x7f) << 7; + if (rQ[cl_offset + 1] & 0x80) { + cl_header++; + cl_data += rQ[cl_offset + 2] << 14; + } + } + // end inline getTightCLength } - this._FBU.bytes = 1 + clength[0] + clength[1]; + this._FBU.bytes = 1 + cl_header + cl_data; if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) { return false; } // Shift ctl, clength off - this._sock.rQshiftBytes(1 + clength[0]); + this._sock.rQshiftBytes(1 + cl_header); if (raw) { - data = this._sock.rQshiftBytes(clength[1]); + data = this._sock.rQshiftBytes(cl_data); } else { - data = decompress(this._sock.rQshiftBytes(clength[1])); + data = decompress(this._sock.rQshiftBytes(cl_data), uncompressedSize); } - this._display.renderQ_push({ - 'type': 'blitRgb', - 'data': data, - 'x': this._FBU.x, - 'y': this._FBU.y, - 'width': this._FBU.width, - 'height': this._FBU.height - }); + this._display.blitRgbImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, data, 0, false); return true; }.bind(this); @@ -1812,10 +2258,13 @@ var RFB; else if (ctl === 0x0A) cmode = "png"; else if (ctl & 0x04) cmode = "filter"; else if (ctl < 0x04) cmode = "copy"; - else return this._fail("Illegal tight compression received, ctl: " + ctl); + else return this._fail("Unexpected server message", + "Illegal tight compression received, " + + "ctl: " + ctl); if (isTightPNG && (cmode === "filter" || cmode === "copy")) { - return this._fail("filter/copy received in tightPNG mode"); + return this._fail("Unexpected server message", + "filter/copy received in tightPNG mode"); } switch (cmode) { @@ -1841,35 +2290,33 @@ var RFB; // Determine FBU.bytes switch (cmode) { case "fill": - this._sock.rQskip8(); // shift off ctl - var color = this._sock.rQshiftBytes(this._fb_depth); - this._display.renderQ_push({ - 'type': 'fill', - 'x': this._FBU.x, - 'y': this._FBU.y, - 'width': this._FBU.width, - 'height': this._FBU.height, - 'color': [color[2], color[1], color[0]] - }); + // skip ctl byte + this._display.fillRect(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, [rQ[rQi + 3], rQ[rQi + 2], rQ[rQi + 1]], false); + this._sock.rQskipBytes(4); break; case "png": case "jpeg": - clength = RFB.encodingHandlers.getTightCLength(this._sock.rQslice(1, 4)); - this._FBU.bytes = 1 + clength[0] + clength[1]; // ctl + clength size + jpeg-data + // begin inline getTightCLength (returning two-item arrays is for peformance with GC) + var cl_offset = rQi + 1; + cl_header = 1; + cl_data = 0; + cl_data += rQ[cl_offset] & 0x7f; + if (rQ[cl_offset] & 0x80) { + cl_header++; + cl_data += (rQ[cl_offset + 1] & 0x7f) << 7; + if (rQ[cl_offset + 1] & 0x80) { + cl_header++; + cl_data += rQ[cl_offset + 2] << 14; + } + } + // end inline getTightCLength + this._FBU.bytes = 1 + cl_header + cl_data; // ctl + clength size + jpeg-data if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) { return false; } // We have everything, render it - this._sock.rQskipBytes(1 + clength[0]); // shift off clt + compact length - var img = new Image(); - img.src = "data: image/" + cmode + - RFB.extract_data_uri(this._sock.rQshiftBytes(clength[1])); - this._display.renderQ_push({ - 'type': 'img', - 'img': img, - 'x': this._FBU.x, - 'y': this._FBU.y - }); - img = null; + this._sock.rQskipBytes(1 + cl_header); // shift off clt + compact length + data = this._sock.rQshiftBytes(cl_data); + this._display.imageRect(this._FBU.x, this._FBU.y, "image/" + cmode, data); break; case "filter": var filterId = rQ[rQi + 1]; @@ -1878,8 +2325,9 @@ var RFB; } else { // Filter 0, Copy could be valid here, but servers don't send it as an explicit filter // Filter 2, Gradient is valid but not use if jpeg is enabled - // TODO(directxman12): why aren't we just calling '_fail' here - throw new Error("Unsupported tight subencoding received, filter: " + filterId); + this._fail("Unexpected server message", + "Unsupported tight subencoding received, " + + "filter: " + filterId); } break; case "copy": @@ -1905,9 +2353,11 @@ var RFB; handle_FB_resize: function () { this._fb_width = this._FBU.width; this._fb_height = this._FBU.height; + this._destBuff = new Uint8Array(this._fb_width * this._fb_height * 4); this._display.resize(this._fb_width, this._fb_height); this._onFBResize(this, this._fb_width, this._fb_height); this._timing.fbu_rt_start = (new Date()).getTime(); + this._updateContinuousUpdates(); this._FBU.bytes = 0; this._FBU.rects -= 1; @@ -1927,9 +2377,9 @@ var RFB; this._sock.rQskipBytes(1); // number-of-screens this._sock.rQskipBytes(3); // padding - for (var i=0; i 0) || + (navigator.msMaxTouchPoints > 0); +window.addEventListener('touchstart', function onFirstTouch() { + Util.isTouchDevice = true; + window.removeEventListener('touchstart', onFirstTouch, false); +}, false); + +Util._cursor_uris_supported = null; + +Util.browserSupportsCursorURIs = function () { + if (Util._cursor_uris_supported === null) { + try { + var target = document.createElement('canvas'); + target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default'; + + if (target.style.cursor) { + Util.Info("Data URI scheme cursor supported"); + Util._cursor_uris_supported = true; + } else { + Util.Warn("Data URI scheme cursor not supported"); + Util._cursor_uris_supported = false; + } + } catch (exc) { + Util.Error("Data URI scheme cursor test exception: " + exc); + Util._cursor_uris_supported = false; + } + } + + return Util._cursor_uris_supported; +}; + +// Set browser engine versions. Based on mootools. +Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}; + +(function () { + "use strict"; + // 'presto': (function () { return (!window.opera) ? false : true; }()), + var detectPresto = function () { + return !!window.opera; + }; + + // 'trident': (function () { return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); + var detectTrident = function () { + if (!window.ActiveXObject) { + return false; + } else { + if (window.XMLHttpRequest) { + return (document.querySelectorAll) ? 6 : 5; + } else { + return 4; + } + } + }; + + // 'webkit': (function () { try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()), + var detectInitialWebkit = function () { + try { + if (navigator.taintEnabled) { + return false; + } else { + if (Util.Features.xpath) { + return (Util.Features.query) ? 525 : 420; + } else { + return 419; + } + } + } catch (e) { + return false; + } + }; + + var detectActualWebkit = function (initial_ver) { + var re = /WebKit\/([0-9\.]*) /; + var str_ver = (navigator.userAgent.match(re) || ['', initial_ver])[1]; + return parseFloat(str_ver, 10); + }; + + // 'gecko': (function () { return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19ssName) ? 19 : 18 : 18); }()) + var detectGecko = function () { + /* jshint -W041 */ + if (!document.getBoxObjectFor && window.mozInnerScreenX == null) { + return false; + } else { + return (document.getElementsByClassName) ? 19 : 18; + } + /* jshint +W041 */ + }; + + Util.Engine = { + // Version detection break in Opera 11.60 (errors on arguments.callee.caller reference) + //'presto': (function() { + // return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()), + 'presto': detectPresto(), + 'trident': detectTrident(), + 'webkit': detectInitialWebkit(), + 'gecko': detectGecko() + }; + + if (Util.Engine.webkit) { + // Extract actual webkit version if available + Util.Engine.webkit = detectActualWebkit(Util.Engine.webkit); + } +})(); + +Util.Flash = (function () { + "use strict"; + var v, version; + try { + v = navigator.plugins['Shockwave Flash'].description; + } catch (err1) { + try { + v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); + } catch (err2) { + v = '0 r0'; + } + } + version = v.match(/\d+/g); + return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; +}()); + + +Util.Localisation = { + // Currently configured language + language: 'en', + + // Configure suitable language based on user preferences + setup: function (supportedLanguages) { + var userLanguages; + + Util.Localisation.language = 'en'; // Default: US English + + /* + * Navigator.languages only available in Chrome (32+) and FireFox (32+) + * Fall back to navigator.language for other browsers + */ + if (typeof window.navigator.languages == 'object') { + userLanguages = window.navigator.languages; + } else { + userLanguages = [navigator.language || navigator.userLanguage]; + } + + for (var i = 0;i < userLanguages.length;i++) { + var userLang = userLanguages[i]; + userLang = userLang.toLowerCase(); + userLang = userLang.replace("_", "-"); + userLang = userLang.split("-"); + + // Built-in default? + if ((userLang[0] === 'en') && + ((userLang[1] === undefined) || (userLang[1] === 'us'))) { + return; + } + + // First pass: perfect match + for (var j = 0;j < supportedLanguages.length;j++) { + var supLang = supportedLanguages[j]; + supLang = supLang.toLowerCase(); + supLang = supLang.replace("_", "-"); + supLang = supLang.split("-"); + + if (userLang[0] !== supLang[0]) + continue; + if (userLang[1] !== supLang[1]) + continue; + + Util.Localisation.language = supportedLanguages[j]; + return; + } + + // Second pass: fallback + for (var j = 0;j < supportedLanguages.length;j++) { + supLang = supportedLanguages[j]; + supLang = supLang.toLowerCase(); + supLang = supLang.replace("_", "-"); + supLang = supLang.split("-"); + + if (userLang[0] !== supLang[0]) + continue; + if (supLang[1] !== undefined) + continue; + + Util.Localisation.language = supportedLanguages[j]; + return; + } + } + }, + + // Retrieve localised text + get: function (id) { + if (typeof Language !== 'undefined' && Language[id]) { + return Language[id]; + } else { + return id; + } + }, + + // Traverses the DOM and translates relevant fields + // See https://html.spec.whatwg.org/multipage/dom.html#attr-translate + translateDOM: function () { + function process(elem, enabled) { + function isAnyOf(searchElement, items) { + return items.indexOf(searchElement) !== -1; + } + + function translateAttribute(elem, attr) { + var str = elem.getAttribute(attr); + str = Util.Localisation.get(str); + elem.setAttribute(attr, str); + } + + function translateTextNode(node) { + var str = node.data.trim(); + str = Util.Localisation.get(str); + node.data = str; + } + + if (elem.hasAttribute("translate")) { + if (isAnyOf(elem.getAttribute("translate"), ["", "yes"])) { + enabled = true; + } else if (isAnyOf(elem.getAttribute("translate"), ["no"])) { + enabled = false; + } + } + + if (enabled) { + if (elem.hasAttribute("abbr") && + elem.tagName === "TH") { + translateAttribute(elem, "abbr"); + } + if (elem.hasAttribute("alt") && + isAnyOf(elem.tagName, ["AREA", "IMG", "INPUT"])) { + translateAttribute(elem, "alt"); + } + if (elem.hasAttribute("download") && + isAnyOf(elem.tagName, ["A", "AREA"])) { + translateAttribute(elem, "download"); + } + if (elem.hasAttribute("label") && + isAnyOf(elem.tagName, ["MENUITEM", "MENU", "OPTGROUP", + "OPTION", "TRACK"])) { + translateAttribute(elem, "label"); + } + // FIXME: Should update "lang" + if (elem.hasAttribute("placeholder") && + isAnyOf(elem.tagName, ["INPUT", "TEXTAREA"])) { + translateAttribute(elem, "placeholder"); + } + if (elem.hasAttribute("title")) { + translateAttribute(elem, "title"); + } + if (elem.hasAttribute("value") && + elem.tagName === "INPUT" && + isAnyOf(elem.getAttribute("type"), ["reset", "button"])) { + translateAttribute(elem, "value"); + } + } + + for (var i = 0;i < elem.childNodes.length;i++) { + node = elem.childNodes[i]; + if (node.nodeType === node.ELEMENT_NODE) { + process(node, enabled); + } else if (node.nodeType === node.TEXT_NODE && enabled) { + translateTextNode(node); + } + } + } + + process(document.body, true); + }, +}; + +// Emulate Element.setCapture() when not supported + +Util._captureRecursion = false; +Util._captureProxy = function (e) { + // Recursion protection as we'll see our own event + if (Util._captureRecursion) return; + + // Clone the event as we cannot dispatch an already dispatched event + var newEv = new e.constructor(e.type, e); + + Util._captureRecursion = true; + Util._captureElem.dispatchEvent(newEv); + Util._captureRecursion = false; + + // Avoid double events + e.stopPropagation(); + + // Respect the wishes of the redirected event handlers + if (newEv.defaultPrevented) { + e.preventDefault(); + } + + // Implicitly release the capture on button release + if ((e.type === "mouseup") || (e.type === "touchend")) { + Util.releaseCapture(); + } +}; + +// Follow cursor style of target element +Util._captureElemChanged = function() { + var captureElem = document.getElementById("noVNC_mouse_capture_elem"); + captureElem.style.cursor = window.getComputedStyle(Util._captureElem).cursor; +}; +Util._captureObserver = new MutationObserver(Util._captureElemChanged); + +Util._captureIndex = 0; + +Util.setCapture = function (elem) { + if (elem.setCapture) { + + elem.setCapture(); + + // IE releases capture on 'click' events which might not trigger + elem.addEventListener('mouseup', Util.releaseCapture); + elem.addEventListener('touchend', Util.releaseCapture); + + } else { + // Release any existing capture in case this method is + // called multiple times without coordination + Util.releaseCapture(); + + // Safari on iOS 9 has a broken constructor for TouchEvent. + // We are fine in this case however, since Safari seems to + // have some sort of implicit setCapture magic anyway. + if (window.TouchEvent !== undefined) { + try { + new TouchEvent("touchstart"); + } catch (TypeError) { + return; + } + } + + var captureElem = document.getElementById("noVNC_mouse_capture_elem"); + + if (captureElem === null) { + captureElem = document.createElement("div"); + captureElem.id = "noVNC_mouse_capture_elem"; + captureElem.style.position = "fixed"; + captureElem.style.top = "0px"; + captureElem.style.left = "0px"; + captureElem.style.width = "100%"; + captureElem.style.height = "100%"; + captureElem.style.zIndex = 10000; + captureElem.style.display = "none"; + document.body.appendChild(captureElem); + + // This is to make sure callers don't get confused by having + // our blocking element as the target + captureElem.addEventListener('contextmenu', Util._captureProxy); + + captureElem.addEventListener('mousemove', Util._captureProxy); + captureElem.addEventListener('mouseup', Util._captureProxy); + + captureElem.addEventListener('touchmove', Util._captureProxy); + captureElem.addEventListener('touchend', Util._captureProxy); + } + + Util._captureElem = elem; + Util._captureIndex++; + + // Track cursor and get initial cursor + Util._captureObserver.observe(elem, {attributes:true}); + Util._captureElemChanged(); + + captureElem.style.display = null; + + // We listen to events on window in order to keep tracking if it + // happens to leave the viewport + window.addEventListener('mousemove', Util._captureProxy); + window.addEventListener('mouseup', Util._captureProxy); + + window.addEventListener('touchmove', Util._captureProxy); + window.addEventListener('touchend', Util._captureProxy); + } +}; + +Util.releaseCapture = function () { + if (document.releaseCapture) { + + document.releaseCapture(); + + } else { + if (!Util._captureElem) { + return; + } + + // There might be events already queued, so we need to wait for + // them to flush. E.g. contextmenu in Microsoft Edge + window.setTimeout(function(expected) { + // Only clear it if it's the expected grab (i.e. no one + // else has initiated a new grab) + if (Util._captureIndex === expected) { + Util._captureElem = null; + } + }, 0, Util._captureIndex); + + Util._captureObserver.disconnect(); + + var captureElem = document.getElementById("noVNC_mouse_capture_elem"); + captureElem.style.display = "none"; + + window.removeEventListener('mousemove', Util._captureProxy); + window.removeEventListener('mouseup', Util._captureProxy); + + window.removeEventListener('touchmove', Util._captureProxy); + window.removeEventListener('touchend', Util._captureProxy); + } +}; + +/* [module] export default Util; */ diff --git a/noVNC/include/websock.js b/noVNC/core/websock.js similarity index 53% rename from noVNC/include/websock.js rename to noVNC/core/websock.js index cc82e5a..51d9b62 100644 --- a/noVNC/include/websock.js +++ b/noVNC/core/websock.js @@ -3,10 +3,8 @@ * Copyright (C) 2012 Joel Martin * Licensed under MPL 2.0 (see LICENSE.txt) * - * Websock is similar to the standard WebSocket object but Websock - * enables communication with raw TCP sockets (i.e. the binary stream) - * via websockify. This is accomplished by base64 encoding the data - * stream between Websock and websockify. + * Websock is similar to the standard WebSocket object but with extra + * buffer handling. * * Websock has built-in receive queue buffering; the message event * does not contain actual data but is simply a notification that @@ -14,50 +12,29 @@ * read binary data off of the receive queue. */ +/* [module] + * import Util from "./util"; + */ + /*jslint browser: true, bitwise: true */ -/*global Util, Base64 */ +/*global Util*/ - -// Load Flash WebSocket emulator if needed - -// To force WebSocket emulator even when native WebSocket available -//window.WEB_SOCKET_FORCE_FLASH = true; -// To enable WebSocket emulator debug: -//window.WEB_SOCKET_DEBUG=1; - -if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) { - Websock_native = true; -} else if (window.MozWebSocket && !window.WEB_SOCKET_FORCE_FLASH) { - Websock_native = true; - window.WebSocket = window.MozWebSocket; -} else { - /* no builtin WebSocket so load web_socket.js */ - - Websock_native = false; - (function () { - window.WEB_SOCKET_SWF_LOCATION = Util.get_include_uri() + - "web-socket-js/WebSocketMain.swf"; - if (Util.Engine.trident) { - Util.Debug("Forcing uncached load of WebSocketMain.swf"); - window.WEB_SOCKET_SWF_LOCATION += "?" + Math.random(); - } - Util.load_scripts(["web-socket-js/swfobject.js", - "web-socket-js/web_socket.js"]); - })(); -} - - -function Websock() { +/* [module] export default */ function Websock() { "use strict"; this._websocket = null; // WebSocket object - this._rQ = []; // Receive queue - this._rQi = 0; // Receive queue index - this._rQmax = 10000; // Max receive queue size before compacting - this._sQ = []; // Send queue - this._mode = 'base64'; // Current WebSocket mode: 'binary', 'base64' - this.maxBufferedAmount = 200; + this._rQi = 0; // Receive queue index + this._rQlen = 0; // Next write position in the receive queue + this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB) + this._rQmax = this._rQbufferSize / 8; + // called in init: this._rQ = new Uint8Array(this._rQbufferSize); + this._rQ = null; // Receive queue + + this._sQbufferSize = 1024 * 10; // 10 KiB + // called in init: this._sQ = new Uint8Array(this._sQbufferSize); + this._sQlen = 0; + this._sQ = null; // Send queue this._eventHandlers = { 'message': function () {}, @@ -65,10 +42,32 @@ function Websock() { 'close': function () {}, 'error': function () {} }; -} +}; (function () { "use strict"; + // this has performance issues in some versions Chromium, and + // doesn't gain a tremendous amount of performance increase in Firefox + // at the moment. It may be valuable to turn it on in the future. + var ENABLE_COPYWITHIN = false; + + var MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB + + var typedArrayToString = (function () { + // This is only for PhantomJS, which doesn't like apply-ing + // with Typed Arrays + try { + var arr = new Uint8Array([1, 2, 3]); + String.fromCharCode.apply(null, arr); + return function (a) { return String.fromCharCode.apply(null, a); }; + } catch (ex) { + return function (a) { + return String.fromCharCode.apply( + null, Array.prototype.slice.call(a)); + }; + } + })(); + Websock.prototype = { // Getters and Setters get_sQ: function () { @@ -89,7 +88,7 @@ function Websock() { // Receive Queue rQlen: function () { - return this._rQ.length - this._rQi; + return this._rQlen - this._rQi; }, rQpeek8: function () { @@ -108,15 +107,7 @@ function Websock() { this._rQi += num; }, - rQunshift8: function (num) { - if (this._rQi === 0) { - this._rQ.unshift(num); - } else { - this._rQi--; - this._rQ[this._rQi] = num; - } - }, - + // TODO(directxman12): test performance with these vs a DataView rQshift16: function () { return (this._rQ[this._rQi++] << 8) + this._rQ[this._rQi++]; @@ -131,22 +122,33 @@ function Websock() { rQshiftStr: function (len) { if (typeof(len) === 'undefined') { len = this.rQlen(); } - var arr = this._rQ.slice(this._rQi, this._rQi + len); + var arr = new Uint8Array(this._rQ.buffer, this._rQi, len); this._rQi += len; - return String.fromCharCode.apply(null, arr); + return typedArrayToString(arr); }, rQshiftBytes: function (len) { if (typeof(len) === 'undefined') { len = this.rQlen(); } this._rQi += len; - return this._rQ.slice(this._rQi - len, this._rQi); + return new Uint8Array(this._rQ.buffer, this._rQi - len, len); + }, + + rQshiftTo: function (target, len) { + if (len === undefined) { len = this.rQlen(); } + // TODO: make this just use set with views when using a ArrayBuffer to store the rQ + target.set(new Uint8Array(this._rQ.buffer, this._rQi, len)); + this._rQi += len; + }, + + rQwhole: function () { + return new Uint8Array(this._rQ.buffer, 0, this._rQlen); }, rQslice: function (start, end) { if (end) { - return this._rQ.slice(this._rQi + start, this._rQi + end); + return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start); } else { - return this._rQ.slice(this._rQi + start); + return new Uint8Array(this._rQ.buffer, this._rQi + start, this._rQlen - this._rQi - start); } }, @@ -154,7 +156,7 @@ function Websock() { // to be available in the receive queue. Return true if we need to // wait (and possibly print a debug message), otherwise false. rQwait: function (msg, num, goback) { - var rQlen = this._rQ.length - this._rQi; // Skip rQlen() function call + var rQlen = this._rQlen - this._rQi; // Skip rQlen() function call if (rQlen < num) { if (goback) { if (this._rQi < goback) { @@ -174,23 +176,16 @@ function Websock() { Util.Debug("bufferedAmount: " + this._websocket.bufferedAmount); } - if (this._websocket.bufferedAmount < this.maxBufferedAmount) { - if (this._sQ.length > 0) { - this._websocket.send(this._encode_message()); - this._sQ = []; - } - - return true; - } else { - Util.Info("Delaying send, bufferedAmount: " + - this._websocket.bufferedAmount); - return false; + if (this._sQlen > 0 && this._websocket.readyState === WebSocket.OPEN) { + this._websocket.send(this._encode_message()); + this._sQlen = 0; } }, send: function (arr) { - this._sQ = this._sQ.concat(arr); - return this.flush(); + this._sQ.set(arr, this._sQlen); + this._sQlen += arr.length; + this.flush(); }, send_string: function (str) { @@ -208,90 +203,31 @@ function Websock() { this._eventHandlers[evt] = handler; }, - init: function (protocols, ws_schema) { - this._rQ = []; + _allocate_buffers: function () { + this._rQ = new Uint8Array(this._rQbufferSize); + this._sQ = new Uint8Array(this._sQbufferSize); + }, + + init: function () { + this._allocate_buffers(); this._rQi = 0; - this._sQ = []; this._websocket = null; - - // Check for full typed array support - var bt = false; - if (('Uint8Array' in window) && - ('set' in Uint8Array.prototype)) { - bt = true; - } - - // Check for full binary type support in WebSockets - // Inspired by: - // https://github.com/Modernizr/Modernizr/issues/370 - // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/websockets/binary.js - var wsbt = false; - try { - if (bt && ('binaryType' in WebSocket.prototype || - !!(new WebSocket(ws_schema + '://.').binaryType))) { - Util.Info("Detected binaryType support in WebSockets"); - wsbt = true; - } - } catch (exc) { - // Just ignore failed test localhost connection - } - - // Default protocols if not specified - if (typeof(protocols) === "undefined") { - if (wsbt) { - protocols = ['binary', 'base64']; - } else { - protocols = 'base64'; - } - } - - if (!wsbt) { - if (protocols === 'binary') { - throw new Error('WebSocket binary sub-protocol requested but not supported'); - } - - if (typeof(protocols) === 'object') { - var new_protocols = []; - - for (var i = 0; i < protocols.length; i++) { - if (protocols[i] === 'binary') { - Util.Error('Skipping unsupported WebSocket binary sub-protocol'); - } else { - new_protocols.push(protocols[i]); - } - } - - if (new_protocols.length > 0) { - protocols = new_protocols; - } else { - throw new Error("Only WebSocket binary sub-protocol was requested and is not supported."); - } - } - } - - return protocols; }, open: function (uri, protocols) { var ws_schema = uri.match(/^([a-z]+):\/\//)[1]; - protocols = this.init(protocols, ws_schema); + this.init(); this._websocket = new WebSocket(uri, protocols); - - if (protocols.indexOf('binary') >= 0) { - this._websocket.binaryType = 'arraybuffer'; - } + this._websocket.binaryType = 'arraybuffer'; this._websocket.onmessage = this._recv_message.bind(this); this._websocket.onopen = (function () { Util.Debug('>> WebSock.onopen'); if (this._websocket.protocol) { - this._mode = this._websocket.protocol; Util.Info("Server choose sub-protocol: " + this._websocket.protocol); - } else { - this._mode = 'base64'; - Util.Error('Server select no sub-protocol!: ' + this._websocket.protocol); } + this._eventHandlers.open(); Util.Debug("<< WebSock.onopen"); }).bind(this); @@ -321,26 +257,56 @@ function Websock() { // private methods _encode_message: function () { - if (this._mode === 'binary') { - // Put in a binary arraybuffer - return (new Uint8Array(this._sQ)).buffer; - } else { - // base64 encode - return Base64.encode(this._sQ); + // Put in a binary arraybuffer + // according to the spec, you can send ArrayBufferViews with the send method + return new Uint8Array(this._sQ.buffer, 0, this._sQlen); + }, + + _expand_compact_rQ: function (min_fit) { + var resizeNeeded = min_fit || this._rQlen - this._rQi > this._rQbufferSize / 2; + if (resizeNeeded) { + if (!min_fit) { + // just double the size if we need to do compaction + this._rQbufferSize *= 2; + } else { + // otherwise, make sure we satisy rQlen - rQi + min_fit < rQbufferSize / 8 + this._rQbufferSize = (this._rQlen - this._rQi + min_fit) * 8; + } } + + // we don't want to grow unboundedly + if (this._rQbufferSize > MAX_RQ_GROW_SIZE) { + this._rQbufferSize = MAX_RQ_GROW_SIZE; + if (this._rQbufferSize - this._rQlen - this._rQi < min_fit) { + throw new Exception("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit"); + } + } + + if (resizeNeeded) { + var old_rQbuffer = this._rQ.buffer; + this._rQmax = this._rQbufferSize / 8; + this._rQ = new Uint8Array(this._rQbufferSize); + this._rQ.set(new Uint8Array(old_rQbuffer, this._rQi)); + } else { + if (ENABLE_COPYWITHIN) { + this._rQ.copyWithin(0, this._rQi); + } else { + this._rQ.set(new Uint8Array(this._rQ.buffer, this._rQi)); + } + } + + this._rQlen = this._rQlen - this._rQi; + this._rQi = 0; }, _decode_message: function (data) { - if (this._mode === 'binary') { - // push arraybuffer values onto the end - var u8 = new Uint8Array(data); - for (var i = 0; i < u8.length; i++) { - this._rQ.push(u8[i]); - } - } else { - // base64 decode and concat to end - this._rQ = this._rQ.concat(Base64.decode(data, 0)); + // push arraybuffer values onto the end + var u8 = new Uint8Array(data); + if (u8.length > this._rQbufferSize - this._rQlen) { + this._expand_compact_rQ(u8.length); } + this._rQ.set(u8, this._rQlen); + this._rQlen += u8.length; }, _recv_message: function (e) { @@ -349,9 +315,11 @@ function Websock() { if (this.rQlen() > 0) { this._eventHandlers.message(); // Compact the receive queue - if (this._rQ.length > this._rQmax) { - this._rQ = this._rQ.slice(this._rQi); + if (this._rQlen == this._rQi) { + this._rQlen = 0; this._rQi = 0; + } else if (this._rQlen > this._rQmax) { + this._expand_compact_rQ(); } } else { Util.Debug("Ignoring empty message"); diff --git a/noVNC/custom.css b/noVNC/custom.css deleted file mode 100644 index 582b821..0000000 --- a/noVNC/custom.css +++ /dev/null @@ -1,116 +0,0 @@ -.custom_toolbar { - position: absolute; - width: 52px; - height: 99.5%; - top: 0px; - left: -65px; - z-index: 100; - padding: 2px; - background-color: #EEEEEE; - box-shadow: 1px 0 5px #000000; -} - -.custom_toolbar_divider1 { - width: 40px; - height: 1px; - margin: 5px; - background-color: #000; - opacity: 0.1; -} - -.custom_toolbar_divider2 { - width: 40px; - height: 1px; - margin: 5px; - background-color: #000; - opacity: 0.0; -} - -.custom_toolbar_clicker { - position: absolute; - width: 43px; - height: 36px; - margin-top: -2px; - margin-left: 54px; - line-height: 60px; - text-align: center; - opacity: 1.0; - cursor: pointer; - background-repeat: no-repeat; - background-position: center; - background-image: url(images/pop_more.png); -} - -.custom_toolbar_btn { - width: 40px; - height: 20px; - - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - font-size: 13px; - line-height: 20px; - text-align: center; - margin: 15px 5px 15px 5px; - - border: 1px solid #bbbbbb; - border-radius: 4px; - color: #33444E; - background-color: #EEEEEE; - box-shadow: 0px 0px 3px #bbbbbb; - cursor: pointer; -} - -.custom_toolbar_btn_hover { - -webkit-box-shadow: inset 0px 0px 5px 2px rgba(0,0,0,0.3); - -moz-box-shadow: inset 0px 0px 5px 2px rgba(0,0,0,0.3); - box-shadow: inset 0px 0px 5px 2px rgba(0,0,0,0.3); -} - -.custom_toolbar_btn_selected { - background-color: #bfbfbf; -} - -.custom_mask { - top: 0px; - left: 0px; - display: none;; - position: absolute; - background-color: #000; - opacity: 0.5; - z-index: 200; -} - -.custom_pause_icon { - background-repeat: no-repeat; - background-position: center; - background-image: url("images/pause.png"); -} - -.custom_resume_icon { - background-repeat: no-repeat; - background-position: center; - background-image: url("images/resume.png"); -} - -.custom_scale_icon { - background-repeat: no-repeat; - background-position: center; - background-image: url("images/scale.png"); -} - -.custom_not_scale_icon { - background-repeat: no-repeat; - background-position: center; - background-image: url("images/not_scale.png"); -} - -.custom_quality_icon { - margin: 3px 0px 0px 8px; - width: 24px; - height: 14px; - border-radius: 12px; - color: #fff; - background-color: #4d4d4d; - font-size: 12px; - line-height: 14px; - font-weight: bolder; -} \ No newline at end of file diff --git a/noVNC/docs/LICENSE.pako b/noVNC/docs/LICENSE.pako new file mode 100644 index 0000000..e6c9e5a --- /dev/null +++ b/noVNC/docs/LICENSE.pako @@ -0,0 +1,21 @@ +(The MIT License) + +Copyright (C) 2014 by Vitaly Puzrin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/noVNC/docs/VERSION b/noVNC/docs/VERSION index bd73f47..ee6cdce 100644 --- a/noVNC/docs/VERSION +++ b/noVNC/docs/VERSION @@ -1 +1 @@ -0.4 +0.6.1 diff --git a/noVNC/docs/notes b/noVNC/docs/notes index 9bcc6af..dfef0bd 100644 --- a/noVNC/docs/notes +++ b/noVNC/docs/notes @@ -1,17 +1,5 @@ -Some implementation notes: +Rebuilding inflator.js -There is an included flash object (web-socket-js) that is used to -emulate websocket support on browsers without websocket support -(currently only Chrome has WebSocket support). - -Javascript doesn't have a bytearray type, so what you get out of -a WebSocket object is just Javascript strings. Javascript has UTF-16 -unicode strings and anything sent through the WebSocket gets converted -to UTF-8 and vice-versa. So, one additional (and necessary) function -of websockify is base64 encoding/decoding what is sent to/from the -browser. - -Building web-socket-js emulator: - -cd include/web-socket-js/flash-src -mxmlc -static-link-runtime-shared-libraries WebSocketMain.as +- Download pako from npm +- Install browserify using npm +- browserify core/inflator.mod.js -o core/inflator.js -s Inflator diff --git a/noVNC/docs/release.txt b/noVNC/docs/release.txt index 1660b9b..3e03635 100644 --- a/noVNC/docs/release.txt +++ b/noVNC/docs/release.txt @@ -1,9 +1,34 @@ -- Update and commit docs/VERSION -- Create version tag and tarball from tag - WVER=0.3 - git tag v${WVER} - git push origin master - git push origin v${WVER} - git archive --format=tar --prefix=novnc-${WVER}/ v${WVER} > novnc-${WVER}.tar - gzip novnc-${WVER}.tar -- Upload tarball to repo +- Decide a new version number X.Y.Z (follow SemVer) +- Update version in package.json +- Update version in docs/VERSION +- Commit the change with a commit like "Release X.Y.Z" +- Add a new release on GitHub called "vX.Y.Z", and populate it with + release notes of the following form (where A.B.C is the last release): + +Major Changes Since A.B.C +========================= + +*Insert warnings here about incompatibilities* + +*Thanks to all the contributors who filed bugs, added features, and fixed bugs +during this release :tada:* + +App-visible Changes +------------------- + +- *feature* a feature which improves the app usage (#PRNUM) +- *bugfix* a bug fix which fixes the app usage (#PRNUM) +- *refactor* a refactor which changes the app usage (#PRNUM) + +Library-visible Changes +----------------------- + +- *feature* a feature which improves the noVNC APIs (#PRNUM) +- *bugfix* a bug fix which fixes the noVNC APIs (#PRNUM) +- *refactor* a refactor which changes the noVNC APIs (#PRNUM) + +App-internals Changes +--------------------- + +- *bugfix* a bug fix with affects the internals of noVNC only (#PRNUM) +- *refactor* a refactor which affects the internals of noVNC only (#PRNUM) diff --git a/noVNC/favicon.ico b/noVNC/favicon.ico deleted file mode 120000 index 45399c8..0000000 --- a/noVNC/favicon.ico +++ /dev/null @@ -1 +0,0 @@ -images/favicon.ico \ No newline at end of file diff --git a/noVNC/images/.@__thumb/defaultscreen_320x460.png b/noVNC/images/.@__thumb/defaultscreen_320x460.png deleted file mode 100755 index b22e38e..0000000 Binary files a/noVNC/images/.@__thumb/defaultscreen_320x460.png and /dev/null differ diff --git a/noVNC/images/.@__thumb/defaultscreen_700x700.png b/noVNC/images/.@__thumb/defaultscreen_700x700.png deleted file mode 100755 index cec5e4f..0000000 Binary files a/noVNC/images/.@__thumb/defaultscreen_700x700.png and /dev/null differ diff --git a/noVNC/images/.@__thumb/s100screen_320x460.png b/noVNC/images/.@__thumb/s100screen_320x460.png deleted file mode 100755 index 2d02e0a..0000000 Binary files a/noVNC/images/.@__thumb/s100screen_320x460.png and /dev/null differ diff --git a/noVNC/images/.@__thumb/s100screen_700x700.png b/noVNC/images/.@__thumb/s100screen_700x700.png deleted file mode 100755 index e525593..0000000 Binary files a/noVNC/images/.@__thumb/s100screen_700x700.png and /dev/null differ diff --git a/noVNC/images/.@__thumb/s800screen_320x460.png b/noVNC/images/.@__thumb/s800screen_320x460.png deleted file mode 100755 index b22e38e..0000000 Binary files a/noVNC/images/.@__thumb/s800screen_320x460.png and /dev/null differ diff --git a/noVNC/images/.@__thumb/s800screen_700x700.png b/noVNC/images/.@__thumb/s800screen_700x700.png deleted file mode 100755 index d73af5b..0000000 Binary files a/noVNC/images/.@__thumb/s800screen_700x700.png and /dev/null differ diff --git a/noVNC/images/alt.png b/noVNC/images/alt.png deleted file mode 100644 index d42af7b..0000000 Binary files a/noVNC/images/alt.png and /dev/null differ diff --git a/noVNC/images/clipboard.png b/noVNC/images/clipboard.png deleted file mode 100644 index 24df33c..0000000 Binary files a/noVNC/images/clipboard.png and /dev/null differ diff --git a/noVNC/images/connect.png b/noVNC/images/connect.png deleted file mode 100644 index 79e71ad..0000000 Binary files a/noVNC/images/connect.png and /dev/null differ diff --git a/noVNC/images/ctrl.png b/noVNC/images/ctrl.png deleted file mode 100644 index a63b601..0000000 Binary files a/noVNC/images/ctrl.png and /dev/null differ diff --git a/noVNC/images/ctrlaltdel.png b/noVNC/images/ctrlaltdel.png deleted file mode 100644 index 31922e5..0000000 Binary files a/noVNC/images/ctrlaltdel.png and /dev/null differ diff --git a/noVNC/images/disconnect.png b/noVNC/images/disconnect.png deleted file mode 100644 index 8832f5e..0000000 Binary files a/noVNC/images/disconnect.png and /dev/null differ diff --git a/noVNC/images/drag.png b/noVNC/images/drag.png deleted file mode 100644 index 433f896..0000000 Binary files a/noVNC/images/drag.png and /dev/null differ diff --git a/noVNC/images/esc.png b/noVNC/images/esc.png deleted file mode 100644 index ece5f7c..0000000 Binary files a/noVNC/images/esc.png and /dev/null differ diff --git a/noVNC/images/favicon.ico b/noVNC/images/favicon.ico deleted file mode 100644 index c999634..0000000 Binary files a/noVNC/images/favicon.ico and /dev/null differ diff --git a/noVNC/images/favicon.png b/noVNC/images/favicon.png deleted file mode 100644 index e2bdb19..0000000 Binary files a/noVNC/images/favicon.png and /dev/null differ diff --git a/noVNC/images/keyboard.png b/noVNC/images/keyboard.png deleted file mode 100644 index f797952..0000000 Binary files a/noVNC/images/keyboard.png and /dev/null differ diff --git a/noVNC/images/mouse_left.png b/noVNC/images/mouse_left.png deleted file mode 100644 index 1de7a48..0000000 Binary files a/noVNC/images/mouse_left.png and /dev/null differ diff --git a/noVNC/images/mouse_middle.png b/noVNC/images/mouse_middle.png deleted file mode 100644 index 81fbd9b..0000000 Binary files a/noVNC/images/mouse_middle.png and /dev/null differ diff --git a/noVNC/images/mouse_none.png b/noVNC/images/mouse_none.png deleted file mode 100644 index 93dbf57..0000000 Binary files a/noVNC/images/mouse_none.png and /dev/null differ diff --git a/noVNC/images/mouse_right.png b/noVNC/images/mouse_right.png deleted file mode 100644 index 355b25d..0000000 Binary files a/noVNC/images/mouse_right.png and /dev/null differ diff --git a/noVNC/images/not_scale.png b/noVNC/images/not_scale.png deleted file mode 100644 index b293432..0000000 Binary files a/noVNC/images/not_scale.png and /dev/null differ diff --git a/noVNC/images/pause.png b/noVNC/images/pause.png deleted file mode 100644 index c8905e1..0000000 Binary files a/noVNC/images/pause.png and /dev/null differ diff --git a/noVNC/images/pop_less.png b/noVNC/images/pop_less.png deleted file mode 100755 index 1092476..0000000 Binary files a/noVNC/images/pop_less.png and /dev/null differ diff --git a/noVNC/images/pop_less_hover.png b/noVNC/images/pop_less_hover.png deleted file mode 100755 index 1092476..0000000 Binary files a/noVNC/images/pop_less_hover.png and /dev/null differ diff --git a/noVNC/images/pop_more.png b/noVNC/images/pop_more.png deleted file mode 100755 index 626299e..0000000 Binary files a/noVNC/images/pop_more.png and /dev/null differ diff --git a/noVNC/images/pop_more_hover.png b/noVNC/images/pop_more_hover.png deleted file mode 100755 index 626299e..0000000 Binary files a/noVNC/images/pop_more_hover.png and /dev/null differ diff --git a/noVNC/images/power.png b/noVNC/images/power.png deleted file mode 100644 index f68fd08..0000000 Binary files a/noVNC/images/power.png and /dev/null differ diff --git a/noVNC/images/resume.png b/noVNC/images/resume.png deleted file mode 100644 index 17e6a27..0000000 Binary files a/noVNC/images/resume.png and /dev/null differ diff --git a/noVNC/images/scale.png b/noVNC/images/scale.png deleted file mode 100644 index d370551..0000000 Binary files a/noVNC/images/scale.png and /dev/null differ diff --git a/noVNC/images/screen_320x460.png b/noVNC/images/screen_320x460.png deleted file mode 100644 index 172ec55..0000000 Binary files a/noVNC/images/screen_320x460.png and /dev/null differ diff --git a/noVNC/images/screen_57x57.png b/noVNC/images/screen_57x57.png deleted file mode 100644 index e2085f2..0000000 Binary files a/noVNC/images/screen_57x57.png and /dev/null differ diff --git a/noVNC/images/screen_700x700.png b/noVNC/images/screen_700x700.png deleted file mode 100644 index ae67768..0000000 Binary files a/noVNC/images/screen_700x700.png and /dev/null differ diff --git a/noVNC/images/settings.png b/noVNC/images/settings.png deleted file mode 100644 index a43f5e1..0000000 Binary files a/noVNC/images/settings.png and /dev/null differ diff --git a/noVNC/images/showextrakeys.png b/noVNC/images/showextrakeys.png deleted file mode 100644 index ad8e0a7..0000000 Binary files a/noVNC/images/showextrakeys.png and /dev/null differ diff --git a/noVNC/images/tab.png b/noVNC/images/tab.png deleted file mode 100644 index 8413487..0000000 Binary files a/noVNC/images/tab.png and /dev/null differ diff --git a/noVNC/images/topbackground.png b/noVNC/images/topbackground.png deleted file mode 100755 index c2b6d46..0000000 Binary files a/noVNC/images/topbackground.png and /dev/null differ diff --git a/noVNC/include/base.css b/noVNC/include/base.css deleted file mode 100644 index 90c17e4..0000000 --- a/noVNC/include/base.css +++ /dev/null @@ -1,519 +0,0 @@ -/* - * noVNC base CSS - * Copyright (C) 2012 Joel Martin - * Copyright (C) 2013 Samuel Mannehed for Cendio AB - * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) - * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). - */ - -body { - margin:0; - padding:0; - font-family: Helvetica; - /*Background image with light grey curve.*/ - background-color:#494949; - background-repeat:no-repeat; - background-position:right bottom; - height:100%; -} - -html { - height:100%; -} - -#noVNC_controls ul { - list-style: none; - margin: 0px; - padding: 0px; -} -#noVNC_controls li { - padding-bottom:8px; -} - -#noVNC_host { - width:150px; -} -#noVNC_port { - width: 80px; -} -#noVNC_password { - width: 150px; -} -#noVNC_encrypt { -} -#noVNC_path { - width: 100px; -} -#noVNC_connect_button { - width: 110px; - float:right; -} - -#noVNC_buttons { - white-space: nowrap; -} - -#noVNC_view_drag_button { - display: none; -} -#sendCtrlAltDelButton { - display: none; -} -#noVNC_xvp_buttons { - display: none; -} -#noVNC_mobile_buttons { - display: none; -} - -#noVNC_extra_keys { - display: inline; - list-style-type: none; - padding: 0px; - margin: 0px; - position: relative; -} - -.noVNC-buttons-left { - float: left; - z-index: 1; - position: relative; -} - -.noVNC-buttons-right { - float:right; - right: 0px; - z-index: 2; - position: absolute; -} - -#noVNC_status { - font-size: 12px; - padding-top: 4px; - height:32px; - text-align: center; - font-weight: bold; - color: #fff; -} - -#noVNC_settings_menu { - margin: 3px; - text-align: left; -} -#noVNC_settings_menu ul { - list-style: none; - margin: 0px; - padding: 0px; -} - -#noVNC_apply { - float:right; -} - -/* Do not set width/height for VNC_screen or VNC_canvas or incorrect - * scaling will occur. Canvas resizes to remote VNC settings */ -#noVNC_screen { - display: table; - width:100%; - height:100%; - background-color:#313131; - border-bottom-right-radius: 800px 600px; - /*border-top-left-radius: 800px 600px;*/ -} - -#noVNC_container { - display: none; - position: absolute; - margin: 0px; - padding: 0px; - bottom: 0px; - top: 36px; /* the height of the control bar */ - left: 0px; - right: 0px; - width: auto; - height: auto; -} - -#noVNC_canvas { - position: absolute; - left: 0; - right: 0; - margin-left: auto; - margin-right: auto; -} - -#VNC_clipboard_clear_button { - float:right; -} -#VNC_clipboard_text { - font-size: 11px; -} - -#noVNC_clipboard_clear_button { - float:right; -} - -/*Bubble contents divs*/ -#noVNC_settings { - display:none; - margin-top:73px; - right:20px; - position:fixed; -} - -#noVNC_controls { - display:none; - margin-top:73px; - right:12px; - position:fixed; -} -#noVNC_controls.top:after { - right:15px; -} - -#noVNC_description { - display:none; - position:fixed; - - margin-top:73px; - right:20px; - left:20px; - padding:15px; - color:#000; - background:#eee; /* default background for browsers without gradient support */ - - border:2px solid #E0E0E0; - -webkit-border-radius:10px; - -moz-border-radius:10px; - border-radius:10px; -} - -#noVNC_popup_status_panel { - display:none; - position: fixed; - z-index: 1; - - margin:15px; - margin-top:60px; - padding:15px; - width:auto; - - text-align:center; - font-weight:bold; - word-wrap:break-word; - color:#fff; - background:rgba(0,0,0,0.65); - - -webkit-border-radius:10px; - -moz-border-radius:10px; - border-radius:10px; -} - -#noVNC_xvp { - display:none; - margin-top:73px; - right:30px; - position:fixed; -} -#noVNC_xvp.top:after { - right:125px; -} - -#noVNC_clipboard { - display:none; - margin-top:73px; - right:30px; - position:fixed; -} -#noVNC_clipboard.top:after { - right:85px; -} - -#keyboardinput { - width:1px; - height:1px; - background-color:#fff; - color:#fff; - border:0; - position: relative; - left: -40px; - z-index: -1; - ime-mode: disabled; -} - -/* - * Advanced Styling - */ - -.noVNC_status_normal { - background: #b2bdcd; /* Old browsers */ - background: -moz-linear-gradient(top, #b2bdcd 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b2bdcd), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */ - background: linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */ -} -.noVNC_status_error { - background: #f04040; /* Old browsers */ - background: -moz-linear-gradient(top, #f04040 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f04040), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */ - background: linear-gradient(top, #f04040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */ -} -.noVNC_status_warn { - background: #f0f040; /* Old browsers */ - background: -moz-linear-gradient(top, #f0f040 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f0f040), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */ - background: linear-gradient(top, #f0f040 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */ -} - -/* Control bar */ -#noVNC-control-bar { - position:fixed; - - display:block; - height:36px; - left:0; - top:0; - width:100%; - z-index:200; -} - -.noVNC_status_button { - padding: 4px 4px; - vertical-align: middle; - border:1px solid #869dbc; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - background: #b2bdcd; /* Old browsers */ - background: -moz-linear-gradient(top, #b2bdcd 0%, #899cb3 49%, #7e93af 51%, #6e84a3 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b2bdcd), color-stop(49%,#899cb3), color-stop(51%,#7e93af), color-stop(100%,#6e84a3)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* IE10+ */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b2bdcd', endColorstr='#6e84a3',GradientType=0 ); /* IE6-9 */ - background: linear-gradient(top, #b2bdcd 0%,#899cb3 49%,#7e93af 51%,#6e84a3 100%); /* W3C */ - /*box-shadow:inset 0.4px 0.4px 0.4px #000000;*/ -} - -.noVNC_status_button_selected { - padding: 4px 4px; - vertical-align: middle; - border:1px solid #4366a9; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - background: #779ced; /* Old browsers */ - background: -moz-linear-gradient(top, #779ced 0%, #3970e0 49%, #2160dd 51%, #2463df 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#779ced), color-stop(49%,#3970e0), color-stop(51%,#2160dd), color-stop(100%,#2463df)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #779ced 0%,#3970e0 49%,#2160dd 51%,#2463df 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #779ced 0%,#3970e0 49%,#2160dd 51%,#2463df 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, #779ced 0%,#3970e0 49%,#2160dd 51%,#2463df 100%); /* IE10+ */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#779ced', endColorstr='#2463df',GradientType=0 ); /* IE6-9 */ - background: linear-gradient(top, #779ced 0%,#3970e0 49%,#2160dd 51%,#2463df 100%); /* W3C */ - /*box-shadow:inset 0.4px 0.4px 0.4px #000000;*/ -} - - -/*Settings Bubble*/ -.triangle-right { - position:relative; - padding:15px; - margin:1em 0 3em; - color:#fff; - background:#fff; /* default background for browsers without gradient support */ - /* css3 */ - /*background:-webkit-gradient(linear, 0 0, 0 100%, from(#2e88c4), to(#075698)); - background:-moz-linear-gradient(#2e88c4, #075698); - background:-o-linear-gradient(#2e88c4, #075698); - background:linear-gradient(#2e88c4, #075698);*/ - -webkit-border-radius:10px; - -moz-border-radius:10px; - border-radius:10px; - color:#000; - border:2px solid #E0E0E0; -} - -.triangle-right.top:after { - border-color: transparent #E0E0E0; - border-width: 20px 20px 0 0; - bottom: auto; - left: auto; - right: 50px; - top: -20px; -} - -.triangle-right:after { - content:""; - position:absolute; - bottom:-20px; /* value = - border-top-width - border-bottom-width */ - left:50px; /* controls horizontal position */ - border-width:20px 0 0 20px; /* vary these values to change the angle of the vertex */ - border-style:solid; - border-color:#E0E0E0 transparent; - /* reduce the damage in FF3.0 */ - display:block; - width:0; -} - -.triangle-right.top:after { - top:-40px; /* value = - border-top-width - border-bottom-width */ - right:50px; /* controls horizontal position */ - bottom:auto; - left:auto; - border-width:40px 40px 0 0; /* vary these values to change the angle of the vertex */ - border-color:transparent #E0E0E0; -} - -/*Default noVNC logo.*/ -/* From: http://fonts.googleapis.com/css?family=Orbitron:700 */ -@font-face { - font-family: 'Orbitron'; - font-style: normal; - font-weight: 700; - src: local('?'), url('Orbitron700.woff') format('woff'), - url('Orbitron700.ttf') format('truetype'); -} - -#noVNC_logo { - margin-top: 170px; - margin-left: 10px; - color:yellow; - text-align:left; - font-family: 'Orbitron', 'OrbitronTTF', sans-serif; - line-height:90%; - text-shadow: - 5px 5px 0 #000, - -1px -1px 0 #000, - 1px -1px 0 #000, - -1px 1px 0 #000, - 1px 1px 0 #000; -} - - -#noVNC_logo span{ - color:green; -} - -/* ---------------------------------------- - * Media sizing - * ---------------------------------------- - */ - - -.noVNC_status_button { - font-size: 12px; -} - -#noVNC_clipboard_text { - width: 500px; -} - -#noVNC_logo { - font-size: 180px; -} - -.noVNC-buttons-left { - padding-left: 10px; -} - -.noVNC-buttons-right { - padding-right: 10px; -} - -#noVNC_status { - z-index: 0; - position: absolute; - width: 100%; - margin-left: 0px; -} - -#showExtraKeysButton { display: none; } -#toggleCtrlButton { display: inline; } -#toggleAltButton { display: inline; } -#sendTabButton { display: inline; } -#sendEscButton { display: inline; } - -/* left-align the status text on lower resolutions */ -@media screen and (max-width: 800px){ - #noVNC_status { - z-index: 1; - position: relative; - width: auto; - float: left; - margin-left: 4px; - } -} - -@media screen and (max-width: 640px){ - #noVNC_clipboard_text { - width: 410px; - } - #noVNC_logo { - font-size: 150px; - } - .noVNC_status_button { - font-size: 10px; - } - .noVNC-buttons-left { - padding-left: 0px; - } - .noVNC-buttons-right { - padding-right: 0px; - } - /* collapse the extra keys on lower resolutions */ - #showExtraKeysButton { - display: inline; - } - #toggleCtrlButton { - display: none; - position: absolute; - top: 30px; - left: 0px; - } - #toggleAltButton { - display: none; - position: absolute; - top: 65px; - left: 0px; - } - #sendTabButton { - display: none; - position: absolute; - top: 100px; - left: 0px; - } - #sendEscButton { - display: none; - position: absolute; - top: 135px; - left: 0px; - } -} - -@media screen and (min-width: 321px) and (max-width: 480px) { - #noVNC_clipboard_text { - width: 250px; - } - #noVNC_logo { - font-size: 110px; - } -} - -@media screen and (max-width: 320px) { - .noVNC_status_button { - font-size: 9px; - } - #noVNC_clipboard_text { - width: 220px; - } - #noVNC_logo { - font-size: 90px; - } -} diff --git a/noVNC/include/black.css b/noVNC/include/black.css deleted file mode 100644 index 7d940c5..0000000 --- a/noVNC/include/black.css +++ /dev/null @@ -1,71 +0,0 @@ -/* - * noVNC black CSS - * Copyright (C) 2012 Joel Martin - * Copyright (C) 2013 Samuel Mannehed for Cendio AB - * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) - * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). - */ - -#keyboardinput { - background-color:#000; -} - -.noVNC_status_normal { - background: #4c4c4c; /* Old browsers */ - background: -moz-linear-gradient(top, #4c4c4c 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4c4c4c), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */ - background: linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */ -} -.noVNC_status_error { - background: #f04040; /* Old browsers */ - background: -moz-linear-gradient(top, #f04040 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f04040), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */ - background: linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */ -} -.noVNC_status_warn { - background: #f0f040; /* Old browsers */ - background: -moz-linear-gradient(top, #f0f040 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f0f040), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */ - background: linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */ -} - -.triangle-right { - border:2px solid #fff; - background:#000; - color:#fff; -} - -.noVNC_status_button { - font-size: 12px; - vertical-align: middle; - border:1px solid #4c4c4c; - - background: #4c4c4c; /* Old browsers */ - background: -moz-linear-gradient(top, #4c4c4c 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4c4c4c), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 ); /* IE6-9 */ - background: linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */ -} - -.noVNC_status_button_selected { - background: #9dd53a; /* Old browsers */ - background: -moz-linear-gradient(top, #9dd53a 0%, #a1d54f 50%, #80c217 51%, #7cbc0a 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#9dd53a), color-stop(50%,#a1d54f), color-stop(51%,#80c217), color-stop(100%,#7cbc0a)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #9dd53a 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #9dd53a 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%); /* Opera11.10+ */ - background: -ms-linear-gradient(top, #9dd53a 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%); /* IE10+ */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9dd53a', endColorstr='#7cbc0a',GradientType=0 ); /* IE6-9 */ - background: linear-gradient(top, #9dd53a 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%); /* W3C */ -} diff --git a/noVNC/include/blue.css b/noVNC/include/blue.css deleted file mode 100644 index b2a0adc..0000000 --- a/noVNC/include/blue.css +++ /dev/null @@ -1,64 +0,0 @@ -/* - * noVNC blue CSS - * Copyright (C) 2012 Joel Martin - * Copyright (C) 2013 Samuel Mannehed for Cendio AB - * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) - * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). - */ - -.noVNC_status_normal { - background-color:#04073d; - background-image: -webkit-gradient( - linear, - left bottom, - left top, - color-stop(0.54, rgb(10,15,79)), - color-stop(0.5, rgb(4,7,61)) - ); - background-image: -moz-linear-gradient( - center bottom, - rgb(10,15,79) 54%, - rgb(4,7,61) 50% - ); -} -.noVNC_status_error { - background-color:#f04040; - background-image: -webkit-gradient( - linear, - left bottom, - left top, - color-stop(0.54, rgb(240,64,64)), - color-stop(0.5, rgb(4,7,61)) - ); - background-image: -moz-linear-gradient( - center bottom, - rgb(4,7,61) 54%, - rgb(249,64,64) 50% - ); -} -.noVNC_status_warn { - background-color:#f0f040; - background-image: -webkit-gradient( - linear, - left bottom, - left top, - color-stop(0.54, rgb(240,240,64)), - color-stop(0.5, rgb(4,7,61)) - ); - background-image: -moz-linear-gradient( - center bottom, - rgb(4,7,61) 54%, - rgb(240,240,64) 50% - ); -} - -.triangle-right { - border:2px solid #fff; - background:#04073d; - color:#fff; -} - -#keyboardinput { - background-color:#04073d; -} - diff --git a/noVNC/include/chrome-app/tcp-client.js b/noVNC/include/chrome-app/tcp-client.js deleted file mode 100644 index b8c125f..0000000 --- a/noVNC/include/chrome-app/tcp-client.js +++ /dev/null @@ -1,321 +0,0 @@ -/* -Copyright 2012 Google Inc. - -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. - -Author: Boris Smus (smus@chromium.org) -*/ - -(function(exports) { - - // Define some local variables here. - var socket = chrome.socket || chrome.experimental.socket; - var dns = chrome.experimental.dns; - - /** - * Creates an instance of the client - * - * @param {String} host The remote host to connect to - * @param {Number} port The port to connect to at the remote host - */ - function TcpClient(host, port, pollInterval) { - this.host = host; - this.port = port; - this.pollInterval = pollInterval || 15; - - // Callback functions. - this.callbacks = { - connect: null, // Called when socket is connected. - disconnect: null, // Called when socket is disconnected. - recvBuffer: null, // Called (as ArrayBuffer) when client receives data from server. - recvString: null, // Called (as string) when client receives data from server. - sent: null // Called when client sends data to server. - }; - - // Socket. - this.socketId = null; - this.isConnected = false; - - log('initialized tcp client'); - } - - /** - * Connects to the TCP socket, and creates an open socket. - * - * @see http://developer.chrome.com/trunk/apps/socket.html#method-create - * @param {Function} callback The function to call on connection - */ - TcpClient.prototype.connect = function(callback) { - // First resolve the hostname to an IP. - dns.resolve(this.host, function(result) { - this.addr = result.address; - socket.create('tcp', {}, this._onCreate.bind(this)); - - // Register connect callback. - this.callbacks.connect = callback; - }.bind(this)); - }; - - /** - * Sends an arraybuffer/view down the wire to the remote side - * - * @see http://developer.chrome.com/trunk/apps/socket.html#method-write - * @param {String} msg The arraybuffer/view to send - * @param {Function} callback The function to call when the message has sent - */ - TcpClient.prototype.sendBuffer = function(buf, callback) { - if (buf.buffer) { - buf = buf.buffer; - } - - /* - // Debug - var bytes = [], u8 = new Uint8Array(buf); - for (var i = 0; i < u8.length; i++) { - bytes.push(u8[i]); - } - log("sending bytes: " + (bytes.join(','))); - */ - - socket.write(this.socketId, buf, this._onWriteComplete.bind(this)); - - // Register sent callback. - this.callbacks.sent = callback; - }; - - /** - * Sends a string down the wire to the remote side - * - * @see http://developer.chrome.com/trunk/apps/socket.html#method-write - * @param {String} msg The string to send - * @param {Function} callback The function to call when the message has sent - */ - TcpClient.prototype.sendString = function(msg, callback) { - /* - // Debug - log("sending string: " + msg); - */ - - this._stringToArrayBuffer(msg, function(arrayBuffer) { - socket.write(this.socketId, arrayBuffer, this._onWriteComplete.bind(this)); - }.bind(this)); - - // Register sent callback. - this.callbacks.sent = callback; - }; - - /** - * Sets the callback for when a message is received - * - * @param {Function} callback The function to call when a message has arrived - * @param {String} type The callback argument type: "arraybuffer" or "string" - */ - TcpClient.prototype.addResponseListener = function(callback, type) { - if (typeof type === "undefined") { - type = "arraybuffer"; - } - // Register received callback. - if (type === "string") { - this.callbacks.recvString = callback; - } else { - this.callbacks.recvBuffer = callback; - } - }; - - /** - * Sets the callback for when the socket disconnects - * - * @param {Function} callback The function to call when the socket disconnects - * @param {String} type The callback argument type: "arraybuffer" or "string" - */ - TcpClient.prototype.addDisconnectListener = function(callback) { - // Register disconnect callback. - this.callbacks.disconnect = callback; - }; - - /** - * Disconnects from the remote side - * - * @see http://developer.chrome.com/trunk/apps/socket.html#method-disconnect - */ - TcpClient.prototype.disconnect = function() { - if (this.isConnected) { - this.isConnected = false; - socket.disconnect(this.socketId); - if (this.callbacks.disconnect) { - this.callbacks.disconnect(); - } - log('socket disconnected'); - } - }; - - /** - * The callback function used for when we attempt to have Chrome - * create a socket. If the socket is successfully created - * we go ahead and connect to the remote side. - * - * @private - * @see http://developer.chrome.com/trunk/apps/socket.html#method-connect - * @param {Object} createInfo The socket details - */ - TcpClient.prototype._onCreate = function(createInfo) { - this.socketId = createInfo.socketId; - if (this.socketId > 0) { - socket.connect(this.socketId, this.addr, this.port, this._onConnectComplete.bind(this)); - } else { - error('Unable to create socket'); - } - }; - - /** - * The callback function used for when we attempt to have Chrome - * connect to the remote side. If a successful connection is - * made then polling starts to check for data to read - * - * @private - * @param {Number} resultCode Indicates whether the connection was successful - */ - TcpClient.prototype._onConnectComplete = function(resultCode) { - // Start polling for reads. - this.isConnected = true; - setTimeout(this._periodicallyRead.bind(this), this.pollInterval); - - if (this.callbacks.connect) { - log('connect complete'); - this.callbacks.connect(); - } - log('onConnectComplete'); - }; - - /** - * Checks for new data to read from the socket - * - * @see http://developer.chrome.com/trunk/apps/socket.html#method-read - */ - TcpClient.prototype._periodicallyRead = function() { - var that = this; - socket.getInfo(this.socketId, function (info) { - if (info.connected) { - setTimeout(that._periodicallyRead.bind(that), that.pollInterval); - socket.read(that.socketId, null, that._onDataRead.bind(that)); - } else if (that.isConnected) { - log('socket disconnect detected'); - that.disconnect(); - } - }); - }; - - /** - * Callback function for when data has been read from the socket. - * Converts the array buffer that is read in to a string - * and sends it on for further processing by passing it to - * the previously assigned callback function. - * - * @private - * @see TcpClient.prototype.addResponseListener - * @param {Object} readInfo The incoming message - */ - TcpClient.prototype._onDataRead = function(readInfo) { - // Call received callback if there's data in the response. - if (readInfo.resultCode > 0) { - log('onDataRead'); - - /* - // Debug - var bytes = [], u8 = new Uint8Array(readInfo.data); - for (var i = 0; i < u8.length; i++) { - bytes.push(u8[i]); - } - log("received bytes: " + (bytes.join(','))); - */ - - if (this.callbacks.recvBuffer) { - // Return raw ArrayBuffer directly. - this.callbacks.recvBuffer(readInfo.data); - } - if (this.callbacks.recvString) { - // Convert ArrayBuffer to string. - this._arrayBufferToString(readInfo.data, function(str) { - this.callbacks.recvString(str); - }.bind(this)); - } - - // Trigger another read right away - setTimeout(this._periodicallyRead.bind(this), 0); - } - }; - - /** - * Callback for when data has been successfully - * written to the socket. - * - * @private - * @param {Object} writeInfo The outgoing message - */ - TcpClient.prototype._onWriteComplete = function(writeInfo) { - log('onWriteComplete'); - // Call sent callback. - if (this.callbacks.sent) { - this.callbacks.sent(writeInfo); - } - }; - - /** - * Converts an array buffer to a string - * - * @private - * @param {ArrayBuffer} buf The buffer to convert - * @param {Function} callback The function to call when conversion is complete - */ - TcpClient.prototype._arrayBufferToString = function(buf, callback) { - var bb = new Blob([new Uint8Array(buf)]); - var f = new FileReader(); - f.onload = function(e) { - callback(e.target.result); - }; - f.readAsText(bb); - }; - - /** - * Converts a string to an array buffer - * - * @private - * @param {String} str The string to convert - * @param {Function} callback The function to call when conversion is complete - */ - TcpClient.prototype._stringToArrayBuffer = function(str, callback) { - var bb = new Blob([str]); - var f = new FileReader(); - f.onload = function(e) { - callback(e.target.result); - }; - f.readAsArrayBuffer(bb); - }; - - /** - * Wrapper function for logging - */ - function log(msg) { - console.log(msg); - } - - /** - * Wrapper function for error logging - */ - function error(msg) { - console.error(msg); - } - - exports.TcpClient = TcpClient; - -})(window); diff --git a/noVNC/include/display.js b/noVNC/include/display.js deleted file mode 100644 index 9a8e455..0000000 --- a/noVNC/include/display.js +++ /dev/null @@ -1,793 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2012 Joel Martin - * Copyright (C) 2015 Samuel Mannehed for Cendio AB - * Licensed under MPL 2.0 (see LICENSE.txt) - * - * See README.md for usage and integration instructions. - */ - -/*jslint browser: true, white: false */ -/*global Util, Base64, changeCursor */ - -var Display; - -(function () { - "use strict"; - - Display = function (defaults) { - this._drawCtx = null; - this._c_forceCanvas = false; - - this._renderQ = []; // queue drawing actions for in-oder rendering - - // the full frame buffer (logical canvas) size - this._fb_width = 0; - this._fb_height = 0; - - // the size limit of the viewport (start disabled) - this._maxWidth = 0; - this._maxHeight = 0; - - // the visible "physical canvas" viewport - this._viewportLoc = { 'x': 0, 'y': 0, 'w': 0, 'h': 0 }; - this._cleanRect = { 'x1': 0, 'y1': 0, 'x2': -1, 'y2': -1 }; - - this._prevDrawStyle = ""; - this._tile = null; - this._tile16x16 = null; - this._tile_x = 0; - this._tile_y = 0; - - Util.set_defaults(this, defaults, { - 'true_color': true, - 'colourMap': [], - 'scale': 1.0, - 'viewport': false, - 'render_mode': '' - }); - - Util.Debug(">> Display.constructor"); - - if (!this._target) { - throw new Error("Target must be set"); - } - - if (typeof this._target === 'string') { - throw new Error('target must be a DOM element'); - } - - if (!this._target.getContext) { - throw new Error("no getContext method"); - } - - if (!this._drawCtx) { - this._drawCtx = this._target.getContext('2d'); - } - - Util.Debug("User Agent: " + navigator.userAgent); - if (Util.Engine.gecko) { Util.Debug("Browser: gecko " + Util.Engine.gecko); } - if (Util.Engine.webkit) { Util.Debug("Browser: webkit " + Util.Engine.webkit); } - if (Util.Engine.trident) { Util.Debug("Browser: trident " + Util.Engine.trident); } - if (Util.Engine.presto) { Util.Debug("Browser: presto " + Util.Engine.presto); } - - this.clear(); - - // Check canvas features - if ('createImageData' in this._drawCtx) { - this._render_mode = 'canvas rendering'; - } else { - throw new Error("Canvas does not support createImageData"); - } - - if (this._prefer_js === null) { - Util.Info("Prefering javascript operations"); - this._prefer_js = true; - } - - // Determine browser support for setting the cursor via data URI scheme - if (this._cursor_uri || this._cursor_uri === null || - this._cursor_uri === undefined) { - this._cursor_uri = Util.browserSupportsCursorURIs(); - } - - Util.Debug("<< Display.constructor"); - }; - - Display.prototype = { - // Public methods - viewportChangePos: function (deltaX, deltaY) { - var vp = this._viewportLoc; - - if (!this._viewport) { - deltaX = -vp.w; // clamped later of out of bounds - deltaY = -vp.h; - } - - var vx2 = vp.x + vp.w - 1; - var vy2 = vp.y + vp.h - 1; - - // Position change - - if (deltaX < 0 && vp.x + deltaX < 0) { - deltaX = -vp.x; - } - if (vx2 + deltaX >= this._fb_width) { - deltaX -= vx2 + deltaX - this._fb_width + 1; - } - - if (vp.y + deltaY < 0) { - deltaY = -vp.y; - } - if (vy2 + deltaY >= this._fb_height) { - deltaY -= (vy2 + deltaY - this._fb_height + 1); - } - - if (deltaX === 0 && deltaY === 0) { - return; - } - Util.Debug("viewportChange deltaX: " + deltaX + ", deltaY: " + deltaY); - - vp.x += deltaX; - vx2 += deltaX; - vp.y += deltaY; - vy2 += deltaY; - - // Update the clean rectangle - var cr = this._cleanRect; - if (vp.x > cr.x1) { - cr.x1 = vp.x; - } - if (vx2 < cr.x2) { - cr.x2 = vx2; - } - if (vp.y > cr.y1) { - cr.y1 = vp.y; - } - if (vy2 < cr.y2) { - cr.y2 = vy2; - } - - var x1, w; - if (deltaX < 0) { - // Shift viewport left, redraw left section - x1 = 0; - w = -deltaX; - } else { - // Shift viewport right, redraw right section - x1 = vp.w - deltaX; - w = deltaX; - } - - var y1, h; - if (deltaY < 0) { - // Shift viewport up, redraw top section - y1 = 0; - h = -deltaY; - } else { - // Shift viewport down, redraw bottom section - y1 = vp.h - deltaY; - h = deltaY; - } - - // Copy the valid part of the viewport to the shifted location - var saveStyle = this._drawCtx.fillStyle; - var canvas = this._target; - this._drawCtx.fillStyle = "rgb(255,255,255)"; - if (deltaX !== 0) { - this._drawCtx.drawImage(canvas, 0, 0, vp.w, vp.h, -deltaX, 0, vp.w, vp.h); - this._drawCtx.fillRect(x1, 0, w, vp.h); - } - if (deltaY !== 0) { - this._drawCtx.drawImage(canvas, 0, 0, vp.w, vp.h, 0, -deltaY, vp.w, vp.h); - this._drawCtx.fillRect(0, y1, vp.w, h); - } - this._drawCtx.fillStyle = saveStyle; - }, - - viewportChangeSize: function(width, height) { - - if (typeof(width) === "undefined" || typeof(height) === "undefined") { - - Util.Debug("Setting viewport to full display region"); - width = this._fb_width; - height = this._fb_height; - } - - var vp = this._viewportLoc; - if (vp.w !== width || vp.h !== height) { - - if (this._viewport) { - if (this._maxWidth !== 0 && width > this._maxWidth) { - width = this._maxWidth; - } - if (this._maxHeight !== 0 && height > this._maxHeight) { - height = this._maxHeight; - } - } - - var cr = this._cleanRect; - - if (width < vp.w && cr.x2 > vp.x + width - 1) { - cr.x2 = vp.x + width - 1; - } - if (height < vp.h && cr.y2 > vp.y + height - 1) { - cr.y2 = vp.y + height - 1; - } - - vp.w = width; - vp.h = height; - - var canvas = this._target; - if (canvas.width !== width || canvas.height !== height) { - - // We have to save the canvas data since changing the size will clear it - var saveImg = null; - if (vp.w > 0 && vp.h > 0 && canvas.width > 0 && canvas.height > 0) { - var img_width = canvas.width < vp.w ? canvas.width : vp.w; - var img_height = canvas.height < vp.h ? canvas.height : vp.h; - saveImg = this._drawCtx.getImageData(0, 0, img_width, img_height); - } - - if (canvas.width !== width) { canvas.width = width; } - if (canvas.height !== height) { canvas.height = height; } - - if (this._viewport) { - canvas.style.height = height + 'px'; - canvas.style.width = width + 'px'; - } - - if (saveImg) { - this._drawCtx.putImageData(saveImg, 0, 0); - } - } - } - }, - - // Return a map of clean and dirty areas of the viewport and reset the - // tracking of clean and dirty areas - // - // Returns: { 'cleanBox': { 'x': x, 'y': y, 'w': w, 'h': h}, - // 'dirtyBoxes': [{ 'x': x, 'y': y, 'w': w, 'h': h }, ...] } - getCleanDirtyReset: function () { - var vp = this._viewportLoc; - var cr = this._cleanRect; - - var cleanBox = { 'x': cr.x1, 'y': cr.y1, - 'w': cr.x2 - cr.x1 + 1, 'h': cr.y2 - cr.y1 + 1 }; - - var dirtyBoxes = []; - if (cr.x1 >= cr.x2 || cr.y1 >= cr.y2) { - // Whole viewport is dirty - dirtyBoxes.push({ 'x': vp.x, 'y': vp.y, 'w': vp.w, 'h': vp.h }); - } else { - // Redraw dirty regions - var vx2 = vp.x + vp.w - 1; - var vy2 = vp.y + vp.h - 1; - - if (vp.x < cr.x1) { - // left side dirty region - dirtyBoxes.push({'x': vp.x, 'y': vp.y, - 'w': cr.x1 - vp.x + 1, 'h': vp.h}); - } - if (vx2 > cr.x2) { - // right side dirty region - dirtyBoxes.push({'x': cr.x2 + 1, 'y': vp.y, - 'w': vx2 - cr.x2, 'h': vp.h}); - } - if(vp.y < cr.y1) { - // top/middle dirty region - dirtyBoxes.push({'x': cr.x1, 'y': vp.y, - 'w': cr.x2 - cr.x1 + 1, 'h': cr.y1 - vp.y}); - } - if (vy2 > cr.y2) { - // bottom/middle dirty region - dirtyBoxes.push({'x': cr.x1, 'y': cr.y2 + 1, - 'w': cr.x2 - cr.x1 + 1, 'h': vy2 - cr.y2}); - } - } - - this._cleanRect = {'x1': vp.x, 'y1': vp.y, - 'x2': vp.x + vp.w - 1, 'y2': vp.y + vp.h - 1}; - - return {'cleanBox': cleanBox, 'dirtyBoxes': dirtyBoxes}; - }, - - absX: function (x) { - return x + this._viewportLoc.x; - }, - - absY: function (y) { - return y + this._viewportLoc.y; - }, - - resize: function (width, height) { - this._prevDrawStyle = ""; - - this._fb_width = width; - this._fb_height = height; - - this._rescale(this._scale); - - this.viewportChangeSize(); - }, - - clear: function () { - if (this._logo) { - this.resize(this._logo.width, this._logo.height); - this.blitStringImage(this._logo.data, 0, 0); - } else { - if (Util.Engine.trident === 6) { - // NB(directxman12): there's a bug in IE10 where we can fail to actually - // clear the canvas here because of the resize. - // Clearing the current viewport first fixes the issue - this._drawCtx.clearRect(0, 0, this._viewportLoc.w, this._viewportLoc.h); - } - this.resize(240, 20); - this._drawCtx.clearRect(0, 0, this._viewportLoc.w, this._viewportLoc.h); - } - - this._renderQ = []; - }, - - fillRect: function (x, y, width, height, color) { - this._setFillColor(color); - this._drawCtx.fillRect(x - this._viewportLoc.x, y - this._viewportLoc.y, width, height); - }, - - copyImage: function (old_x, old_y, new_x, new_y, w, h) { - var x1 = old_x - this._viewportLoc.x; - var y1 = old_y - this._viewportLoc.y; - var x2 = new_x - this._viewportLoc.x; - var y2 = new_y - this._viewportLoc.y; - - this._drawCtx.drawImage(this._target, x1, y1, w, h, x2, y2, w, h); - }, - - // start updating a tile - startTile: function (x, y, width, height, color) { - this._tile_x = x; - this._tile_y = y; - if (width === 16 && height === 16) { - this._tile = this._tile16x16; - } else { - this._tile = this._drawCtx.createImageData(width, height); - } - - if (this._prefer_js) { - var bgr; - if (this._true_color) { - bgr = color; - } else { - bgr = this._colourMap[color[0]]; - } - var red = bgr[2]; - var green = bgr[1]; - var blue = bgr[0]; - - var data = this._tile.data; - for (var i = 0; i < width * height * 4; i += 4) { - data[i] = red; - data[i + 1] = green; - data[i + 2] = blue; - data[i + 3] = 255; - } - } else { - this.fillRect(x, y, width, height, color); - } - }, - - // update sub-rectangle of the current tile - subTile: function (x, y, w, h, color) { - if (this._prefer_js) { - var bgr; - if (this._true_color) { - bgr = color; - } else { - bgr = this._colourMap[color[0]]; - } - var red = bgr[2]; - var green = bgr[1]; - var blue = bgr[0]; - var xend = x + w; - var yend = y + h; - - var data = this._tile.data; - var width = this._tile.width; - for (var j = y; j < yend; j++) { - for (var i = x; i < xend; i++) { - var p = (i + (j * width)) * 4; - data[p] = red; - data[p + 1] = green; - data[p + 2] = blue; - data[p + 3] = 255; - } - } - } else { - this.fillRect(this._tile_x + x, this._tile_y + y, w, h, color); - } - }, - - // draw the current tile to the screen - finishTile: function () { - if (this._prefer_js) { - this._drawCtx.putImageData(this._tile, this._tile_x - this._viewportLoc.x, - this._tile_y - this._viewportLoc.y); - } - // else: No-op -- already done by setSubTile - }, - - blitImage: function (x, y, width, height, arr, offset) { - if (this._true_color) { - this._bgrxImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset); - } else { - this._cmapImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset); - } - }, - - blitRgbImage: function (x, y , width, height, arr, offset) { - if (this._true_color) { - this._rgbImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset); - } else { - // probably wrong? - this._cmapImageData(x, y, this._viewportLoc.x, this._viewportLoc.y, width, height, arr, offset); - } - }, - - blitStringImage: function (str, x, y) { - var img = new Image(); - img.onload = function () { - this._drawCtx.drawImage(img, x - this._viewportLoc.x, y - this._viewportLoc.y); - }.bind(this); - img.src = str; - return img; // for debugging purposes - }, - - // wrap ctx.drawImage but relative to viewport - drawImage: function (img, x, y) { - this._drawCtx.drawImage(img, x - this._viewportLoc.x, y - this._viewportLoc.y); - }, - - renderQ_push: function (action) { - this._renderQ.push(action); - if (this._renderQ.length === 1) { - // If this can be rendered immediately it will be, otherwise - // the scanner will start polling the queue (every - // requestAnimationFrame interval) - this._scan_renderQ(); - } - }, - - changeCursor: function (pixels, mask, hotx, hoty, w, h) { - if (this._cursor_uri === false) { - Util.Warn("changeCursor called but no cursor data URI support"); - return; - } - - if (this._true_color) { - Display.changeCursor(this._target, pixels, mask, hotx, hoty, w, h); - } else { - Display.changeCursor(this._target, pixels, mask, hotx, hoty, w, h, this._colourMap); - } - }, - - defaultCursor: function () { - this._target.style.cursor = "default"; - }, - - disableLocalCursor: function () { - this._target.style.cursor = "none"; - }, - - clippingDisplay: function () { - var vp = this._viewportLoc; - - var fbClip = this._fb_width > vp.w || this._fb_height > vp.h; - var limitedVp = this._maxWidth !== 0 && this._maxHeight !== 0; - var clipping = false; - - if (limitedVp) { - clipping = vp.w > this._maxWidth || vp.h > this._maxHeight; - } - - return fbClip || (limitedVp && clipping); - }, - - // Overridden getters/setters - get_context: function () { - return this._drawCtx; - }, - - set_scale: function (scale) { - this._rescale(scale); - }, - - set_width: function (w) { - this._fb_width = w; - }, - get_width: function () { - return this._fb_width; - }, - - set_height: function (h) { - this._fb_height = h; - }, - get_height: function () { - return this._fb_height; - }, - - autoscale: function (containerWidth, containerHeight, downscaleOnly) { - var targetAspectRatio = containerWidth / containerHeight; - var fbAspectRatio = this._fb_width / this._fb_height; - - var scaleRatio; - if (fbAspectRatio >= targetAspectRatio) { - scaleRatio = containerWidth / this._fb_width; - } else { - scaleRatio = containerHeight / this._fb_height; - } - - var targetW, targetH; - if (scaleRatio > 1.0 && downscaleOnly) { - targetW = this._fb_width; - targetH = this._fb_height; - scaleRatio = 1.0; - } else if (fbAspectRatio >= targetAspectRatio) { - targetW = containerWidth; - targetH = Math.round(containerWidth / fbAspectRatio); - } else { - targetW = Math.round(containerHeight * fbAspectRatio); - targetH = containerHeight; - } - - // NB(directxman12): If you set the width directly, or set the - // style width to a number, the canvas is cleared. - // However, if you set the style width to a string - // ('NNNpx'), the canvas is scaled without clearing. - this._target.style.width = targetW + 'px'; - this._target.style.height = targetH + 'px'; - - this._scale = scaleRatio; - - return scaleRatio; // so that the mouse, etc scale can be set - }, - - // Private Methods - _rescale: function (factor) { - this._scale = factor; - - var w; - var h; - - if (this._viewport && - this._maxWidth !== 0 && this._maxHeight !== 0) { - w = Math.min(this._fb_width, this._maxWidth); - h = Math.min(this._fb_height, this._maxHeight); - } else { - w = this._fb_width; - h = this._fb_height; - } - - this._target.style.width = Math.round(factor * w) + 'px'; - this._target.style.height = Math.round(factor * h) + 'px'; - }, - - _setFillColor: function (color) { - var bgr; - if (this._true_color) { - bgr = color; - } else { - bgr = this._colourMap[color[0]]; - } - - var newStyle = 'rgb(' + bgr[2] + ',' + bgr[1] + ',' + bgr[0] + ')'; - if (newStyle !== this._prevDrawStyle) { - this._drawCtx.fillStyle = newStyle; - this._prevDrawStyle = newStyle; - } - }, - - _rgbImageData: function (x, y, vx, vy, width, height, arr, offset) { - var img = this._drawCtx.createImageData(width, height); - var data = img.data; - for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 3) { - data[i] = arr[j]; - data[i + 1] = arr[j + 1]; - data[i + 2] = arr[j + 2]; - data[i + 3] = 255; // Alpha - } - this._drawCtx.putImageData(img, x - vx, y - vy); - }, - - _bgrxImageData: function (x, y, vx, vy, width, height, arr, offset) { - var img = this._drawCtx.createImageData(width, height); - var data = img.data; - for (var i = 0, j = offset; i < width * height * 4; i += 4, j += 4) { - data[i] = arr[j + 2]; - data[i + 1] = arr[j + 1]; - data[i + 2] = arr[j]; - data[i + 3] = 255; // Alpha - } - this._drawCtx.putImageData(img, x - vx, y - vy); - }, - - _cmapImageData: function (x, y, vx, vy, width, height, arr, offset) { - var img = this._drawCtx.createImageData(width, height); - var data = img.data; - var cmap = this._colourMap; - for (var i = 0, j = offset; i < width * height * 4; i += 4, j++) { - var bgr = cmap[arr[j]]; - data[i] = bgr[2]; - data[i + 1] = bgr[1]; - data[i + 2] = bgr[0]; - data[i + 3] = 255; // Alpha - } - this._drawCtx.putImageData(img, x - vx, y - vy); - }, - - _scan_renderQ: function () { - var ready = true; - while (ready && this._renderQ.length > 0) { - var a = this._renderQ[0]; - switch (a.type) { - case 'copy': - this.copyImage(a.old_x, a.old_y, a.x, a.y, a.width, a.height); - break; - case 'fill': - this.fillRect(a.x, a.y, a.width, a.height, a.color); - break; - case 'blit': - this.blitImage(a.x, a.y, a.width, a.height, a.data, 0); - break; - case 'blitRgb': - this.blitRgbImage(a.x, a.y, a.width, a.height, a.data, 0); - break; - case 'img': - if (a.img.complete) { - this.drawImage(a.img, a.x, a.y); - } else { - // We need to wait for this image to 'load' - // to keep things in-order - ready = false; - } - break; - } - - if (ready) { - this._renderQ.shift(); - } - } - - if (this._renderQ.length > 0) { - requestAnimFrame(this._scan_renderQ.bind(this)); - } - }, - }; - - Util.make_properties(Display, [ - ['target', 'wo', 'dom'], // Canvas element for rendering - ['context', 'ro', 'raw'], // Canvas 2D context for rendering (read-only) - ['logo', 'rw', 'raw'], // Logo to display when cleared: {"width": w, "height": h, "data": data} - ['true_color', 'rw', 'bool'], // Use true-color pixel data - ['colourMap', 'rw', 'arr'], // Colour map array (when not true-color) - ['scale', 'rw', 'float'], // Display area scale factor 0.0 - 1.0 - ['viewport', 'rw', 'bool'], // Use viewport clipping - ['width', 'rw', 'int'], // Display area width - ['height', 'rw', 'int'], // Display area height - ['maxWidth', 'rw', 'int'], // Viewport max width (0 if disabled) - ['maxHeight', 'rw', 'int'], // Viewport max height (0 if disabled) - - ['render_mode', 'ro', 'str'], // Canvas rendering mode (read-only) - - ['prefer_js', 'rw', 'str'], // Prefer Javascript over canvas methods - ['cursor_uri', 'rw', 'raw'] // Can we render cursor using data URI - ]); - - // Class Methods - Display.changeCursor = function (target, pixels, mask, hotx, hoty, w0, h0, cmap) { - var w = w0; - var h = h0; - if (h < w) { - h = w; // increase h to make it square - } else { - w = h; // increase w to make it square - } - - var cur = []; - - // Push multi-byte little-endian values - cur.push16le = function (num) { - this.push(num & 0xFF, (num >> 8) & 0xFF); - }; - cur.push32le = function (num) { - this.push(num & 0xFF, - (num >> 8) & 0xFF, - (num >> 16) & 0xFF, - (num >> 24) & 0xFF); - }; - - var IHDRsz = 40; - var RGBsz = w * h * 4; - var XORsz = Math.ceil((w * h) / 8.0); - var ANDsz = Math.ceil((w * h) / 8.0); - - cur.push16le(0); // 0: Reserved - cur.push16le(2); // 2: .CUR type - cur.push16le(1); // 4: Number of images, 1 for non-animated ico - - // Cursor #1 header (ICONDIRENTRY) - cur.push(w); // 6: width - cur.push(h); // 7: height - cur.push(0); // 8: colors, 0 -> true-color - cur.push(0); // 9: reserved - cur.push16le(hotx); // 10: hotspot x coordinate - cur.push16le(hoty); // 12: hotspot y coordinate - cur.push32le(IHDRsz + RGBsz + XORsz + ANDsz); - // 14: cursor data byte size - cur.push32le(22); // 18: offset of cursor data in the file - - // Cursor #1 InfoHeader (ICONIMAGE/BITMAPINFO) - cur.push32le(IHDRsz); // 22: InfoHeader size - cur.push32le(w); // 26: Cursor width - cur.push32le(h * 2); // 30: XOR+AND height - cur.push16le(1); // 34: number of planes - cur.push16le(32); // 36: bits per pixel - cur.push32le(0); // 38: Type of compression - - cur.push32le(XORsz + ANDsz); - // 42: Size of Image - cur.push32le(0); // 46: reserved - cur.push32le(0); // 50: reserved - cur.push32le(0); // 54: reserved - cur.push32le(0); // 58: reserved - - // 62: color data (RGBQUAD icColors[]) - var y, x; - for (y = h - 1; y >= 0; y--) { - for (x = 0; x < w; x++) { - if (x >= w0 || y >= h0) { - cur.push(0); // blue - cur.push(0); // green - cur.push(0); // red - cur.push(0); // alpha - } else { - var idx = y * Math.ceil(w0 / 8) + Math.floor(x / 8); - var alpha = (mask[idx] << (x % 8)) & 0x80 ? 255 : 0; - if (cmap) { - idx = (w0 * y) + x; - var rgb = cmap[pixels[idx]]; - cur.push(rgb[2]); // blue - cur.push(rgb[1]); // green - cur.push(rgb[0]); // red - cur.push(alpha); // alpha - } else { - idx = ((w0 * y) + x) * 4; - cur.push(pixels[idx + 2]); // blue - cur.push(pixels[idx + 1]); // green - cur.push(pixels[idx]); // red - cur.push(alpha); // alpha - } - } - } - } - - // XOR/bitmask data (BYTE icXOR[]) - // (ignored, just needs to be the right size) - for (y = 0; y < h; y++) { - for (x = 0; x < Math.ceil(w / 8); x++) { - cur.push(0); - } - } - - // AND/bitmask data (BYTE icAND[]) - // (ignored, just needs to be the right size) - for (y = 0; y < h; y++) { - for (x = 0; x < Math.ceil(w / 8); x++) { - cur.push(0); - } - } - - var url = 'data:image/x-icon;base64,' + Base64.encode(cur); - target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default'; - }; -})(); diff --git a/noVNC/include/font-awesome/css/font-awesome.css b/noVNC/include/font-awesome/css/font-awesome.css deleted file mode 100755 index ab5a4c1..0000000 --- a/noVNC/include/font-awesome/css/font-awesome.css +++ /dev/null @@ -1,66 +0,0 @@ -/*! - * Font Awesome 3.2.1 - * the iconic font designed for Bootstrap - * ------------------------------------------------------------------------------ - * The full suite of pictographic icons, examples, and documentation can be - * found at http://fontawesome.io. Stay up to date on Twitter at - * http://twitter.com/fontawesome. - * - * License - * ------------------------------------------------------------------------------ - * - The Font Awesome font is licensed under SIL OFL 1.1 - - * http://scripts.sil.org/OFL - * - Font Awesome CSS, LESS, and SASS files are licensed under MIT License - - * http://opensource.org/licenses/mit-license.html - * - Font Awesome documentation licensed under CC BY 3.0 - - * http://creativecommons.org/licenses/by/3.0/ - * - Attribution is no longer required in Font Awesome 3.0, but much appreciated: - * "Font Awesome by Dave Gandy - http://fontawesome.io" - * - * Author - Dave Gandy - * ------------------------------------------------------------------------------ - * Email: dave@fontawesome.io - * Twitter: http://twitter.com/davegandy - * Work: Lead Product Designer @ Kyruus - http://kyruus.com - */ -/* FONT PATH - * -------------------------- */ -@font-face { - font-family: 'FontAwesome'; - src: url('../font/fontawesome-webfont.eot?v=3.2.1'); - src: url('../font/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'), url('../font/fontawesome-webfont.woff?v=3.2.1') format('woff'), url('../font/fontawesome-webfont.ttf?v=3.2.1') format('truetype'), url('../font/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg'); - font-weight: normal; - font-style: normal; -} -/* FONT AWESOME CORE - * -------------------------- */ -[class^="icon-"], -[class*=" icon-"] { - font-family: FontAwesome; - font-weight: normal; - font-style: normal; - text-decoration: inherit; - -webkit-font-smoothing: antialiased; - *margin-right: .3em; -} -[class^="icon-"]:before, -[class*=" icon-"]:before { - text-decoration: inherit; - display: inline-block; - speak: none; -} - -/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen - readers do not read off random characters that represent icons */ -.icon-long-arrow-down:before { - content: "\f175"; -} -.icon-long-arrow-up:before { - content: "\f176"; -} -.icon-long-arrow-left:before { - content: "\f177"; -} -.icon-long-arrow-right:before { - content: "\f178"; -} diff --git a/noVNC/include/font-awesome/font/FontAwesome.otf b/noVNC/include/font-awesome/font/FontAwesome.otf deleted file mode 100755 index 8b0f54e..0000000 Binary files a/noVNC/include/font-awesome/font/FontAwesome.otf and /dev/null differ diff --git a/noVNC/include/font-awesome/font/fontawesome-webfont.eot b/noVNC/include/font-awesome/font/fontawesome-webfont.eot deleted file mode 100755 index 7c79c6a..0000000 Binary files a/noVNC/include/font-awesome/font/fontawesome-webfont.eot and /dev/null differ diff --git a/noVNC/include/font-awesome/font/fontawesome-webfont.svg b/noVNC/include/font-awesome/font/fontawesome-webfont.svg deleted file mode 100755 index 45fdf33..0000000 --- a/noVNC/include/font-awesome/font/fontawesome-webfont.svg +++ /dev/null @@ -1,414 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/noVNC/include/font-awesome/font/fontawesome-webfont.ttf b/noVNC/include/font-awesome/font/fontawesome-webfont.ttf deleted file mode 100755 index e89738d..0000000 Binary files a/noVNC/include/font-awesome/font/fontawesome-webfont.ttf and /dev/null differ diff --git a/noVNC/include/font-awesome/font/fontawesome-webfont.woff b/noVNC/include/font-awesome/font/fontawesome-webfont.woff deleted file mode 100755 index 8c1748a..0000000 Binary files a/noVNC/include/font-awesome/font/fontawesome-webfont.woff and /dev/null differ diff --git a/noVNC/include/jsunzip.js b/noVNC/include/jsunzip.js deleted file mode 100755 index 8968f86..0000000 --- a/noVNC/include/jsunzip.js +++ /dev/null @@ -1,676 +0,0 @@ -/* - * JSUnzip - * - * Copyright (c) 2011 by Erik Moller - * All Rights Reserved - * - * This software is provided 'as-is', without any express - * or implied warranty. In no event will the authors be - * held liable for any damages arising from the use of - * this software. - * - * Permission is granted to anyone to use this software - * for any purpose, including commercial applications, - * and to alter it and redistribute it freely, subject to - * the following restrictions: - * - * 1. The origin of this software must not be - * misrepresented; you must not claim that you - * wrote the original software. If you use this - * software in a product, an acknowledgment in - * the product documentation would be appreciated - * but is not required. - * - * 2. Altered source versions must be plainly marked - * as such, and must not be misrepresented as - * being the original software. - * - * 3. This notice may not be removed or altered from - * any source distribution. - */ - -var tinf; - -function JSUnzip() { - - this.getInt = function(offset, size) { - switch (size) { - case 4: - return (this.data.charCodeAt(offset + 3) & 0xff) << 24 | - (this.data.charCodeAt(offset + 2) & 0xff) << 16 | - (this.data.charCodeAt(offset + 1) & 0xff) << 8 | - (this.data.charCodeAt(offset + 0) & 0xff); - break; - case 2: - return (this.data.charCodeAt(offset + 1) & 0xff) << 8 | - (this.data.charCodeAt(offset + 0) & 0xff); - break; - default: - return this.data.charCodeAt(offset) & 0xff; - break; - } - }; - - this.getDOSDate = function(dosdate, dostime) { - var day = dosdate & 0x1f; - var month = ((dosdate >> 5) & 0xf) - 1; - var year = 1980 + ((dosdate >> 9) & 0x7f) - var second = (dostime & 0x1f) * 2; - var minute = (dostime >> 5) & 0x3f; - hour = (dostime >> 11) & 0x1f; - return new Date(year, month, day, hour, minute, second); - } - - this.open = function(data) { - this.data = data; - this.files = []; - - if (this.data.length < 22) - return { 'status' : false, 'error' : 'Invalid data' }; - var endOfCentralDirectory = this.data.length - 22; - while (endOfCentralDirectory >= 0 && this.getInt(endOfCentralDirectory, 4) != 0x06054b50) - --endOfCentralDirectory; - if (endOfCentralDirectory < 0) - return { 'status' : false, 'error' : 'Invalid data' }; - if (this.getInt(endOfCentralDirectory + 4, 2) != 0 || this.getInt(endOfCentralDirectory + 6, 2) != 0) - return { 'status' : false, 'error' : 'No multidisk support' }; - - var entriesInThisDisk = this.getInt(endOfCentralDirectory + 8, 2); - var centralDirectoryOffset = this.getInt(endOfCentralDirectory + 16, 4); - var globalCommentLength = this.getInt(endOfCentralDirectory + 20, 2); - this.comment = this.data.slice(endOfCentralDirectory + 22, endOfCentralDirectory + 22 + globalCommentLength); - - var fileOffset = centralDirectoryOffset; - - for (var i = 0; i < entriesInThisDisk; ++i) { - if (this.getInt(fileOffset + 0, 4) != 0x02014b50) - return { 'status' : false, 'error' : 'Invalid data' }; - if (this.getInt(fileOffset + 6, 2) > 20) - return { 'status' : false, 'error' : 'Unsupported version' }; - if (this.getInt(fileOffset + 8, 2) & 1) - return { 'status' : false, 'error' : 'Encryption not implemented' }; - - var compressionMethod = this.getInt(fileOffset + 10, 2); - if (compressionMethod != 0 && compressionMethod != 8) - return { 'status' : false, 'error' : 'Unsupported compression method' }; - - var lastModFileTime = this.getInt(fileOffset + 12, 2); - var lastModFileDate = this.getInt(fileOffset + 14, 2); - var lastModifiedDate = this.getDOSDate(lastModFileDate, lastModFileTime); - - var crc = this.getInt(fileOffset + 16, 4); - // TODO: crc - - var compressedSize = this.getInt(fileOffset + 20, 4); - var uncompressedSize = this.getInt(fileOffset + 24, 4); - - var fileNameLength = this.getInt(fileOffset + 28, 2); - var extraFieldLength = this.getInt(fileOffset + 30, 2); - var fileCommentLength = this.getInt(fileOffset + 32, 2); - - var relativeOffsetOfLocalHeader = this.getInt(fileOffset + 42, 4); - - var fileName = this.data.slice(fileOffset + 46, fileOffset + 46 + fileNameLength); - var fileComment = this.data.slice(fileOffset + 46 + fileNameLength + extraFieldLength, fileOffset + 46 + fileNameLength + extraFieldLength + fileCommentLength); - - if (this.getInt(relativeOffsetOfLocalHeader + 0, 4) != 0x04034b50) - return { 'status' : false, 'error' : 'Invalid data' }; - var localFileNameLength = this.getInt(relativeOffsetOfLocalHeader + 26, 2); - var localExtraFieldLength = this.getInt(relativeOffsetOfLocalHeader + 28, 2); - var localFileContent = relativeOffsetOfLocalHeader + 30 + localFileNameLength + localExtraFieldLength; - - this.files[fileName] = - { - 'fileComment' : fileComment, - 'compressionMethod' : compressionMethod, - 'compressedSize' : compressedSize, - 'uncompressedSize' : uncompressedSize, - 'localFileContent' : localFileContent, - 'lastModifiedDate' : lastModifiedDate - }; - - fileOffset += 46 + fileNameLength + extraFieldLength + fileCommentLength; - } - return { 'status' : true } - }; - - - this.read = function(fileName) { - var fileInfo = this.files[fileName]; - if (fileInfo) { - if (fileInfo.compressionMethod == 8) { - if (!tinf) { - tinf = new TINF(); - tinf.init(); - } - var result = tinf.uncompress(this.data, fileInfo.localFileContent); - if (result.status == tinf.OK) - return { 'status' : true, 'data' : result.data }; - else - return { 'status' : false, 'error' : result.error }; - } else { - return { 'status' : true, 'data' : this.data.slice(fileInfo.localFileContent, fileInfo.localFileContent + fileInfo.uncompressedSize) }; - } - } - return { 'status' : false, 'error' : "File '" + fileName + "' doesn't exist in zip" }; - }; - -}; - - - -/* - * tinflate - tiny inflate - * - * Copyright (c) 2003 by Joergen Ibsen / Jibz - * All Rights Reserved - * - * http://www.ibsensoftware.com/ - * - * This software is provided 'as-is', without any express - * or implied warranty. In no event will the authors be - * held liable for any damages arising from the use of - * this software. - * - * Permission is granted to anyone to use this software - * for any purpose, including commercial applications, - * and to alter it and redistribute it freely, subject to - * the following restrictions: - * - * 1. The origin of this software must not be - * misrepresented; you must not claim that you - * wrote the original software. If you use this - * software in a product, an acknowledgment in - * the product documentation would be appreciated - * but is not required. - * - * 2. Altered source versions must be plainly marked - * as such, and must not be misrepresented as - * being the original software. - * - * 3. This notice may not be removed or altered from - * any source distribution. - */ - -/* - * tinflate javascript port by Erik Moller in May 2011. - * emoller@opera.com - * - * read_bits() patched by mike@imidio.com to allow - * reading more then 8 bits (needed in some zlib streams) - */ - -"use strict"; - -function TINF() { - -this.OK = 0; -this.DATA_ERROR = (-3); -this.WINDOW_SIZE = 32768; - -/* ------------------------------ * - * -- internal data structures -- * - * ------------------------------ */ - -this.TREE = function() { - this.table = new Array(16); /* table of code length counts */ - this.trans = new Array(288); /* code -> symbol translation table */ -}; - -this.DATA = function(that) { - this.source = ''; - this.sourceIndex = 0; - this.tag = 0; - this.bitcount = 0; - - this.dest = []; - - this.history = []; - - this.ltree = new that.TREE(); /* dynamic length/symbol tree */ - this.dtree = new that.TREE(); /* dynamic distance tree */ -}; - -/* --------------------------------------------------- * - * -- uninitialized global data (static structures) -- * - * --------------------------------------------------- */ - -this.sltree = new this.TREE(); /* fixed length/symbol tree */ -this.sdtree = new this.TREE(); /* fixed distance tree */ - -/* extra bits and base tables for length codes */ -this.length_bits = new Array(30); -this.length_base = new Array(30); - -/* extra bits and base tables for distance codes */ -this.dist_bits = new Array(30); -this.dist_base = new Array(30); - -/* special ordering of code length codes */ -this.clcidx = [ - 16, 17, 18, 0, 8, 7, 9, 6, - 10, 5, 11, 4, 12, 3, 13, 2, - 14, 1, 15 -]; - -/* ----------------------- * - * -- utility functions -- * - * ----------------------- */ - -/* build extra bits and base tables */ -this.build_bits_base = function(bits, base, delta, first) -{ - var i, sum; - - /* build bits table */ - for (i = 0; i < delta; ++i) bits[i] = 0; - for (i = 0; i < 30 - delta; ++i) bits[i + delta] = Math.floor(i / delta); - - /* build base table */ - for (sum = first, i = 0; i < 30; ++i) - { - base[i] = sum; - sum += 1 << bits[i]; - } -} - -/* build the fixed huffman trees */ -this.build_fixed_trees = function(lt, dt) -{ - var i; - - /* build fixed length tree */ - for (i = 0; i < 7; ++i) lt.table[i] = 0; - - lt.table[7] = 24; - lt.table[8] = 152; - lt.table[9] = 112; - - for (i = 0; i < 24; ++i) lt.trans[i] = 256 + i; - for (i = 0; i < 144; ++i) lt.trans[24 + i] = i; - for (i = 0; i < 8; ++i) lt.trans[24 + 144 + i] = 280 + i; - for (i = 0; i < 112; ++i) lt.trans[24 + 144 + 8 + i] = 144 + i; - - /* build fixed distance tree */ - for (i = 0; i < 5; ++i) dt.table[i] = 0; - - dt.table[5] = 32; - - for (i = 0; i < 32; ++i) dt.trans[i] = i; -} - -/* given an array of code lengths, build a tree */ -this.build_tree = function(t, lengths, loffset, num) -{ - var offs = new Array(16); - var i, sum; - - /* clear code length count table */ - for (i = 0; i < 16; ++i) t.table[i] = 0; - - /* scan symbol lengths, and sum code length counts */ - for (i = 0; i < num; ++i) t.table[lengths[loffset + i]]++; - - t.table[0] = 0; - - /* compute offset table for distribution sort */ - for (sum = 0, i = 0; i < 16; ++i) - { - offs[i] = sum; - sum += t.table[i]; - } - - /* create code->symbol translation table (symbols sorted by code) */ - for (i = 0; i < num; ++i) - { - if (lengths[loffset + i]) t.trans[offs[lengths[loffset + i]]++] = i; - } -} - -/* ---------------------- * - * -- decode functions -- * - * ---------------------- */ - -/* get one bit from source stream */ -this.getbit = function(d) -{ - var bit; - - /* check if tag is empty */ - if (!d.bitcount--) - { - /* load next tag */ - d.tag = d.source[d.sourceIndex++] & 0xff; - d.bitcount = 7; - } - - /* shift bit out of tag */ - bit = d.tag & 0x01; - d.tag >>= 1; - - return bit; -} - -/* read a num bit value from a stream and add base */ -function read_bits_direct(source, bitcount, tag, idx, num) -{ - var val = 0; - while (bitcount < 24) { - tag = tag | (source[idx++] & 0xff) << bitcount; - bitcount += 8; - } - val = tag & (0xffff >> (16 - num)); - tag >>= num; - bitcount -= num; - return [bitcount, tag, idx, val]; -} -this.read_bits = function(d, num, base) -{ - if (!num) - return base; - - var ret = read_bits_direct(d.source, d.bitcount, d.tag, d.sourceIndex, num); - d.bitcount = ret[0]; - d.tag = ret[1]; - d.sourceIndex = ret[2]; - return ret[3] + base; -} - -/* given a data stream and a tree, decode a symbol */ -this.decode_symbol = function(d, t) -{ - while (d.bitcount < 16) { - d.tag = d.tag | (d.source[d.sourceIndex++] & 0xff) << d.bitcount; - d.bitcount += 8; - } - - var sum = 0, cur = 0, len = 0; - do { - cur = 2 * cur + ((d.tag & (1 << len)) >> len); - - ++len; - - sum += t.table[len]; - cur -= t.table[len]; - - } while (cur >= 0); - - d.tag >>= len; - d.bitcount -= len; - - return t.trans[sum + cur]; -} - -/* given a data stream, decode dynamic trees from it */ -this.decode_trees = function(d, lt, dt) -{ - var code_tree = new this.TREE(); - var lengths = new Array(288+32); - var hlit, hdist, hclen; - var i, num, length; - - /* get 5 bits HLIT (257-286) */ - hlit = this.read_bits(d, 5, 257); - - /* get 5 bits HDIST (1-32) */ - hdist = this.read_bits(d, 5, 1); - - /* get 4 bits HCLEN (4-19) */ - hclen = this.read_bits(d, 4, 4); - - for (i = 0; i < 19; ++i) lengths[i] = 0; - - /* read code lengths for code length alphabet */ - for (i = 0; i < hclen; ++i) - { - /* get 3 bits code length (0-7) */ - var clen = this.read_bits(d, 3, 0); - - lengths[this.clcidx[i]] = clen; - } - - /* build code length tree */ - this.build_tree(code_tree, lengths, 0, 19); - - /* decode code lengths for the dynamic trees */ - for (num = 0; num < hlit + hdist; ) - { - var sym = this.decode_symbol(d, code_tree); - - switch (sym) - { - case 16: - /* copy previous code length 3-6 times (read 2 bits) */ - { - var prev = lengths[num - 1]; - for (length = this.read_bits(d, 2, 3); length; --length) - { - lengths[num++] = prev; - } - } - break; - case 17: - /* repeat code length 0 for 3-10 times (read 3 bits) */ - for (length = this.read_bits(d, 3, 3); length; --length) - { - lengths[num++] = 0; - } - break; - case 18: - /* repeat code length 0 for 11-138 times (read 7 bits) */ - for (length = this.read_bits(d, 7, 11); length; --length) - { - lengths[num++] = 0; - } - break; - default: - /* values 0-15 represent the actual code lengths */ - lengths[num++] = sym; - break; - } - } - - /* build dynamic trees */ - this.build_tree(lt, lengths, 0, hlit); - this.build_tree(dt, lengths, hlit, hdist); -} - -/* ----------------------------- * - * -- block inflate functions -- * - * ----------------------------- */ - -/* given a stream and two trees, inflate a block of data */ -this.inflate_block_data = function(d, lt, dt) -{ - // js optimization. - var ddest = d.dest; - var ddestlength = ddest.length; - - while (1) - { - var sym = this.decode_symbol(d, lt); - - /* check for end of block */ - if (sym == 256) - { - return this.OK; - } - - if (sym < 256) - { - ddest[ddestlength++] = sym; // ? String.fromCharCode(sym); - d.history.push(sym); - } else { - - var length, dist, offs; - var i; - - sym -= 257; - - /* possibly get more bits from length code */ - length = this.read_bits(d, this.length_bits[sym], this.length_base[sym]); - - dist = this.decode_symbol(d, dt); - - /* possibly get more bits from distance code */ - offs = d.history.length - this.read_bits(d, this.dist_bits[dist], this.dist_base[dist]); - - if (offs < 0) - throw ("Invalid zlib offset " + offs); - - /* copy match */ - for (i = offs; i < offs + length; ++i) { - //ddest[ddestlength++] = ddest[i]; - ddest[ddestlength++] = d.history[i]; - d.history.push(d.history[i]); - } - } - } -} - -/* inflate an uncompressed block of data */ -this.inflate_uncompressed_block = function(d) -{ - var length, invlength; - var i; - - if (d.bitcount > 7) { - var overflow = Math.floor(d.bitcount / 8); - d.sourceIndex -= overflow; - d.bitcount = 0; - d.tag = 0; - } - - /* get length */ - length = d.source[d.sourceIndex+1]; - length = 256*length + d.source[d.sourceIndex]; - - /* get one's complement of length */ - invlength = d.source[d.sourceIndex+3]; - invlength = 256*invlength + d.source[d.sourceIndex+2]; - - /* check length */ - if (length != (~invlength & 0x0000ffff)) return this.DATA_ERROR; - - d.sourceIndex += 4; - - /* copy block */ - for (i = length; i; --i) { - d.history.push(d.source[d.sourceIndex]); - d.dest[d.dest.length] = d.source[d.sourceIndex++]; - } - - /* make sure we start next block on a byte boundary */ - d.bitcount = 0; - - return this.OK; -} - -/* inflate a block of data compressed with fixed huffman trees */ -this.inflate_fixed_block = function(d) -{ - /* decode block using fixed trees */ - return this.inflate_block_data(d, this.sltree, this.sdtree); -} - -/* inflate a block of data compressed with dynamic huffman trees */ -this.inflate_dynamic_block = function(d) -{ - /* decode trees from stream */ - this.decode_trees(d, d.ltree, d.dtree); - - /* decode block using decoded trees */ - return this.inflate_block_data(d, d.ltree, d.dtree); -} - -/* ---------------------- * - * -- public functions -- * - * ---------------------- */ - -/* initialize global (static) data */ -this.init = function() -{ - /* build fixed huffman trees */ - this.build_fixed_trees(this.sltree, this.sdtree); - - /* build extra bits and base tables */ - this.build_bits_base(this.length_bits, this.length_base, 4, 3); - this.build_bits_base(this.dist_bits, this.dist_base, 2, 1); - - /* fix a special case */ - this.length_bits[28] = 0; - this.length_base[28] = 258; - - this.reset(); -} - -this.reset = function() -{ - this.d = new this.DATA(this); - delete this.header; -} - -/* inflate stream from source to dest */ -this.uncompress = function(source, offset) -{ - - var d = this.d; - var bfinal; - - /* initialise data */ - d.source = source; - d.sourceIndex = offset; - d.bitcount = 0; - - d.dest = []; - - // Skip zlib header at start of stream - if (typeof this.header == 'undefined') { - this.header = this.read_bits(d, 16, 0); - /* byte 0: 0x78, 7 = 32k window size, 8 = deflate */ - /* byte 1: check bits for header and other flags */ - } - - var blocks = 0; - - do { - - var btype; - var res; - - /* read final block flag */ - bfinal = this.getbit(d); - - /* read block type (2 bits) */ - btype = this.read_bits(d, 2, 0); - - /* decompress block */ - switch (btype) - { - case 0: - /* decompress uncompressed block */ - res = this.inflate_uncompressed_block(d); - break; - case 1: - /* decompress block with fixed huffman trees */ - res = this.inflate_fixed_block(d); - break; - case 2: - /* decompress block with dynamic huffman trees */ - res = this.inflate_dynamic_block(d); - break; - default: - return { 'status' : this.DATA_ERROR }; - } - - if (res != this.OK) return { 'status' : this.DATA_ERROR }; - blocks++; - - } while (!bfinal && d.sourceIndex < d.source.length); - - d.history = d.history.slice(-this.WINDOW_SIZE); - - return { 'status' : this.OK, 'data' : d.dest }; -} - -}; diff --git a/noVNC/include/keysym.js b/noVNC/include/keysym.js deleted file mode 100644 index 58b107c..0000000 --- a/noVNC/include/keysym.js +++ /dev/null @@ -1,378 +0,0 @@ -var XK_VoidSymbol = 0xffffff, /* Void symbol */ - -XK_BackSpace = 0xff08, /* Back space, back char */ -XK_Tab = 0xff09, -XK_Linefeed = 0xff0a, /* Linefeed, LF */ -XK_Clear = 0xff0b, -XK_Return = 0xff0d, /* Return, enter */ -XK_Pause = 0xff13, /* Pause, hold */ -XK_Scroll_Lock = 0xff14, -XK_Sys_Req = 0xff15, -XK_Escape = 0xff1b, -XK_Delete = 0xffff, /* Delete, rubout */ - -/* Cursor control & motion */ - -XK_Home = 0xff50, -XK_Left = 0xff51, /* Move left, left arrow */ -XK_Up = 0xff52, /* Move up, up arrow */ -XK_Right = 0xff53, /* Move right, right arrow */ -XK_Down = 0xff54, /* Move down, down arrow */ -XK_Prior = 0xff55, /* Prior, previous */ -XK_Page_Up = 0xff55, -XK_Next = 0xff56, /* Next */ -XK_Page_Down = 0xff56, -XK_End = 0xff57, /* EOL */ -XK_Begin = 0xff58, /* BOL */ - - -/* Misc functions */ - -XK_Select = 0xff60, /* Select, mark */ -XK_Print = 0xff61, -XK_Execute = 0xff62, /* Execute, run, do */ -XK_Insert = 0xff63, /* Insert, insert here */ -XK_Undo = 0xff65, -XK_Redo = 0xff66, /* Redo, again */ -XK_Menu = 0xff67, -XK_Find = 0xff68, /* Find, search */ -XK_Cancel = 0xff69, /* Cancel, stop, abort, exit */ -XK_Help = 0xff6a, /* Help */ -XK_Break = 0xff6b, -XK_Mode_switch = 0xff7e, /* Character set switch */ -XK_script_switch = 0xff7e, /* Alias for mode_switch */ -XK_Num_Lock = 0xff7f, - -/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ - -XK_KP_Space = 0xff80, /* Space */ -XK_KP_Tab = 0xff89, -XK_KP_Enter = 0xff8d, /* Enter */ -XK_KP_F1 = 0xff91, /* PF1, KP_A, ... */ -XK_KP_F2 = 0xff92, -XK_KP_F3 = 0xff93, -XK_KP_F4 = 0xff94, -XK_KP_Home = 0xff95, -XK_KP_Left = 0xff96, -XK_KP_Up = 0xff97, -XK_KP_Right = 0xff98, -XK_KP_Down = 0xff99, -XK_KP_Prior = 0xff9a, -XK_KP_Page_Up = 0xff9a, -XK_KP_Next = 0xff9b, -XK_KP_Page_Down = 0xff9b, -XK_KP_End = 0xff9c, -XK_KP_Begin = 0xff9d, -XK_KP_Insert = 0xff9e, -XK_KP_Delete = 0xff9f, -XK_KP_Equal = 0xffbd, /* Equals */ -XK_KP_Multiply = 0xffaa, -XK_KP_Add = 0xffab, -XK_KP_Separator = 0xffac, /* Separator, often comma */ -XK_KP_Subtract = 0xffad, -XK_KP_Decimal = 0xffae, -XK_KP_Divide = 0xffaf, - -XK_KP_0 = 0xffb0, -XK_KP_1 = 0xffb1, -XK_KP_2 = 0xffb2, -XK_KP_3 = 0xffb3, -XK_KP_4 = 0xffb4, -XK_KP_5 = 0xffb5, -XK_KP_6 = 0xffb6, -XK_KP_7 = 0xffb7, -XK_KP_8 = 0xffb8, -XK_KP_9 = 0xffb9, - -/* - * Auxiliary functions; note the duplicate definitions for left and right - * function keys; Sun keyboards and a few other manufacturers have such - * function key groups on the left and/or right sides of the keyboard. - * We've not found a keyboard with more than 35 function keys total. - */ - -XK_F1 = 0xffbe, -XK_F2 = 0xffbf, -XK_F3 = 0xffc0, -XK_F4 = 0xffc1, -XK_F5 = 0xffc2, -XK_F6 = 0xffc3, -XK_F7 = 0xffc4, -XK_F8 = 0xffc5, -XK_F9 = 0xffc6, -XK_F10 = 0xffc7, -XK_F11 = 0xffc8, -XK_L1 = 0xffc8, -XK_F12 = 0xffc9, -XK_L2 = 0xffc9, -XK_F13 = 0xffca, -XK_L3 = 0xffca, -XK_F14 = 0xffcb, -XK_L4 = 0xffcb, -XK_F15 = 0xffcc, -XK_L5 = 0xffcc, -XK_F16 = 0xffcd, -XK_L6 = 0xffcd, -XK_F17 = 0xffce, -XK_L7 = 0xffce, -XK_F18 = 0xffcf, -XK_L8 = 0xffcf, -XK_F19 = 0xffd0, -XK_L9 = 0xffd0, -XK_F20 = 0xffd1, -XK_L10 = 0xffd1, -XK_F21 = 0xffd2, -XK_R1 = 0xffd2, -XK_F22 = 0xffd3, -XK_R2 = 0xffd3, -XK_F23 = 0xffd4, -XK_R3 = 0xffd4, -XK_F24 = 0xffd5, -XK_R4 = 0xffd5, -XK_F25 = 0xffd6, -XK_R5 = 0xffd6, -XK_F26 = 0xffd7, -XK_R6 = 0xffd7, -XK_F27 = 0xffd8, -XK_R7 = 0xffd8, -XK_F28 = 0xffd9, -XK_R8 = 0xffd9, -XK_F29 = 0xffda, -XK_R9 = 0xffda, -XK_F30 = 0xffdb, -XK_R10 = 0xffdb, -XK_F31 = 0xffdc, -XK_R11 = 0xffdc, -XK_F32 = 0xffdd, -XK_R12 = 0xffdd, -XK_F33 = 0xffde, -XK_R13 = 0xffde, -XK_F34 = 0xffdf, -XK_R14 = 0xffdf, -XK_F35 = 0xffe0, -XK_R15 = 0xffe0, - -/* Modifiers */ - -XK_Shift_L = 0xffe1, /* Left shift */ -XK_Shift_R = 0xffe2, /* Right shift */ -XK_Control_L = 0xffe3, /* Left control */ -XK_Control_R = 0xffe4, /* Right control */ -XK_Caps_Lock = 0xffe5, /* Caps lock */ -XK_Shift_Lock = 0xffe6, /* Shift lock */ - -XK_Meta_L = 0xffe7, /* Left meta */ -XK_Meta_R = 0xffe8, /* Right meta */ -XK_Alt_L = 0xffe9, /* Left alt */ -XK_Alt_R = 0xffea, /* Right alt */ -XK_Super_L = 0xffeb, /* Left super */ -XK_Super_R = 0xffec, /* Right super */ -XK_Hyper_L = 0xffed, /* Left hyper */ -XK_Hyper_R = 0xffee, /* Right hyper */ - -XK_ISO_Level3_Shift = 0xfe03, /* AltGr */ - -/* - * Latin 1 - * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF) - * Byte 3 = 0 - */ - -XK_space = 0x0020, /* U+0020 SPACE */ -XK_exclam = 0x0021, /* U+0021 EXCLAMATION MARK */ -XK_quotedbl = 0x0022, /* U+0022 QUOTATION MARK */ -XK_numbersign = 0x0023, /* U+0023 NUMBER SIGN */ -XK_dollar = 0x0024, /* U+0024 DOLLAR SIGN */ -XK_percent = 0x0025, /* U+0025 PERCENT SIGN */ -XK_ampersand = 0x0026, /* U+0026 AMPERSAND */ -XK_apostrophe = 0x0027, /* U+0027 APOSTROPHE */ -XK_quoteright = 0x0027, /* deprecated */ -XK_parenleft = 0x0028, /* U+0028 LEFT PARENTHESIS */ -XK_parenright = 0x0029, /* U+0029 RIGHT PARENTHESIS */ -XK_asterisk = 0x002a, /* U+002A ASTERISK */ -XK_plus = 0x002b, /* U+002B PLUS SIGN */ -XK_comma = 0x002c, /* U+002C COMMA */ -XK_minus = 0x002d, /* U+002D HYPHEN-MINUS */ -XK_period = 0x002e, /* U+002E FULL STOP */ -XK_slash = 0x002f, /* U+002F SOLIDUS */ -XK_0 = 0x0030, /* U+0030 DIGIT ZERO */ -XK_1 = 0x0031, /* U+0031 DIGIT ONE */ -XK_2 = 0x0032, /* U+0032 DIGIT TWO */ -XK_3 = 0x0033, /* U+0033 DIGIT THREE */ -XK_4 = 0x0034, /* U+0034 DIGIT FOUR */ -XK_5 = 0x0035, /* U+0035 DIGIT FIVE */ -XK_6 = 0x0036, /* U+0036 DIGIT SIX */ -XK_7 = 0x0037, /* U+0037 DIGIT SEVEN */ -XK_8 = 0x0038, /* U+0038 DIGIT EIGHT */ -XK_9 = 0x0039, /* U+0039 DIGIT NINE */ -XK_colon = 0x003a, /* U+003A COLON */ -XK_semicolon = 0x003b, /* U+003B SEMICOLON */ -XK_less = 0x003c, /* U+003C LESS-THAN SIGN */ -XK_equal = 0x003d, /* U+003D EQUALS SIGN */ -XK_greater = 0x003e, /* U+003E GREATER-THAN SIGN */ -XK_question = 0x003f, /* U+003F QUESTION MARK */ -XK_at = 0x0040, /* U+0040 COMMERCIAL AT */ -XK_A = 0x0041, /* U+0041 LATIN CAPITAL LETTER A */ -XK_B = 0x0042, /* U+0042 LATIN CAPITAL LETTER B */ -XK_C = 0x0043, /* U+0043 LATIN CAPITAL LETTER C */ -XK_D = 0x0044, /* U+0044 LATIN CAPITAL LETTER D */ -XK_E = 0x0045, /* U+0045 LATIN CAPITAL LETTER E */ -XK_F = 0x0046, /* U+0046 LATIN CAPITAL LETTER F */ -XK_G = 0x0047, /* U+0047 LATIN CAPITAL LETTER G */ -XK_H = 0x0048, /* U+0048 LATIN CAPITAL LETTER H */ -XK_I = 0x0049, /* U+0049 LATIN CAPITAL LETTER I */ -XK_J = 0x004a, /* U+004A LATIN CAPITAL LETTER J */ -XK_K = 0x004b, /* U+004B LATIN CAPITAL LETTER K */ -XK_L = 0x004c, /* U+004C LATIN CAPITAL LETTER L */ -XK_M = 0x004d, /* U+004D LATIN CAPITAL LETTER M */ -XK_N = 0x004e, /* U+004E LATIN CAPITAL LETTER N */ -XK_O = 0x004f, /* U+004F LATIN CAPITAL LETTER O */ -XK_P = 0x0050, /* U+0050 LATIN CAPITAL LETTER P */ -XK_Q = 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */ -XK_R = 0x0052, /* U+0052 LATIN CAPITAL LETTER R */ -XK_S = 0x0053, /* U+0053 LATIN CAPITAL LETTER S */ -XK_T = 0x0054, /* U+0054 LATIN CAPITAL LETTER T */ -XK_U = 0x0055, /* U+0055 LATIN CAPITAL LETTER U */ -XK_V = 0x0056, /* U+0056 LATIN CAPITAL LETTER V */ -XK_W = 0x0057, /* U+0057 LATIN CAPITAL LETTER W */ -XK_X = 0x0058, /* U+0058 LATIN CAPITAL LETTER X */ -XK_Y = 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */ -XK_Z = 0x005a, /* U+005A LATIN CAPITAL LETTER Z */ -XK_bracketleft = 0x005b, /* U+005B LEFT SQUARE BRACKET */ -XK_backslash = 0x005c, /* U+005C REVERSE SOLIDUS */ -XK_bracketright = 0x005d, /* U+005D RIGHT SQUARE BRACKET */ -XK_asciicircum = 0x005e, /* U+005E CIRCUMFLEX ACCENT */ -XK_underscore = 0x005f, /* U+005F LOW LINE */ -XK_grave = 0x0060, /* U+0060 GRAVE ACCENT */ -XK_quoteleft = 0x0060, /* deprecated */ -XK_a = 0x0061, /* U+0061 LATIN SMALL LETTER A */ -XK_b = 0x0062, /* U+0062 LATIN SMALL LETTER B */ -XK_c = 0x0063, /* U+0063 LATIN SMALL LETTER C */ -XK_d = 0x0064, /* U+0064 LATIN SMALL LETTER D */ -XK_e = 0x0065, /* U+0065 LATIN SMALL LETTER E */ -XK_f = 0x0066, /* U+0066 LATIN SMALL LETTER F */ -XK_g = 0x0067, /* U+0067 LATIN SMALL LETTER G */ -XK_h = 0x0068, /* U+0068 LATIN SMALL LETTER H */ -XK_i = 0x0069, /* U+0069 LATIN SMALL LETTER I */ -XK_j = 0x006a, /* U+006A LATIN SMALL LETTER J */ -XK_k = 0x006b, /* U+006B LATIN SMALL LETTER K */ -XK_l = 0x006c, /* U+006C LATIN SMALL LETTER L */ -XK_m = 0x006d, /* U+006D LATIN SMALL LETTER M */ -XK_n = 0x006e, /* U+006E LATIN SMALL LETTER N */ -XK_o = 0x006f, /* U+006F LATIN SMALL LETTER O */ -XK_p = 0x0070, /* U+0070 LATIN SMALL LETTER P */ -XK_q = 0x0071, /* U+0071 LATIN SMALL LETTER Q */ -XK_r = 0x0072, /* U+0072 LATIN SMALL LETTER R */ -XK_s = 0x0073, /* U+0073 LATIN SMALL LETTER S */ -XK_t = 0x0074, /* U+0074 LATIN SMALL LETTER T */ -XK_u = 0x0075, /* U+0075 LATIN SMALL LETTER U */ -XK_v = 0x0076, /* U+0076 LATIN SMALL LETTER V */ -XK_w = 0x0077, /* U+0077 LATIN SMALL LETTER W */ -XK_x = 0x0078, /* U+0078 LATIN SMALL LETTER X */ -XK_y = 0x0079, /* U+0079 LATIN SMALL LETTER Y */ -XK_z = 0x007a, /* U+007A LATIN SMALL LETTER Z */ -XK_braceleft = 0x007b, /* U+007B LEFT CURLY BRACKET */ -XK_bar = 0x007c, /* U+007C VERTICAL LINE */ -XK_braceright = 0x007d, /* U+007D RIGHT CURLY BRACKET */ -XK_asciitilde = 0x007e, /* U+007E TILDE */ - -XK_nobreakspace = 0x00a0, /* U+00A0 NO-BREAK SPACE */ -XK_exclamdown = 0x00a1, /* U+00A1 INVERTED EXCLAMATION MARK */ -XK_cent = 0x00a2, /* U+00A2 CENT SIGN */ -XK_sterling = 0x00a3, /* U+00A3 POUND SIGN */ -XK_currency = 0x00a4, /* U+00A4 CURRENCY SIGN */ -XK_yen = 0x00a5, /* U+00A5 YEN SIGN */ -XK_brokenbar = 0x00a6, /* U+00A6 BROKEN BAR */ -XK_section = 0x00a7, /* U+00A7 SECTION SIGN */ -XK_diaeresis = 0x00a8, /* U+00A8 DIAERESIS */ -XK_copyright = 0x00a9, /* U+00A9 COPYRIGHT SIGN */ -XK_ordfeminine = 0x00aa, /* U+00AA FEMININE ORDINAL INDICATOR */ -XK_guillemotleft = 0x00ab, /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ -XK_notsign = 0x00ac, /* U+00AC NOT SIGN */ -XK_hyphen = 0x00ad, /* U+00AD SOFT HYPHEN */ -XK_registered = 0x00ae, /* U+00AE REGISTERED SIGN */ -XK_macron = 0x00af, /* U+00AF MACRON */ -XK_degree = 0x00b0, /* U+00B0 DEGREE SIGN */ -XK_plusminus = 0x00b1, /* U+00B1 PLUS-MINUS SIGN */ -XK_twosuperior = 0x00b2, /* U+00B2 SUPERSCRIPT TWO */ -XK_threesuperior = 0x00b3, /* U+00B3 SUPERSCRIPT THREE */ -XK_acute = 0x00b4, /* U+00B4 ACUTE ACCENT */ -XK_mu = 0x00b5, /* U+00B5 MICRO SIGN */ -XK_paragraph = 0x00b6, /* U+00B6 PILCROW SIGN */ -XK_periodcentered = 0x00b7, /* U+00B7 MIDDLE DOT */ -XK_cedilla = 0x00b8, /* U+00B8 CEDILLA */ -XK_onesuperior = 0x00b9, /* U+00B9 SUPERSCRIPT ONE */ -XK_masculine = 0x00ba, /* U+00BA MASCULINE ORDINAL INDICATOR */ -XK_guillemotright = 0x00bb, /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ -XK_onequarter = 0x00bc, /* U+00BC VULGAR FRACTION ONE QUARTER */ -XK_onehalf = 0x00bd, /* U+00BD VULGAR FRACTION ONE HALF */ -XK_threequarters = 0x00be, /* U+00BE VULGAR FRACTION THREE QUARTERS */ -XK_questiondown = 0x00bf, /* U+00BF INVERTED QUESTION MARK */ -XK_Agrave = 0x00c0, /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ -XK_Aacute = 0x00c1, /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ -XK_Acircumflex = 0x00c2, /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ -XK_Atilde = 0x00c3, /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ -XK_Adiaeresis = 0x00c4, /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ -XK_Aring = 0x00c5, /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ -XK_AE = 0x00c6, /* U+00C6 LATIN CAPITAL LETTER AE */ -XK_Ccedilla = 0x00c7, /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ -XK_Egrave = 0x00c8, /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ -XK_Eacute = 0x00c9, /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ -XK_Ecircumflex = 0x00ca, /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ -XK_Ediaeresis = 0x00cb, /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ -XK_Igrave = 0x00cc, /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ -XK_Iacute = 0x00cd, /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ -XK_Icircumflex = 0x00ce, /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ -XK_Idiaeresis = 0x00cf, /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ -XK_ETH = 0x00d0, /* U+00D0 LATIN CAPITAL LETTER ETH */ -XK_Eth = 0x00d0, /* deprecated */ -XK_Ntilde = 0x00d1, /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ -XK_Ograve = 0x00d2, /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ -XK_Oacute = 0x00d3, /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ -XK_Ocircumflex = 0x00d4, /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ -XK_Otilde = 0x00d5, /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ -XK_Odiaeresis = 0x00d6, /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ -XK_multiply = 0x00d7, /* U+00D7 MULTIPLICATION SIGN */ -XK_Oslash = 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ -XK_Ooblique = 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ -XK_Ugrave = 0x00d9, /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ -XK_Uacute = 0x00da, /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ -XK_Ucircumflex = 0x00db, /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ -XK_Udiaeresis = 0x00dc, /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ -XK_Yacute = 0x00dd, /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ -XK_THORN = 0x00de, /* U+00DE LATIN CAPITAL LETTER THORN */ -XK_Thorn = 0x00de, /* deprecated */ -XK_ssharp = 0x00df, /* U+00DF LATIN SMALL LETTER SHARP S */ -XK_agrave = 0x00e0, /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ -XK_aacute = 0x00e1, /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ -XK_acircumflex = 0x00e2, /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ -XK_atilde = 0x00e3, /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ -XK_adiaeresis = 0x00e4, /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ -XK_aring = 0x00e5, /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ -XK_ae = 0x00e6, /* U+00E6 LATIN SMALL LETTER AE */ -XK_ccedilla = 0x00e7, /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ -XK_egrave = 0x00e8, /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ -XK_eacute = 0x00e9, /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ -XK_ecircumflex = 0x00ea, /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ -XK_ediaeresis = 0x00eb, /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ -XK_igrave = 0x00ec, /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ -XK_iacute = 0x00ed, /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ -XK_icircumflex = 0x00ee, /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ -XK_idiaeresis = 0x00ef, /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ -XK_eth = 0x00f0, /* U+00F0 LATIN SMALL LETTER ETH */ -XK_ntilde = 0x00f1, /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ -XK_ograve = 0x00f2, /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ -XK_oacute = 0x00f3, /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ -XK_ocircumflex = 0x00f4, /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ -XK_otilde = 0x00f5, /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ -XK_odiaeresis = 0x00f6, /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ -XK_division = 0x00f7, /* U+00F7 DIVISION SIGN */ -XK_oslash = 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ -XK_ooblique = 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ -XK_ugrave = 0x00f9, /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ -XK_uacute = 0x00fa, /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ -XK_ucircumflex = 0x00fb, /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ -XK_udiaeresis = 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ -XK_yacute = 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ -XK_thorn = 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */ -XK_ydiaeresis = 0x00ff; /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ diff --git a/noVNC/include/logo.js b/noVNC/include/logo.js deleted file mode 100644 index befa598..0000000 --- a/noVNC/include/logo.js +++ /dev/null @@ -1 +0,0 @@ -noVNC_logo = {"width": 640, "height": 435, "data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAGzCAYAAAC/y6a9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAStAAAErQBBHTWggAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7N13fBvlwQfw3522ZMm2vPdIGCFkA4GyoYyGsCmjk+7dQksHL2/H2/dtC4W2tLTlfelu2VA2lEILFCgQIHEGJCQkdjzkLdmWZGvfvX8oOkmJEy/pNO73/Xz44DtLzz2RT7qfnnXC8uXLZUxDlqfdnUYQhIP+bjbPn+5xhypzrmUf6rGzOc5cjzVduXN9/nTPyfRrMt/jzOcY05U5n3L2f95s/34LPW4m/p6FbLp/73xe+5nKnWuZs/07ZOOcnusx5nucbJU727LneuxslDmdTBxn/2NmusyEuZS7kHMxG/XP5Gf3TOVmQzY+u/PhPMnkMcSsH5WIiIiI8goDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMAASERERaQwDIBEREZHGMADSrMmynOsqEBERUQboc10Bym+SJMHv92NiYgJ+vx+CIECv18NgMCj/N5lMcDgcua4qERERzRIDIE0rEfp8Ph8kSVL2y7KMcDiMcDic9niPx4O6ujqYTCa1q1qU/H4/fD4fBEFQ9iV+NplMKC0tTfsdERHRXDAA0gFcLhcmJibS9pkrAJ1ZgBxD/D9JhhQBwt747wOBALq6uuB0OlFZWQlR5OiCuZJlGV6vF263+4CAvT+3242KigoGQSIimhcGQErT19cHr9erbFuqBSy6SETN8QKmyxnurTJ23iNhalCGLMtwu93wer2oq6uDzWZTseaFS5IkjI+Pw+PxIBqNHvB7vQWwVArwu2TI+xpjI5EIBgcH4Xa74XQ6UVZWxiBIRESzJixfvnzakf2zGfB/qAvObCcM7P+42VzE5jIZ4WCPne3Fcq4TH/Yvdz4TJ7L9mkz3HFmW0d/fr4Q/UxnQdoGIhlNECLoZyokBPc9K6HpMQjSQrHN9fT1KS0szUtf9nzefsDOf42bi7zmT3t5eTE5OKtuliwWULRbgaBVgbwWs1QIgABE/MNIhYXijDM/2eAtsgtlsRktLS8ZD4HT/3kwcYz7n+KGefzAzlZuJv2e23p/ZKne2Zc/12NkoczrZOMez9eVpLuUu5FzMRv2nK1Ot90smZOOzOx/Ok0wegwEwg8eartxCCID7h7+K5QJWfEEH0Ti38sJe4J0/xzC8MVmXhoaGA0IgA2DS0NAQxsbG9h0MWHypiNbzZu4+j4WAgX9L2HmXpLQKOhwO1NfXZ7R+DIALP8Z8j8MAOD0GwIUdZyFl5nOImuk4+Vz3XAVAdgETxsbGlPCntwBHXT338AcARgew7As6bP9dDAP/jr/ZXC4XAEzbEqh14+PjSvjTGYGln9ahes3sPgh0JqDxDBE6k4C3fxcDZMDr9cJisaC8vDyb1Z6TcDiMQCCAQCCAYDDIpYRySKfTQa/XQ6/Xo7S0lBO2iDSOAZDSJnwcdrkI0wLygyAAR31CB0GU0P9SvGnK5XJBlmWUlZUttKpFY2pqCkNDQwDi3e0rvqKDo3Xu3wLrThQQDYrYeWf8tR4eHobZbIbFYslofefC6/XC6/UiEAggFovlrB50cB6PByUlJXA6nbBarbmuDhHlAAOgxoXDYQSDQQBA+RECGk5d+OxdQQCO+lh87KDrhXgw6e/vhyzLedU6lSuSJCmhGABWf10HW/38uwCazhQRCwG7H5AgyzJcLhfa2tqg080weDPDZFnG0NAQxsfHD/idIALWOgGiulWiBBmYGpERCyZ3+f1++P1+mM1mVFRUwG63565+RKQ6BkCNS7T+CSKw5GMikKmhCAKw5CMiBBHoey4eAgcGBgBA8y2BU1NTSstY6WJhQeEvoXWdCPdbMsZ2yIhGo/D7/ap2u0ejUbhcLgQCAWWfrUFAxVECyo8SUH6EAH3uGiUJ8cla47tluLfKcG+T4euNfwEJBoNwuVwoLy9HTU1NjmtJRGphANS4RAC01gqw1mR4IKoAHPnheEtg77PJEChJEpxOZ2aPVUCmpqaUn+tPzNxrXrFUwNiO+EU9EAioFgCnpqbQ39+vLGFjbxGw4ss6mLX7J85Lgi7eyl9+hIDF7wdC48DuB5PjdcfGxmAymTT/BY1IKxgANSwQCCASia8lYsvs5NE0R3wg3hLY8/d4CEyMfdNqCEwEQNEA1ByXuQWzy49MhsnUlrhsCgaD6O3tVbqzyw4TsPJaHVv7CoCpDFi633jdoaEhGI1Gjgsk0gDerkHDUu82UdKQ3Wnoh18pomVd8nQbGhqC2+3O6jHzUSwWU8ZcVq0SoM/gddbRJkBnjv8cCoVUmYDhdruV8FdxtIBV1zH8FZR943XrT46/NxNjSGe6Ew0RFT4GQA1LDQhGFXoLD3u/iLb1yVNueHgYo6Oj2T9wHkltmXMuzWzoFkSg/PBkmYmgmS2hUAg+nw8AULVSwIqv6KCbx/JBlGP7hcBYLIa+vr4cV4qIso0BkABg2tu8ZcOiS0W0X5g87UZGRjQVAlNDmd6U+Rfd3qJeN3Dq323RJSJEDigpXAKw5GpRab0Nh8MIhUK5rRMRZRUDIKmu/SIRiy5JD4EjIyM5rFGOZCF0p962L5uLLqe2/lmqBJQ08T7EhU4Q01ulU29PSETFhwGQcqLtfBGLL0uefqOjoxgeHs5hjWguPB6P8vNs715C+a9yRfJvmTpbnYiKDwMg5UzreSIOuyJ5CrrdbobAApHaPVi1mgGwWFQcnVwLVK2Z5ESUGwyAlFMt54o4/Kr0EJhYJobyV2L5IKM9vpg1FQdTGWBvjv89U2esE1HxYQCknGs+W8QRH0qeih6PhyEwj8myrMwgN1cJqk0gInUkAiCQ/ZnkRJQ7DICUF5rOFHHkR5LdTx6PB4ODg7mtFE1LkiTlZ4a/4pM6mzv1b01ExYUBkPJG4+killydDIFjY2PK/YOJSB2iIflzNmeSE1FuMQBSXmk4RcRRHxeVlqXx8XGGQCIVMQASaQMDIOWd+pNEHPVJHYR9Z+f4+Dj6+/tzWykijUjtAmYAJCpeDICUl+reI2Dpp5MhcGJigiGQSAVsASTSBgZAylu1awUc/dlkCPR6vXC5XLwoEWURAyCRNjAAUl6rOVbAss/rlFuc+Xw+9Pf388JElCXsAibSBgZAynvVawQs/4JOuTD5fD62BBJlCZeBIdIGBkAqCFWrBCz/YnoI7OvrYwgkyjDBkFzcke8vouLFAEgFo3KFgBVf1iljlPx+P0MgUYaxC5hIG/QzP4Qof1QsE7DyKzps/kUMUjgeAnt7e9HU1ASBt6UoCtEA8MLno7muRkFoO1/Eoksy+z2ek0CItIEtgFRwnEsFrLxGB50xvj05OYne3l6OVyLNkbKQk9kCSKQNDIBUkJxLBKz8qg46U3ybIZC0SIpkvky2ABJpA7uAqWCVHyFg1dd06PhpDLEgMDU1pXQHiyK/2xQDQRDQ0tKS62rklXA4rCyKzhZAIpovBkAqaGWHCVi9LwRGA/EQ2NPTg+bmZobAImE2mw/YN9tgMtO40EwEnNmMPZ3PcQ5Wbup+KZL5gMYWQCJt4BWSCl7pYgGrr9NBb41vBwIB9PT0sDuYilJaAMxyCyDfQ0TFiwGQioKjXcDqr+tgsMW3A4EAuru7EYvFclsxogxLbwHMfPlsASTSBgZAKhqOVgGrv6GDoSS+HQwG0dPTwxBIRSX7LYBcCJpICxgAKWv8fTJklXuQ7M0C1nxDB6M9vs0QSMUmNQDKbAEkonliAKSs8eyQsfVXMcgqZ6+SJgFrvqmD0RHfDgaD7A6mopH1FkAGQCJNYACkrBrZJGPrL2NZuVAdiq1hXwgsjW+HQiH09PQgGuUdJqiwpc5uz8oYQC4DQ6QJDICUdSObZWy9LQchsF7AMd/SwVQW32YIpGKTjQAo6ACkrEDDEEhUnBgASRWjW2Vs+XksKxesQ7HWClhzvQ6m8vh2OBxmCKSCl2gFzNaXKrYCEhU/BkBSjfstGZtvjSEWVve41moBx1yvg7kivh0Oh9Hd3Y1IROU0SpQhiXGAUjQ74YzjAImKHwMgqcqzXcbmn8UQC6l7XEuVgGOu18NSFb9wRiIR9PT0MARSQVICYJZOXy4GTVT8GABJFTqdTvl57B05fv9elUOguQJY8y0dLNUMgVTYsh4A2QJIVPQYAEkVDocD1dXVyvb4Lhmbbonfv1dNZidwzLd0sNYkQ2B3dzfCYZX7pYkWINkFnJ3yuRg0UfFjACTVVFZWpoXAid0yOnIQAk3l8ZZAa238IheNRtHT08MQSAUj6wGQLYBERY8BkFR1QAjslLHp5hgik+rWw1QGHHO9DrZ6hkAqPMpi0DKystA6ZwETFT8GQFJdRUUFampqlG1vV25CoNEBrPmmDiUNyRDY3d2NUEjlwYlEc5R2NxDeDo6I5oEBkHLC6XSitrZW2fZ1y9h0UwwRv7r1MDri3cH2pvgFNRaLoaenhyGQ8lra3UCycTs4tgASFT0GQMqZ8vLy9BDYK2PjTTGEverWw1ACrP6mDvaW9BAYDAbVrQjRLGW7BVBIaQHkMjBExYkBkHKqvLwcdXV1yra/L0ch0Aas/roOjtZkCOzt7WUIpLyUFgCzsBi0jl3AREWPAZByrqysLC0ETvbL2HhjDKFxdethsAGrv6FDaXt6S2AgoPI0ZaIZZL0FkF3AREWPAZDyQllZGerr65XtyYF9IXBM3XroLcCq63QoXcwQSPkr65NAGACJih4DIOWN0tLStBA4NSTjzRtjCHrUrYfeAqy+Toeyw/ettSZJ6OnpwdTUlLoVITqI9C7gzJcvGrgQNFGxYwCkvFJaWoqGhgblAhcYjrcEBt3q1kNnAlZ9VYfyI5MhsLe3lyGQ8kL2A2DyZwZAouLEAEh5x+FwoL6+PhkCR2S8+aMoAiPqXoh0JmDltTo4j0qGwL6+PoZAyjl2ARPRQjEAUl5yOBxpLYFBN/Dmj2KYGlY5BBqBldfoUHF0ekvg5KTKq1YTpVAzAHIZGKLixABIectut6eFwNAYsPFHMUwNqhsCRQOw4is6VC6P10OWZfT19TEEUs5kfSFodgETFT0GQMprdrsdjY2NyRA4Drx5YwyT/SqHQD2w/Es6VK1MD4F+v8q3LiGCCmMA2QVMVPQYACnvlZSUoKmpSbnohSeAjTfFMOnKQQj8og5Vq5Mh0OVyMQSS6tK7gDP/PmALIFHxYwCkgmCz2dJaAsPeeAj096p7cRJ0wPIv6FB9THoI9Pl8qtaDtI2TQIhooRgAqWDYbDY0NTUp45/CPmDjj2Pw9agcAkVg2ed0qDkuGQL7+/sZAkk1qQFQ5jqARDQPDIBUUKxWKxobG5UQGPEDm34cg3ev+iHw6M/oUHtCekug16vyTYxJkzgGkIgWigGQCo7Vak1rCYxMAptujsHbqX4IXPopHepOTF6M+/v7GQIp67LeBcwxgERFjwGQCpLVakVzc7MSAqNTwKZbYpjYrXIIFICjPqFD/cnJt1J/fz8mJiZUrQdpS9oyMBwDSETzwABIBctisaSHwACw6ScxjL+bgxD4MRENpyXfTgMDAxgfH1e1HqQd2e4CFlJaALkQNFFxYgCkgmaxWNDS0gKdTgcAiAWBjp/EMLZT5VYLAVjyERGNZyTfUoODgwyBlBWcBUxEC8UASAXPbDajubk5GQJDwOafxjC2Q/0QeOSHRTSdlR4Cx8bG1K0HFT2OASSihWIApKJwQAgMAx23xuB5W/2L1xEfENF8TvKtNTQ0xBBIGZXeBcyFoIlo7hgAqWiYzWa0tLRAr4/3X0lhYPPPY3BvU/8CdviVIlrWpYdAj8ejej2oOHEZGCJaKAZAKiomkwnNzc3JEBgBtvwihtEt6l/EDnu/iLb1ybfY8PAwl4ihjMj+GEAuBE1U7BgAqeiYTKb0lsAosPWXMYx0qH8hW3SpiPYLk2+zcDiseh2o+GS9BZBdwERFjwGQipLRaDwwBP4qhuGN6l/M2i8SsegSvtUoc9ScBMJlYIiKE69KVLQSIdBgiF/N5Biw7dcxDL2hfghsO1/E4sv4dqPMSFsImmMAiWgeeEWionZACJSAt/43hsEN6l/UWs8TcdgVfMvRwqW2AMpZXgcQYAgkKka8GlHRMxgMB4TAt++IYeAV9S9qLeeKOPwqvu1o4RIhMBstgBAAQZfcZAAkKj76mR9CVPgMBgOam5vR09ODSCQCWQK2/zYGWRJRf5K6gaz5bDHt4ko0H4IgQJblrIwBBOKtgLFY/GcGQKLiw6YI0oxES6DRaAQAyDKw/fcSXC+qP8i96UwRVauEmR9IdBDJFsDshDPOBCYqbgyApCl6vR7Nzc1KCIQM7PijhL7n1Q+BqRdYorlSAmC2WgAZAImKGgMgaU4iBJpMpvgOGXjnLxJ6/8nlLqhwZHUMILgYNFGxYwAkTZouBO68U0LPMwyBVBjUbAHkWoBExYcBkDRLp9Olh0AAu+6R0P00L3aU/xIBUJbi/2Uau4CJihsDIGlaIgSazWZl37v3Sdj7JEMg5bes3w6Oi0ETFTUGQNI8nU6HpqamtBC4+0EJXY8zBFL+SrsbSJYXg2YAJCo+DIBEmD4E7nlIQucjDIGUn9S8HzADIFHxYQAk2ifRHWyxWJR9nY9K2PNXhkDKP+ldwJkPaAyARMWNAZAohSiKaGpqSguBXU9IePcBhkDKL2n3A+YYQCKaIwZAov0kQqDValX2dT8lYde9DIGUP7LeBZwSALkMDFHxYQAkmoYoimhsbEwLgT1/l7Dzbl4IKT9kOwAKBi4ETVTMGACJDkIURTQ3N8Nmsyn7ep+V8M5fJIDXQ8oxLgNDRAvBAEh0CIIgoKmpKS0E9j0nYcefGQIpt7IeADkJhKioMQASzSARAktKSpR9rhckbP+DBF4XKVe4DiARLQQDINEsCIKAxsbGtBDY/5KE7b+LMQRSTnAdQCJaCP3MDyEiIH7BbWhoQH9/P3w+HwBg4N8yZCmGpZ/UQeDXqayIRA5MN7MNJKkhaTqZCDYzHWO+x5mp3NSZuRwDSERzxQBINAeCIKC+vj4tBA6+KkOOxXD0ZxgCM02WZezZsyfX1ch78YWgZw6ic8EWQKLixssV0RwlQqDD4VD2Db0uY9vtMchcJYZygF3ARDRXbAEkmodECAQAr9cLABh+U8bWX8Ww/PM6CLpc1q6wiQag/SJ+N50Le0tmW/8ALgRNVOwYAIkWoL6+HoIgYGJiAgAwsknG1l/GsOwLurQLKM2eqAfaL2QAzDVRz4WgiYoZP2WJFqiurg6lpaXK9shmGVtvi2VlYD6RWtgFTFTcGACJMqCurg5lZWXK9uhWGVt+HsvK2CwiNTAAEhU3BkCiDKmtrU0Lge63ZGy+NYZYOIeVIponLgNDVNwYAIkyqLa2FuXl5cq2Z7uMzT+LIRbKYaWI5kFgACQqagyAGpZ6K6mgJ/Ply7Hkz7NZLLdY1NTUwOl0Kttj78jo+Kk6ITD1NSdaCHYBExU3BkANs1gsys+eHZn/gA+MJH82m80ZLz+fVVdXp4XA8V0yNt0SQzSQ3eNODSf/jloK3ZR5qQGQy8AQFR8GQA0zmUzQ6eIL1nm75Iy2UElRYGhD8qJhtVozV3iBqK6uRkVFhbI9sVtGR5ZD4NRA8meDwXDwBxLNgGMAiYobA6DGJVoB5Rgw/m7mPuRHOmREJuM/GwwGGI3GjJVdSKqqqtJDYKeMTT+OKa9NJskyMDUY/xsKgoCSkpLMH4Q0gwGQqLgxAGpctrqB+19Otv7ZbLaMlVuIqqqqUFlZqWx798rYdHPmQ2Dfc5Iy49hmsymtu0TzIRq4EDRRMWMA1LjUrtnBVyWExhZeZmgM8LyVvGBosft3f5WVlaiqqlK2fd0yNt0UQ8SfmfKDbmD3A8nQnbowdaalTh4KjTEYFK2UP23q35yIigPf1RpnsViUCRqhMWDjj2MIe+dfXiwE7PhjDPK+LCKKIrsi96moqEgPgb0yNt64sNc7YfsfkrOMs/2aC4KgnDNBT/rEEyoenneSf1e9nvc1JCo2DIAaJwgCGhsble7CqcH4bNX5dE+GxoA3fxjD6NbkhaOxsZEXjxQVFRWorq5Wtv0uGRtvWlgI7H9Jguft5GvucDiyPgM4dejAWBZmkFPujWxKtijzPUxUfBgACQaDAfX19cq2v3ffunXB2Zfh65bx+vej8PUkw0BNTQ1b/6bhdDrTQuBkv4wN34ti8FU5rdttJrIMDLwqY9c9yQu10WhMG2+YLdleQohyS4oA7m3Jv6tWJ3ERFTNdTU3N9+b75Gy0Mqi1dlm2jlOor4nRaIQoipicjDf9hcaAgX9LCIzE1wMzOwUI+31dkCVg0iVj6HUZb90hpbUalpWVobq6uqBeZzWPY7FYoNPplNc7FgSGN8pwvy3D3iTAVH7o4450yNj2KwmuFyRI0fg+o9GI5ubmrLfWCIIAnU4Hjye+enjEB7S8j98li8noNhkD/07OKK+vr59xHGAhvyf5OaVOmdksV43jFPJrMt0x2K5PisrKSgQCAfh8PgBAaDw+s7TvOUBvBapWCCg9TMDUYHzdQF+3PO19bq1WK2pra1WufeEpLy+HKIoYGhpSFtqd2C3j9f+Oof5EETVrBYg6QEj5L+wFuh6TMLEnvdVNrfCXoNfrYTAYEIlEEPbGZ33Xn8QQWCxS1/AsLS1lFzBRERKWL18+bf/NbKb9Hyq1znbZgP0fN5skPJclCQ722Nkm7rkuf7B/ufNZPiHbr8lMx/H5fBgZGUEwOIc+YMS7kp1OJ8rKypTWgunqPt8lJVKfN59vTPM5bib+njOJRqMYHh6G1zu/gYDZDH/T/XsTr4nb7cbISPx2L4IILPucDtXH8O4jhW7PwxK6HosHQEEQ0N7ePu2i4vP5nJrJQq878z1mPrTsLOSzRa3Wrkx8/uWqBTCf684WQMobdrsddrsdPp8Po6OjCAQOfesKk8mEiooKVSYfFCO9Xo/6+nqUlpZicHAQkUhkVs8zGo1wOBwoLy/PyZp/FRUVCAaD8Pl8kCXgrf+LYYVRh4rlPAcK1a57JPQ8k976xzvKEBUntgBm8FjTlVuILYD78/v9CAQCkGVZeU7i/zab7ZATPdgCODeyLMPj8SAYDCISiSAajSIajSq/NxgMsNvtcDgcqtxf+VAtgED8HrF79+5FOBwfCyAagVXX6lB+JENgIZFl4J0/SXD9Kxn+DtX6F38OWwBnwhbA2ZWbDWwBnPkYDIAZPNZ05RZDAFzIMRgAMyMajSIWi8FkMql63JkCIACEw2Hs3btXGcco6gHnUgHVawRUrhRhtKtSVZqHoBvw7JAwtEGGO2Xx9kSr9KEWcWcAnBkD4OzKzQYGwJmPwS5gogKg1+vzdiC+0WhEXV0dXC4XAECKAqNbZIxukSEIEsoOF1C1SoClSgDYMJhz0SlgfJcMzw4ZgZEDL4oWiwUNDQ15e74RUWbwHU5EC2a329He3g63242JiQllvywDYztljO3kWoGFoLy8PKvLNxFR/mAAJKKMSLQEVlRUHBAEKX+JogiLxYLS0lI4HI5cV4eIVMIASEQZlRoEJyYmEA6HD5jMQrkjCAIsFovyn9rjSokoPzAAElFWGI1GVFVVTfu7hU4gmO2A7mxMbJrrMeZ7nGyVO9uyiai4cel+IiIiIo1hACQiIiLSGAZAIiIiIo1hACQiIiLSGAZAIiIiIo1hACQiIiLSGAZAIiIiIo1hACQiIiLSGAZAIiIiIo1hACQiIiLSGAZAIiIiIo3hvYBp3iRJQigUUu4rmnp/UaPRyPuN0rQkSYLX64XP50MkEoFer1f+MxgM0Ov1sNlsEEV+PyUiyhYGQJqzWCwGj8eDsbExxGKxaR9jMBhQUVGB8vJyBsEFkGUZExMTymudGrYFQYAoiigvL4fD4chxTQ9NkiT4/X54vV5MTk5ClmXld+Fw+IDH6/V61NTUwG63q1nNopUI3YlzKPU8EkURdru9oAJ3NBpFIBBAIBBAJBJJO5/yyVw++xbyb8jlZ6zZbIbVaoXFYuFnfYERli9fPu1ZN5uT8VB/7NmezPs/bjYn0FzeKAd77GxP1Lm+Kfcvdz5v6my/JvM9Tjgchtvtxvj4+KyPZzAYUFlZibKyMqX8+X7QpT5vPh808zluJv6e8yFJEsbHx+HxeBCNRmd8vNFoREVFBRwOR0Y/hKf79861/HA4jJ6engP+HSUlOsSiMiJRGdHo9K9rSUkJampqYDAYZqzXdGaqayb+ntl6f2ai3FgshrGxMYyPjx/0yxoA6HQ6lJeXw+l0zjoIzudzaq5lppqYmMDU1JQS+ii/CIIAi8UCm80Gm80Gi8Vy0MepVZ9Uar3X86ncmY7BAJjBY01Xnw4y4QAAIABJREFUbrEEwOHhYYyOjqbtq6o0YsXyEqxaYcfKFXZUVBjwzD88ePzJEby7eyrtsXq9HnV1dbDb7QyAMxgdHZ22dbWkRIeVy+1YtdKOvr4QnvmnG5OT6Y9JBO7S0tKM1GWhATAUCqG3tzct/J1+mhPfu6Edq1amt+5FozLe3T2F//jObvzzeY+yXxRFVFZWwul0HrJe09FqAIxEIhgbG8PExAQkSTrg9xaLDtGohEgk/fmJFmWn0wmdTjenY2crAMZiMfT392NqamqaZwBmU+G0XBabmCQfcA4lVFVVobKy8oD9DIDqlTvTMRgAM3is6cothgA4Pj6O/v5+Zfvs91bg1psPR2Oj+aBl73p3Co8/OYI77xnAns4AgPjFpbW1FSaTac513b++xRoAR0ZG4Ha7le2zzqzA+y+pxupVDixeZIEoJusTCkt44V9jePzJEfzt726MjCa7Uqurq9MC03wtJACGQiH09PQoQfbYYxz47g3tOOWk8hmf+9TTo7j+27vRtTeg7HM4HKivrz9ovaajxQAYDAbR09Oj/M5gELDsaDvWrIp/eVi10oEjD7fC74/h6WfcePypETz7Tw8CgeSXCVEU0djYCKvVOutjZyMABoNBuFyutC8QTU1mnHZyOU47pRynnFyOmmrjgo9L8+f1RvHI4yO48+4BvPb6RNrvEu/Z1HODAVC9cmc6BgNgBo81XbmFHgCnpqbQ3d2tPPYzn2zEjf+zGDrd7F4/tyeC913QgXd2TgKIt1C1tbXN2LowU32LMQBOTExgYGBA2f7yF5rx/e+0p4W+g4nFZHzmiztw/4NDAOL1bmpqOuQFfDbmGwBTw58gAL/59VG4/LKaOR07HJbwy9t78T83dildxHa7XQmBs6G1ABiNRtHd3a0EptoaI+79yzKsXnXoMaKBoITnnvfg+m/vxt7ueOjW6/VobW2FXj/9UPFsB8CJiQkMDQ0p+654fw3+4xttaGudvmuRcm/3nincde8g7rpnAIND8S+kZrMZTU1NynnEAKheuTMdgwEwg8eartxCDoCRSASdnZ2IxWLQ6QTc+D+L8ZlPNs75OINDYZyzfpPSmmOz2dDc3Lyg+hZbAAwEAkqrjV4v4Kc/PhxXf3j2QQeId6F++ONv4cm/xbvqdTod2traDnoBn435BEBZlrFnzx4lhFz94Xr84qdHzLsOjz0xgo99+m2lq8lut6Ourm5W54CWAqAsy+jp6UEwGAQArFhWgnvvXI6G+tm3uPf0BnHO+k1w9YcAABaLBc3NzdPWJZsB0OPxYGRkRNn/6U804OYfHQ7OMSgMA4MhnHHORuU80uv1aGlpUXV1CAbAmY/BwRM0LUmS0rrv7vnzsnmFPyDeCvHEQyvR2BC/EE1OTmJ4eDhjdS10kUgELpcLsizD4dDjr/eumHP4AwC9XsAff7sUp58a72KNxWJKuWqamppSwl9drQn/871FCyrvgvVV+Mvvj4bRGP+48vl86O/vz9uZn7kyODiohL/zz6vC359YPafwBwDNTWY89teVqKqMd6sGAgHV36uSJKUNg7jumhbcciPDXyGpqzXhvruWw2aL9/REo9EDxpBT7jEA0rT8fj9Cofi3t+OPK8W5Z1csqLymfReWxIBtt9vNmXz7DA8PK4HpG19tUQLcfJiMIu758zIce0y8yy8QCKj+wTsxkRwH9LObD4fDsfDVptadW4m7/ng0TPtCoN/vz0m4zVdjY2Pwer0AgHPPrsCdfzgaVuvch1kAwGGLrXjkwRUoK9MrZaf+TbNtbGxMmbjyX99ehO/c0K7asSlzlh9dgj/csVQZwuL1evmZn2cYAGlak5OTys8fuLI2I2UuXmTF8WuTs1MPNqtPaxKvtV4v4MrLF/5aW606XP/1NmXb7/cvuMzZSqz3BwAXX1CNdeceOAtwvs45qwL3/GWZ8iVicnKSIXCfRPgDgE9+rGHBrWXLlpbgFz89Utn2eDyHeHTmSJKEsbExAMDSJTZc++W5DxWh/HHu2RX40X8vBhDvglXrPKLZYQCkaSVCidkk4pILqzNW7skpM0ADgcAhHqkNwWBQae04+70VqK7KzIzG9xxfqnSZhkKhQ64Bl0l+v1/591xycebOm4T3nuHEfXcug8XMEJggSZLS9VtTbcSZpy989jcAnHlauTLZKxQKTbucTKalLn+0fl1V1o9H2ffZTzUqvQAzrUdJ6mIApANEo1Hl7gzr11VmpAsv4dSTypSfGQDTW0E/dFVdxsq1WnU4dk1y5mciIGRbakvUkYfbsnKM009z4v67l8NiiXdxTk5Ooq+vT5WAko9S30eXX1Yz6xn6M7Hb9WlrNWb7/SrLstL6BwDrz2MALAaCAKxcHj+PJEliK2AeYQCkA6R2/1568dyW7pjJ6lUOZWBwauuXViVe68oKA845a2HjLPd36inJ1la1utsTQdNoFLGoPXvLdZx6cjn+eu9yZZzb1NQUXC6XJs+n1L/tB67M3JcIAGlrNmY7AEYiEaV1qKnJjBXLSrJ6PFLP6lXJLxIc+pM/GADpAKlv0LnOIpyJXi/g+OOS4wC13Aooy7Ly719ypA0GQ2anOZ52ivrd7YkAVl1thF6f3WmbJ72nDA/fvwIlJckQqMWWwMT7tbHRjKVLMtvqqmaLfeoEgfXvy9zYUcq9/e/6Q/mBAZAOkDpGQ5eFi3h5WbJLeTb3uS1WsVhMCSuJ8XqZlLpgbmJGd7YlxuLNYu3qjDhhbSkeuX8F7Pb4ORUIBDQVAmVZVlpdyzI4VCPhmJRhBGoGwCOyNHyAcmNNykLkaq0DSDNjACTKA9n4TEwts5gnSRx3bCkee3AFSkuTIbC3t1czITBBzMKnuTHlPrvZfj219vfSktSPNwbA/MEASEQFb81qBx7/60pl7bpgMIje3l7OOCTKA08+nVyLlAEwfzAAElFRWLnCjscfWgWn0wCAIZAoXzz+5MjMDyLVMQASUdFYsawETzy8EhUpITD1loZEpC6PJ4JXXkveScZm4/jOfMEASERF5eijSvDkI6uU+9mGQiGGQKIc+dszbsRi8THIBoMBZWVlMzyD1MIASERF56glNjz16CrUVKeHQC3POidS2+BQGD/7RbeyXVFRwTGAeYQBkIiK0hGHW/HUo6tQVxtfy5IhkEg9Pb1BnLN+E3a9G1+nUq/Xs/UvzzAAElHROmxxPAQmFjQPh8MMgURZtuvdKZyzfhO69ibXjmTrX/5hACSiorao3YK/PbYKjY1mAPEQ2N3dnbbwMBFlxqsbJnDu+Zvg6k8uPm+1Wtn6l4cyv3Q8EVGeaW2x4OnHVmHdhR3o6Q0iEomgp6cHTU1NMBgMua4eUcHq7Q3ihZfG8MKLY3jxpTEMDYfTfu90OlFTk9l7ylNmMAASkSY0N5njIfCizdjbHUAkEkFvby9DoEbcc98gfvLz7pkfSLM2NRVDn2v620yKooi6ujo4HI5pf0+5xwBIRJrR2GjG3x5bhfMu6kBnV0BpCWxubmYILHLjE1FlQgJll9FoRGNjI0wmU66rQofAMYBEpCkN9Sb87bFVWLzICgCIRqPo6elBOBye4ZlENB29Xg+73Y6amhq0traivb2d4a8AsAWQiDSnrjYeAtdf3IGdu6YQjUaV7mCj0Zjr6lGW2Ww2lJaWZv04c5n1KsuyKsdZSJn711EQBJjNZraeFygGQCLSpJpqI556dBXWX7wZO96ZZAjUEIPBoIxNk2U5a8uTFHsApMLGLmAi0qyqSiOefGQVjj6qBECyOzgUmn5gOxFRsWAAJCJNq6ww4ImHV2L50fEQGIvF0NvbyxBIREWNAZCINM/pNOCJh1dh5Qo7gGQIDAaDOa4ZEVF2MAASEQEoK9Pj8b+uxJrV8bFhsVgMfX19DIFEVJQYAImI9ikt1eOxB1fg2GOSIZAtgURUjBgAiYhS2O16PPrAShx/XHyZEEmS0Nvbi0AgMMMziYgKBwMgEdF+Skp0ePj+FTjxhPgN7CVJQl9fH0MgERUNBkAiomnYbDo8dN9ynHJSOYBkCJya4u3EiKjwMQASUcHo6VV3LJ7FosMD9yzH6acmQ6DL5WIIJKKCxwBIRAVj/cWb8e5udcOXxSzivruW48zTnQCSLYGTk5Oq1oOIKJMYAImoYAwOhrDuwvj9e9VkNom4985lOPu9FQDit8RyuVwMgURUsBgAiaigDA2Hse7CDux4R93wZTKKuPtPR2PduZUAkiHQ7/erWg8iokxgACSigjMyGsZ5F3Xgre3qhi+jUcRffn80zj+vCgBDIBEVLgZAyqnJyUlIkpTralABGnVHsP7izdiyTd3wZTAI+NNvl+Ki89NDoM/nU7UeREQLwQBIqjOakqfdxMQEOjs74fV6c1gjKlQeTwTnX9KBzVvUDV96vYDf37EUl11cDSAeAvv7+xkCiahgMACS6m695Qhc/402mPcFwUgkApfLhZ6eHoRCoRzXjgqFKMbPn/HxKM6/dDM2blL3S4ReL+A3tx+Fyy+rAZBsCeSXGSIqBAyApDqzScT1X2/Fm6+uxfp1lcr+yclJdHV1YWhoiN3CNKP6+nolBE5MRHHBZVvw+hsTqtZBpxNwx6+W4ANX1ir7+vv7MTGhbj2IiOaKAZByprnJjLv/tAwP378CixdZAcRbUTweD/bs2cOLKB2SxWJBU1MTdDodAMDni+Kiy7fg1Q3qnjeiKODXPz8SH/lgnbJvYGCA5y8R5TUGQMq5M0934rUXj8V/fXsRrNb4xTwajaK/vx/d3d0IBtW9+wMVDrPZnBYC/f4YLr58C15+ZVzVeoiigNt+diQ+9pF6Zd/AwADGx9WtBxHRbDEAUl4wGkVc++VmbHptrTKwHgCmpqbQ1dWFwcFBxGKxHNaQ8pXJZEoLgVNTMVx65Vb866UxVeshCPHxrZ/6eIOyb3BwkCGQiPISAyAdktpD8errTPj9HUvx5COrcNQSm7J/bGwMnZ2dvJjStBIhUK/XAwACgRgu/8BWPP+CR9V6CALwk5sOx2c/1ajsGxwcxNiYumGUiGgmDIB0gMRFFAB27MjNArcnn1iGl587Fjf94DA4HPH6xGIxDA4OYu/evQgEAjmpF+WvA0JgUMIVH9qGfzynbggEgB//8DB88XNNyvbw8DBDIBHlFQZAOoDValV+fvHl3LW46fUCPvfpRnRsWIsPXlkLQYjvDwaD2Lt3LwYGBtgtTGmMRmNaCAyGJFz14W14+hm36nX54fcX45ovNSvbw8PD8HjUD6NERNNhAKQDWCwW5ed/vZz7VouqSiNuv20J/vHUGqxYblf2j4+PY8+ePWxZoTT7h8BQWMKHPvYWnvzbqOp1+f53FuG6a1qU7ZGREYZAIsoLDIB0AIPBAIPBAADo7Q2iuyc/ZuEee4wD/3p2DW695Qg4nfH6JbqFu7q62C1MCqPRiObmZuU8DoclfOQTb+GxJ0ZUr8t3bmjHt65rVbZHRkbgdqvfIklElIoBkKaV1gqo8mzKQxFFAR//aD06XluLT1zdAFGM9wsnuoX7+/sRjUZzXEvKBwaDIS0ERiIyrv7U23jo0WHV6/If32zDDd9qU7ZHR0cxOqp+iyQRUQIDIE0rdRzgD27sQtfe/GpdKy834Gc3H45/PbsGxx1bquyfmJjAnj174PF4IMtyDmtI+WD/EBiNyvjEZ7bjwYeGVK/LN7/Wiu/e0K5su91uhkAiyhkGQJpWWVkZTCYTAGBgMITzL9kMV3/+3ad3xXI7nn1yNf73tiWorjICACRJwtDQELq6ujA5OZnjGlKuGQwGtLS0wGiMnx+xmIxPfX4H7r1/UPW6fO2aFvz3dxcp2263GyMj6ndLExExANK0RFFEU1OTcq/Vnt4gzr9kM0ZGwzmu2YEEAfjAlbXo2LAWn/9ME/T6eLdwKBRCT08PXC4XIpFIjmtJuaTX69Hc3JwWAj/7pXdw5z0DqtflK19sxo/+e7Gy7fF4GAKJSHUMgHRQRqMRDQ3Juxrs3jOFCy/dglF3foYpu12PG/9nMf79/LE45aRyZb/X60VnZyfcbje7hTVs/xAoSTK+8JV38Me/9Ktely98tgk3/+gwZdvj8WB4WP2xiUSkXQyAdEh2ux2VlZXK9lvb/Vhzwgb87o8uSFJ+hqklR9rwxMMr8YffLEVDfbwbW5IkjIyMsFtY4xIhMDG8QZaBr3xtJ373R5fqdfnMJxvx0x8frqxvOTY2xhBIRKphAKQZVVdXw+FwKNtjYxFc+/VdOPWsjXj9jYkc1uzQLr2oGhtfXYuvfqUFRmP8VA+Hw+jt7UVfXx+7hTVquhB47dd34Y7f9qlel09+rAE//8kRaSFwaEj9CSpEpD0MgDQrjY2NqK+vh06nU/Zt2erDWedtwue+tAPDI/k3NhAArFYdvvef7djw0nF47xlOZb/f70dnZydGR0fZLaxBOp0uLQQCwHXXv4tf/1+v6nW5+sP1+NXPj1SWNBofH8fgoPoTVIhIWxgAadZKS0uxaNEilJWVKftkGbjr3kGsPn4Dbr+jD9FofoapRe0WPHTfCtzz52VoaTYDAGRZxujoKDo7O+Hz+XJcQ1KbTqdDU1MTzGazsu9b/7kbv/hVj+p1+dBVdbj9F8kQODExgYEB9SeoEJF2MADSnOh0OtTV1aGtrS1tsWivN4pv3vAuTjrjDbz8Su7uHzyT895XiTdeWYvrv9EGizl++kciEbhcLvT29iIczs+WTMqO6ULgf35vD35ya7fqdbnqilr85tdLoNMxBBJR9jEA0ryYzWa0trairq5OuecqAGzfMYl1F3bg459+G/0D+bduIACYTSKu/3or3nhlLdavS05wmZycRFdXF0ZGRiBJUg5rSGpKLHmUGgL/6weduOkne1Wvy/svrcFv//coZSmjiYkJ9PerP0uZiIofAyAtSFlZGRYtWgSn05m2/8GHh7HmhA249bYehMP5Gaaam8y4+0/L8PD9K7B4UfzOJ7Isw+12o7OzE16vN8c1JLUkQmBqq/YPbuzCD2/qUr0ul15UjT/8ZikMhngI9Hq9cLlcHKtKRBnFAEgLJooiampq0N7ennYLucnJGL7z/T044dQ38NzznhzW8NDOPN2J1148Fv/17UWw2eKTXKLRKPr7+9Hd3Y1QKD9bMimzRFFEY2NjWgi88Za9+P4POlWvy4Xrq/Cn3x6thECfz4f+/n6GQCLKGAZAyhiTyYSWlhY0NDSkdQu/u3sKF12+BR+8+i309gZzWMODMxpFXPvlZmx8dS0uu7ha2T81NYWuri4MDQ2xW1gDEiEw9YvMLbd24zvf36N6Xdavq8SdfzhaWcLI5/OxJZCIMoYBkDLO4XBg0aJFqKiogJBY4AzA40+O4Jj3bMCNt+xFMJSfYaq+zoTf37EUTz26CkctsQGIdwt7PB7s2bMHExP5u+4hZYYoimhoaEgLgbfe1oPrv71b9bq875xK3PPno2HaFwL9fj9DIBFlBAMgZYUoiqiurkZ7eztsNpuyPxCU8MObunDcia/jqadHc1jDQzvpPWV4+bljcdMPDoPDEW/NjEajGBgYQHd3N4LB/GzJpMxItASmnru/+t9efP36d1Wvy1lnVuC+O5fBbEqGwL6+PoZAIloQBkDKqkS3cGNjIwwGg7J/b3cAV354Gy69cis6uwI5rOHB6fUCPvfpRnRsWIsPXlmr3K0hEAhg7969GBwcRCwWy20lKWsEQUBDQ0NaCPy/3/bhq9/YBbWz1xmnO3H/3cthscTHqE5OTqKvr4/DEoho3hgASRWJbuHKysq0buFn/+nGcSe9ju//oBOBQH6GqapKI26/bQn+8dQarFxhV/aPj4+js7MT4+P5u+4hLUwiBJaUlCj7fvsHF665bqfqIfC0U8rx4D3LYbUmQ6DLpf49jImoODAAkmpSu4VTL6jhsIRbbu3GmhM24OHHhnNYw0M79hgHXnhmDW695Qg4nfHWzFgshsHBQezduxeBQH62ZNLCCIKA+vr6tHP2D3/uxxeveQeSpG4KPPnEMjx033JltjrPOSKaLwZAUp3RaERTUxOamppgNBqV/X2uED76ibdx/iWb8c7OyRzW8OBEUcDHP1qPjtfW4hNXNyi37goGg+ju7sbAwAC7hYtQIgTa7ckW4L/cPYDPfVn9EPie48vwyAMrUFKim/nBREQHwQBIOVNSUoL29nZUVVVBFJOn4r9eGsN7TnsD//Gd3fD78zNMlZcb8LObD8e//nEM1h5bquyfmJjAnj17MDY2lsPaUTYIgoC6urq0EHjPfYP41Od3IBZTNwSuPbYUjz24UpmgREQ0VwyAlFOCIKCyshLt7e1pF9ZoVMYvb+/FqrWv4b4HhnJYw0NbsawEzzy5Gv/3yyWoroq3ZkqShKGhIXR1dWFqairHNaRMSrQEOhwOZd8Dfx3CJz+7HdGouiHwmDUOPPbgCpSWMgQS0dwxAFJeMBgMaGxsRHNzc1q38NBwGJ/6/Hacs34Ttr3tz2END04QgKuuqEXHhrX4wmeblPu4hkIh9PT0oL+/H9FoNMe1pEyqq6tLC4F/fWQYH/vU24hE1A2Bq1c58MRDK1Febpj5wUREKRgAKa/YbDa0t7ejuro6rVv41Q0TOOXMN3Hdt3ZhfDw/w5TdrseP/nsx/v38sTjlpHJlv9frRWdnJ9xuN9duKyJ1dXUoLU12/z/6xAg++sm3VA+BK5bb8cTDK1FRwRBIRLPHAEh5RxAEVFRUYNGiRWmtLLGYjDt+58Kqta/hT3cOqL4Mx2wtOdKGJx5eiT/+dika6k0A4t3CIyMj6OrqwuRkfk5wobmrra1FWVmZsv3EU6P44NXbEA6ruz7fsqUl+N3/LVX1mERU2BgAKW/p9Xo0NDSgpaUFJpNJ2e/2RPCla9/B6edsxMZN3hzW8NAuubAaG19di69d06LczzUcDqO3txculwuRSCTHNaRM2D8EPv2MG1d95C3Vb3dYyRZAIpoDBkDKe1arFe3t7aipqYFOl1z6YlOHF2ecuxFfvOYdjLrzM0xZrTp894Z2bHjpOJx1ZoWy3+fzoaenJ4c1o0yqra1FeXmy2//Zf7px5Ye3IRDknTqIKD8xAFLBKC8vR3t7e9q4K1kG/nzXAFYf/xru+J1L9eU4ZmtRuwV/vXc57v3LMrQ0mwGA4wGLTE1NTVoIfO55D6744Na8vcMNEWkbAyAVFJ1Oh7q6OrS2tsJsNiv7x8ejuO5bu3DKmW/i1Q0TOazhoa07txJvvLIW//HNNljMfPsVm5qaGjidTmX7hRfHcNlVWzE1xRBIRPmFVyAqSBaLBW1tbairq0vrFt72th/nrN+ET31+OwaHwjms4cGZTSK+dV0r3nhlLc4/ryrX1aEMq66uRkVFsrv/pX+P45IrtmJykiGQiPIHAyAVtLKyMixatCit6w0A7ntgCKuPfw23/bpX9WU5Zqu5yYy7/ng0Hrl/BQ5bbM11dSiDqqqq0kLgK6+N46L3b4HPl59LGBGR9jAAUsHT6XSora1FW1sbLBaLst/vj+GG7+7Ge057HS+8mL+3ZjvjdCdu+sFhua4GZVhVVRUqKyuV7Q1vTODC92+B18sQSES5xwBIRcNsNqO1tRX19fXQ65O3x9q5awoXXLoZH/3E2+hzhXJYQ9KaysrKtBD45kYvzr90c94uZk5E2sEASEWntLQUixYtgtPphCAIyv6HHxvGmhM24JZbuxFSeaFe0q79Q2DHZh/Ov6QDY2P5uXQREWkDAyAVJVEUUVNTg7a2NlityfF1gUAM3/9BJ9ae9Dqe+Yc7hzUkLamoqEBVVXLCz5Ztfqy/eDPcHoZAIsoNBkAqaiaTCS0tLWhoaEjrFu7sCuCyq7biig9tw97uQA5rSFrhdDpRXV2tbG9724/zLurAyGh+zlYnouKmn/khRIXP4XDAZrPB7XbD4/EoizD/7e+jeP4FD77yxWZ89ZoWrs1HWZWYrT48PAwA2L5jEuddtBmPP7QSNdXGXFZNU8bHxzE+Pp7rahQVURRhtVphtVphs9nS1mml/MSrHWmGKIqoqqpCW1sbbDabsj8YknDTT/bimPdswONPjuSwhqQF5eXlqKmpUbbf2TmJdRd2YGCQE5SocEmSBL/fj+HhYXR1dWHnzp3o7e3F1NRUrqtGB8EWQNIco9GIpqYm+Hw+DA8PIxKJj8Pq7Q3ig1e/hTNOd+LmHx7Gtfkoa8rKygAAQ0NDAIB3d09h3YUdeOLhVWioN+WyakVr8SILLru4euYH0pzJMhAKS9iyzY/e3iCAZCCcnJw84DaJlB8YAEmz7HY7SkpK4Ha74Xa7lW7h55734PhTXscXPtuEb36tFTabboaSiOaurKwMgiBgcHAQALCnM4D3XdCBpx5ZicZGdp9l2llnVuCsMytmfiDNmywDL78yjrvvHcAjj49gcjIGWZYxODiIUCiEmpqatJUZKHdEUWQXMGmbIAiorKxEe3s7SkpKlP2RiIxbb+vBmhM24MGHhnJYQypmpaWlqK2tVbb3dgdw7gUd6NnXikJUSAQBOPnEMtx+2xLs2X4i7vjVEmVs69jYGHp7exGL8ZaIuSTLMkRRhCAIDIBEAGAwGNDY2IjGxkYYjcnB+P0DIXz8M9ux7sIOvL1jMoc1pGJVWlqKuro6ZbunN4hzL+jg7HQqaFarDldeXov77lymTK6bnJxEd3d3jmumXbIsQ6fTKa2wDIBEKUpKStDW1oaqqiqIYvLt8fIr4zj5jDfwzRve5a28KOMcDkdaCOzrC+J9F3Sgs4shkArb6lUO/Ob2o5Do+Q0Gg/D5fLmtlEbp9fq0LngGQKL9CIKAiooKtLW1weFwKPujURm339GHVWs34K57B7FvyCBRRjgcDtTX1ysf0K7+EN53QQfe3c1ZlFTYLlhfhf/69iJle3R0NIe10R5BEKDTHTiWnQGQ6CAMBgMaGhrQ3NwMkyk5M3NkNIzPfWkH3rtuI7Zs5TdZyhy73Y7vreEdAAAQDUlEQVS6ujolBA4MhrDuwg7s3MUQSIXtmi814+IL4rOwA4EAl4dRiSiK04Y/gAGQaEY2mw1tbW2oqalJ6xZ+400vTj1rI665bic8vKUXZYjdbk9rCRwaDmPdhR3YzjGoVODOPy95T2y3m7fizCZBEOIzfcWDxzwGQKJZEAQBTqcT7e3tad3CkiTj93/qx6rjN+B3f3RBktgvTAtXUlKChoYGJQSOjIax/uIOvLXdn+OaEc3fyhV25Wefz4dwmLdBzIbZhD+AAZBoTvR6Perr69HS0pLWLTw2FsG1X9+FU8/aiNffmMhhDalYlJSUoLGxUQmBo+4I1l+8GVu2MQRSYVrUbkVJSbI7MhrlhLpMS4S/2ay3yABINA8Wi0XpFk4dX7Flqw9nnbcJn/vSDgyP8NstLYzNZksLgR5PBOdf0oHNWzj2lAqPIAArltlnfiDNS2Kyx2wX22YAJFqA8vJytLe3K7f2AuKr4d917yBWH78Bt9/Rh2g0N93CqbOU1Vp9P9HlMDYezUp3eEyDXeyJEJh4bcfHozj/0s3YuMmb9WNLMfVe79TuKjfH1BatZUcnF9znXUEy52AzfQ+FAZBogXQ6HWpra9Ha2gqzOXkLL683im/e8C5OOuMNvPzKuOr1GhtLXkT1enXu+pj49/t8UWzNcFel2xNBJBIPJHq9fsbxLcVk/xA4MRHFBZdtyfpwg+6e5B1Jsn2xTn3vvPzvsawei3JnF5c1yrhDzfQ95POyUBciTTKbzWhtbUVtbW3am3H7jkmsu7ADH//02+gfCKlWnyf/llxrK/XuJtlksViUn//1UmYv4vc9MKj8bLVaM1p2IbBarWkh0OeL4qLLt+DVDdkLgbveTV6ss/0lwmQyKSHztQ0TCIelrB6P1DcxEcVLLyc/F9gCuDCJVr/5fhlmACTKsLKyMrS3t6O8vDxt/4MPD2PNCRtw6209qlzcHki5h3HqhJVsymYAvPNubQdAIP7vbmpqUj7w/f4YLr58S9ZamFNba1LvlZ0NgiAorYCBoIQ3VejiJnX9/Vm30ooPMAAuxFzH+02HAZAoC3Q6HWpqatDa2poWiiYnY/jO9/fghFPfwHPPe7J2/O07JtPWjctFAHx1w0TGxj9u2epLWwJFqwEQiL/GqSFwaiqGS6/cmvHAHQpLuPf+ZOguLS3NaPnTST1/XnxZ/WETlF1PPDWi/Gy1WlX7XCo28xnvNx0GQKIsMpvNaGlpQV1dXVoX2ru7p3DR5VvwwavfQm9v8BAlzE9q658oimkX1mwSRVFpxZmcjOG+B4dmeMbs/OXuAeVng8EAg8GQkXILlcViQXNzsxICA4EYLv/AVjz/Qua+VNx4816lC9hoNKaN0cuW1PP0oUeG4ffHsn5MUkcgEMOzzyXPz6qqqhzWpnDNd7zftGVlpBQiOqTS0lK0t7fD6XSmNdk//uQIjnnPBtx4y14EQ5npFh51R9JabqqqqlSbBAIgbaHsL137Dp56emH3/XzjTS/uuT8ZJLPdFVkozGYzmpqalItBICjhig9twz+eW3gI3LLVh5//skfZVqP1D4i3CiXO1Xd2TuLyD25FIMixgIVuaiqGKz60DZOT8UBvtVphs9lyXKvCstDxftNhACRSiSiKqK6uRmtra1oXZiAo4Yc3deG4E19fcFjq2hvAe9+3Ea7++GQTs9l8wFjEbHM6nbDb42t9RaMyPvqJt/H8v+bXPfnQo8M476IO+HzxBWPNZjNbDlLsHwKDIQlXfXgbnn5m/rfZikRkfP7L76R136eG+mwSRTHtDigvvzKOD350GyeEFDCvN4oLL9uCF15MfgZUVlYe4hm0v0yM95uOrqam5nvzfXI2BnCqNSg0W8fha5L9MrNZrhrH0ev1KC0thclkQiAQgCTFL27jE1E8+PAw3tzkw7FrHCgvn1s356YOL9ZfvFkJfwDQ2NiY8da/2bwmJSUl8Pl8iMViiMVkPPr4CE4+sQyNDbPvRrzl1m589Ru7lCCi1+vR3Nw8p+4PNc6TXJ/jer0eNpsNPp8PsizHX+8nRhCNyjhmjQMGw+y/53u9UXzrP3fjmX8kA6TT6ZxVAMzU66DX66HT6TA5GR/D2tkVwDu7pnDh+VUQRU4aKCRuTwQXXLIZGzuSC5dbLBbU1NRk/djFcj3LZJfv/hgAC6DcQn5NCul1Vvs4JpNJWUA6GEyOA+zsCuD3f+pHICjhsMVWOOwzB7hn/uHGZR/Yhglv8tZKZWVlaQtUZ8psXhNBEGC1WuH1eiHLMqJRGQ89Oozu7gD0egGNjWbodQeWI0ky3t0dwA3f241f3t6bVl5zc/Ocl7PRQgAEkiHQ7/dDkiTEYjJefmUc994/iJpqI45acuhu80BQwq9u78VHPvk2XktZVsbpdKK6ujrj9Z2J2WxGNBpFKBT/MrNz1xSee8GDUFBCba1pVu8Jyp3BoTCeenoUn//yDrydMhnNYrGgsbExa4EmVTFczzLd5XvAcZcvXz7tND1Znnn23qFejNk8f7rHzeYFnm3Zh3rsbP+QcznWdOXO9fnTPSfTr8l8jzOfY0xX5nzK2f9583kjZqL+8637TMLhMIaGhpRWj1RLl9hw9lkVOPu9FVh7bCn0egG790zh9Te8eP3NCWx4fQI7dk6l3XmjpKQE9fX1C/7wmO7fO5fX3ufzweVyHbC/pESHs8+swPp1lRBEAR2bfejY7EXHFt+0A//r6+vTWqFm+3fIxjk912PM9zjzKTccDsPlciEcTr8N4fHHleK7/9mO+joT9DoBeoMAvV6AThTw8GPD+PFPujEwmL5G5Uzhbz6fUzNJLVOWZfT09KR9OYofB1i10oHz11XitFPKYTRxJFOuyXL8i+uLL43hxZfH0taPTCgrK0Ntba1qC7hn47NbrQA4l/v5Lui4DICZO9Z05TIAMgDOhd/vx9DQECKR6W+F5XDoYdALB71VVmL5mUyN2VpoAASAQCAAt9sNv3/udwaxWCyoqKg4YOIHA+DBy5VlGR6PB263e97/vtm0/GU7AAKAJEkYHx+Hx+NBLMYZwYVIEATU1tYqvRG56r0plACYqSVeZnVcBsDMHWu6chkAGQDnKnEB93q9ShfYbDgcDtTU1GT0wyMTATAhGAxidHR0VkGwpKQETqfzoOv9MQDOXG44HMbw8PC0rcoHYzab/7+9e1mO4gYDMKq+mAIvhuL9H9IuXCzMDDSbaCLL3fZc+q5zNoCTjG2STL78aknh+/fvF20cmiMAoxiCT09P4XQ69f45rEtVVefn/dIjhATg8OvWdT3rFZcCcMTP1fe6AlAA3uP379/h5eUlvLy8vFsKa9v2fCbe4XCY5HiUMQMwen19DU9PT+fNL+nnaJom/Pjx49MDYgXg5a/78+fP8Pz8HE6nUzidTu/+mi9fvoTD4RAOh8NVz1jOGYDpH39+fg6/fv0Kx+MxHI/H2f+dpF/TNOHx8TF8+/YtPD4+hq9fv/b+MyEA34vhN/fNKAJwxM/V97oCUACO5Xg8htfX13P0zfF/ilMEYN/rXvuaAvD21z2dTuHPnz/heDyGh4eHmw94XiIA+z7PvX8Pu65bxUaee76PuTY8fPQ1Xvo1CMC3ptzl+xlbqWAj3IDBGOLkeI6bPeYwxn+U1xCAa/s8c0+jShOf9Vvy91kAAgDMZMmpX0oAAgBMLB7vMudGj48IQACACa1hyTcnAAEAJrKWJd+cAAQAGNkap34pAQgAMKK1Tv1SAhAAYCRN06xmo8dHBCAAwJ3WvuSbE4AAAHfYytQvJQABAG6wtalfSgACAFxpi1O/lAAEALjQlqd+KQEIAHCBLRzvcikBCADwgRh+W5/6pQQgAECPuNy75Wf9hghAAIBM0zS7We7tIwABAP6z56lfSgACAIT9T/1SAhAAKFpVVaFt211t8viMAAQAitW27e6Xe/sIQACgOHs82uUaAhAAKEo+9YsR2HXdUl/S7AQgAFCEfJNHqdO/EAQgALBz+XJvyeEXCUAAYLfSM/2E3/8EIACwK13XvVnuFX7vCUAAYDfS5V7hN0wAAgCbF69wK+Umj3sJQABgs9K7e038LicAAYBNiuFX4k0e9xKAAMCmxLt7hd/tBCAAsAnCbzwCEABYvaZpQtvKlrH4nQQAVivu7LXBY1wCEABYnbquQ9u2wm8iAhAAWA3hNw8BCAAszgaPeQlAAGAxVVWFh4cHE7+ZCUAAYHYmfssSgADAbITfOghAAGBydV2fj3RheQIQAJhMvKvXWX7rIgABgNEJv3UTgADAaKqqcnvHBghAAOBucdpX17Xw2wABCADcTPhtkwAEAK5SVdX5OJf4c7ZFAAIAF0nDzzl+2yYAAYAPpeEXz/Hrum7hr4p7CEAAoFcMPwc4748ABADesNS7fwIQADhv5KjrWvgVQAACQMFi+MVlXuFXBgEIAAXKn+9zlEtZBCAAFCJd5nV4c9kEIADsXJz22dFLJAABYKdi9KUTPwhBAALArqRXs8XoE37kBCAA7EC6zBsnfp7vY4gABIANS8PP+X1cSgACwMbk0762bU37uIoABICN6Jv2CT9uIQABYMX6NnU4xoV7CUAAWKG+s/tM+xiLAASAlcif7TPtYyoCEAAWlC7xptFn2seUBCAALCCd9qVn98EcBCAAzCQNvhCCaR+LEYAAMKG+6HM9G0sTgAAwsrikm0720nP7uq5b8KsDAQgAo4nhl/48nt0HayIAAeAOQ8/1uaWDNROAAHClPPriYc2e7WMrBCAAXGAo+uziZYsEIAAMMOljrwQgACTy6AshnKPPQc3shQAEoHh90VfXdWjb9t3HYQ8EIABFSq9gGzqvD/ZKAAJQjDz4uq47P89nMwclEYAA7FrflC+NPiiRAARgdz6LvvTjrmWjRAIQgM1LN3Hk0edWDnhPAAKwSekmjvRj6ZRP9EE/AQjAZsRJXh52zumD6whAAFYrX9qN4Ref53MjB9xGAAKwKukGjnTSV1WVM/pgJAIQgEXld+3mP3dGH4xPAAIwu74pX3oo89CzfsA4BCAAkxta1g0hvIs+YHoCEIDRDd2zG8LwBg4HMsN8BCAAd0t36fbtyo3HtJjywToIQABuEmNu6CiWpmls3oCVEoAAXOSj5/jix9zAAdsgAAHolQZfPuFLl3xN+WB7BCAAIYT3E778EOY0BgUfbJsABChUumnjs926wL4IQICCpLdqpGGX37qRcjwL7I8ABNixvp26+a8t6UJ5BCDATgw9p5du1kgjECiXAATYqDz2YtSlv47RZxkXSLXpG0PXdaGqKm8UACuTX60W37vzjRyWc4FLtCGEN8sE8ceu696EIQDzyXfnpu/PYg+41+AScN9J7qIQYBpp1KVhF3fkOmwZGNNVzwDmUSgGAa7XN8WLP6ZXqcX3W++xwNju2gSSLx2HIAoBUvlze0PRBzCn0XcB58sW0d+/f0MIwhDYv/xQ5aE7deNjNafTacGvtl9J79WlfK+lfJ8hlPW93uofobzfbYnRxloAAAAASUVORK5CYII="}; diff --git a/noVNC/include/multiKeyCode.js b/noVNC/include/multiKeyCode.js deleted file mode 100755 index e232112..0000000 --- a/noVNC/include/multiKeyCode.js +++ /dev/null @@ -1,38 +0,0 @@ -function getMultiKeyCode(){ - var multiKeyCode = { - "0":{"id":"Esc","name":"Escape","code":"0xff1b"}, - "1":{"id":"Shift","name":"Shift","code":"0xffe1"}, - "2":{"id":"Ins","name":"Insert","code":"0xff63"}, - "3":{"id":"Left","name":"Left","code":"0xff51"}, - "4":{"id":"UP","name":"UP","code":"0xff52"}, - "5":{"id":"Right","name":"Right","code":"0xff53"}, - "6":{"id":"Home","name":"Home","code":"0xff50"}, - "7":{"id":"PgUP","name":"PageUp","code":"0xff55"}, - "8":{"id":"Caps","name":"CapsLock","code":"0xffe5"}, - "9":{"id":"Ctrl","name":"Ctrl","code":"0xffe3"}, - "10":{"id":"Alt","name":"Alt","code":"0xffe9"}, - "11":{"id":"Win","name":"Win Key","code":"0xffeb"}, - "12":{"id":"Down","name":"Down","code":"0xff54"}, - "13":{"id":"Del","name":"Delete","code":"0xffff"}, - "14":{"id":"End","name":"End","code":"0xff57"}, - "15":{"id":"PgDn","name":"PageDown","code":"0xff56"}, - "16":{"id":"F1","name":"F1","code":"0xffbe"}, - "17":{"id":"F2","name":"F2","code":"0xffbf"}, - "18":{"id":"F3","name":"F3","code":"0xffc0"}, - "19":{"id":"F4","name":"F4","code":"0xffc1"}, - "20":{"id":"F5","name":"F5","code":"0xffc2"}, - "21":{"id":"F6","name":"F6","code":"0xffc3"}, - "22":{"id":"F7","name":"F7","code":"0xffc4"}, - "23":{"id":"F8","name":"F8","code":"0xffc5"}, - "24":{"id":"Back","name":"Backspace","code":"0xff08"}, - "25":{"id":"Tab","name":"Tab","code":"0xff09"}, - "26":{"id":"PrtSc","name":"Print Screen","code":"0xff61"}, - "27":{"id":"Pause","name":"Pause","code":"0xff13"}, - "28":{"id":"F9","name":"F9","code":"0xffc6"}, - "29":{"id":"F10","name":"F10","code":"0xffc7"}, - "30":{"id":"F11","name":"F11","code":"0xffc8"}, - "31":{"id":"F12","name":"F12","code":"0xffc9"} - }; - - return multiKeyCode; -} \ No newline at end of file diff --git a/noVNC/include/playback.js b/noVNC/include/playback.js deleted file mode 100644 index 7756529..0000000 --- a/noVNC/include/playback.js +++ /dev/null @@ -1,102 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2012 Joel Martin - * Licensed under MPL 2.0 (see LICENSE.txt) - */ - -"use strict"; -/*jslint browser: true, white: false */ -/*global Util, VNC_frame_data, finish */ - -var rfb, mode, test_state, frame_idx, frame_length, - iteration, iterations, istart_time, - - // Pre-declarations for jslint - send_array, next_iteration, queue_next_packet, do_packet; - -// Override send_array -send_array = function (arr) { - // Stub out send_array -}; - -next_iteration = function () { - if (iteration === 0) { - frame_length = VNC_frame_data.length; - test_state = 'running'; - } else { - rfb.disconnect(); - } - - if (test_state !== 'running') { return; } - - iteration += 1; - if (iteration > iterations) { - finish(); - return; - } - - frame_idx = 0; - istart_time = (new Date()).getTime(); - rfb.connect('test', 0, "bogus"); - - queue_next_packet(); - -}; - -queue_next_packet = function () { - var frame, foffset, toffset, delay; - if (test_state !== 'running') { return; } - - frame = VNC_frame_data[frame_idx]; - while ((frame_idx < frame_length) && (frame.charAt(0) === "}")) { - //Util.Debug("Send frame " + frame_idx); - frame_idx += 1; - frame = VNC_frame_data[frame_idx]; - } - - if (frame === 'EOF') { - Util.Debug("Finished, found EOF"); - next_iteration(); - return; - } - if (frame_idx >= frame_length) { - Util.Debug("Finished, no more frames"); - next_iteration(); - return; - } - - if (mode === 'realtime') { - foffset = frame.slice(1, frame.indexOf('{', 1)); - toffset = (new Date()).getTime() - istart_time; - delay = foffset - toffset; - if (delay < 1) { - delay = 1; - } - - setTimeout(do_packet, delay); - } else { - setTimeout(do_packet, 1); - } -}; - -var bytes_processed = 0; - -do_packet = function () { - //Util.Debug("Processing frame: " + frame_idx); - var frame = VNC_frame_data[frame_idx], - start = frame.indexOf('{', 1) + 1; - bytes_processed += frame.length - start; - if (VNC_frame_encoding === 'binary') { - var u8 = new Uint8Array(frame.length - start); - for (var i = 0; i < frame.length - start; i++) { - u8[i] = frame.charCodeAt(start + i); - } - rfb.recv_message({'data' : u8}); - } else { - rfb.recv_message({'data' : frame.slice(start)}); - } - frame_idx += 1; - - queue_next_packet(); -}; - diff --git a/noVNC/include/ui.js b/noVNC/include/ui.js deleted file mode 100644 index 9baf40c..0000000 --- a/noVNC/include/ui.js +++ /dev/null @@ -1,1110 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2012 Joel Martin - * Copyright (C) 2015 Samuel Mannehed for Cendio AB - * Licensed under MPL 2.0 (see LICENSE.txt) - * - * See README.md for usage and integration instructions. - */ - -/* jslint white: false, browser: true */ -/* global window, $D, Util, WebUtil, RFB, Display */ - -var UI; - -(function () { - "use strict"; - - var resizeTimeout; - - // Load supporting scripts - window.onscriptsload = function () { UI.load(); }; - Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js", - "keysymdef.js", "keyboard.js", "input.js", "display.js", - "jsunzip.js", "rfb.js", "keysym.js"]); - - UI = { - - rfb_state : 'loaded', - settingsOpen : false, - connSettingsOpen : false, - popupStatusOpen : false, - clipboardOpen: false, - keyboardVisible: false, - hideKeyboardTimeout: null, - lastKeyboardinput: null, - defaultKeyboardinputLen: 100, - extraKeysVisible: false, - ctrlOn: false, - altOn: false, - isTouchDevice: false, - - // Setup rfb object, load settings from browser storage, then call - // UI.init to setup the UI/menus - load: function (callback) { - WebUtil.initSettings(UI.start, callback); - }, - - // Render default UI and initialize settings menu - start: function(callback) { - UI.isTouchDevice = 'ontouchstart' in document.documentElement; - - // Stylesheet selection dropdown - var sheet = WebUtil.selectStylesheet(); - var sheets = WebUtil.getStylesheets(); - var i; - for (i = 0; i < sheets.length; i += 1) { - UI.addOption($D('noVNC_stylesheet'),sheets[i].title, sheets[i].title); - } - - // Logging selection dropdown - var llevels = ['error', 'warn', 'info', 'debug']; - for (i = 0; i < llevels.length; i += 1) { - UI.addOption($D('noVNC_logging'),llevels[i], llevels[i]); - } - - // Settings with immediate effects - UI.initSetting('logging', 'warn'); - WebUtil.init_logging(UI.getSetting('logging')); - - UI.initSetting('stylesheet', 'default'); - WebUtil.selectStylesheet(null); - // call twice to get around webkit bug - WebUtil.selectStylesheet(UI.getSetting('stylesheet')); - - // if port == 80 (or 443) then it won't be present and should be - // set manually - var port = window.location.port; - if (!port) { - if (window.location.protocol.substring(0,5) == 'https') { - port = 443; - } - else if (window.location.protocol.substring(0,4) == 'http') { - port = 80; - } - } - - /* Populate the controls if defaults are provided in the URL */ - UI.initSetting('host', window.location.hostname); - UI.initSetting('port', port); - UI.initSetting('password', ''); - UI.initSetting('encrypt', (window.location.protocol === "https:")); - UI.initSetting('true_color', true); - UI.initSetting('cursor', !UI.isTouchDevice); - UI.initSetting('resize', 'off'); - UI.initSetting('shared', true); - UI.initSetting('view_only', false); - UI.initSetting('path', 'websockify'); - UI.initSetting('repeaterID', ''); - - var autoconnect = WebUtil.getQueryVar('autoconnect', false); - if (autoconnect === 'true' || autoconnect == '1') { - autoconnect = true; - UI.connect(); - } else { - autoconnect = false; - } - - UI.updateVisualState(); - - $D('noVNC_host').focus(); - - // Show mouse selector buttons on touch screen devices - if (UI.isTouchDevice) { - // Show mobile buttons - $D('noVNC_mobile_buttons').style.display = "inline"; - UI.setMouseButton(); - // Remove the address bar - setTimeout(function() { window.scrollTo(0, 1); }, 100); - UI.forceSetting('clip', true); - } else { - UI.initSetting('clip', false); - } - - UI.setViewClip(); - UI.setBarPosition(); - - Util.addEvent(window, 'resize', function () { - UI.onresize(); - UI.setViewClip(); - UI.updateViewDragButton(); - UI.setBarPosition(); - } ); - - Util.addEvent(window, 'load', UI.keyboardinputReset); - - Util.addEvent(window, 'beforeunload', function () { - if (UI.rfb && UI.rfb_state === 'normal') { - return "You are currently connected."; - } - } ); - - // Show description by default when hosted at for kanaka.github.com - if (location.host === "kanaka.github.io") { - // Open the description dialog - $D('noVNC_description').style.display = "block"; - } else { - // Show the connect panel on first load unless autoconnecting - if (autoconnect === UI.connSettingsOpen) { - UI.toggleConnectPanel(); - } - } - - // Add mouse event click/focus/blur event handlers to the UI - UI.addMouseHandlers(); - - if (typeof callback === "function") { - callback(UI.rfb); - } - }, - - initRFB: function () { - try { - UI.rfb = new RFB({'target': $D('noVNC_canvas'), - 'onUpdateState': UI.updateState, - 'onXvpInit': UI.updateXvpVisualState, - 'onClipboard': UI.clipReceive, - 'onFBUComplete': UI.FBUComplete, - 'onFBResize': UI.updateViewDragButton, - 'onDesktopName': UI.updateDocumentTitle}); - return true; - } catch (exc) { - UI.updateState(null, 'fatal', null, 'Unable to create RFB client -- ' + exc); - return false; - } - }, - - addMouseHandlers: function() { - // Setup interface handlers that can't be inline - $D("noVNC_view_drag_button").onclick = UI.setViewDrag; - $D("noVNC_mouse_button0").onclick = function () { UI.setMouseButton(1); }; - $D("noVNC_mouse_button1").onclick = function () { UI.setMouseButton(2); }; - $D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); }; - $D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); }; - $D("showKeyboard").onclick = UI.showKeyboard; - - $D("keyboardinput").oninput = UI.keyInput; - $D("keyboardinput").onblur = UI.keyInputBlur; - $D("keyboardinput").onsubmit = function () { return false; }; - - $D("showExtraKeysButton").onclick = UI.showExtraKeys; - $D("toggleCtrlButton").onclick = UI.toggleCtrl; - $D("toggleAltButton").onclick = UI.toggleAlt; - $D("sendTabButton").onclick = UI.sendTab; - $D("sendEscButton").onclick = UI.sendEsc; - - $D("sendCtrlAltDelButton").onclick = UI.sendCtrlAltDel; - $D("xvpShutdownButton").onclick = UI.xvpShutdown; - $D("xvpRebootButton").onclick = UI.xvpReboot; - $D("xvpResetButton").onclick = UI.xvpReset; - $D("noVNC_status").onclick = UI.togglePopupStatusPanel; - $D("noVNC_popup_status_panel").onclick = UI.togglePopupStatusPanel; - $D("xvpButton").onclick = UI.toggleXvpPanel; - $D("clipboardButton").onclick = UI.toggleClipboardPanel; - $D("settingsButton").onclick = UI.toggleSettingsPanel; - $D("connectButton").onclick = UI.toggleConnectPanel; - $D("disconnectButton").onclick = UI.disconnect; - $D("descriptionButton").onclick = UI.toggleConnectPanel; - - $D("noVNC_clipboard_text").onfocus = UI.displayBlur; - $D("noVNC_clipboard_text").onblur = UI.displayFocus; - $D("noVNC_clipboard_text").onchange = UI.clipSend; - $D("noVNC_clipboard_clear_button").onclick = UI.clipClear; - - $D("noVNC_settings_menu").onmouseover = UI.displayBlur; - $D("noVNC_settings_menu").onmouseover = UI.displayFocus; - $D("noVNC_apply").onclick = UI.settingsApply; - - $D("noVNC_connect_button").onclick = UI.connect; - - $D("noVNC_resize").onchange = function () { - var connected = UI.rfb && UI.rfb_state === 'normal'; - UI.enableDisableClip(connected); - }; - }, - - onresize: function (callback) { - if (!UI.rfb) return; - - var size = UI.getCanvasLimit(); - - if (size && UI.rfb_state === 'normal' && UI.rfb.get_display()) { - var display = UI.rfb.get_display(); - var scaleType = UI.getSetting('resize'); - if (scaleType === 'remote') { - // use remote resizing - - // When the local window has been resized, wait until the size remains - // the same for 0.5 seconds before sending the request for changing - // the resolution of the session - clearTimeout(resizeTimeout); - resizeTimeout = setTimeout(function(){ - display.set_maxWidth(size.w); - display.set_maxHeight(size.h); - Util.Debug('Attempting setDesktopSize(' + - size.w + ', ' + size.h + ')'); - UI.rfb.setDesktopSize(size.w, size.h); - }, 500); - } else if (scaleType === 'scale' || scaleType === 'downscale') { - // use local scaling - - var downscaleOnly = scaleType === 'downscale'; - var scaleRatio = display.autoscale(size.w, size.h, downscaleOnly); - UI.rfb.get_mouse().set_scale(scaleRatio); - Util.Debug('Scaling by ' + UI.rfb.get_mouse().get_scale()); - } - } - }, - - getCanvasLimit: function () { - var container = $D('noVNC_container'); - - // Hide the scrollbars until the size is calculated - container.style.overflow = "hidden"; - - var pos = Util.getPosition(container); - var w = pos.width; - var h = pos.height; - - container.style.overflow = "visible"; - - if (isNaN(w) || isNaN(h)) { - return false; - } else { - return {w: w, h: h}; - } - }, - - // Read form control compatible setting from cookie - getSetting: function(name) { - var ctrl = $D('noVNC_' + name); - var val = WebUtil.readSetting(name); - if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') { - if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) { - val = false; - } else { - val = true; - } - } - return val; - }, - - // Update cookie and form control setting. If value is not set, then - // updates from control to current cookie setting. - updateSetting: function(name, value) { - - // Save the cookie for this session - if (typeof value !== 'undefined') { - WebUtil.writeSetting(name, value); - } - - // Update the settings control - value = UI.getSetting(name); - - var ctrl = $D('noVNC_' + name); - if (ctrl.type === 'checkbox') { - ctrl.checked = value; - - } else if (typeof ctrl.options !== 'undefined') { - for (var i = 0; i < ctrl.options.length; i += 1) { - if (ctrl.options[i].value === value) { - ctrl.selectedIndex = i; - break; - } - } - } else { - /*Weird IE9 error leads to 'null' appearring - in textboxes instead of ''.*/ - if (value === null) { - value = ""; - } - ctrl.value = value; - } - }, - - // Save control setting to cookie - saveSetting: function(name) { - var val, ctrl = $D('noVNC_' + name); - if (ctrl.type === 'checkbox') { - val = ctrl.checked; - } else if (typeof ctrl.options !== 'undefined') { - val = ctrl.options[ctrl.selectedIndex].value; - } else { - val = ctrl.value; - } - WebUtil.writeSetting(name, val); - //Util.Debug("Setting saved '" + name + "=" + val + "'"); - return val; - }, - - // Initial page load read/initialization of settings - initSetting: function(name, defVal) { - // Check Query string followed by cookie - var val = WebUtil.getQueryVar(name); - if (val === null) { - val = WebUtil.readSetting(name, defVal); - } - UI.updateSetting(name, val); - return val; - }, - - // Force a setting to be a certain value - forceSetting: function(name, val) { - UI.updateSetting(name, val); - return val; - }, - - - // Show the popup status panel - togglePopupStatusPanel: function() { - var psp = $D('noVNC_popup_status_panel'); - if (UI.popupStatusOpen === true) { - psp.style.display = "none"; - UI.popupStatusOpen = false; - } else { - psp.innerHTML = $D('noVNC_status').innerHTML; - psp.style.display = "block"; - psp.style.left = window.innerWidth/2 - - parseInt(window.getComputedStyle(psp, false).width)/2 -30 + "px"; - UI.popupStatusOpen = true; - } - }, - - // Show the XVP panel - toggleXvpPanel: function() { - // Close the description panel - $D('noVNC_description').style.display = "none"; - // Close settings if open - if (UI.settingsOpen === true) { - UI.settingsApply(); - UI.closeSettingsMenu(); - } - // Close connection settings if open - if (UI.connSettingsOpen === true) { - UI.toggleConnectPanel(); - } - // Close popup status panel if open - if (UI.popupStatusOpen === true) { - UI.togglePopupStatusPanel(); - } - // Close clipboard panel if open - if (UI.clipboardOpen === true) { - UI.toggleClipboardPanel(); - } - // Toggle XVP panel - if (UI.xvpOpen === true) { - $D('noVNC_xvp').style.display = "none"; - $D('xvpButton').className = "noVNC_status_button"; - UI.xvpOpen = false; - } else { - $D('noVNC_xvp').style.display = "block"; - $D('xvpButton').className = "noVNC_status_button_selected"; - UI.xvpOpen = true; - } - }, - - // Show the clipboard panel - toggleClipboardPanel: function() { - // Close the description panel - $D('noVNC_description').style.display = "none"; - // Close settings if open - if (UI.settingsOpen === true) { - UI.settingsApply(); - UI.closeSettingsMenu(); - } - // Close connection settings if open - if (UI.connSettingsOpen === true) { - UI.toggleConnectPanel(); - } - // Close popup status panel if open - if (UI.popupStatusOpen === true) { - UI.togglePopupStatusPanel(); - } - // Close XVP panel if open - if (UI.xvpOpen === true) { - UI.toggleXvpPanel(); - } - // Toggle Clipboard Panel - if (UI.clipboardOpen === true) { - $D('noVNC_clipboard').style.display = "none"; - $D('clipboardButton').className = "noVNC_status_button"; - UI.clipboardOpen = false; - } else { - $D('noVNC_clipboard').style.display = "block"; - $D('clipboardButton').className = "noVNC_status_button_selected"; - UI.clipboardOpen = true; - } - }, - - // Show the connection settings panel/menu - toggleConnectPanel: function() { - // Close the description panel - $D('noVNC_description').style.display = "none"; - // Close connection settings if open - if (UI.settingsOpen === true) { - UI.settingsApply(); - UI.closeSettingsMenu(); - $D('connectButton').className = "noVNC_status_button"; - } - // Close clipboard panel if open - if (UI.clipboardOpen === true) { - UI.toggleClipboardPanel(); - } - // Close popup status panel if open - if (UI.popupStatusOpen === true) { - UI.togglePopupStatusPanel(); - } - // Close XVP panel if open - if (UI.xvpOpen === true) { - UI.toggleXvpPanel(); - } - - // Toggle Connection Panel - if (UI.connSettingsOpen === true) { - $D('noVNC_controls').style.display = "none"; - $D('connectButton').className = "noVNC_status_button"; - UI.connSettingsOpen = false; - UI.saveSetting('host'); - UI.saveSetting('port'); - //UI.saveSetting('password'); - } else { - $D('noVNC_controls').style.display = "block"; - $D('connectButton').className = "noVNC_status_button_selected"; - UI.connSettingsOpen = true; - $D('noVNC_host').focus(); - } - }, - - // Toggle the settings menu: - // On open, settings are refreshed from saved cookies. - // On close, settings are applied - toggleSettingsPanel: function() { - // Close the description panel - $D('noVNC_description').style.display = "none"; - if (UI.settingsOpen) { - UI.settingsApply(); - UI.closeSettingsMenu(); - } else { - UI.updateSetting('encrypt'); - UI.updateSetting('true_color'); - if (Util.browserSupportsCursorURIs()) { - UI.updateSetting('cursor'); - } else { - UI.updateSetting('cursor', !UI.isTouchDevice); - $D('noVNC_cursor').disabled = true; - } - UI.updateSetting('clip'); - UI.updateSetting('resize'); - UI.updateSetting('shared'); - UI.updateSetting('view_only'); - UI.updateSetting('path'); - UI.updateSetting('repeaterID'); - UI.updateSetting('stylesheet'); - UI.updateSetting('logging'); - - UI.openSettingsMenu(); - } - }, - - // Open menu - openSettingsMenu: function() { - // Close the description panel - $D('noVNC_description').style.display = "none"; - // Close clipboard panel if open - if (UI.clipboardOpen === true) { - UI.toggleClipboardPanel(); - } - // Close connection settings if open - if (UI.connSettingsOpen === true) { - UI.toggleConnectPanel(); - } - // Close popup status panel if open - if (UI.popupStatusOpen === true) { - UI.togglePopupStatusPanel(); - } - // Close XVP panel if open - if (UI.xvpOpen === true) { - UI.toggleXvpPanel(); - } - $D('noVNC_settings').style.display = "block"; - $D('settingsButton').className = "noVNC_status_button_selected"; - UI.settingsOpen = true; - }, - - // Close menu (without applying settings) - closeSettingsMenu: function() { - $D('noVNC_settings').style.display = "none"; - $D('settingsButton').className = "noVNC_status_button"; - UI.settingsOpen = false; - }, - - // Save/apply settings when 'Apply' button is pressed - settingsApply: function() { - //Util.Debug(">> settingsApply"); - UI.saveSetting('encrypt'); - UI.saveSetting('true_color'); - if (Util.browserSupportsCursorURIs()) { - UI.saveSetting('cursor'); - } - - UI.saveSetting('resize'); - - if (UI.getSetting('resize') === 'downscale' || UI.getSetting('resize') === 'scale') { - UI.forceSetting('clip', false); - } - - UI.saveSetting('clip'); - UI.saveSetting('shared'); - UI.saveSetting('view_only'); - UI.saveSetting('path'); - UI.saveSetting('repeaterID'); - UI.saveSetting('stylesheet'); - UI.saveSetting('logging'); - - // Settings with immediate (non-connected related) effect - WebUtil.selectStylesheet(UI.getSetting('stylesheet')); - WebUtil.init_logging(UI.getSetting('logging')); - UI.setViewClip(); - UI.setViewDrag(UI.rfb && UI.rfb.get_viewportDrag()); - //Util.Debug("<< settingsApply"); - }, - - - - setPassword: function() { - UI.rfb.sendPassword($D('noVNC_password').value); - //Reset connect button. - $D('noVNC_connect_button').value = "Connect"; - $D('noVNC_connect_button').onclick = UI.Connect; - //Hide connection panel. - UI.toggleConnectPanel(); - return false; - }, - - sendCtrlAltDel: function() { - UI.rfb.sendCtrlAltDel(); - }, - - xvpShutdown: function() { - UI.rfb.xvpShutdown(); - }, - - xvpReboot: function() { - UI.rfb.xvpReboot(); - }, - - xvpReset: function() { - UI.rfb.xvpReset(); - }, - - setMouseButton: function(num) { - if (typeof num === 'undefined') { - // Disable mouse buttons - num = -1; - } - if (UI.rfb) { - UI.rfb.get_mouse().set_touchButton(num); - } - - var blist = [0, 1,2,4]; - for (var b = 0; b < blist.length; b++) { - var button = $D('noVNC_mouse_button' + blist[b]); - if (blist[b] === num) { - button.style.display = ""; - } else { - button.style.display = "none"; - } - } - }, - - updateState: function(rfb, state, oldstate, msg) { - UI.rfb_state = state; - var klass; - switch (state) { - case 'failed': - case 'fatal': - klass = "noVNC_status_error"; - break; - case 'normal': - klass = "noVNC_status_normal"; - break; - case 'disconnected': - $D('noVNC_logo').style.display = "block"; - $D('noVNC_container').style.display = "none"; - /* falls through */ - case 'loaded': - klass = "noVNC_status_normal"; - break; - case 'password': - UI.toggleConnectPanel(); - - $D('noVNC_connect_button').value = "Send Password"; - $D('noVNC_connect_button').onclick = UI.setPassword; - $D('noVNC_password').focus(); - - klass = "noVNC_status_warn"; - break; - default: - klass = "noVNC_status_warn"; - break; - } - - if (typeof(msg) !== 'undefined') { - $D('noVNC-control-bar').setAttribute("class", klass); - $D('noVNC_status').innerHTML = msg; - } - - UI.updateVisualState(); - }, - - // Disable/enable controls depending on connection state - updateVisualState: function() { - var connected = UI.rfb && UI.rfb_state === 'normal'; - - //Util.Debug(">> updateVisualState"); - $D('noVNC_encrypt').disabled = connected; - $D('noVNC_true_color').disabled = connected; - if (Util.browserSupportsCursorURIs()) { - $D('noVNC_cursor').disabled = connected; - } else { - UI.updateSetting('cursor', !UI.isTouchDevice); - $D('noVNC_cursor').disabled = true; - } - - UI.enableDisableClip(connected); - $D('noVNC_resize').disabled = connected; - $D('noVNC_shared').disabled = connected; - $D('noVNC_view_only').disabled = connected; - $D('noVNC_path').disabled = connected; - $D('noVNC_repeaterID').disabled = connected; - - if (connected) { - UI.setViewClip(); - UI.setMouseButton(1); - $D('clipboardButton').style.display = "inline"; - $D('showKeyboard').style.display = "inline"; - $D('noVNC_extra_keys').style.display = ""; - $D('sendCtrlAltDelButton').style.display = "inline"; - } else { - UI.setMouseButton(); - $D('clipboardButton').style.display = "none"; - $D('showKeyboard').style.display = "none"; - $D('noVNC_extra_keys').style.display = "none"; - $D('sendCtrlAltDelButton').style.display = "none"; - UI.updateXvpVisualState(0); - } - - // State change disables viewport dragging. - // It is enabled (toggled) by direct click on the button - UI.setViewDrag(false); - - switch (UI.rfb_state) { - case 'fatal': - case 'failed': - case 'disconnected': - $D('connectButton').style.display = ""; - $D('disconnectButton').style.display = "none"; - UI.connSettingsOpen = false; - UI.toggleConnectPanel(); - break; - case 'loaded': - $D('connectButton').style.display = ""; - $D('disconnectButton').style.display = "none"; - break; - default: - $D('connectButton').style.display = "none"; - $D('disconnectButton').style.display = ""; - break; - } - - //Util.Debug("<< updateVisualState"); - }, - - // Disable/enable XVP button - updateXvpVisualState: function(ver) { - if (ver >= 1) { - $D('xvpButton').style.display = 'inline'; - } else { - $D('xvpButton').style.display = 'none'; - // Close XVP panel if open - if (UI.xvpOpen === true) { - UI.toggleXvpPanel(); - } - } - }, - - enableDisableClip: function (connected) { - var resizeElem = $D('noVNC_resize'); - if (resizeElem.value === 'downscale' || resizeElem.value === 'scale') { - UI.forceSetting('clip', false); - $D('noVNC_clip').disabled = true; - } else { - $D('noVNC_clip').disabled = connected || UI.isTouchDevice; - if (UI.isTouchDevice) { - UI.forceSetting('clip', true); - } - } - }, - - // This resize can not be done until we know from the first Frame Buffer Update - // if it is supported or not. - // The resize is needed to make sure the server desktop size is updated to the - // corresponding size of the current local window when reconnecting to an - // existing session. - FBUComplete: function(rfb, fbu) { - UI.onresize(); - UI.rfb.set_onFBUComplete(function() { }); - }, - - // Display the desktop name in the document title - updateDocumentTitle: function(rfb, name) { - document.title = name + " - noVNC"; - }, - - clipReceive: function(rfb, text) { - Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "..."); - $D('noVNC_clipboard_text').value = text; - Util.Debug("<< UI.clipReceive"); - }, - - connect: function() { - UI.closeSettingsMenu(); - UI.toggleConnectPanel(); - - var host = $D('noVNC_host').value; - var port = $D('noVNC_port').value; - var password = $D('noVNC_password').value; - var path = $D('noVNC_path').value; - if ((!host) || (!port)) { - throw new Error("Must set host and port"); - } - - if (!UI.initRFB()) return; - - UI.rfb.set_encrypt(UI.getSetting('encrypt')); - UI.rfb.set_true_color(UI.getSetting('true_color')); - UI.rfb.set_local_cursor(UI.getSetting('cursor')); - UI.rfb.set_shared(UI.getSetting('shared')); - UI.rfb.set_view_only(UI.getSetting('view_only')); - UI.rfb.set_repeaterID(UI.getSetting('repeaterID')); - - UI.rfb.connect(host, port, password, path); - - //Close dialog. - setTimeout(UI.setBarPosition, 100); - $D('noVNC_logo').style.display = "none"; - $D('noVNC_container').style.display = "inline"; - }, - - disconnect: function() { - UI.closeSettingsMenu(); - UI.rfb.disconnect(); - - // Restore the callback used for initial resize - UI.rfb.set_onFBUComplete(UI.FBUComplete); - - $D('noVNC_logo').style.display = "block"; - $D('noVNC_container').style.display = "none"; - - // Don't display the connection settings until we're actually disconnected - }, - - displayBlur: function() { - if (!UI.rfb) return; - - UI.rfb.get_keyboard().set_focused(false); - UI.rfb.get_mouse().set_focused(false); - }, - - displayFocus: function() { - if (!UI.rfb) return; - - UI.rfb.get_keyboard().set_focused(true); - UI.rfb.get_mouse().set_focused(true); - }, - - clipClear: function() { - $D('noVNC_clipboard_text').value = ""; - UI.rfb.clipboardPasteFrom(""); - }, - - clipSend: function() { - var text = $D('noVNC_clipboard_text').value; - Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "..."); - UI.rfb.clipboardPasteFrom(text); - Util.Debug("<< UI.clipSend"); - }, - - // Enable/disable and configure viewport clipping - setViewClip: function(clip) { - var display; - if (UI.rfb) { - display = UI.rfb.get_display(); - } else { - return; - } - - var cur_clip = display.get_viewport(); - - if (typeof(clip) !== 'boolean') { - // Use current setting - clip = UI.getSetting('clip'); - } - - if (clip && !cur_clip) { - // Turn clipping on - UI.updateSetting('clip', true); - } else if (!clip && cur_clip) { - // Turn clipping off - UI.updateSetting('clip', false); - display.set_viewport(false); - display.set_maxWidth(0); - display.set_maxHeight(0); - display.viewportChangeSize(); - } - if (UI.getSetting('clip')) { - // If clipping, update clipping settings - display.set_viewport(true); - - var size = UI.getCanvasLimit(); - if (size) { - display.set_maxWidth(size.w); - display.set_maxHeight(size.h); - - // Hide potential scrollbars that can skew the position - $D('noVNC_container').style.overflow = "hidden"; - - // The x position marks the left margin of the canvas, - // remove the margin from both sides to keep it centered - var new_w = size.w - (2 * Util.getPosition($D('noVNC_canvas')).x); - - $D('noVNC_container').style.overflow = "visible"; - - display.viewportChangeSize(new_w, size.h); - } - } - }, - - // Toggle/set/unset the viewport drag/move button - setViewDrag: function(drag) { - if (!UI.rfb) return; - - UI.updateViewDragButton(); - - if (typeof(drag) === "undefined" || - typeof(drag) === "object") { - // If not specified, then toggle - drag = !UI.rfb.get_viewportDrag(); - } - var vmb = $D('noVNC_view_drag_button'); - if (drag) { - vmb.className = "noVNC_status_button_selected"; - UI.rfb.set_viewportDrag(true); - } else { - vmb.className = "noVNC_status_button"; - UI.rfb.set_viewportDrag(false); - } - }, - - updateViewDragButton: function() { - var vmb = $D('noVNC_view_drag_button'); - if (UI.rfb_state === 'normal' && - UI.rfb.get_display().get_viewport() && - UI.rfb.get_display().clippingDisplay()) { - vmb.style.display = "inline"; - } else { - vmb.style.display = "none"; - } - }, - - // On touch devices, show the OS keyboard - showKeyboard: function() { - var kbi = $D('keyboardinput'); - var skb = $D('showKeyboard'); - var l = kbi.value.length; - if(UI.keyboardVisible === false) { - kbi.focus(); - try { kbi.setSelectionRange(l, l); } // Move the caret to the end - catch (err) {} // setSelectionRange is undefined in Google Chrome - UI.keyboardVisible = true; - skb.className = "noVNC_status_button_selected"; - } else if(UI.keyboardVisible === true) { - kbi.blur(); - skb.className = "noVNC_status_button"; - UI.keyboardVisible = false; - } - }, - - keepKeyboard: function() { - clearTimeout(UI.hideKeyboardTimeout); - if(UI.keyboardVisible === true) { - $D('keyboardinput').focus(); - $D('showKeyboard').className = "noVNC_status_button_selected"; - } else if(UI.keyboardVisible === false) { - $D('keyboardinput').blur(); - $D('showKeyboard').className = "noVNC_status_button"; - } - }, - - keyboardinputReset: function() { - var kbi = $D('keyboardinput'); - kbi.value = new Array(UI.defaultKeyboardinputLen).join("_"); - UI.lastKeyboardinput = kbi.value; - }, - - // When normal keyboard events are left uncought, use the input events from - // the keyboardinput element instead and generate the corresponding key events. - // This code is required since some browsers on Android are inconsistent in - // sending keyCodes in the normal keyboard events when using on screen keyboards. - keyInput: function(event) { - - if (!UI.rfb) return; - - var newValue = event.target.value; - - if (!UI.lastKeyboardinput) { - UI.keyboardinputReset(); - } - var oldvalue = UI.lastKeyboardinput; - - var newLen; - try { - // Try to check caret position since whitespace at the end - // will not be considered by value.length in some browsers - newLen = Math.max(event.target.selectionStart, newValue.length); - } catch (err) { - // selectionStart is undefined in Google Chrome - newLen = newValue.length; - } - var oldLen = oldValue.length; - - var backspaces; - var inputs = newLen - oldLen; - if (inputs < 0) { - backspaces = -inputs; - } else { - backspaces = 0; - } - - // Compare the old string with the new to account for - // text-corrections or other input that modify existing text - var i; - for (i = 0; i < Math.min(oldLen, newLen); i++) { - if (newValue.charAt(i) != oldValue.charAt(i)) { - inputs = newLen - i; - backspaces = oldLen - i; - break; - } - } - - // Send the key events - for (i = 0; i < backspaces; i++) { - UI.rfb.sendKey(XK_BackSpace); - } - for (i = newLen - inputs; i < newLen; i++) { - UI.rfb.sendKey(newValue.charCodeAt(i)); - } - - // Control the text content length in the keyboardinput element - if (newLen > 2 * UI.defaultKeyboardinputLen) { - UI.keyboardinputReset(); - } else if (newLen < 1) { - // There always have to be some text in the keyboardinput - // element with which backspace can interact. - UI.keyboardinputReset(); - // This sometimes causes the keyboard to disappear for a second - // but it is required for the android keyboard to recognize that - // text has been added to the field - event.target.blur(); - // This has to be ran outside of the input handler in order to work - setTimeout(function() { UI.keepKeyboard(); }, 0); - } else { - UI.lastKeyboardinput = newValue; - } - }, - - keyInputBlur: function() { - $D('showKeyboard').className = "noVNC_status_button"; - //Weird bug in iOS if you change keyboardVisible - //here it does not actually occur so next time - //you click keyboard icon it doesnt work. - UI.hideKeyboardTimeout = setTimeout(function() { UI.setKeyboard(); },100); - }, - - showExtraKeys: function() { - UI.keepKeyboard(); - if(UI.extraKeysVisible === false) { - $D('toggleCtrlButton').style.display = "inline"; - $D('toggleAltButton').style.display = "inline"; - $D('sendTabButton').style.display = "inline"; - $D('sendEscButton').style.display = "inline"; - $D('showExtraKeysButton').className = "noVNC_status_button_selected"; - UI.extraKeysVisible = true; - } else if(UI.extraKeysVisible === true) { - $D('toggleCtrlButton').style.display = ""; - $D('toggleAltButton').style.display = ""; - $D('sendTabButton').style.display = ""; - $D('sendEscButton').style.display = ""; - $D('showExtraKeysButton').className = "noVNC_status_button"; - UI.extraKeysVisible = false; - } - }, - - toggleCtrl: function() { - UI.keepKeyboard(); - if(UI.ctrlOn === false) { - UI.rfb.sendKey(XK_Control_L, true); - $D('toggleCtrlButton').className = "noVNC_status_button_selected"; - UI.ctrlOn = true; - } else if(UI.ctrlOn === true) { - UI.rfb.sendKey(XK_Control_L, false); - $D('toggleCtrlButton').className = "noVNC_status_button"; - UI.ctrlOn = false; - } - }, - - toggleAlt: function() { - UI.keepKeyboard(); - if(UI.altOn === false) { - UI.rfb.sendKey(XK_Alt_L, true); - $D('toggleAltButton').className = "noVNC_status_button_selected"; - UI.altOn = true; - } else if(UI.altOn === true) { - UI.rfb.sendKey(XK_Alt_L, false); - $D('toggleAltButton').className = "noVNC_status_button"; - UI.altOn = false; - } - }, - - sendTab: function() { - UI.keepKeyboard(); - UI.rfb.sendKey(XK_Tab); - }, - - sendEsc: function() { - UI.keepKeyboard(); - UI.rfb.sendKey(XK_Escape); - }, - - setKeyboard: function() { - UI.keyboardVisible = false; - }, - - //Helper to add options to dropdown. - addOption: function(selectbox, text, value) { - var optn = document.createElement("OPTION"); - optn.text = text; - optn.value = value; - selectbox.options.add(optn); - }, - - setBarPosition: function() { - $D('noVNC-control-bar').style.top = (window.pageYOffset) + 'px'; - $D('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px'; - - var vncwidth = $D('noVNC_screen').style.offsetWidth; - $D('noVNC-control-bar').style.width = vncwidth + 'px'; - } - - }; -})(); diff --git a/noVNC/include/util.js b/noVNC/include/util.js deleted file mode 100644 index 406adbe..0000000 --- a/noVNC/include/util.js +++ /dev/null @@ -1,631 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2012 Joel Martin - * Licensed under MPL 2.0 (see LICENSE.txt) - * - * See README.md for usage and integration instructions. - */ - -/* jshint white: false, nonstandard: true */ -/*global window, console, document, navigator, ActiveXObject, INCLUDE_URI */ - -// Globals defined here -var Util = {}; - - -/* - * Make arrays quack - */ - -var addFunc = function (cl, name, func) { - if (!cl.prototype[name]) { - Object.defineProperty(cl.prototype, name, { enumerable: false, value: func }); - } -}; - -addFunc(Array, 'push8', function (num) { - "use strict"; - this.push(num & 0xFF); -}); - -addFunc(Array, 'push16', function (num) { - "use strict"; - this.push((num >> 8) & 0xFF, - num & 0xFF); -}); - -addFunc(Array, 'push32', function (num) { - "use strict"; - this.push((num >> 24) & 0xFF, - (num >> 16) & 0xFF, - (num >> 8) & 0xFF, - num & 0xFF); -}); - -// IE does not support map (even in IE9) -//This prototype is provided by the Mozilla foundation and -//is distributed under the MIT license. -//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license -addFunc(Array, 'map', function (fun /*, thisp*/) { - "use strict"; - var len = this.length; - if (typeof fun != "function") { - throw new TypeError(); - } - - var res = new Array(len); - var thisp = arguments[1]; - for (var i = 0; i < len; i++) { - if (i in this) { - res[i] = fun.call(thisp, this[i], i, this); - } - } - - return res; -}); - -// IE <9 does not support indexOf -//This prototype is provided by the Mozilla foundation and -//is distributed under the MIT license. -//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license -addFunc(Array, 'indexOf', function (elt /*, from*/) { - "use strict"; - var len = this.length >>> 0; - - var from = Number(arguments[1]) || 0; - from = (from < 0) ? Math.ceil(from) : Math.floor(from); - if (from < 0) { - from += len; - } - - for (; from < len; from++) { - if (from in this && - this[from] === elt) { - return from; - } - } - return -1; -}); - -// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys -if (!Object.keys) { - Object.keys = (function () { - 'use strict'; - var hasOwnProperty = Object.prototype.hasOwnProperty, - hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), - dontEnums = [ - 'toString', - 'toLocaleString', - 'valueOf', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'constructor' - ], - dontEnumsLength = dontEnums.length; - - return function (obj) { - if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { - throw new TypeError('Object.keys called on non-object'); - } - - var result = [], prop, i; - - for (prop in obj) { - if (hasOwnProperty.call(obj, prop)) { - result.push(prop); - } - } - - if (hasDontEnumBug) { - for (i = 0; i < dontEnumsLength; i++) { - if (hasOwnProperty.call(obj, dontEnums[i])) { - result.push(dontEnums[i]); - } - } - } - return result; - }; - })(); -} - -// PhantomJS 1.x doesn't support bind, -// so leave this in until PhantomJS 2.0 is released -//This prototype is provided by the Mozilla foundation and -//is distributed under the MIT license. -//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license -addFunc(Function, 'bind', function (oThis) { - if (typeof this !== "function") { - // closest thing possible to the ECMAScript 5 - // internal IsCallable function - throw new TypeError("Function.prototype.bind - " + - "what is trying to be bound is not callable"); - } - - var aArgs = Array.prototype.slice.call(arguments, 1), - fToBind = this, - fNOP = function () {}, - fBound = function () { - return fToBind.apply(this instanceof fNOP && oThis ? this - : oThis, - aArgs.concat(Array.prototype.slice.call(arguments))); - }; - - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP(); - - return fBound; -}); - -// -// requestAnimationFrame shim with setTimeout fallback -// - -window.requestAnimFrame = (function () { - "use strict"; - return window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function (callback) { - window.setTimeout(callback, 1000 / 60); - }; -})(); - -/* - * ------------------------------------------------------ - * Namespaced in Util - * ------------------------------------------------------ - */ - -/* - * Logging/debug routines - */ - -Util._log_level = 'warn'; -Util.init_logging = function (level) { - "use strict"; - if (typeof level === 'undefined') { - level = Util._log_level; - } else { - Util._log_level = level; - } - if (typeof window.console === "undefined") { - if (typeof window.opera !== "undefined") { - window.console = { - 'log' : window.opera.postError, - 'warn' : window.opera.postError, - 'error': window.opera.postError - }; - } else { - window.console = { - 'log' : function (m) {}, - 'warn' : function (m) {}, - 'error': function (m) {} - }; - } - } - - Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {}; - /* jshint -W086 */ - switch (level) { - case 'debug': - Util.Debug = function (msg) { console.log(msg); }; - case 'info': - Util.Info = function (msg) { console.log(msg); }; - case 'warn': - Util.Warn = function (msg) { console.warn(msg); }; - case 'error': - Util.Error = function (msg) { console.error(msg); }; - case 'none': - break; - default: - throw new Error("invalid logging type '" + level + "'"); - } - /* jshint +W086 */ -}; -Util.get_logging = function () { - return Util._log_level; -}; -// Initialize logging level -Util.init_logging(); - -Util.make_property = function (proto, name, mode, type) { - "use strict"; - - var getter; - if (type === 'arr') { - getter = function (idx) { - if (typeof idx !== 'undefined') { - return this['_' + name][idx]; - } else { - return this['_' + name]; - } - }; - } else { - getter = function () { - return this['_' + name]; - }; - } - - var make_setter = function (process_val) { - if (process_val) { - return function (val, idx) { - if (typeof idx !== 'undefined') { - this['_' + name][idx] = process_val(val); - } else { - this['_' + name] = process_val(val); - } - }; - } else { - return function (val, idx) { - if (typeof idx !== 'undefined') { - this['_' + name][idx] = val; - } else { - this['_' + name] = val; - } - }; - } - }; - - var setter; - if (type === 'bool') { - setter = make_setter(function (val) { - if (!val || (val in {'0': 1, 'no': 1, 'false': 1})) { - return false; - } else { - return true; - } - }); - } else if (type === 'int') { - setter = make_setter(function (val) { return parseInt(val, 10); }); - } else if (type === 'float') { - setter = make_setter(parseFloat); - } else if (type === 'str') { - setter = make_setter(String); - } else if (type === 'func') { - setter = make_setter(function (val) { - if (!val) { - return function () {}; - } else { - return val; - } - }); - } else if (type === 'arr' || type === 'dom' || type == 'raw') { - setter = make_setter(); - } else { - throw new Error('Unknown property type ' + type); // some sanity checking - } - - // set the getter - if (typeof proto['get_' + name] === 'undefined') { - proto['get_' + name] = getter; - } - - // set the setter if needed - if (typeof proto['set_' + name] === 'undefined') { - if (mode === 'rw') { - proto['set_' + name] = setter; - } else if (mode === 'wo') { - proto['set_' + name] = function (val, idx) { - if (typeof this['_' + name] !== 'undefined') { - throw new Error(name + " can only be set once"); - } - setter.call(this, val, idx); - }; - } - } - - // make a special setter that we can use in set defaults - proto['_raw_set_' + name] = function (val, idx) { - setter.call(this, val, idx); - //delete this['_init_set_' + name]; // remove it after use - }; -}; - -Util.make_properties = function (constructor, arr) { - "use strict"; - for (var i = 0; i < arr.length; i++) { - Util.make_property(constructor.prototype, arr[i][0], arr[i][1], arr[i][2]); - } -}; - -Util.set_defaults = function (obj, conf, defaults) { - var defaults_keys = Object.keys(defaults); - var conf_keys = Object.keys(conf); - var keys_obj = {}; - var i; - for (i = 0; i < defaults_keys.length; i++) { keys_obj[defaults_keys[i]] = 1; } - for (i = 0; i < conf_keys.length; i++) { keys_obj[conf_keys[i]] = 1; } - var keys = Object.keys(keys_obj); - - for (i = 0; i < keys.length; i++) { - var setter = obj['_raw_set_' + keys[i]]; - if (!setter) { - Util.Warn('Invalid property ' + keys[i]); - continue; - } - - if (keys[i] in conf) { - setter.call(obj, conf[keys[i]]); - } else { - setter.call(obj, defaults[keys[i]]); - } - } -}; - -/* - * Decode from UTF-8 - */ -Util.decodeUTF8 = function (utf8string) { - "use strict"; - return decodeURIComponent(escape(utf8string)); -}; - - - -/* - * Cross-browser routines - */ - - -// Dynamically load scripts without using document.write() -// Reference: http://unixpapa.com/js/dyna.html -// -// Handles the case where load_scripts is invoked from a script that -// itself is loaded via load_scripts. Once all scripts are loaded the -// window.onscriptsloaded handler is called (if set). -Util.get_include_uri = function () { - return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI : "include/"; -}; -Util._loading_scripts = []; -Util._pending_scripts = []; -Util.load_scripts = function (files) { - "use strict"; - var head = document.getElementsByTagName('head')[0], script, - ls = Util._loading_scripts, ps = Util._pending_scripts; - - var loadFunc = function (e) { - while (ls.length > 0 && (ls[0].readyState === 'loaded' || - ls[0].readyState === 'complete')) { - // For IE, append the script to trigger execution - var s = ls.shift(); - //console.log("loaded script: " + s.src); - head.appendChild(s); - } - if (!this.readyState || - (Util.Engine.presto && this.readyState === 'loaded') || - this.readyState === 'complete') { - if (ps.indexOf(this) >= 0) { - this.onload = this.onreadystatechange = null; - //console.log("completed script: " + this.src); - ps.splice(ps.indexOf(this), 1); - - // Call window.onscriptsload after last script loads - if (ps.length === 0 && window.onscriptsload) { - window.onscriptsload(); - } - } - } - }; - - for (var f = 0; f < files.length; f++) { - script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = Util.get_include_uri() + files[f]; - //console.log("loading script: " + script.src); - script.onload = script.onreadystatechange = loadFunc; - // In-order script execution tricks - if (Util.Engine.trident) { - // For IE wait until readyState is 'loaded' before - // appending it which will trigger execution - // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order - ls.push(script); - } else { - // For webkit and firefox set async=false and append now - // https://developer.mozilla.org/en-US/docs/HTML/Element/script - script.async = false; - head.appendChild(script); - } - ps.push(script); - } -}; - - -Util.getPosition = function(obj) { - "use strict"; - // NB(sross): the Mozilla developer reference seems to indicate that - // getBoundingClientRect includes border and padding, so the canvas - // style should NOT include either. - var objPosition = obj.getBoundingClientRect(); - return {'x': objPosition.left + window.pageXOffset, 'y': objPosition.top + window.pageYOffset, - 'width': objPosition.width, 'height': objPosition.height}; -}; - - -// Get mouse event position in DOM element -Util.getEventPosition = function (e, obj, scale) { - "use strict"; - var evt, docX, docY, pos; - //if (!e) evt = window.event; - evt = (e ? e : window.event); - evt = (evt.changedTouches ? evt.changedTouches[0] : evt.touches ? evt.touches[0] : evt); - if (evt.pageX || evt.pageY) { - docX = evt.pageX; - docY = evt.pageY; - } else if (evt.clientX || evt.clientY) { - docX = evt.clientX + document.body.scrollLeft + - document.documentElement.scrollLeft; - docY = evt.clientY + document.body.scrollTop + - document.documentElement.scrollTop; - } - pos = Util.getPosition(obj); - if (typeof scale === "undefined") { - scale = 1; - } - var realx = docX - pos.x; - var realy = docY - pos.y; - var x = Math.max(Math.min(realx, pos.width - 1), 0); - var y = Math.max(Math.min(realy, pos.height - 1), 0); - - try{ - // Use my custom 'Scale' rate. - return {'x': x / Scale.x, 'y': y / Scale.y, 'realx': realx / Scale.x, 'realy': realy / Scale.y}; - } - catch(e){ - // If my custom 'Scale' is not defined, just use default 'scale'. - return {'x': x / scale, 'y': y / scale, 'realx': realx / scale, 'realy': realy / scale}; - } - -}; - - -// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events -Util.addEvent = function (obj, evType, fn) { - "use strict"; - if (obj.attachEvent) { - var r = obj.attachEvent("on" + evType, fn); - return r; - } else if (obj.addEventListener) { - obj.addEventListener(evType, fn, false); - return true; - } else { - throw new Error("Handler could not be attached"); - } -}; - -Util.removeEvent = function (obj, evType, fn) { - "use strict"; - if (obj.detachEvent) { - var r = obj.detachEvent("on" + evType, fn); - return r; - } else if (obj.removeEventListener) { - obj.removeEventListener(evType, fn, false); - return true; - } else { - throw new Error("Handler could not be removed"); - } -}; - -Util.stopEvent = function (e) { - "use strict"; - if (e.stopPropagation) { e.stopPropagation(); } - else { e.cancelBubble = true; } - - if (e.preventDefault) { e.preventDefault(); } - else { e.returnValue = false; } -}; - -Util._cursor_uris_supported = null; - -Util.browserSupportsCursorURIs = function () { - if (Util._cursor_uris_supported === null) { - try { - var target = document.createElement('canvas'); - target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default'; - - if (target.style.cursor) { - Util.Info("Data URI scheme cursor supported"); - Util._cursor_uris_supported = true; - } else { - Util.Warn("Data URI scheme cursor not supported"); - Util._cursor_uris_supported = false; - } - } catch (exc) { - Util.Error("Data URI scheme cursor test exception: " + exc); - Util._cursor_uris_supported = false; - } - } - - return Util._cursor_uris_supported; -}; - -// Set browser engine versions. Based on mootools. -Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}; - -(function () { - "use strict"; - // 'presto': (function () { return (!window.opera) ? false : true; }()), - var detectPresto = function () { - return !!window.opera; - }; - - // 'trident': (function () { return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); - var detectTrident = function () { - if (!window.ActiveXObject) { - return false; - } else { - if (window.XMLHttpRequest) { - return (document.querySelectorAll) ? 6 : 5; - } else { - return 4; - } - } - }; - - // 'webkit': (function () { try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()), - var detectInitialWebkit = function () { - try { - if (navigator.taintEnabled) { - return false; - } else { - if (Util.Features.xpath) { - return (Util.Features.query) ? 525 : 420; - } else { - return 419; - } - } - } catch (e) { - return false; - } - }; - - var detectActualWebkit = function (initial_ver) { - var re = /WebKit\/([0-9\.]*) /; - var str_ver = (navigator.userAgent.match(re) || ['', initial_ver])[1]; - return parseFloat(str_ver, 10); - }; - - // 'gecko': (function () { return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19ssName) ? 19 : 18 : 18); }()) - var detectGecko = function () { - /* jshint -W041 */ - if (!document.getBoxObjectFor && window.mozInnerScreenX == null) { - return false; - } else { - return (document.getElementsByClassName) ? 19 : 18; - } - /* jshint +W041 */ - }; - - Util.Engine = { - // Version detection break in Opera 11.60 (errors on arguments.callee.caller reference) - //'presto': (function() { - // return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()), - 'presto': detectPresto(), - 'trident': detectTrident(), - 'webkit': detectInitialWebkit(), - 'gecko': detectGecko(), - }; - - if (Util.Engine.webkit) { - // Extract actual webkit version if available - Util.Engine.webkit = detectActualWebkit(Util.Engine.webkit); - } -})(); - -Util.Flash = (function () { - "use strict"; - var v, version; - try { - v = navigator.plugins['Shockwave Flash'].description; - } catch (err1) { - try { - v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); - } catch (err2) { - v = '0 r0'; - } - } - version = v.match(/\d+/g); - return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; -}()); diff --git a/noVNC/include/web-socket-js/README.txt b/noVNC/include/web-socket-js/README.txt deleted file mode 100644 index 2e32ea7..0000000 --- a/noVNC/include/web-socket-js/README.txt +++ /dev/null @@ -1,109 +0,0 @@ -* How to try - -Assuming you have Web server (e.g. Apache) running at http://example.com/ . - -- Download web_socket.rb from: - http://github.com/gimite/web-socket-ruby/tree/master -- Run sample Web Socket server (echo server) in example.com with: (#1) - $ ruby web-socket-ruby/samples/echo_server.rb example.com 10081 -- If your server already provides socket policy file at port 843, modify the file to allow access to port 10081. Otherwise you can skip this step. See below for details. -- Publish the web-socket-js directory with your Web server (e.g. put it in ~/public_html). -- Change ws://localhost:10081 to ws://example.com:10081 in sample.html. -- Open sample.html in your browser. -- After "onopen" is shown, input something, click [Send] and confirm echo back. - -#1: First argument of echo_server.rb means that it accepts Web Socket connection from HTML pages in example.com. - - -* Troubleshooting - -If it doesn't work, try these: - -1. Try Chrome and Firefox 3.x. -- It doesn't work on Chrome: --- It's likely an issue of your code or the server. Debug your code as usual e.g. using console.log. -- It works on Chrome but it doesn't work on Firefox: --- It's likely an issue of web-socket-js specific configuration (e.g. 3 and 4 below). -- It works on both Chrome and Firefox, but it doesn't work on your browser: --- Check "Supported environment" section below. Your browser may not be supported by web-socket-js. - -2. Add this line before your code: - WEB_SOCKET_DEBUG = true; -and use Developer Tools (Chrome/Safari) or Firebug (Firefox) to see if console.log outputs any errors. - -3. Make sure you do NOT open your HTML page as local file e.g. file:///.../sample.html. web-socket-js doesn't work on local file. Open it via Web server e.g. http:///.../sample.html. - -4. If you are NOT using web-socket-ruby as your WebSocket server, you need to place Flash socket policy file on your server. See "Flash socket policy file" section below for details. - -5. Check if sample.html bundled with web-socket-js works. - -6. Make sure the port used for WebSocket (10081 in example above) is not blocked by your server/client's firewall. - -7. Install debugger version of Flash Player available here to see Flash errors: -http://www.adobe.com/support/flashplayer/downloads.html - - -* Supported environments - -It should work on: -- Google Chrome 4 or later (just uses native implementation) -- Firefox 3.x, Internet Explorer 8 + Flash Player 9 or later - -It may or may not work on other browsers such as Safari, Opera or IE 6. Patch for these browsers are appreciated, but I will not work on fixing issues specific to these browsers by myself. - - -* Flash socket policy file - -This implementation uses Flash's socket, which means that your server must provide Flash socket policy file to declare the server accepts connections from Flash. - -If you use web-socket-ruby available at -http://github.com/gimite/web-socket-ruby/tree/master -, you don't need anything special, because web-socket-ruby handles Flash socket policy file request. But if you already provide socket policy file at port 843, you need to modify the file to allow access to Web Socket port, because it precedes what web-socket-ruby provides. - -If you use other Web Socket server implementation, you need to provide socket policy file yourself. See -http://www.lightsphere.com/dev/articles/flash_socket_policy.html -for details and sample script to run socket policy file server. node.js implementation is available here: -http://github.com/LearnBoost/Socket.IO-node/blob/master/lib/socket.io/transports/flashsocket.js - -Actually, it's still better to provide socket policy file at port 843 even if you use web-socket-ruby. Flash always try to connect to port 843 first, so providing the file at port 843 makes startup faster. - - -* Cookie considerations - -Cookie is sent if Web Socket host is the same as the origin of JavaScript. Otherwise it is not sent, because I don't know way to send right Cookie (which is Cookie of the host of Web Socket, I heard). - -Note that it's technically possible that client sends arbitrary string as Cookie and any other headers (by modifying this library for example) once you place Flash socket policy file in your server. So don't trust Cookie and other headers if you allow connection from untrusted origin. - - -* Proxy considerations - -The WebSocket spec (http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol) specifies instructions for User Agents to support proxied connections by implementing the HTTP CONNECT method. - -The AS3 Socket class doesn't implement this mechanism, which renders it useless for the scenarios where the user trying to open a socket is behind a proxy. - -The class RFC2817Socket (by Christian Cantrell) effectively lets us implement this, as long as the proxy settings are known and provided by the interface that instantiates the WebSocket. As such, if you want to support proxied conncetions, you'll have to supply this information to the WebSocket constructor when Flash is being used. One way to go about it would be to ask the user for proxy settings information if the initial connection fails. - - -* How to host HTML file and SWF file in different domains - -By default, HTML file and SWF file must be in the same domain. You can follow steps below to allow hosting them in different domain. - -WARNING: If you use the method below, HTML files in ANY domains can send arbitrary TCP data to your WebSocket server, regardless of configuration in Flash socket policy file. Arbitrary TCP data means that they can even fake request headers including Origin and Cookie. - -- Unzip WebSocketMainInsecure.zip to extract WebSocketMainInsecure.swf. -- Put WebSocketMainInsecure.swf on your server, instead of WebSocketMain.swf. -- In JavaScript, set WEB_SOCKET_SWF_LOCATION to URL of your WebSocketMainInsecure.swf. - - -* How to build WebSocketMain.swf - -Install Flex 4 SDK: -http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4 - -$ cd flash-src -$ ./build.sh - - -* License - -New BSD License. diff --git a/noVNC/include/web-socket-js/WebSocketMain.swf b/noVNC/include/web-socket-js/WebSocketMain.swf deleted file mode 100644 index f286c81..0000000 Binary files a/noVNC/include/web-socket-js/WebSocketMain.swf and /dev/null differ diff --git a/noVNC/include/web-socket-js/swfobject.js b/noVNC/include/web-socket-js/swfobject.js deleted file mode 100644 index 8eafe9d..0000000 --- a/noVNC/include/web-socket-js/swfobject.js +++ /dev/null @@ -1,4 +0,0 @@ -/* SWFObject v2.2 - is released under the MIT License -*/ -var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab -// License: New BSD License -// Reference: http://dev.w3.org/html5/websockets/ -// Reference: http://tools.ietf.org/html/rfc6455 - -(function() { - - if (window.WEB_SOCKET_FORCE_FLASH) { - // Keeps going. - } else if (window.WebSocket) { - return; - } else if (window.MozWebSocket) { - // Firefox. - window.WebSocket = MozWebSocket; - return; - } - - var logger; - if (window.WEB_SOCKET_LOGGER) { - logger = WEB_SOCKET_LOGGER; - } else if (window.console && window.console.log && window.console.error) { - // In some environment, console is defined but console.log or console.error is missing. - logger = window.console; - } else { - logger = {log: function(){ }, error: function(){ }}; - } - - // swfobject.hasFlashPlayerVersion("10.0.0") doesn't work with Gnash. - if (swfobject.getFlashPlayerVersion().major < 10) { - logger.error("Flash Player >= 10.0.0 is required."); - return; - } - if (location.protocol == "file:") { - logger.error( - "WARNING: web-socket-js doesn't work in file:///... URL " + - "unless you set Flash Security Settings properly. " + - "Open the page via Web server i.e. http://..."); - } - - /** - * Our own implementation of WebSocket class using Flash. - * @param {string} url - * @param {array or string} protocols - * @param {string} proxyHost - * @param {int} proxyPort - * @param {string} headers - */ - window.WebSocket = function(url, protocols, proxyHost, proxyPort, headers) { - var self = this; - self.__id = WebSocket.__nextId++; - WebSocket.__instances[self.__id] = self; - self.readyState = WebSocket.CONNECTING; - self.bufferedAmount = 0; - self.__events = {}; - if (!protocols) { - protocols = []; - } else if (typeof protocols == "string") { - protocols = [protocols]; - } - // Uses setTimeout() to make sure __createFlash() runs after the caller sets ws.onopen etc. - // Otherwise, when onopen fires immediately, onopen is called before it is set. - self.__createTask = setTimeout(function() { - WebSocket.__addTask(function() { - self.__createTask = null; - WebSocket.__flash.create( - self.__id, url, protocols, proxyHost || null, proxyPort || 0, headers || null); - }); - }, 0); - }; - - /** - * Send data to the web socket. - * @param {string} data The data to send to the socket. - * @return {boolean} True for success, false for failure. - */ - WebSocket.prototype.send = function(data) { - if (this.readyState == WebSocket.CONNECTING) { - throw "INVALID_STATE_ERR: Web Socket connection has not been established"; - } - // We use encodeURIComponent() here, because FABridge doesn't work if - // the argument includes some characters. We don't use escape() here - // because of this: - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Functions#escape_and_unescape_Functions - // But it looks decodeURIComponent(encodeURIComponent(s)) doesn't - // preserve all Unicode characters either e.g. "\uffff" in Firefox. - // Note by wtritch: Hopefully this will not be necessary using ExternalInterface. Will require - // additional testing. - var result = WebSocket.__flash.send(this.__id, encodeURIComponent(data)); - if (result < 0) { // success - return true; - } else { - this.bufferedAmount += result; - return false; - } - }; - - /** - * Close this web socket gracefully. - */ - WebSocket.prototype.close = function() { - if (this.__createTask) { - clearTimeout(this.__createTask); - this.__createTask = null; - this.readyState = WebSocket.CLOSED; - return; - } - if (this.readyState == WebSocket.CLOSED || this.readyState == WebSocket.CLOSING) { - return; - } - this.readyState = WebSocket.CLOSING; - WebSocket.__flash.close(this.__id); - }; - - /** - * Implementation of {@link DOM 2 EventTarget Interface} - * - * @param {string} type - * @param {function} listener - * @param {boolean} useCapture - * @return void - */ - WebSocket.prototype.addEventListener = function(type, listener, useCapture) { - if (!(type in this.__events)) { - this.__events[type] = []; - } - this.__events[type].push(listener); - }; - - /** - * Implementation of {@link DOM 2 EventTarget Interface} - * - * @param {string} type - * @param {function} listener - * @param {boolean} useCapture - * @return void - */ - WebSocket.prototype.removeEventListener = function(type, listener, useCapture) { - if (!(type in this.__events)) return; - var events = this.__events[type]; - for (var i = events.length - 1; i >= 0; --i) { - if (events[i] === listener) { - events.splice(i, 1); - break; - } - } - }; - - /** - * Implementation of {@link DOM 2 EventTarget Interface} - * - * @param {Event} event - * @return void - */ - WebSocket.prototype.dispatchEvent = function(event) { - var events = this.__events[event.type] || []; - for (var i = 0; i < events.length; ++i) { - events[i](event); - } - var handler = this["on" + event.type]; - if (handler) handler.apply(this, [event]); - }; - - /** - * Handles an event from Flash. - * @param {Object} flashEvent - */ - WebSocket.prototype.__handleEvent = function(flashEvent) { - - if ("readyState" in flashEvent) { - this.readyState = flashEvent.readyState; - } - if ("protocol" in flashEvent) { - this.protocol = flashEvent.protocol; - } - - var jsEvent; - if (flashEvent.type == "open" || flashEvent.type == "error") { - jsEvent = this.__createSimpleEvent(flashEvent.type); - } else if (flashEvent.type == "close") { - jsEvent = this.__createSimpleEvent("close"); - jsEvent.wasClean = flashEvent.wasClean ? true : false; - jsEvent.code = flashEvent.code; - jsEvent.reason = flashEvent.reason; - } else if (flashEvent.type == "message") { - var data = decodeURIComponent(flashEvent.message); - jsEvent = this.__createMessageEvent("message", data); - } else { - throw "unknown event type: " + flashEvent.type; - } - - this.dispatchEvent(jsEvent); - - }; - - WebSocket.prototype.__createSimpleEvent = function(type) { - if (document.createEvent && window.Event) { - var event = document.createEvent("Event"); - event.initEvent(type, false, false); - return event; - } else { - return {type: type, bubbles: false, cancelable: false}; - } - }; - - WebSocket.prototype.__createMessageEvent = function(type, data) { - if (document.createEvent && window.MessageEvent && !window.opera) { - var event = document.createEvent("MessageEvent"); - event.initMessageEvent("message", false, false, data, null, null, window, null); - return event; - } else { - // IE and Opera, the latter one truncates the data parameter after any 0x00 bytes. - return {type: type, data: data, bubbles: false, cancelable: false}; - } - }; - - /** - * Define the WebSocket readyState enumeration. - */ - WebSocket.CONNECTING = 0; - WebSocket.OPEN = 1; - WebSocket.CLOSING = 2; - WebSocket.CLOSED = 3; - - // Field to check implementation of WebSocket. - WebSocket.__isFlashImplementation = true; - WebSocket.__initialized = false; - WebSocket.__flash = null; - WebSocket.__instances = {}; - WebSocket.__tasks = []; - WebSocket.__nextId = 0; - - /** - * Load a new flash security policy file. - * @param {string} url - */ - WebSocket.loadFlashPolicyFile = function(url){ - WebSocket.__addTask(function() { - WebSocket.__flash.loadManualPolicyFile(url); - }); - }; - - /** - * Loads WebSocketMain.swf and creates WebSocketMain object in Flash. - */ - WebSocket.__initialize = function() { - - if (WebSocket.__initialized) return; - WebSocket.__initialized = true; - - if (WebSocket.__swfLocation) { - // For backword compatibility. - window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation; - } - if (!window.WEB_SOCKET_SWF_LOCATION) { - logger.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf"); - return; - } - if (!window.WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR && - !WEB_SOCKET_SWF_LOCATION.match(/(^|\/)WebSocketMainInsecure\.swf(\?.*)?$/) && - WEB_SOCKET_SWF_LOCATION.match(/^\w+:\/\/([^\/]+)/)) { - var swfHost = RegExp.$1; - if (location.host != swfHost) { - logger.error( - "[WebSocket] You must host HTML and WebSocketMain.swf in the same host " + - "('" + location.host + "' != '" + swfHost + "'). " + - "See also 'How to host HTML file and SWF file in different domains' section " + - "in README.md. If you use WebSocketMainInsecure.swf, you can suppress this message " + - "by WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR = true;"); - } - } - var container = document.createElement("div"); - container.id = "webSocketContainer"; - // Hides Flash box. We cannot use display: none or visibility: hidden because it prevents - // Flash from loading at least in IE. So we move it out of the screen at (-100, -100). - // But this even doesn't work with Flash Lite (e.g. in Droid Incredible). So with Flash - // Lite, we put it at (0, 0). This shows 1x1 box visible at left-top corner but this is - // the best we can do as far as we know now. - container.style.position = "absolute"; - if (WebSocket.__isFlashLite()) { - container.style.left = "0px"; - container.style.top = "0px"; - } else { - container.style.left = "-100px"; - container.style.top = "-100px"; - } - var holder = document.createElement("div"); - holder.id = "webSocketFlash"; - container.appendChild(holder); - document.body.appendChild(container); - // See this article for hasPriority: - // http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html - swfobject.embedSWF( - WEB_SOCKET_SWF_LOCATION, - "webSocketFlash", - "1" /* width */, - "1" /* height */, - "10.0.0" /* SWF version */, - null, - null, - {hasPriority: true, swliveconnect : true, allowScriptAccess: "always"}, - null, - function(e) { - if (!e.success) { - logger.error("[WebSocket] swfobject.embedSWF failed"); - } - } - ); - - }; - - /** - * Called by Flash to notify JS that it's fully loaded and ready - * for communication. - */ - WebSocket.__onFlashInitialized = function() { - // We need to set a timeout here to avoid round-trip calls - // to flash during the initialization process. - setTimeout(function() { - WebSocket.__flash = document.getElementById("webSocketFlash"); - WebSocket.__flash.setCallerUrl(location.href); - WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG); - for (var i = 0; i < WebSocket.__tasks.length; ++i) { - WebSocket.__tasks[i](); - } - WebSocket.__tasks = []; - }, 0); - }; - - /** - * Called by Flash to notify WebSockets events are fired. - */ - WebSocket.__onFlashEvent = function() { - setTimeout(function() { - try { - // Gets events using receiveEvents() instead of getting it from event object - // of Flash event. This is to make sure to keep message order. - // It seems sometimes Flash events don't arrive in the same order as they are sent. - var events = WebSocket.__flash.receiveEvents(); - for (var i = 0; i < events.length; ++i) { - WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]); - } - } catch (e) { - logger.error(e); - } - }, 0); - return true; - }; - - // Called by Flash. - WebSocket.__log = function(message) { - logger.log(decodeURIComponent(message)); - }; - - // Called by Flash. - WebSocket.__error = function(message) { - logger.error(decodeURIComponent(message)); - }; - - WebSocket.__addTask = function(task) { - if (WebSocket.__flash) { - task(); - } else { - WebSocket.__tasks.push(task); - } - }; - - /** - * Test if the browser is running flash lite. - * @return {boolean} True if flash lite is running, false otherwise. - */ - WebSocket.__isFlashLite = function() { - if (!window.navigator || !window.navigator.mimeTypes) { - return false; - } - var mimeType = window.navigator.mimeTypes["application/x-shockwave-flash"]; - if (!mimeType || !mimeType.enabledPlugin || !mimeType.enabledPlugin.filename) { - return false; - } - return mimeType.enabledPlugin.filename.match(/flashlite/i) ? true : false; - }; - - if (!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION) { - // NOTE: - // This fires immediately if web_socket.js is dynamically loaded after - // the document is loaded. - swfobject.addDomLoadEvent(function() { - WebSocket.__initialize(); - }); - } - -})(); diff --git a/noVNC/index.html b/noVNC/index.html deleted file mode 100644 index 8efdfb1..0000000 --- a/noVNC/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Page Redirection - - - - If you are not redirected automatically, follow the link to example - - diff --git a/noVNC/karma.conf.js b/noVNC/karma.conf.js index d8b8e90..5f3c20b 100644 --- a/noVNC/karma.conf.js +++ b/noVNC/karma.conf.js @@ -110,18 +110,19 @@ module.exports = function(config) { files: [ 'tests/fake.*.js', 'tests/assertions.js', - 'include/util.js', // load first to avoid issues, since methods are called immediately - //'../include/*.js', - 'include/base64.js', - 'include/keysym.js', - 'include/keysymdef.js', - 'include/keyboard.js', - 'include/input.js', - 'include/websock.js', - 'include/rfb.js', - 'include/jsunzip.js', - 'include/des.js', - 'include/display.js', + 'core/util.js', // load first to avoid issues, since methods are called immediately + //'../core/*.js', + 'core/base64.js', + 'core/input/keysym.js', + 'core/input/keysymdef.js', + 'core/input/xtscancodes.js', + 'core/input/util.js', + 'core/input/devices.js', + 'core/websock.js', + 'core/rfb.js', + 'core/des.js', + 'core/display.js', + 'core/inflator.js', 'tests/test.*.js' ], @@ -133,8 +134,8 @@ module.exports = function(config) { // list of files to exclude exclude: [ - '../include/playback.js', - '../include/ui.js' + '../tests/playback.js', + '../app/ui.js' ], customLaunchers: customLaunchers, diff --git a/noVNC/media/css/bootstrap-responsive.css b/noVNC/media/css/bootstrap-responsive.css deleted file mode 100755 index 9053414..0000000 --- a/noVNC/media/css/bootstrap-responsive.css +++ /dev/null @@ -1,1090 +0,0 @@ -/*! - * Bootstrap Responsive v2.2.2 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ - -@-ms-viewport { - width: device-width; -} - -.clearfix { - *zoom: 1; -} - -.clearfix:before, -.clearfix:after { - display: table; - line-height: 0; - content: ""; -} - -.clearfix:after { - clear: both; -} - -.hide-text { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - -.input-block-level { - display: block; - width: 100%; - min-height: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.hidden { - display: none; - visibility: hidden; -} - -.visible-phone { - display: none !important; -} - -.visible-tablet { - display: none !important; -} - -.hidden-desktop { - display: none !important; -} - -.visible-desktop { - display: inherit !important; -} - -@media (min-width: 768px) and (max-width: 979px) { - .hidden-desktop { - display: inherit !important; - } - .visible-desktop { - display: none !important ; - } - .visible-tablet { - display: inherit !important; - } - .hidden-tablet { - display: none !important; - } -} - -@media (max-width: 767px) { - .hidden-desktop { - display: inherit !important; - } - .visible-desktop { - display: none !important; - } - .visible-phone { - display: inherit !important; - } - .hidden-phone { - display: none !important; - } -} - -@media (min-width: 980px) { - .row { - margin-left: 0px; - *zoom: 1; - } - .row:before, - .row:after { - display: table; - line-height: 0; - content: ""; - } - .row:after { - clear: both; - } - [class*="span"] { - float: left; - min-height: 1px; - margin-left: 30px; - } - .container, - .navbar-static-top .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - width: 1020px; - } - .span12 { - width: 1170px; - } - .span11 { - width: 1070px; - } - .span10 { - width: 970px; - } - .span9 { - width: 870px; - } - .span8 { - width: 770px; - } - .span7 { - width: 670px; - } - .span6 { - width: 570px; - } - .span5 { - width: 470px; - } - .span4 { - width: 370px; - } - .span3 { - width: 270px; - } - .span2 { - width: 170px; - } - .span1 { - width: 70px; - } - .offset12 { - margin-left: 1230px; - } - .offset11 { - margin-left: 1130px; - } - .offset10 { - margin-left: 1030px; - } - .offset9 { - margin-left: 930px; - } - .offset8 { - margin-left: 830px; - } - .offset7 { - margin-left: 730px; - } - .offset6 { - margin-left: 630px; - } - .offset5 { - margin-left: 530px; - } - .offset4 { - margin-left: 430px; - } - .offset3 { - margin-left: 330px; - } - .offset2 { - margin-left: 230px; - } - .offset1 { - margin-left: 130px; - } - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - line-height: 0; - content: ""; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - float: left; - width: 100%; - min-height: 30px; - margin-left: 2.564102564102564%; - *margin-left: 2.5109110747408616%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.564102564102564%; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851063829%; - } - .row-fluid .span11 { - width: 91.45299145299145%; - *width: 91.39979996362975%; - } - .row-fluid .span10 { - width: 82.90598290598291%; - *width: 82.8527914166212%; - } - .row-fluid .span9 { - width: 74.35897435897436%; - *width: 74.30578286961266%; - } - .row-fluid .span8 { - width: 65.81196581196582%; - *width: 65.75877432260411%; - } - .row-fluid .span7 { - width: 57.26495726495726%; - *width: 57.21176577559556%; - } - .row-fluid .span6 { - width: 48.717948717948715%; - *width: 48.664757228587014%; - } - .row-fluid .span5 { - width: 40.17094017094017%; - *width: 40.11774868157847%; - } - .row-fluid .span4 { - width: 31.623931623931625%; - *width: 31.570740134569924%; - } - .row-fluid .span3 { - width: 23.076923076923077%; - *width: 23.023731587561375%; - } - .row-fluid .span2 { - width: 14.52991452991453%; - *width: 14.476723040552828%; - } - .row-fluid .span1 { - width: 5.982905982905983%; - *width: 5.929714493544281%; - } - .row-fluid .offset12 { - margin-left: 105.12820512820512%; - *margin-left: 105.02182214948171%; - } - .row-fluid .offset12:first-child { - margin-left: 102.56410256410257%; - *margin-left: 102.45771958537915%; - } - .row-fluid .offset11 { - margin-left: 96.58119658119658%; - *margin-left: 96.47481360247316%; - } - .row-fluid .offset11:first-child { - margin-left: 94.01709401709402%; - *margin-left: 93.91071103837061%; - } - .row-fluid .offset10 { - margin-left: 88.03418803418803%; - *margin-left: 87.92780505546462%; - } - .row-fluid .offset10:first-child { - margin-left: 85.47008547008548%; - *margin-left: 85.36370249136206%; - } - .row-fluid .offset9 { - margin-left: 79.48717948717949%; - *margin-left: 79.38079650845607%; - } - .row-fluid .offset9:first-child { - margin-left: 76.92307692307693%; - *margin-left: 76.81669394435352%; - } - .row-fluid .offset8 { - margin-left: 70.94017094017094%; - *margin-left: 70.83378796144753%; - } - .row-fluid .offset8:first-child { - margin-left: 68.37606837606839%; - *margin-left: 68.26968539734497%; - } - .row-fluid .offset7 { - margin-left: 62.393162393162385%; - *margin-left: 62.28677941443899%; - } - .row-fluid .offset7:first-child { - margin-left: 59.82905982905982%; - *margin-left: 59.72267685033642%; - } - .row-fluid .offset6 { - margin-left: 53.84615384615384%; - *margin-left: 53.739770867430444%; - } - .row-fluid .offset6:first-child { - margin-left: 51.28205128205128%; - *margin-left: 51.175668303327875%; - } - .row-fluid .offset5 { - margin-left: 45.299145299145295%; - *margin-left: 45.1927623204219%; - } - .row-fluid .offset5:first-child { - margin-left: 42.73504273504273%; - *margin-left: 42.62865975631933%; - } - .row-fluid .offset4 { - margin-left: 36.75213675213675%; - *margin-left: 36.645753773413354%; - } - .row-fluid .offset4:first-child { - margin-left: 34.18803418803419%; - *margin-left: 34.081651209310785%; - } - .row-fluid .offset3 { - margin-left: 28.205128205128204%; - *margin-left: 28.0987452264048%; - } - .row-fluid .offset3:first-child { - margin-left: 25.641025641025642%; - *margin-left: 25.53464266230224%; - } - .row-fluid .offset2 { - margin-left: 19.65811965811966%; - *margin-left: 19.551736679396257%; - } - .row-fluid .offset2:first-child { - margin-left: 17.094017094017094%; - *margin-left: 16.98763411529369%; - } - .row-fluid .offset1 { - margin-left: 11.11111111111111%; - *margin-left: 11.004728132387708%; - } - .row-fluid .offset1:first-child { - margin-left: 8.547008547008547%; - *margin-left: 8.440625568285142%; - } - input, - textarea, - .uneditable-input { - margin-left: 0; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 30px; - } - input.span12, - textarea.span12, - .uneditable-input.span12 { - width: 1156px; - } - input.span11, - textarea.span11, - .uneditable-input.span11 { - width: 1056px; - } - input.span10, - textarea.span10, - .uneditable-input.span10 { - width: 956px; - } - input.span9, - textarea.span9, - .uneditable-input.span9 { - width: 856px; - } - input.span8, - textarea.span8, - .uneditable-input.span8 { - width: 756px; - } - input.span7, - textarea.span7, - .uneditable-input.span7 { - width: 656px; - } - input.span6, - textarea.span6, - .uneditable-input.span6 { - width: 556px; - } - input.span5, - textarea.span5, - .uneditable-input.span5 { - width: 456px; - } - input.span4, - textarea.span4, - .uneditable-input.span4 { - width: 356px; - } - input.span3, - textarea.span3, - .uneditable-input.span3 { - width: 256px; - } - input.span2, - textarea.span2, - .uneditable-input.span2 { - width: 156px; - } - input.span1, - textarea.span1, - .uneditable-input.span1 { - width: 56px; - } - .thumbnails { - margin-left: -30px; - } - .thumbnails > li { - margin-left: 30px; - } - .row-fluid .thumbnails { - margin-left: 0; - } -} - -@media (min-width: 768px) and (max-width: 979px) { - .row { - margin-left: -20px; - *zoom: 1; - } - .row:before, - .row:after { - display: table; - line-height: 0; - content: ""; - } - .row:after { - clear: both; - } - [class*="span"] { - float: left; - min-height: 1px; - margin-left: 20px; - } - .container, - .navbar-static-top .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - width: 724px; - } - .span12 { - width: 724px; - } - .span11 { - width: 662px; - } - .span10 { - width: 600px; - } - .span9 { - width: 538px; - } - .span8 { - width: 476px; - } - .span7 { - width: 414px; - } - .span6 { - width: 352px; - } - .span5 { - width: 290px; - } - .span4 { - width: 228px; - } - .span3 { - width: 166px; - } - .span2 { - width: 104px; - } - .span1 { - width: 42px; - } - .offset12 { - margin-left: 764px; - } - .offset11 { - margin-left: 702px; - } - .offset10 { - margin-left: 640px; - } - .offset9 { - margin-left: 578px; - } - .offset8 { - margin-left: 516px; - } - .offset7 { - margin-left: 454px; - } - .offset6 { - margin-left: 392px; - } - .offset5 { - margin-left: 330px; - } - .offset4 { - margin-left: 268px; - } - .offset3 { - margin-left: 206px; - } - .offset2 { - margin-left: 144px; - } - .offset1 { - margin-left: 82px; - } - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - line-height: 0; - content: ""; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - float: left; - width: 100%; - min-height: 30px; - margin-left: 2.7624309392265194%; - *margin-left: 2.709239449864817%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.7624309392265194%; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851063829%; - } - .row-fluid .span11 { - width: 91.43646408839778%; - *width: 91.38327259903608%; - } - .row-fluid .span10 { - width: 82.87292817679558%; - *width: 82.81973668743387%; - } - .row-fluid .span9 { - width: 74.30939226519337%; - *width: 74.25620077583166%; - } - .row-fluid .span8 { - width: 65.74585635359117%; - *width: 65.69266486422946%; - } - .row-fluid .span7 { - width: 57.18232044198895%; - *width: 57.12912895262725%; - } - .row-fluid .span6 { - width: 48.61878453038674%; - *width: 48.56559304102504%; - } - .row-fluid .span5 { - width: 40.05524861878453%; - *width: 40.00205712942283%; - } - .row-fluid .span4 { - width: 31.491712707182323%; - *width: 31.43852121782062%; - } - .row-fluid .span3 { - width: 22.92817679558011%; - *width: 22.87498530621841%; - } - .row-fluid .span2 { - width: 14.3646408839779%; - *width: 14.311449394616199%; - } - .row-fluid .span1 { - width: 5.801104972375691%; - *width: 5.747913483013988%; - } - .row-fluid .offset12 { - margin-left: 105.52486187845304%; - *margin-left: 105.41847889972962%; - } - .row-fluid .offset12:first-child { - margin-left: 102.76243093922652%; - *margin-left: 102.6560479605031%; - } - .row-fluid .offset11 { - margin-left: 96.96132596685082%; - *margin-left: 96.8549429881274%; - } - .row-fluid .offset11:first-child { - margin-left: 94.1988950276243%; - *margin-left: 94.09251204890089%; - } - .row-fluid .offset10 { - margin-left: 88.39779005524862%; - *margin-left: 88.2914070765252%; - } - .row-fluid .offset10:first-child { - margin-left: 85.6353591160221%; - *margin-left: 85.52897613729868%; - } - .row-fluid .offset9 { - margin-left: 79.8342541436464%; - *margin-left: 79.72787116492299%; - } - .row-fluid .offset9:first-child { - margin-left: 77.07182320441989%; - *margin-left: 76.96544022569647%; - } - .row-fluid .offset8 { - margin-left: 71.2707182320442%; - *margin-left: 71.16433525332079%; - } - .row-fluid .offset8:first-child { - margin-left: 68.50828729281768%; - *margin-left: 68.40190431409427%; - } - .row-fluid .offset7 { - margin-left: 62.70718232044199%; - *margin-left: 62.600799341718584%; - } - .row-fluid .offset7:first-child { - margin-left: 59.94475138121547%; - *margin-left: 59.838368402492065%; - } - .row-fluid .offset6 { - margin-left: 54.14364640883978%; - *margin-left: 54.037263430116376%; - } - .row-fluid .offset6:first-child { - margin-left: 51.38121546961326%; - *margin-left: 51.27483249088986%; - } - .row-fluid .offset5 { - margin-left: 45.58011049723757%; - *margin-left: 45.47372751851417%; - } - .row-fluid .offset5:first-child { - margin-left: 42.81767955801105%; - *margin-left: 42.71129657928765%; - } - .row-fluid .offset4 { - margin-left: 37.01657458563536%; - *margin-left: 36.91019160691196%; - } - .row-fluid .offset4:first-child { - margin-left: 34.25414364640884%; - *margin-left: 34.14776066768544%; - } - .row-fluid .offset3 { - margin-left: 28.45303867403315%; - *margin-left: 28.346655695309746%; - } - .row-fluid .offset3:first-child { - margin-left: 25.69060773480663%; - *margin-left: 25.584224756083227%; - } - .row-fluid .offset2 { - margin-left: 19.88950276243094%; - *margin-left: 19.783119783707537%; - } - .row-fluid .offset2:first-child { - margin-left: 17.12707182320442%; - *margin-left: 17.02068884448102%; - } - .row-fluid .offset1 { - margin-left: 11.32596685082873%; - *margin-left: 11.219583872105325%; - } - .row-fluid .offset1:first-child { - margin-left: 8.56353591160221%; - *margin-left: 8.457152932878806%; - } - input, - textarea, - .uneditable-input { - margin-left: 0; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 20px; - } - input.span12, - textarea.span12, - .uneditable-input.span12 { - width: 710px; - } - input.span11, - textarea.span11, - .uneditable-input.span11 { - width: 648px; - } - input.span10, - textarea.span10, - .uneditable-input.span10 { - width: 586px; - } - input.span9, - textarea.span9, - .uneditable-input.span9 { - width: 524px; - } - input.span8, - textarea.span8, - .uneditable-input.span8 { - width: 462px; - } - input.span7, - textarea.span7, - .uneditable-input.span7 { - width: 400px; - } - input.span6, - textarea.span6, - .uneditable-input.span6 { - width: 338px; - } - input.span5, - textarea.span5, - .uneditable-input.span5 { - width: 276px; - } - input.span4, - textarea.span4, - .uneditable-input.span4 { - width: 214px; - } - input.span3, - textarea.span3, - .uneditable-input.span3 { - width: 152px; - } - input.span2, - textarea.span2, - .uneditable-input.span2 { - width: 90px; - } - input.span1, - textarea.span1, - .uneditable-input.span1 { - width: 28px; - } -} - -@media (min-width: 900px) { - body { - padding-right: 0px; - padding-left: 0px; - } - .navbar-fixed-top, - .navbar-fixed-bottom, - .navbar-static-top { - margin-right: -20px; - margin-left: -20px; - } - .container-fluid { - padding: 0; - } - .dl-horizontal dt { - float: none; - width: auto; - clear: none; - text-align: left; - } - .dl-horizontal dd { - margin-left: 0; - } - .container { - width: auto; - } - .row-fluid { - width: 100%; - } - .row, - .thumbnails { - margin-left: 0; - } - .thumbnails > li { - float: none; - margin-left: 0; - } - [class*="span"], - .uneditable-input[class*="span"], - .row-fluid [class*="span"] { - display: block; - float: none; - width: 100%; - margin-left: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .span12, - .row-fluid .span12 { - width: 100%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .row-fluid [class*="offset"]:first-child { - margin-left: 0; - } - .input-large, - .input-xlarge, - .input-xxlarge, - input[class*="span"], - select[class*="span"], - textarea[class*="span"], - .uneditable-input { - display: block; - min-height: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .input-prepend input, - .input-append input, - .input-prepend input[class*="span"], - .input-append input[class*="span"] { - display: inline-block; - width: auto; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 1px; - } - .modal { - position: fixed; - top: 20px; - right: 0; - left: 0; - margin: 0 auto; - } - .modal.fade { - top: -100px; - } - .modal.fade.in { - top: 20px; - } -} - -@media (max-width: 480px) { - .nav-collapse { - -webkit-transform: translate3d(0, 0, 0); - } - .page-header h1 small { - display: block; - line-height: 20px; - } - input[type="checkbox"], - input[type="radio"] { - border: 1px solid #ccc; - } - .form-horizontal .control-label { - float: none; - width: auto; - padding-top: 0; - text-align: left; - } - .form-horizontal .controls { - margin-left: 0; - } - .form-horizontal .control-list { - padding-top: 0; - } - .form-horizontal .form-actions { - padding-right: 10px; - padding-left: 10px; - } - .media .pull-left, - .media .pull-right { - display: block; - float: none; - margin-bottom: 10px; - } - .media-object { - margin-right: 0; - margin-left: 0; - } - .modal { - top: 10px; - right: 10px; - left: 10px; - } - .modal-header .close { - padding: 10px; - margin: -10px; - } - .carousel-caption { - position: static; - } -} - -@media (max-width: 979px) { - body { - padding-top: 0; - } - .navbar-fixed-top, - .navbar-fixed-bottom { - position: static; - } - .navbar-fixed-top { - margin-bottom: 20px; - } - .navbar-fixed-bottom { - margin-top: 20px; - } - .navbar-fixed-top .navbar-inner, - .navbar-fixed-bottom .navbar-inner { - padding: 5px; - } - .navbar .container { - width: auto; - padding: 0; - } - .navbar .brand { - padding-right: 10px; - padding-left: 10px; - margin: 0 0 0 -5px; - } - .nav-collapse { - clear: both; - } - .nav-collapse .nav { - float: none; - margin: 0 0 10px; - } - .nav-collapse .nav > li { - float: none; - } - .nav-collapse .nav > li > a { - margin-bottom: 2px; - } - .nav-collapse .nav > .divider-vertical { - display: none; - } - .nav-collapse .nav .nav-header { - color: #777777; - text-shadow: none; - } - .nav-collapse .nav > li > a, - .nav-collapse .dropdown-menu a { - padding: 9px 15px; - font-weight: bold; - color: #777777; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - } - .nav-collapse .btn { - padding: 4px 10px 4px; - font-weight: normal; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - } - .nav-collapse .dropdown-menu li + li a { - margin-bottom: 2px; - } - .nav-collapse .nav > li > a:hover, - .nav-collapse .dropdown-menu a:hover { - background-color: #f2f2f2; - } - .navbar-inverse .nav-collapse .nav > li > a, - .navbar-inverse .nav-collapse .dropdown-menu a { - color: #999999; - } - .navbar-inverse .nav-collapse .nav > li > a:hover, - .navbar-inverse .nav-collapse .dropdown-menu a:hover { - background-color: #111111; - } - .nav-collapse.in .btn-group { - padding: 0; - margin-top: 5px; - } - .nav-collapse .dropdown-menu { - position: static; - top: auto; - left: auto; - display: none; - float: none; - max-width: none; - padding: 0; - margin: 0 15px; - background-color: transparent; - border: none; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - } - .nav-collapse .open > .dropdown-menu { - display: block; - } - .nav-collapse .dropdown-menu:before, - .nav-collapse .dropdown-menu:after { - display: none; - } - .nav-collapse .dropdown-menu .divider { - display: none; - } - .nav-collapse .nav > li > .dropdown-menu:before, - .nav-collapse .nav > li > .dropdown-menu:after { - display: none; - } - .nav-collapse .navbar-form, - .nav-collapse .navbar-search { - float: none; - padding: 10px 15px; - margin: 10px 0; - border-top: 1px solid #f2f2f2; - border-bottom: 1px solid #f2f2f2; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - } - .navbar-inverse .nav-collapse .navbar-form, - .navbar-inverse .nav-collapse .navbar-search { - border-top-color: #111111; - border-bottom-color: #111111; - } - .navbar .nav-collapse .nav.pull-right { - float: none; - margin-left: 0; - } - .nav-collapse, - .nav-collapse.collapse { - height: 0; - overflow: hidden; - } - .navbar .btn-navbar { - display: block; - } - .navbar-static .navbar-inner { - padding-right: 10px; - padding-left: 10px; - } -} - -@media (min-width: 1200px) { - .nav-collapse.collapse { - height: auto !important; - overflow: visible !important; - } -} diff --git a/noVNC/media/css/bootstrap.css b/noVNC/media/css/bootstrap.css deleted file mode 100755 index a871838..0000000 --- a/noVNC/media/css/bootstrap.css +++ /dev/null @@ -1,7241 +0,0 @@ -/*! - * Bootstrap v2.2.2 - * - * Copyright 2012 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section { - display: block; -} - -::-webkit-scrollbar { - -webkit-appearance: none; - width: 4px; - height: 4px; -} -::-webkit-scrollbar-thumb { - border-radius: 4px; - background-color: rgba(0,0,0,.5); - -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5); -} - -audio, -canvas, -video { - display: inline-block; - *display: inline; - *zoom: 1; -} - -audio:not([controls]) { - display: none; -} - -html { - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} - -#rightDiv{ - -webkit-overflow-scrolling: touch; -} - -a:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -a:hover, -a:active { - outline: 0; -} - -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -img { - width: auto\9; - height: auto; - max-width: 100%; - vertical-align: middle; - border: 0; - -ms-interpolation-mode: bicubic; -} - -#map_canvas img, -.google-maps img { - max-width: none; -} - -button, -input, -select, -textarea { - margin: 0; - font-size: 100%; - vertical-align: middle; -} - -button, -input { - *overflow: visible; - line-height: normal; -} - -button::-moz-focus-inner, -input::-moz-focus-inner { - padding: 0; - border: 0; -} - -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - cursor: pointer; - -webkit-appearance: button; -} - -label, -select, -button, -input[type="button"], -input[type="reset"], -input[type="submit"], -input[type="radio"], -input[type="checkbox"] { - cursor: pointer; -} - -input[type="search"] { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; -} - -input[type="search"]::-webkit-search-decoration, -input[type="search"]::-webkit-search-cancel-button { - -webkit-appearance: none; -} - -textarea { - overflow: auto; - vertical-align: top; -} - -@media print { - * { - color: #000 !important; - text-shadow: none !important; - background: transparent !important; - box-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - @page { - margin: 0.5cm; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } -} - -.clearfix { - *zoom: 1; -} - -.clearfix:before, -.clearfix:after { - display: table; - line-height: 0; - content: ""; -} - -.clearfix:after { - clear: both; -} - -.hide-text { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - -.input-block-level { - display: block; - width: 100%; - min-height: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -body { - margin: 0; - font-family: QNAPCustomFont,'Lucida Grande','Verdana','Tahoma','Arial','Helvetica','sans-serif','Microsoft JhengHei'; - font-size: 12px; - line-height: 20px; - color: #333333; - background-color: #ffffff; - overflow:hidden; -} - -a { - color: #000000; - text-decoration: none; -} - -a:hover { - color: #000000; - text-decoration: underline; -} - -.left_menu li > a { - color: #ffffff; - text-decoration: none; -} - -.left_menu li > a:hover { - color: #ffffff; - text-decoration: underline; -} - -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.img-polaroid { - padding: 4px; - background-color: #fff; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); -} - -.img-circle { - -webkit-border-radius: 500px; - -moz-border-radius: 500px; - border-radius: 500px; -} - -.row { - margin-left: -20px; - *zoom: 1; -} - -.row:before, -.row:after { - display: table; - line-height: 0; - content: ""; -} - -.row:after { - clear: both; -} - -[class*="span"] { - float: left; - min-height: 1px; - margin-left: 20px; -} - -.container, -.navbar-static-top .container, -.navbar-fixed-top .container, -.navbar-fixed-bottom .container { - width: 940px; -} - -.span12 { - width: 940px; -} - -.span11 { - width: 860px; -} - -.span10 { - width: 780px; -} - -.span9 { - width: 700px; -} - -.span8 { - width: 620px; -} - -.span7 { - width: 540px; -} - -.span6 { - width: 460px; -} - -.span5 { - width: 380px; -} - -.span4 { - width: 300px; -} - -.span3 { - width: 220px; -} - -.span2 { - width: 140px; -} - -.span1 { - width: 60px; -} - -.offset12 { - margin-left: 980px; -} - -.offset11 { - margin-left: 900px; -} - -.offset10 { - margin-left: 820px; -} - -.offset9 { - margin-left: 740px; -} - -.offset8 { - margin-left: 660px; -} - -.offset7 { - margin-left: 580px; -} - -.offset6 { - margin-left: 500px; -} - -.offset5 { - margin-left: 420px; -} - -.offset4 { - margin-left: 340px; -} - -.offset3 { - margin-left: 260px; -} - -.offset2 { - margin-left: 180px; -} - -.offset1 { - margin-left: 100px; -} - -.row-fluid { - width: 100%; - *zoom: 1; -} - -.row-fluid-header { - padding-bottom: 4px; -} - -.row-fluid-middle { - padding-top: 4px; - padding-bottom: 4px; -} - -.row-fluid:before, -.row-fluid:after { - display: table; - line-height: 0; - content: ""; -} - -.row-fluid:after { - clear: both; -} - -.row-fluid [class*="span"] { - display: block; - float: left; - width: 100%; - /*min-height: 30px;*/ - margin-left: 1%; - *margin-left: 1%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.row-fluid [class*="span"]:first-child { - margin-left: 0; -} - -.row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.127659574468085%; -} - -.row-fluid .span12 { - width: 100%; - *width: 99.94680851063829%; -} - -.row-fluid .span11 { - width: 91.48936170212765%; - *width: 91.43617021276594%; -} - -.row-fluid .span10 { - width: 82.97872340425532%; - *width: 82.92553191489361%; -} - -.row-fluid .span9 { - width: 74.46808510638297%; - *width: 74.41489361702126%; -} - -.row-fluid .span8 { - width: 65.95744680851064%; - *width: 65.90425531914893%; -} - -.row-fluid .span7 { - width: 57.44680851063829%; - *width: 57.39361702127659%; -} - -.row-fluid .span6 { - width: 48.93617021276595%; - *width: 48.88297872340425%; -} - -.row-fluid .span5 { - width: 40.42553191489362%; - *width: 40.37234042553192%; -} - -.row-fluid .span4 { - width: 31.914893617021278%; - *width: 31.861702127659576%; -} - -.row-fluid .span3 { - width: 23.404255319148934%; - *width: 23.351063829787233%; -} - -.row-fluid .span2 { - width: 14.893617021276595%; - *width: 14.840425531914894%; -} - -.row-fluid .span1 { - width: 6.382978723404255%; - *width: 6.329787234042553%; -} - -.row-fluid .offset12 { - margin-left: 104.25531914893617%; - *margin-left: 104.14893617021275%; -} - -.row-fluid .offset12:first-child { - margin-left: 102.12765957446808%; - *margin-left: 102.02127659574467%; -} - -.row-fluid .offset11 { - margin-left: 95.74468085106382%; - *margin-left: 95.6382978723404%; -} - -.row-fluid .offset11:first-child { - margin-left: 93.61702127659574%; - *margin-left: 93.51063829787232%; -} - -.row-fluid .offset10 { - margin-left: 87.23404255319149%; - *margin-left: 87.12765957446807%; -} - -.row-fluid .offset10:first-child { - margin-left: 85.1063829787234%; - *margin-left: 84.99999999999999%; -} - -.row-fluid .offset9 { - margin-left: 78.72340425531914%; - *margin-left: 78.61702127659572%; -} - -.row-fluid .offset9:first-child { - margin-left: 76.59574468085106%; - *margin-left: 76.48936170212764%; -} - -.row-fluid .offset8 { - margin-left: 70.2127659574468%; - *margin-left: 70.10638297872339%; -} - -.row-fluid .offset8:first-child { - margin-left: 68.08510638297872%; - *margin-left: 67.9787234042553%; -} - -.row-fluid .offset7 { - margin-left: 61.70212765957446%; - *margin-left: 61.59574468085106%; -} - -.row-fluid .offset7:first-child { - margin-left: 59.574468085106375%; - *margin-left: 59.46808510638297%; -} - -.row-fluid .offset6 { - margin-left: 53.191489361702125%; - *margin-left: 53.085106382978715%; -} - -.row-fluid .offset6:first-child { - margin-left: 51.063829787234035%; - *margin-left: 50.95744680851063%; -} - -.row-fluid .offset5 { - margin-left: 44.68085106382979%; - *margin-left: 44.57446808510638%; -} - -.row-fluid .offset5:first-child { - margin-left: 42.5531914893617%; - *margin-left: 42.4468085106383%; -} - -.row-fluid .offset4 { - margin-left: 36.170212765957444%; - *margin-left: 36.06382978723405%; -} - -.row-fluid .offset4:first-child { - margin-left: 34.04255319148936%; - *margin-left: 33.93617021276596%; -} - -.row-fluid .offset3 { - margin-left: 27.659574468085104%; - *margin-left: 27.5531914893617%; -} - -.row-fluid .offset3:first-child { - margin-left: 25.53191489361702%; - *margin-left: 25.425531914893618%; -} - -.row-fluid .offset2 { - margin-left: 19.148936170212764%; - *margin-left: 19.04255319148936%; -} - -.row-fluid .offset2:first-child { - margin-left: 17.02127659574468%; - *margin-left: 16.914893617021278%; -} - -.row-fluid .offset1 { - margin-left: 10.638297872340425%; - *margin-left: 10.53191489361702%; -} - -.row-fluid .offset1:first-child { - margin-left: 8.51063829787234%; - *margin-left: 8.404255319148938%; -} - -[class*="span"].hide, -.row-fluid [class*="span"].hide { - display: none; -} - -[class*="span"].pull-right, -.row-fluid [class*="span"].pull-right { - float: right; -} - -.container { - margin-right: auto; - margin-left: auto; - *zoom: 1; -} - -.container:before, -.container:after { - display: table; - line-height: 0; - content: ""; -} - -.container:after { - clear: both; -} - -.container-fluid { - min-width: 700px; - width: 100%; - padding-right: 0px; - padding-left: 0px; - *zoom: 1; -} - -.container-fluid:before, -.container-fluid:after { - display: table; - line-height: 0; - content: ""; -} - -.container-fluid:after { - clear: both; -} - -p { - margin: 0 0 10px; -} - -.lead { - margin-bottom: 20px; - font-size: 21px; - font-weight: 200; - line-height: 30px; -} - -small { - font-size: 85%; -} - -strong { - font-weight: bold; -} - -em { - font-style: italic; -} - -cite { - font-style: normal; -} - -.muted { - color: #999999; -} - -a.muted:hover { - color: #808080; -} - -.text-warning { - color: #c09853; -} - -a.text-warning:hover { - color: #a47e3c; -} - -.text-error { - color: #b94a48; -} - -a.text-error:hover { - color: #953b39; -} - -.text-info { - color: #3a87ad; -} - -a.text-info:hover { - color: #2d6987; -} - -.text-success { - color: #468847; -} - -a.text-success:hover { - color: #356635; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - margin: 10px 0; - font-family: inherit; - font-weight: bold; - line-height: 14px; - color: inherit; - text-rendering: optimizelegibility; -} - -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small { - font-weight: normal; - line-height: 1; - color: #999999; -} - -h1, -h2, -h3 { - line-height: 40px; -} - -h1 { - font-size: 38.5px; -} - -h2 { - font-size: 31.5px; -} - -h3 { - font-size: 16px; -} - -h4 { - font-size: 12px; - color: rgb(2, 37, 79); -} - -h5 { - font-size: 14px; -} - -h6 { - font-size: 11.9px; -} - -h1 small { - font-size: 24.5px; -} - -h2 small { - font-size: 17.5px; -} - -h3 small { - font-size: 14px; -} - -h4 small { - font-size: 14px; -} - -.page-header { - padding-bottom: 9px; - margin: 20px 0 30px; - line-height: 27px; -} - -ul, -ol { - padding: 0; - margin: 0 0 10px 25px; -} - -ul ul, -ul ol, -ol ol, -ol ul { - margin-bottom: 0; -} - -li { - line-height: 25px; -} - -ul.unstyled, -ol.unstyled { - margin-left: 0; - list-style: none; -} - -ul.inline, -ol.inline { - margin-left: 0; - list-style: none; -} - -ul.inline > li, -ol.inline > li { - display: inline-block; - padding-right: 5px; - padding-left: 5px; -} - -dl { - margin-bottom: 20px; -} - -dt, -dd { - line-height: 20px; -} - -dt { - font-weight: bold; -} - -dd { - margin-left: 10px; -} - -.dl-horizontal { - *zoom: 1; -} - -.dl-horizontal:before, -.dl-horizontal:after { - display: table; - line-height: 0; - content: ""; -} - -.dl-horizontal:after { - clear: both; -} - -.dl-horizontal dt { - float: left; - width: 160px; - overflow: hidden; - clear: left; - text-align: right; - text-overflow: ellipsis; - white-space: nowrap; -} - -.dl-horizontal dd { - margin-left: 180px; -} - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #CDCDCD; - position: 0 0; - margin: 0 -18px; -} - -.subhr{ - border-top: 1.5px dashed #CDCDCD; - margin: 0 0px; -} - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; -} - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #eeeeee; -} - -blockquote p { - margin-bottom: 0; - font-size: 16px; - font-weight: 300; - line-height: 25px; -} - -blockquote small { - display: block; - line-height: 20px; - color: #999999; -} - -blockquote small:before { - content: '\2014 \00A0'; -} - -blockquote.pull-right { - float: right; - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #eeeeee; - border-left: 0; -} - -blockquote.pull-right p, -blockquote.pull-right small { - text-align: right; -} - -blockquote.pull-right small:before { - content: ''; -} - -blockquote.pull-right small:after { - content: '\00A0 \2014'; -} - -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} - -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; -} - -code, -pre { - padding: 0 3px 2px; - font-family: QNAPCustomFont,'Lucida Grande','Verdana','Tahoma','Arial','Helvetica','sans-serif','Microsoft JhengHei'; - font-size: 12px; - color: #333333; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -code { - padding: 2px 4px; - color: #d14; - white-space: nowrap; - background-color: #f7f7f9; - border: 1px solid #e1e1e8; -} - -pre { - display: block; - padding: 9.5px; - margin: 0 0 10px; - font-size: 13px; - line-height: 20px; - word-break: break-all; - word-wrap: break-word; - white-space: pre; - white-space: pre-wrap; - background-color: #f5f5f5; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.15); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -pre.prettyprint { - margin-bottom: 20px; -} - -pre code { - padding: 0; - color: inherit; - white-space: pre; - white-space: pre-wrap; - background-color: transparent; - border: 0; -} - -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} - -form { - margin: 0 0 20px; -} - -fieldset { - padding: 0; - margin: 0; - border: 0; -} - -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 20px; - font-size: 21px; - line-height: 40px; - color: #333333; - border: 0; - border-bottom: 1px solid #e5e5e5; -} - -legend small { - font-size: 15px; - color: #999999; -} - -label, -input, -button, -select, -textarea { - font-size: 12px; - font-weight: normal; - line-height: 20px; -} - -input, -button, -select, -textarea { - font-family: QNAPCustomFont,'Lucida Grande','Verdana','Tahoma','Arial','Helvetica','sans-serif','Microsoft JhengHei'; -} - -label { - display: block; - margin-bottom: 5px; -} - -select, -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - display: inline-block; - height: 20px; - padding: 0px; - margin-bottom: 10px; - font-size: 12px; - line-height: 20px; - color: #555555; - vertical-align: middle; - -webkit-border-radius: 0px; - -moz-border-radius: 0px; - border-radius: 0px; -} - -textarea, -input[type="text"] { - padding: 0 5px; -} - -input, -textarea, -.uneditable-input { - width: 208px; -} - -textarea { - height: auto; -} - -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - background-color: #ffffff; - border: 1px solid #cccccc; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; - -moz-transition: border linear 0.2s, box-shadow linear 0.2s; - -o-transition: border linear 0.2s, box-shadow linear 0.2s; - transition: border linear 0.2s, box-shadow linear 0.2s; -} - -textarea:focus, -input[type="text"]:focus, -input[type="password"]:focus, -input[type="datetime"]:focus, -input[type="datetime-local"]:focus, -input[type="date"]:focus, -input[type="month"]:focus, -input[type="time"]:focus, -input[type="week"]:focus, -input[type="number"]:focus, -input[type="email"]:focus, -input[type="url"]:focus, -input[type="search"]:focus, -input[type="tel"]:focus, -input[type="color"]:focus, -.uneditable-input:focus { - border-color: rgba(82, 168, 236, 0.8); - outline: 0; - outline: thin dotted \9; - /* IE6-9 */ - - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); -} - -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; - *margin-top: 0; - line-height: normal; -} - -input[type="file"], -input[type="image"], -input[type="submit"], -input[type="reset"], -input[type="button"], -input[type="radio"], -input[type="checkbox"] { - width: auto; -} - -select, -input[type="file"] { - height: 20px; - /* In IE7, the height of the select element cannot be changed by height, only font-size */ - - *margin-top: 4px; - /* For IE7, add top margin to align select with labels */ - - line-height: 20px; -} - -select { - width: 220px; - background-color: #ffffff; - border: 1px solid #cccccc; -} - -select[multiple], -select[size] { - height: auto; -} - -select:focus, -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -.uneditable-input, -.uneditable-textarea { - color: #999999; - cursor: not-allowed; - background-color: #fcfcfc; - border-color: #cccccc; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); -} - -.uneditable-input { - overflow: hidden; - white-space: nowrap; -} - -.uneditable-textarea { - width: auto; - height: auto; -} - -input:-moz-placeholder, -textarea:-moz-placeholder { - color: #999999; -} - -input:-ms-input-placeholder, -textarea:-ms-input-placeholder { - color: #999999; -} - -input::-webkit-input-placeholder, -textarea::-webkit-input-placeholder { - color: #999999; -} - -.radio, -.checkbox { - min-height: 20px; - padding-left: 20px; -} - -.radio input[type="radio"], -.checkbox input[type="checkbox"] { - float: left; - margin-left: -20px; -} -/*********** Use image start **************/ -.radio_img input[type="radio"] { - position:absolute; - opacity:0; -} - -.radio_img input[type="radio"] + span { - display: inline-block; - width: 16px; - height: 16px; - margin-top: 1px; - *margin-right: .3em; - padding-right: 6px; - line-height: 16px; - vertical-align: text-top; - background-image: url("../img/radiobutton_no.png"); - background-position: left top; - background-repeat: no-repeat; -} - -.radio_img input[type=radio]:checked + span { - background-image: url("../img/radiobutton_yes.png"); -} - -.radio_img input[type=radio]:disabled + span { - cursor: not-allowed; -} -/*********** Use image end **************/ - -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 5px; -} - -.radio.inline, -.checkbox.inline { - display: inline-block; - padding-top: 5px; - margin-bottom: 0; - vertical-align: middle; -} - -.radio.inline + .radio.inline, -.checkbox.inline + .checkbox.inline { - margin-left: 10px; -} - -.input-mini { - width: 60px; -} - -.input-small { - width: 90px; -} - -.input-medium { - width: 150px; -} - -.input-large { - width: 210px; -} - -.input-xlarge { - width: 270px; -} - -.input-xxlarge { - width: 530px; -} - -input[class*="span"], -select[class*="span"], -textarea[class*="span"], -.uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"] { - float: none; - margin-left: 0; -} - -.input-append input[class*="span"], -.input-append .uneditable-input[class*="span"], -.input-prepend input[class*="span"], -.input-prepend .uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"], -.row-fluid .input-prepend [class*="span"], -.row-fluid .input-append [class*="span"] { - display: inline-block; -} - -input, -textarea, -.uneditable-input { - margin-left: 0; -} - -.controls-row [class*="span"] + [class*="span"] { - margin-left: 20px; -} - -input.span12, -textarea.span12, -.uneditable-input.span12 { - width: 926px; -} - -input.span11, -textarea.span11, -.uneditable-input.span11 { - width: 846px; -} - -input.span10, -textarea.span10, -.uneditable-input.span10 { - width: 766px; -} - -input.span9, -textarea.span9, -.uneditable-input.span9 { - width: 686px; -} - -input.span8, -textarea.span8, -.uneditable-input.span8 { - width: 606px; -} - -input.span7, -textarea.span7, -.uneditable-input.span7 { - width: 526px; -} - -input.span6, -textarea.span6, -.uneditable-input.span6 { - width: 446px; -} - -input.span5, -textarea.span5, -.uneditable-input.span5 { - width: 366px; -} - -input.span4, -textarea.span4, -.uneditable-input.span4 { - width: 286px; -} - -input.span3, -textarea.span3, -.uneditable-input.span3 { - width: 208px; -} - -input.span2, -textarea.span2, -.uneditable-input.span2 { - width: 126px; -} - -input.span1, -textarea.span1, -.uneditable-input.span1 { - width: 46px; -} - -.controls-row { - *zoom: 1; -} - -.controls-row:before, -.controls-row:after { - display: table; - line-height: 0; - content: ""; -} - -.controls-row:after { - clear: both; -} - -.controls-row [class*="span"], -.row-fluid .controls-row [class*="span"] { - float: left; -} - -.controls-row .checkbox[class*="span"], -.controls-row .radio[class*="span"] { - padding-top: 5px; -} - -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - cursor: not-allowed; - background-color: #eeeeee; -} - -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"][readonly], -input[type="checkbox"][readonly] { - background-color: transparent; -} - -.control-group.warning .control-label, -.control-group.warning .help-block, -.control-group.warning .help-inline { - color: #c09853; -} - -.control-group.warning .checkbox, -.control-group.warning .radio, -.control-group.warning input, -.control-group.warning select, -.control-group.warning textarea { - color: #c09853; -} - -.control-group.warning input, -.control-group.warning select, -.control-group.warning textarea { - border-color: #c09853; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.control-group.warning input:focus, -.control-group.warning select:focus, -.control-group.warning textarea:focus { - border-color: #a47e3c; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; -} - -.control-group.warning .input-prepend .add-on, -.control-group.warning .input-append .add-on { - color: #c09853; - background-color: #fcf8e3; - border-color: #c09853; -} - -.control-group.error .control-label, -.control-group.error .help-block, -.control-group.error .help-inline { - color: #b94a48; -} - -.control-group.error .checkbox, -.control-group.error .radio, -.control-group.error input, -.control-group.error select, -.control-group.error textarea { - color: #b94a48; -} - -.control-group.error input, -.control-group.error select, -.control-group.error textarea { - border-color: #b94a48; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.control-group.error input:focus, -.control-group.error select:focus, -.control-group.error textarea:focus { - border-color: #953b39; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; -} - -.control-group.error .input-prepend .add-on, -.control-group.error .input-append .add-on { - color: #b94a48; - background-color: #f2dede; - border-color: #b94a48; -} - -.control-group.success .control-label, -.control-group.success .help-block, -.control-group.success .help-inline { - color: #468847; -} - -.control-group.success .checkbox, -.control-group.success .radio, -.control-group.success input, -.control-group.success select, -.control-group.success textarea { - color: #468847; -} - -.control-group.success input, -.control-group.success select, -.control-group.success textarea { - border-color: #468847; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.control-group.success input:focus, -.control-group.success select:focus, -.control-group.success textarea:focus { - border-color: #356635; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; -} - -.control-group.success .input-prepend .add-on, -.control-group.success .input-append .add-on { - color: #468847; - background-color: #dff0d8; - border-color: #468847; -} - -.control-group.info .control-label, -.control-group.info .help-block, -.control-group.info .help-inline { - color: #3a87ad; -} - -.control-group.info .checkbox, -.control-group.info .radio, -.control-group.info input, -.control-group.info select, -.control-group.info textarea { - color: #3a87ad; -} - -.control-group.info input, -.control-group.info select, -.control-group.info textarea { - border-color: #3a87ad; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -} - -.control-group.info input:focus, -.control-group.info select:focus, -.control-group.info textarea:focus { - border-color: #2d6987; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; -} - -.control-group.info .input-prepend .add-on, -.control-group.info .input-append .add-on { - color: #3a87ad; - background-color: #d9edf7; - border-color: #3a87ad; -} - -input:focus:invalid, -textarea:focus:invalid, -select:focus:invalid { - color: #b94a48; - border-color: #ee5f5b; -} - -input:focus:invalid:focus, -textarea:focus:invalid:focus, -select:focus:invalid:focus { - border-color: #e9322d; - -webkit-box-shadow: 0 0 6px #f8b9b7; - -moz-box-shadow: 0 0 6px #f8b9b7; - box-shadow: 0 0 6px #f8b9b7; -} - -.form-actions { - padding: 19px 20px 20px; - margin-top: 20px; - margin-bottom: 20px; - background-color: #fffff; - border-top: 1px solid #e5e5e5; - *zoom: 1; -} - -.form-actions:before, -.form-actions:after { - display: table; - line-height: 0; - content: ""; -} - -.form-actions:after { - clear: both; -} - -.help-block, -.help-inline { - color: #595959; -} - -.help-block { - display: block; - margin-bottom: 10px; -} - -.help-inline { - display: inline-block; - *display: inline; - padding-left: 5px; - vertical-align: middle; - *zoom: 1; -} - -.input-append, -.input-prepend { - margin-bottom: 5px; - font-size: 0; - white-space: nowrap; -} - -.input-append input, -.input-prepend input, -.input-append select, -.input-prepend select, -.input-append .uneditable-input, -.input-prepend .uneditable-input, -.input-append .dropdown-menu, -.input-prepend .dropdown-menu { - font-size: 14px; -} - -.input-append input, -.input-prepend input, -.input-append select, -.input-prepend select, -.input-append .uneditable-input, -.input-prepend .uneditable-input { - position: relative; - margin-bottom: 0; - *margin-left: 0; - vertical-align: top; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.input-append input:focus, -.input-prepend input:focus, -.input-append select:focus, -.input-prepend select:focus, -.input-append .uneditable-input:focus, -.input-prepend .uneditable-input:focus { - z-index: 2; -} - -.input-append .add-on, -.input-prepend .add-on { - display: inline-block; - width: auto; - height: 20px; - min-width: 16px; - padding: 4px 5px; - font-size: 14px; - font-weight: normal; - line-height: 20px; - text-align: center; - text-shadow: 0 1px 0 #ffffff; - background-color: #eeeeee; - border: 1px solid #ccc; -} - -.input-append .add-on, -.input-prepend .add-on, -.input-append .btn, -.input-prepend .btn, -.input-append .btn-group > .dropdown-toggle, -.input-prepend .btn-group > .dropdown-toggle { - vertical-align: top; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.input-append .active, -.input-prepend .active { - background-color: #a9dba9; - border-color: #46a546; -} - -.input-prepend .add-on, -.input-prepend .btn { - margin-right: -1px; -} - -.input-prepend .add-on:first-child, -.input-prepend .btn:first-child { - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} - -.input-append input, -.input-append select, -.input-append .uneditable-input { - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} - -.input-append input + .btn-group .btn:last-child, -.input-append select + .btn-group .btn:last-child, -.input-append .uneditable-input + .btn-group .btn:last-child { - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.input-append .add-on, -.input-append .btn, -.input-append .btn-group { - margin-left: -1px; -} - -.input-append .add-on:last-child, -.input-append .btn:last-child, -.input-append .btn-group:last-child > .dropdown-toggle { - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.input-prepend.input-append input, -.input-prepend.input-append select, -.input-prepend.input-append .uneditable-input { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.input-prepend.input-append input + .btn-group .btn, -.input-prepend.input-append select + .btn-group .btn, -.input-prepend.input-append .uneditable-input + .btn-group .btn { - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.input-prepend.input-append .add-on:first-child, -.input-prepend.input-append .btn:first-child { - margin-right: -1px; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} - -.input-prepend.input-append .add-on:last-child, -.input-prepend.input-append .btn:last-child { - margin-left: -1px; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.input-prepend.input-append .btn-group:first-child { - margin-left: 0; -} - -input.search-query { - padding-right: 14px; - padding-right: 4px \9; - padding-left: 14px; - padding-left: 4px \9; - /* IE7-8 doesn't have border-radius, so don't indent the padding */ - - margin-bottom: 0; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} - -/* Allow for input prepend/append in search forms */ - -.form-search .input-append .search-query, -.form-search .input-prepend .search-query { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.form-search .input-append .search-query { - -webkit-border-radius: 14px 0 0 14px; - -moz-border-radius: 14px 0 0 14px; - border-radius: 14px 0 0 14px; -} - -.form-search .input-append .btn { - -webkit-border-radius: 0 14px 14px 0; - -moz-border-radius: 0 14px 14px 0; - border-radius: 0 14px 14px 0; -} - -.form-search .input-prepend .search-query { - -webkit-border-radius: 0 14px 14px 0; - -moz-border-radius: 0 14px 14px 0; - border-radius: 0 14px 14px 0; -} - -.form-search .input-prepend .btn { - -webkit-border-radius: 14px 0 0 14px; - -moz-border-radius: 14px 0 0 14px; - border-radius: 14px 0 0 14px; -} - -.form-search input, -.form-inline input, -.form-horizontal input, -.form-search textarea, -.form-inline textarea, -.form-horizontal textarea, -.form-search select, -.form-inline select, -.form-horizontal select, -.form-search .help-inline, -.form-inline .help-inline, -.form-horizontal .help-inline, -.form-search .uneditable-input, -.form-inline .uneditable-input, -.form-horizontal .uneditable-input, -.form-search .input-prepend, -.form-inline .input-prepend, -.form-horizontal .input-prepend, -.form-search .input-append, -.form-inline .input-append, -.form-horizontal .input-append { - display: inline-block; - *display: inline; - margin-bottom: 0; - vertical-align: middle; - *zoom: 1; -} - -.form-search .hide, -.form-inline .hide, -.form-horizontal .hide { - display: none; -} - -.form-search label, -.form-inline label, -.form-search .btn-group, -.form-inline .btn-group { - display: inline-block; -} - -.form-search .input-append, -.form-inline .input-append, -.form-search .input-prepend, -.form-inline .input-prepend { - margin-bottom: 0; -} - -.form-search .radio, -.form-search .checkbox, -.form-inline .radio, -.form-inline .checkbox { - padding-left: 0; - margin-bottom: 0; - vertical-align: middle; -} - -.form-search .radio input[type="radio"], -.form-search .checkbox input[type="checkbox"], -.form-inline .radio input[type="radio"], -.form-inline .checkbox input[type="checkbox"] { - float: left; - margin-right: 3px; - margin-left: 0; -} - -.control-group { - margin-bottom: 10px; -} - -legend + .control-group { - margin-top: 20px; - -webkit-margin-top-collapse: separate; -} - -.form-horizontal .control-group { - margin-bottom: 0px; - *zoom: 1; -} - -.form-horizontal .control-group:before, -.form-horizontal .control-group:after { - display: table; - line-height: 0; - content: ""; -} - -.form-horizontal .control-group:after { - clear: both; -} - -.form-horizontal .control-label { - float: left; - width: 160px; - padding-top: 5px; - text-align: right; -} - -.control-label_newvm { - float: left; - width: 149px; - padding-top: 5px; - text-align: right; -} - -.form-horizontal .controls { - *display: inline-block; - *padding-left: 20px; - padding-top: 5px; - margin-left: 180px; - *margin-left: 0; -} - -.control-label_newvm { - float: left; - width: 139px; - padding-top: 5px; - text-align: right; -} - -.control-label_newvm_grayBox { - width: auto; - float: left; - padding-top: 5px; - text-align: right; -} - -.controls_newvm { - *display: inline-block; - *padding-left: 20px; - padding-top: 5px; - margin-left: 159px; - *margin-left: 0; -} - -.newvm-group { - background:transparent; - border:1px solid #B2B2B2; - margin-top:-110px; - margin-left:67px; - min-width:412px; - width:412px; - height:115px; -} - -.form-horizontal .controls:first-child { - *padding-left: 180px; -} - -.form-horizontal .help-block { - margin-bottom: 0; -} - -.form-horizontal input + .help-block, -.form-horizontal select + .help-block, -.form-horizontal textarea + .help-block, -.form-horizontal .uneditable-input + .help-block, -.form-horizontal .input-prepend + .help-block, -.form-horizontal .input-append + .help-block { - margin-top: 10px; -} - -.form-horizontal .form-actions { - padding-left: 180px; -} - -table { - max-width: 100%; - background-color: transparent; - border-collapse: collapse; - border-spacing: 0; -} - -.table { - width: 100%; - margin-bottom: 20px; -} - -.table th, -.table td { - padding: 2px; - line-height: 20px; - text-align: left; - vertical-align: middle; - border-top: 1px solid #dddddd; - white-space: nowrap -} - -.table-blank td{ - border-top: 0px; -} - -.table-blank-info td{ - border-top: 0px; - padding: 2px; -} - -.table-blank-mini td{ - border-top: 0px; - padding: 0 10px 0 0; - line-height: 32px; -} - -.table-blank-mini td input[type="text"], -.table-blank-mini td input[type="password"]{ - width: 300px; -} - -.table-blank-mini td select{ - width: 309px; - line-height: 20px; -} - -.table th { - font-weight: bold; - color: #ffffff; -} - -.table thead th { - vertical-align: bottom; - background-color: #666666; -} - -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; -} - -.table tbody + tbody { - border-top: 2px solid #dddddd; -} - -.table .table { - background-color: #ffffff; -} - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; -} - -.table-bordered { - border: 1px solid #dddddd; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #dddddd; -} - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; -} - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; -} - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; -} - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; -} - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; -} - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; -} - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; -} - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; -} - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; -} - -.table-striped { - min-width:510px; -} - -.table-striped thead > tr > th:first-child, -.table-striped tbody > tr > td:first-child { - padding-left: 20px; - padding-right: 5; -} - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: #EFEFEF; -} - -.table-striped tbody > tr:nth-child(even) > td, -.table-striped tbody > tr:nth-child(even) > th { - background-color: #DBDBDB; -} - -.table-hover tbody tr:hover td, -.table-hover tbody tr:hover th { - background-color: #f5f5f5; -} - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; -} - -.table td.span1, -.table th.span1 { - float: none; - width: 44px; - margin-left: 0; -} - -.table td.span2, -.table th.span2 { - float: none; - width: 124px; - margin-left: 0; -} - -.table td.span3, -.table th.span3 { - float: none; - width: 204px; - margin-left: 0; -} - -.table td.span4, -.table th.span4 { - float: none; - width: 284px; - margin-left: 0; -} - -.table td.span5, -.table th.span5 { - float: none; - width: 364px; - margin-left: 0; -} - -.table td.span6, -.table th.span6 { - float: none; - width: 444px; - margin-left: 0; -} - -.table td.span7, -.table th.span7 { - float: none; - width: 524px; - margin-left: 0; -} - -.table td.span8, -.table th.span8 { - float: none; - width: 604px; - margin-left: 0; -} - -.table td.span9, -.table th.span9 { - float: none; - width: 684px; - margin-left: 0; -} - -.table td.span10, -.table th.span10 { - float: none; - width: 764px; - margin-left: 0; -} - -.table td.span11, -.table th.span11 { - float: none; - width: 844px; - margin-left: 0; -} - -.table td.span12, -.table th.span12 { - float: none; - width: 924px; - margin-left: 0; -} - -.table tbody tr.success td { - background-color: #dff0d8; -} - -.table tbody tr.error td { - background-color: #f2dede; -} - -.table tbody tr.warning td { - background-color: #fcf8e3; -} - -.table tbody tr.info td { - background-color: #d9edf7; -} - -.table-hover tbody tr.success:hover td { - background-color: #d0e9c6; -} - -.table-hover tbody tr.error:hover td { - background-color: #ebcccc; -} - -.table-hover tbody tr.warning:hover td { - background-color: #faf2cc; -} - -.table-hover tbody tr.info:hover td { - background-color: #c4e3f3; -} - -.help-link { - display: inline-block; - border-left: 1px solid #b2b2b2; - vertical-align: middle; - height: 29px; -} - -.help-icon { - display: inline-block; - background-image: url("../img/question.png"); - width: 20px; - height: 20px; - margin-left: -9px; - -moz-margin-start:0; - margin-top: -3px; - background-repeat:no-repeat; - background-position: 0px 0px; -} -/* -.help-icon:hover { - background-position: -20px 0px; -} -*/ -.refresh2-icon { - background-image: url("../img/refresh.png"); - background-position: 0px 0px; - width: 20px; - height: 20px; - position:relative; - left:100%; - margin-left:-20px; - cursor: pointer; -} - -.refresh2-icon:hover { - background-image: url("../img/refresh.png"); - background-position: -20px 0px; -} - -.task-logs { - display: inline-block; - background-image: url("../img/list_.png"); - width: 28px; - height: 26px; - margin-right: 2px; - vertical-align: middle; -} - -.task-logs:hover { - background-image: url("../img/list_hover.png"); -} - -.running-icon { - display: inline-block; - background-image: url("../img/wait.gif"); - width: 18px; - height: 18px; - float: right; - margin-top: 8px; - margin-right: -20px; -} - -.running-icon3 { - display: inline-block; - background-image: url("../img/wait.gif"); - width: 18px; - height: 18px; - float: left; - margin-top: -27px; - margin-left: 180px; -} - -.bkg-action-running-icon { - display: inline-block; - background-image: url("../img/wait.gif"); - width: 18px; - height: 18px; - vertical-align: top; - margin-top: 5px; -} - -.running-icon2 { - display: inline-block; - background-image: url("../img/wait.gif"); - width: 18px; - height: 18px; - background-repeat: no-repeat; -} - -.ok-icon { - display: block; - background-image: url("../img/ok.png"); - width: 20px; - height: 20px; - background-repeat: no-repeat; -} - -.error-icon { - display: block; - background-image: url("../img/error.png"); - width: 20px; - height: 20px; - background-repeat: no-repeat; -} - -/* KVM - start */ -[class^="icons-"], -[class*=" icons-"] { - display: inline-block; - width: 16px; - height: 16px; - margin-top: 1px; - *margin-right: .3em; - padding-right: 6px; - line-height: 16px; - vertical-align: text-top; - background-image: url("../img/icons.png?cnt=20140424"); /* just random number */ - background-position: 16px 16px; - background-repeat: no-repeat; -} - -/* White icons with optional class, or on hover/active states of certain elements */ - -.icons-over, -.nav-pills > .active > a > [class^="icons-"], -.nav-pills > .active > a > [class*=" icons-"], -.nav-list > .active > a > [class^="icons-"], -.nav-list > .active > a > [class*=" icons-"], -.navbar-inverse .nav > .active > a > [class^="icons-"], -.navbar-inverse .nav > .active > a > [class*=" icons-"], -.dropdown-menu > li > a:hover > [class^="icons-"], -.dropdown-menu > li > a:hover > [class*=" icons-"], -.dropdown-menu > .active > a > [class^="icons-"], -.dropdown-menu > .active > a > [class*=" icons-"], -.dropdown-submenu:hover > a > [class^="icons-"], -.dropdown-submenu:hover > a > [class*=" icons-"] { - background-image: url("../img/icons_over.png"); -} - -.icons-green, -.nav-pills > .active > a > [class^="icons-green"], -.nav-pills > .active > a > [class*=" icons-green"], -.nav-list > .active > a > [class^="icons-green"], -.nav-list > .active > a > [class*=" icons-green"], -.navbar-inverse .nav > .active > a > [class^="icons-green"], -.navbar-inverse .nav > .active > a > [class*=" icons-green"], -.dropdown-menu > li > a:hover > [class^="icons-green"], -.dropdown-menu > li > a:hover > [class*=" icons-green"], -.dropdown-menu > .active > a > [class^="icons-green"], -.dropdown-menu > .active > a > [class*=" icons-green"], -.dropdown-submenu:hover > a > [class^="icons-green"], -.dropdown-submenu:hover > a > [class*=" icons-green"] { - background-image: url("../img/icons_green.png"); -} - -.icons-yellow, -.nav-pills > .active > a > [class^="icons-yellow"], -.nav-pills > .active > a > [class*=" icons-yellow"], -.nav-list > .active > a > [class^="icons-yellow"], -.nav-list > .active > a > [class*=" icons-yellow"], -.navbar-inverse .nav > .active > a > [class^="icons-yellow"], -.navbar-inverse .nav > .active > a > [class*=" icons-yellow"], -.dropdown-menu > li > a:hover > [class^="icons-yellow"], -.dropdown-menu > li > a:hover > [class*=" icons-yellow"], -.dropdown-menu > .active > a > [class^="icons-yellow"], -.dropdown-menu > .active > a > [class*=" icons-yellow"], -.dropdown-submenu:hover > a > [class^="icons-yellow"], -.dropdown-submenu:hover > a > [class*=" icons-yellow"] { - background-image: url("../img/icons_yellow.png"); -} - -.icons-overview { - background-position: 0 0; -} - -.icons-create { - background-position: 0 -17px; -} - -.icons-import { - background-position: 0 -33px; -} - -.icons-export { - background-position: 0 -49px; -} - -.icons-lists { - background-position: 0 -65px; -} - -.icons-network { - background-position: 0 -81px; -} - -.icons-snapshots { - background-position: 0 -97px; -} - -.icons-logs { - background-position: 0 -113px; -} - -.icons-option { - background-position: 0 -129px; -} - -.icons-market { - margin-top: -2px; - background-position: 0 -145px; -} - -.icons-account { - margin-top: -2px; - background-position: 0 -161px; -} - -/* KVM - end */ - - -[class^="icon-"], -[class*=" icon-"] { - display: inline-block; - width: 14px; - height: 14px; - margin-top: 1px; - *margin-right: .3em; - line-height: 14px; - vertical-align: text-top; - background-image: url("../img/glyphicons-halflings.png"); - background-position: 14px 14px; - background-repeat: no-repeat; -} - -/* White icons with optional class, or on hover/active states of certain elements */ - -.icon-white, -.nav-pills > .active > a > [class^="icon-"], -.nav-pills > .active > a > [class*=" icon-"], -.nav-list > .active > a > [class^="icon-"], -.nav-list > .active > a > [class*=" icon-"], -.navbar-inverse .nav > .active > a > [class^="icon-"], -.navbar-inverse .nav > .active > a > [class*=" icon-"], -.dropdown-menu > li > a:hover > [class^="icon-"], -.dropdown-menu > li > a:hover > [class*=" icon-"], -.dropdown-menu > .active > a > [class^="icon-"], -.dropdown-menu > .active > a > [class*=" icon-"], -.dropdown-submenu:hover > a > [class^="icon-"], -.dropdown-submenu:hover > a > [class*=" icon-"] { - background-image: url("../img/glyphicons-halflings-white.png"); -} - -.icon-green, -.nav-pills > .active > a > [class^="icon-green"], -.nav-pills > .active > a > [class*=" icon-green"], -.nav-list > .active > a > [class^="icon-green"], -.nav-list > .active > a > [class*=" icon-green"], -.navbar-inverse .nav > .active > a > [class^="icon-green"], -.navbar-inverse .nav > .active > a > [class*=" icon-green"], -.dropdown-menu > li > a:hover > [class^="icon-green"], -.dropdown-menu > li > a:hover > [class*=" icon-green"], -.dropdown-menu > .active > a > [class^="icon-green"], -.dropdown-menu > .active > a > [class*=" icon-green"], -.dropdown-submenu:hover > a > [class^="icon-green"], -.dropdown-submenu:hover > a > [class*=" icon-green"] { - background-image: url("../img/glyphicons-halflings-green.png"); -} - -.icon-glass { - background-position: 0 0; -} - -.icon-music { - background-position: -24px 0; -} - -.icon-search { - background-position: -48px 0; -} - -.icon-envelope { - background-position: -72px 0; -} - -.icon-heart { - background-position: -96px 0; -} - -.icon-star { - background-position: -120px 0; -} - -.icon-star-empty { - background-position: -144px 0; -} - -.icon-user { - background-position: -168px 0; -} - -.icon-film { - background-position: -192px 0; -} - -.icon-th-large { - background-position: -216px 0; -} - -.icon-th { - background-position: -240px 0; -} - -.icon-th-list { - background-position: -264px 0; -} - -.icon-ok { - background-position: -288px 0; -} - -.icon-remove { - /*background-position: -312px 0;*/ - background-image: url("../img/remove2.png"); - background-position: 0 center; - display: inline-block; - height: 19px; - width: 19px; - margin-top: -2px; - margin-left: -1px; -} - -.icon-zoom-in { - background-position: -336px 0; -} - -.icon-zoom-out { - background-position: -360px 0; -} - -.icon-off { - background-position: -384px 0; -} - -.icon-signal { - background-position: -408px 0; -} - -.icon-cog { - background-position: -432px 0; -} - -.icon-trash { - background-position: -456px 0; -} - -.icon-home { - background-position: 0 -24px; -} - -.icon-file { - background-position: -24px -24px; -} - -.icon-time { - background-position: -48px -24px; -} - -.icon-road { - background-position: -72px -24px; -} - -.icon-download-alt { - background-position: -96px -24px; -} - -.icon-download { - background-position: -120px -24px; -} - -.icon-upload { - background-position: -144px -24px; -} - -.icon-inbox { - background-position: -168px -24px; -} - -.icon-play-circle { - background-position: -192px -24px; -} - -.icon-repeat { - background-position: -216px -24px; -} - -.icon-refresh { - background-position: -240px -24px; -} - -.icon-list-alt { - background-position: -264px -24px; -} - -.icon-lock { - background-position: -287px -24px; -} - -.icon-flag { - background-position: -312px -24px; -} - -.icon-headphones { - background-position: -336px -24px; -} - -.icon-volume-off { - background-position: -360px -24px; -} - -.icon-volume-down { - background-position: -384px -24px; -} - -.icon-volume-up { - background-position: -408px -24px; -} - -.icon-qrcode { - background-position: -432px -24px; -} - -.icon-barcode { - background-position: -456px -24px; -} - -.icon-tag { - background-position: 0 -48px; -} - -.icon-tags { - background-position: -25px -48px; -} - -.icon-book { - background-position: -48px -48px; -} - -.icon-bookmark { - background-position: -72px -48px; -} - -.icon-print { - background-position: -96px -48px; -} - -.icon-camera { - background-position: -120px -48px; -} - -.icon-font { - background-position: -144px -48px; -} - -.icon-bold { - background-position: -167px -48px; -} - -.icon-italic { - background-position: -192px -48px; -} - -.icon-text-height { - background-position: -216px -48px; -} - -.icon-text-width { - background-position: -240px -48px; -} - -.icon-align-left { - background-position: -264px -48px; -} - -.icon-align-center { - background-position: -288px -48px; -} - -.icon-align-right { - background-position: -312px -48px; -} - -.icon-align-justify { - background-position: -336px -48px; -} - -.icon-list { - background-position: -360px -48px; -} - -.icon-indent-left { - background-position: -384px -48px; -} - -.icon-indent-right { - background-position: -408px -48px; -} - -.icon-facetime-video { - background-position: -432px -48px; -} - -.icon-picture { - background-position: -456px -48px; -} - -.icon-pencil { - background-position: 0 -72px; -} - -.icon-map-marker { - background-position: -24px -72px; -} - -.icon-adjust { - background-position: -48px -72px; -} - -.icon-tint { - background-position: -72px -72px; -} - -.icon-edit { - background-position: -96px -72px; -} - -.icon-share { - background-position: -120px -72px; -} - -.icon-check { - background-position: -144px -72px; -} - -.icon-move { - background-position: -168px -72px; -} - -.icon-step-backward { - background-position: -192px -72px; -} - -.icon-fast-backward { - background-position: -216px -72px; -} - -.icon-backward { - background-position: -240px -72px; -} - -.icon-play { - background-position: -264px -72px; -} - -.icon-pause { - background-position: -288px -72px; -} - -.icon-stop { - background-position: -312px -72px; -} - -.icon-forward { - background-position: -336px -72px; -} - -.icon-fast-forward { - background-position: -360px -72px; -} - -.icon-step-forward { - background-position: -384px -72px; -} - -.icon-eject { - background-position: -408px -72px; -} - -.icon-chevron-left { - background-position: -432px -72px; -} - -.icon-chevron-right { - background-position: -456px -72px; -} - -.icon-plus-sign { - background-position: 0 -96px; -} - -.icon-minus-sign { - background-position: -24px -96px; -} - -.icon-remove-sign { - background-position: -48px -96px; -} - -.icon-ok-sign { - background-position: -72px -96px; -} - -.icon-question-sign { - background-position: -96px -96px; -} - -.icon-info-sign { - background-position: -120px -96px; -} - -.icon-screenshot { - background-position: -144px -96px; -} - -.icon-remove-circle { - background-position: -168px -96px; -} - -.icon-ok-circle { - background-position: -192px -96px; -} - -.icon-ban-circle { - background-position: -216px -96px; -} - -.icon-arrow-left { - background-position: -240px -96px; -} - -.icon-arrow-right { - background-position: -264px -96px; -} - -.icon-arrow-up { - background-position: -289px -96px; -} - -.icon-arrow-down { - background-position: -312px -96px; -} - -.icon-share-alt { - background-position: -336px -96px; -} - -.icon-resize-full { - background-position: -360px -96px; -} - -.icon-resize-small { - background-position: -384px -96px; -} - -.icon-plus { - background-position: -408px -96px; -} - -.icon-minus { - background-position: -433px -96px; -} - -.icon-asterisk { - background-position: -456px -96px; -} - -.icon-exclamation-sign { - background-position: 0 -120px; -} - -.icon-gift { - background-position: -24px -120px; -} - -.icon-leaf { - background-position: -48px -120px; -} - -.icon-fire { - background-position: -72px -120px; -} - -.icon-eye-open { - background-position: -96px -120px; -} - -.icon-eye-close { - background-position: -120px -120px; -} - -.icon-warning-sign { - background-position: -144px -120px; -} - -.icon-plane { - background-position: -168px -120px; -} - -.icon-calendar { - background-position: -192px -120px; -} - -.icon-random { - width: 16px; - background-position: -216px -120px; -} - -.icon-comment { - background-position: -240px -120px; -} - -.icon-magnet { - background-position: -264px -120px; -} - -.icon-chevron-up { - background-position: -288px -120px; -} - -.icon-chevron-down { - background-position: -313px -119px; -} - -.icon-retweet { - background-position: -336px -120px; -} - -.icon-shopping-cart { - background-position: -360px -120px; -} - -.icon-folder-close { - background-position: -384px -120px; -} - -.icon-folder-open { - /*width: 16px; - background-position: -408px -120px;*/ - background-image: url("../img/open2.png"); - background-position: 0 center; - display: inline-block; - height: 19px; - width: 19px; - margin-top: -2px; -} - -.icon-resize-vertical { - background-position: -432px -119px; -} - -.icon-resize-horizontal { - background-position: -456px -118px; -} - -.icon-hdd { - background-position: 0 -144px; -} - -.icon-bullhorn { - background-position: -24px -144px; -} - -.icon-bell { - background-position: -48px -144px; -} - -.icon-certificate { - background-position: -72px -144px; -} - -.icon-thumbs-up { - background-position: -96px -144px; -} - -.icon-thumbs-down { - background-position: -120px -144px; -} - -.icon-hand-right { - background-position: -144px -144px; -} - -.icon-hand-left { - background-position: -168px -144px; -} - -.icon-hand-up { - background-position: -192px -144px; -} - -.icon-hand-down { - background-position: -216px -144px; -} - -.icon-circle-arrow-right { - background-position: -240px -144px; -} - -.icon-circle-arrow-left { - background-position: -264px -144px; -} - -.icon-circle-arrow-up { - background-position: -288px -144px; -} - -.icon-circle-arrow-down { - background-position: -312px -144px; -} - -.icon-globe { - background-position: -336px -144px; -} - -.icon-wrench { - background-position: -360px -144px; -} - -.icon-tasks { - background-position: -384px -144px; -} - -.icon-filter { - background-position: -408px -144px; -} - -.icon-briefcase { - background-position: -432px -144px; -} - -.icon-fullscreen { - background-position: -456px -144px; -} - -.dropup, -.dropdown { - position: relative; -} - -.dropdown-toggle { - *margin-bottom: -3px; -} - -.dropdown-toggle:active, -.open .dropdown-toggle { - outline: 0; -} - -.caret { - display: inline-block; - width: 0; - height: 0; - vertical-align: top; - border-top: 4px solid #000000; - border-right: 4px solid transparent; - border-left: 4px solid transparent; - content: ""; -} - -.dropdown .caret { - margin-top: 8px; - margin-left: 2px; -} - -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - background-color: #ffffff; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - *border-right-width: 2px; - *border-bottom-width: 2px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} - -.dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.dropdown-menu .divider { - *width: 100%; - height: 1px; - margin: 9px 1px; - *margin: -5px 0 5px; - overflow: hidden; - background-color: #e5e5e5; - border-bottom: 1px solid #ffffff; -} - -.dropdown-menu li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 20px; - color: #333333; - white-space: nowrap; -} - -.dropdown-menu li > a:hover, -.dropdown-menu li > a:focus, -.dropdown-submenu:hover > a { - color: #ffffff; - text-decoration: none; - background-color: #0081c2; - background-image: -moz-linear-gradient(top, #0088cc, #0077b3); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); - background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); - background-image: -o-linear-gradient(top, #0088cc, #0077b3); - background-image: linear-gradient(to bottom, #0088cc, #0077b3); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); -} - -.dropdown-menu .active > a, -.dropdown-menu .active > a:hover { - color: #ffffff; - text-decoration: none; - background-color: #0081c2; - background-image: -moz-linear-gradient(top, #0088cc, #0077b3); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); - background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); - background-image: -o-linear-gradient(top, #0088cc, #0077b3); - background-image: linear-gradient(to bottom, #0088cc, #0077b3); - background-repeat: repeat-x; - outline: 0; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); -} - -.dropdown-menu .disabled > a, -.dropdown-menu .disabled > a:hover { - color: #999999; -} - -.dropdown-menu .disabled > a:hover { - text-decoration: none; - cursor: default; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.open { - *z-index: 1000; -} - -.open > .dropdown-menu { - display: block; -} - -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} - -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0; - border-bottom: 4px solid #000000; - content: ""; -} - -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; -} - -.dropdown-submenu { - position: relative; -} - -.dropdown-submenu > .dropdown-menu { - top: 0; - left: 100%; - margin-top: -6px; - margin-left: -1px; - -webkit-border-radius: 0 6px 6px 6px; - -moz-border-radius: 0 6px 6px 6px; - border-radius: 0 6px 6px 6px; -} - -.dropdown-submenu:hover > .dropdown-menu { - display: block; -} - -.dropup .dropdown-submenu > .dropdown-menu { - top: auto; - bottom: 0; - margin-top: 0; - margin-bottom: -2px; - -webkit-border-radius: 5px 5px 5px 0; - -moz-border-radius: 5px 5px 5px 0; - border-radius: 5px 5px 5px 0; -} - -.dropdown-submenu > a:after { - display: block; - float: right; - width: 0; - height: 0; - margin-top: 5px; - margin-right: -10px; - border-color: transparent; - border-left-color: #cccccc; - border-style: solid; - border-width: 5px 0 5px 5px; - content: " "; -} - -.dropdown-submenu:hover > a:after { - border-left-color: #ffffff; -} - -.dropdown-submenu.pull-left { - float: none; -} - -.dropdown-submenu.pull-left > .dropdown-menu { - left: -100%; - margin-left: 10px; - -webkit-border-radius: 6px 0 6px 6px; - -moz-border-radius: 6px 0 6px 6px; - border-radius: 6px 0 6px 6px; -} - -.dropdown .dropdown-menu .nav-header { - padding-right: 20px; - padding-left: 20px; -} - -.typeahead { - z-index: 1051; - margin-top: 2px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.left_menu { - height: 100%; -} - -.well { - min-height: 200px; - height: auto; - padding: 4px 19px; - margin-bottom: 20px; - background-color: #ffffff; - border: 1px solid #CCCCCC; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} - -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} - -.well-large { - padding: 24px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.well-small { - padding: 9px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -.fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - -moz-transition: opacity 0.15s linear; - -o-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; -} - -.fade.in { - opacity: 1; -} - -.collapse { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition: height 0.35s ease; - -moz-transition: height 0.35s ease; - -o-transition: height 0.35s ease; - transition: height 0.35s ease; -} - -.collapse.in { - height: auto; -} - -.close { - float: right; - font-size: 20px; - font-weight: bold; - line-height: 20px; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} - -.close:hover { - color: #000000; - text-decoration: none; - cursor: pointer; - opacity: 0.4; - filter: alpha(opacity=40); -} - -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} - -.btn { - display: inline-block; - *display: inline; - padding: 2px 12px; - margin-bottom: 0; - *margin-left: .3em; - font-size: 11px; - line-height: 20px; - color: #333333; - text-align: center; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); - vertical-align: middle; - cursor: pointer; - background-image: url("../img/btn.gif"); - background-position: 0 -2168px; - border: 1px solid #bbbbbb; - *border: 0; - border-color: #e6e6e6 #e6e6e6 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - border-bottom-color: #a2a2a2; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); - *zoom: 1; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn-header { - padding: 0px 0px; - font-size: 11px; - line-height: 25px; - width: 140px; - font-style: normal; - font-weight: normal; - margin-left:8px; -} - -.btn:hover, -.btn:active, -.btn.active, -.btn.disabled, -.btn[disabled] { - color: #808080; -} - -.btn:active, -.btn.active { - background-position: 0 -2195px; -} - -.btn:first-child { - *margin-left: 0; -} - -.btn:hover { - color: #333333; - text-decoration: none; -} - -.btn:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -.btn.active, -.btn:active { - background-position: 0 -2195px; - outline: 0; - -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn.disabled, -.btn[disabled] { - cursor: default; - background-image: url("../img/btn.gif"); - background-position: 0 -2168px; - opacity: 0.4; - filter: alpha(opacity=40); - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -.btn-large { - padding: 11px 19px; - font-size: 17.5px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.btn-large [class^="icon-"], -.btn-large [class*=" icon-"] { - margin-top: 4px; -} - -.btn-small { - padding: 2px 10px; - font-size: 11.9px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -.btn-small [class^="icon-"], -.btn-small [class*=" icon-"] { - margin-top: 0; -} - -.btn-mini [class^="icon-"], -.btn-mini [class*=" icon-"] { - margin-top: -1px; -} - -.btn-mini { - padding: 0 6px; - font-size: 10.5px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -.btn-block { - display: block; - width: 100%; - padding-right: 0; - padding-left: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.btn-block + .btn-block { - margin-top: 5px; -} - -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} - -.btn-primary.active, -.btn-warning.active, -.btn-danger.active, -.btn-success.active, -.btn-info.active, -.btn-inverse.active { - color: rgba(255, 255, 255, 0.75); -} - -.btn { - border-color: #7b7d7f; -} - -.btn-primary { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #006dcc; - *background-color: #0044cc; - background-image: -moz-linear-gradient(top, #0088cc, #0044cc); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); - background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); - background-image: -o-linear-gradient(top, #0088cc, #0044cc); - background-image: linear-gradient(to bottom, #0088cc, #0044cc); - background-repeat: repeat-x; - border-color: #0044cc #0044cc #002a80; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-primary:hover, -.btn-primary:active, -.btn-primary.active, -.btn-primary.disabled, -.btn-primary[disabled] { - color: #ffffff; - background-color: #0044cc; - *background-color: #003bb3; -} - -.btn-primary:active, -.btn-primary.active { - background-color: #003399 \9; -} - -.btn-warning { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #faa732; - *background-color: #f89406; - background-image: -moz-linear-gradient(top, #fbb450, #f89406); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); - background-image: -webkit-linear-gradient(top, #fbb450, #f89406); - background-image: -o-linear-gradient(top, #fbb450, #f89406); - background-image: linear-gradient(to bottom, #fbb450, #f89406); - background-repeat: repeat-x; - border-color: #f89406 #f89406 #ad6704; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-warning:hover, -.btn-warning:active, -.btn-warning.active, -.btn-warning.disabled, -.btn-warning[disabled] { - color: #ffffff; - background-color: #f89406; - *background-color: #df8505; -} - -.btn-warning:active, -.btn-warning.active { - background-color: #c67605 \9; -} - -.btn-danger { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #da4f49; - *background-color: #bd362f; - background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); - background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); - background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); - background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); - background-repeat: repeat-x; - border-color: #bd362f #bd362f #802420; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-danger:hover, -.btn-danger:active, -.btn-danger.active, -.btn-danger.disabled, -.btn-danger[disabled] { - color: #ffffff; - background-color: #bd362f; - *background-color: #a9302a; -} - -.btn-danger:active, -.btn-danger.active { - background-color: #942a25 \9; -} - -.btn-success { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #5bb75b; - *background-color: #51a351; - background-image: -moz-linear-gradient(top, #62c462, #51a351); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); - background-image: -webkit-linear-gradient(top, #62c462, #51a351); - background-image: -o-linear-gradient(top, #62c462, #51a351); - background-image: linear-gradient(to bottom, #62c462, #51a351); - background-repeat: repeat-x; - border-color: #51a351 #51a351 #387038; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-success:hover, -.btn-success:active, -.btn-success.active, -.btn-success.disabled, -.btn-success[disabled] { - color: #ffffff; - background-color: #51a351; - *background-color: #499249; -} - -.btn-success:active, -.btn-success.active { - background-color: #408140 \9; -} - -.btn-info { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #49afcd; - *background-color: #2f96b4; - background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); - background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); - background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); - background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); - background-repeat: repeat-x; - border-color: #2f96b4 #2f96b4 #1f6377; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-info:hover, -.btn-info:active, -.btn-info.active, -.btn-info.disabled, -.btn-info[disabled] { - color: #ffffff; - background-color: #2f96b4; - *background-color: #2a85a0; -} - -.btn-info:active, -.btn-info.active { - background-color: #24748c \9; -} - -.btn-inverse { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #363636; - *background-color: #222222; - background-image: -moz-linear-gradient(top, #444444, #222222); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); - background-image: -webkit-linear-gradient(top, #444444, #222222); - background-image: -o-linear-gradient(top, #444444, #222222); - background-image: linear-gradient(to bottom, #444444, #222222); - background-repeat: repeat-x; - border-color: #222222 #222222 #000000; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.btn-inverse:hover, -.btn-inverse:active, -.btn-inverse.active, -.btn-inverse.disabled, -.btn-inverse[disabled] { - color: #ffffff; - background-color: #222222; - *background-color: #151515; -} - -.btn-inverse:active, -.btn-inverse.active { - background-color: #080808 \9; -} - -button.btn, -input[type="submit"].btn { - *padding-top: 3px; - *padding-bottom: 3px; -} - -button.btn::-moz-focus-inner, -input[type="submit"].btn::-moz-focus-inner { - padding: 0; - border: 0; -} - -button.btn.btn-large, -input[type="submit"].btn.btn-large { - *padding-top: 7px; - *padding-bottom: 7px; -} - -button.btn.btn-small, -input[type="submit"].btn.btn-small { - *padding-top: 3px; - *padding-bottom: 3px; -} - -button.btn.btn-mini, -input[type="submit"].btn.btn-mini { - *padding-top: 1px; - *padding-bottom: 1px; -} - -.btn-link, -.btn-link:active, -.btn-link[disabled] { - background-color: transparent; - background-image: none; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -.btn-link { - color: #0088cc; - cursor: pointer; - border-color: transparent; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.btn-link:hover { - color: #005580; - text-decoration: underline; - background-color: transparent; -} - -.btn-link[disabled]:hover { - color: #333333; - text-decoration: none; -} - -.btn-group { - position: relative; - display: inline-block; - *display: inline; - *margin-left: .3em; - font-size: 0; - white-space: nowrap; - vertical-align: middle; - *zoom: 1; -} - -.btn-group:first-child { - *margin-left: 0; -} - -.btn-group + .btn-group { - margin-left: 5px; -} - -.btn-toolbar { - margin-top: 10px; - margin-bottom: 10px; - font-size: 0; -} - -.btn-toolbar > .btn + .btn, -.btn-toolbar > .btn-group + .btn, -.btn-toolbar > .btn + .btn-group { - margin-left: 5px; -} - -.btn-group > .btn { - position: relative; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.btn-group > .btn + .btn { - margin-left: -1px; -} - -.btn-group > .btn, -.btn-group > .dropdown-menu, -.btn-group > .popover { - font-size: 14px; -} - -.btn-group > .btn-mini { - font-size: 10.5px; -} - -.btn-group > .btn-small { - font-size: 11.9px; -} - -.btn-group > .btn-large { - font-size: 17.5px; -} - -.btn-group > .btn:first-child { - margin-left: 0; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - -moz-border-radius-topleft: 4px; -} - -.btn-group > .btn:last-child, -.btn-group > .dropdown-toggle { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-topright: 4px; - -moz-border-radius-bottomright: 4px; -} - -.btn-group > .btn.large:first-child { - margin-left: 0; - -webkit-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -webkit-border-top-left-radius: 6px; - border-top-left-radius: 6px; - -moz-border-radius-bottomleft: 6px; - -moz-border-radius-topleft: 6px; -} - -.btn-group > .btn.large:last-child, -.btn-group > .large.dropdown-toggle { - -webkit-border-top-right-radius: 6px; - border-top-right-radius: 6px; - -webkit-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - -moz-border-radius-topright: 6px; - -moz-border-radius-bottomright: 6px; -} - -.btn-group > .btn:hover, -.btn-group > .btn:focus, -.btn-group > .btn:active, -.btn-group > .btn.active { - z-index: 2; -} - -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} - -.btn-group > .btn + .dropdown-toggle { - *padding-top: 5px; - padding-right: 8px; - *padding-bottom: 5px; - padding-left: 8px; - -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn-group > .btn-mini + .dropdown-toggle { - *padding-top: 2px; - padding-right: 5px; - *padding-bottom: 2px; - padding-left: 5px; -} - -.btn-group > .btn-small + .dropdown-toggle { - *padding-top: 5px; - *padding-bottom: 4px; -} - -.btn-group > .btn-large + .dropdown-toggle { - *padding-top: 7px; - padding-right: 12px; - *padding-bottom: 7px; - padding-left: 12px; -} - -.btn-group.open .dropdown-toggle { - background-image: none; - -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.btn-group.open .btn.dropdown-toggle { - background-color: #e6e6e6; -} - -.btn-group.open .btn-primary.dropdown-toggle { - background-color: #0044cc; -} - -.btn-group.open .btn-warning.dropdown-toggle { - background-color: #f89406; -} - -.btn-group.open .btn-danger.dropdown-toggle { - background-color: #bd362f; -} - -.btn-group.open .btn-success.dropdown-toggle { - background-color: #51a351; -} - -.btn-group.open .btn-info.dropdown-toggle { - background-color: #2f96b4; -} - -.btn-group.open .btn-inverse.dropdown-toggle { - background-color: #222222; -} - -.btn .caret { - margin-top: 8px; - margin-left: 0; -} - -.btn-mini .caret, -.btn-small .caret, -.btn-large .caret { - margin-top: 6px; -} - -.btn-large .caret { - border-top-width: 5px; - border-right-width: 5px; - border-left-width: 5px; -} - -.dropup .btn-large .caret { - border-bottom-width: 5px; -} - -.btn-primary .caret, -.btn-warning .caret, -.btn-danger .caret, -.btn-info .caret, -.btn-success .caret, -.btn-inverse .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -.btn-group-vertical { - display: inline-block; - *display: inline; - /* IE7 inline-block hack */ - - *zoom: 1; -} - -.btn-group-vertical > .btn { - display: block; - float: none; - max-width: 100%; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.btn-group-vertical > .btn + .btn { - margin-top: -1px; - margin-left: 0; -} - -.btn-group-vertical > .btn:first-child { - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} - -.btn-group-vertical > .btn:last-child { - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; -} - -.btn-group-vertical > .btn-large:first-child { - -webkit-border-radius: 6px 6px 0 0; - -moz-border-radius: 6px 6px 0 0; - border-radius: 6px 6px 0 0; -} - -.btn-group-vertical > .btn-large:last-child { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; -} - -.alert { - padding: 8px 35px 8px 14px; - margin-top: 10px; - margin-bottom: 10px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - background-color: #fcf8e3; - border: 1px solid #fbeed5; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.alert, -.alert h4 { - color: #c09853; -} - -.alert h4 { - margin: 0; -} - -.alert .close { - position: relative; - top: -2px; - right: -21px; - line-height: 20px; -} - -.alert-success { - color: #468847; - background-color: #dff0d8; - border-color: #d6e9c6; -} - -.alert-success h4 { - color: #468847; -} - -.alert-danger, -.alert-error { - color: #b94a48; - background-color: #f2dede; - border-color: #eed3d7; -} - -.alert-danger h4, -.alert-error h4 { - color: #b94a48; -} - -.alert-info { - color: #3a87ad; - background-color: #d9edf7; - border-color: #bce8f1; -} - -.alert-info h4 { - color: #3a87ad; -} - -.alert-block { - padding-top: 14px; - padding-bottom: 14px; -} - -.alert-block > p, -.alert-block > ul { - margin-bottom: 0; -} - -.alert-block p + p { - margin-top: 5px; -} - -.nav { - margin-bottom: 20px; - margin-left: 0; - list-style: none; -} - -.nav > li > a { - display: block; -} - -.nav > li > a:hover { - text-decoration: none; - background-color: #74aae5; -} - -.nav > li > a > img { - max-width: none; -} - -.nav > .pull-right { - float: right; -} - -.nav-header { - display: block; - padding: 0px 13px; - margin-left: 4px; - margin-right: 15px; - font-size: 12px; - font-weight: bold; - line-height: 35px; - color: #ffffff; - text-transform: uppercase; -} - -.nav li + .nav-header { - margin-top: 0px; -} - -.nav-list { - padding-top: 10px; - padding-right: 0px; - padding-left: 25px; - margin-bottom: 20px; -} - -.nav-list .firstli { - background-image: url("../img/line.png"); - background-position: 15px 0; - background-repeat: no-repeat; -} - -.nav-list > li > a, -.nav-list { - margin-right: 0px; - margin-left: -15px; -} - -.nav-list > li > a { - /*padding: 3px 20px;*/ - line-height: 35px; - padding-right: 40px; - padding-left: 38px; - overflow : hidden; - text-overflow : ellipsis; - white-space : nowrap; -} - -.import_link a:hover, -.link_focus, -.nav-list > .active > a { - color: #000000; - background-color: #e0efff; -} - -.nav-list > .active > a:hover { - background-color: #74aae5; -} - -.nav-list [class^="icon-"], -.nav-list [class*=" icon-"] { - margin-right: 2px; -} - -.nav-list .divider { - *width: 100%; - height: 1px; - margin: 9px 1px; - *margin: -5px 0 5px; - overflow: hidden; - background-color: #e5e5e5; - border-bottom: 1px solid #000000; -} - -.nav-tabs, -.nav-pills { - *zoom: 1; - padding-top: 20px; -} - -.nav-tabs:before, -.nav-pills:before, -.nav-tabs:after, -.nav-pills:after { - display: table; - line-height: 0; - content: ""; -} - -.nav-tabs:after, -.nav-pills:after { - clear: both; -} - -.nav-tabs > li, -.nav-pills > li { - min-width: 135px; - float: left; - text-align: center; -} - -.snapPage{ - width: 135px; -} - -.nav-tabs > li > a, -.nav-pills > li > a { - padding-right: 12px; - padding-left: 12px; - line-height: 14px; -} - -.nav-tabs { - border-bottom: 1px solid #CCCCCC; - font-weight: bold; -} - -.nav-tabs > li { - margin-bottom: -1px; - color: #000000; -} - -.nav-tabs > li > a { - padding-top: 0px; - padding-bottom: 0px; - line-height: 29px; - border: 1px solid #CCCCCC; -} - -.nav-tabs > li > input { - padding: 0 12px; - width: 110px; - height: 29px; - margin-bottom: 0px; - text-align: center; - overflow : hidden; - text-overflow : ellipsis; - white-space : nowrap; -} - -.nav-tabs > li > input:focus { - border-color: #C1C1C1; - background-image: url("../img/text-bg.png"); -} - -.nav-tabs > li > a:hover { - border-color: #eeeeee #eeeeee #dddddd; - background-color: #EDEDED; -} - -.nav-tabs > .active > input, -.nav-tabs > .active > a, -.nav-tabs > .active > a:hover { - color: #ffffff; - cursor: default; - background-color: #3581C7; - border: 1px solid #3581C7; -} - -.nav-pills > li > a { - padding-top: 8px; - padding-bottom: 8px; - margin-top: 2px; - margin-bottom: 2px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} - -.nav-pills > .active > a, -.nav-pills > .active > a:hover { - color: #ffffff; - background-color: #0088cc; -} - -.nav-stacked > li { - float: none; -} - -.nav-stacked > li > a { - margin-right: 0; -} - -.nav-tabs.nav-stacked { - border-bottom: 0; -} - -.nav-tabs.nav-stacked > li > a { - border: 1px solid #ddd; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.nav-tabs.nav-stacked > li:first-child > a { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topright: 4px; - -moz-border-radius-topleft: 4px; -} - -.nav-tabs.nav-stacked > li:last-child > a { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomright: 4px; - -moz-border-radius-bottomleft: 4px; -} - -.nav-tabs.nav-stacked > li > a:hover { - z-index: 2; - border-color: #ddd; -} - -.nav-pills.nav-stacked > li > a { - margin-bottom: 3px; -} - -.nav-pills.nav-stacked > li:last-child > a { - margin-bottom: 1px; -} - -.nav-tabs .dropdown-menu { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; -} - -.nav-pills .dropdown-menu { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.nav .dropdown-toggle .caret { - margin-top: 6px; - border-top-color: #0088cc; - border-bottom-color: #0088cc; -} - -.nav .dropdown-toggle:hover .caret { - border-top-color: #005580; - border-bottom-color: #005580; -} - -/* move down carets for tabs */ - -.nav-tabs .dropdown-toggle .caret { - margin-top: 8px; -} - -.nav .active .dropdown-toggle .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} - -.nav-tabs .active .dropdown-toggle .caret { - border-top-color: #555555; - border-bottom-color: #555555; -} - -.nav > .dropdown.active > a:hover { - cursor: pointer; -} - -.nav-tabs .open .dropdown-toggle, -.nav-pills .open .dropdown-toggle, -.nav > li.dropdown.open.active > a:hover { - color: #ffffff; - background-color: #999999; - border-color: #999999; -} - -.nav li.dropdown.open .caret, -.nav li.dropdown.open.active .caret, -.nav li.dropdown.open a:hover .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; - opacity: 1; - filter: alpha(opacity=100); -} - -.tabs-stacked .open > a:hover { - border-color: #999999; -} - -.tabbable { - *zoom: 1; -} - -.tabbable:before, -.tabbable:after { - display: table; - line-height: 0; - content: ""; -} - -.tabbable:after { - clear: both; -} - -.tab-content { - overflow: auto; -} - -.tabs-below > .nav-tabs, -.tabs-right > .nav-tabs, -.tabs-left > .nav-tabs { - border-bottom: 0; -} - -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} - -.tab-content > .active, -.pill-content > .active { - display: block; -} - -.tabs-below > .nav-tabs { - border-top: 1px solid #ddd; -} - -.tabs-below > .nav-tabs > li { - margin-top: -1px; - margin-bottom: 0; -} - -.tabs-below > .nav-tabs > li > a { - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; -} - -.tabs-below > .nav-tabs > li > a:hover { - border-top-color: #ddd; - border-bottom-color: transparent; -} - -.tabs-below > .nav-tabs > .active > a, -.tabs-below > .nav-tabs > .active > a:hover { - border-color: transparent #ddd #ddd #ddd; -} - -.tabs-left > .nav-tabs > li, -.tabs-right > .nav-tabs > li { - float: none; -} - -.tabs-left > .nav-tabs > li > a, -.tabs-right > .nav-tabs > li > a { - min-width: 74px; - margin-right: 0; - margin-bottom: 3px; -} - -.tabs-left > .nav-tabs { - float: left; - margin-right: 19px; - border-right: 1px solid #ddd; -} - -.tabs-left > .nav-tabs > li > a { - margin-right: -1px; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} - -.tabs-left > .nav-tabs > li > a:hover { - border-color: #eeeeee #dddddd #eeeeee #eeeeee; -} - -.tabs-left > .nav-tabs .active > a, -.tabs-left > .nav-tabs .active > a:hover { - border-color: #ddd transparent #ddd #ddd; - *border-right-color: #ffffff; -} - -.tabs-right > .nav-tabs { - float: right; - margin-left: 19px; - border-left: 1px solid #ddd; -} - -.tabs-right > .nav-tabs > li > a { - margin-left: -1px; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} - -.tabs-right > .nav-tabs > li > a:hover { - border-color: #eeeeee #eeeeee #eeeeee #dddddd; -} - -.tabs-right > .nav-tabs .active > a, -.tabs-right > .nav-tabs .active > a:hover { - border-color: #ddd #ddd #ddd transparent; - *border-left-color: #ffffff; -} - -.nav > .disabled > a { - color: #999999; -} - -.nav > .disabled > a:hover { - text-decoration: none; - cursor: default; - background-color: transparent; -} - -.navbar { - *position: relative; - *z-index: 2; - margin-bottom: 20px; - overflow: visible; -} - -.navbar-inner { - min-height: 40px; - padding-right: 20px; - padding-left: 20px; - background-color: #fafafa; - background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); - background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); - background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); - background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); - background-repeat: repeat-x; - border: 1px solid #d4d4d4; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); - *zoom: 1; - -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); - -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); -} - -.navbar-inner:before, -.navbar-inner:after { - display: table; - line-height: 0; - content: ""; -} - -.navbar-inner:after { - clear: both; -} - -.navbar .container { - width: auto; -} - -.nav-collapse.collapse { - height: auto; - overflow: visible; -} - -.navbar .brand { - display: block; - float: left; - padding: 10px 20px 10px; - margin-left: -20px; - font-size: 12px; - font-weight: 200; - color: #777777; - text-shadow: 0 1px 0 #ffffff; -} - -.navbar .brand:hover { - text-decoration: none; -} - -.navbar-text { - margin-bottom: 0; - line-height: 40px; - color: #777777; -} - -.navbar-link { - color: #777777; -} - -.navbar-link:hover { - color: #333333; -} - -.navbar .divider-vertical { - height: 40px; - margin: 0 9px; - border-right: 1px solid #ffffff; - border-left: 1px solid #f2f2f2; -} - -.navbar .btn, -.navbar .btn-group { - margin-top: 5px; -} - -.navbar .btn-group .btn, -.navbar .input-prepend .btn, -.navbar .input-append .btn { - margin-top: 0; -} - -.navbar-form { - margin-bottom: 0; - *zoom: 1; -} - -.navbar-form:before, -.navbar-form:after { - display: table; - line-height: 0; - content: ""; -} - -.navbar-form:after { - clear: both; -} - -.navbar-form input, -.navbar-form select, -.navbar-form .radio, -.navbar-form .checkbox { - margin-top: 5px; -} - -.navbar-form input, -.navbar-form select, -.navbar-form .btn { - display: inline-block; - margin-bottom: 0; -} - -.navbar-form input[type="image"], -.navbar-form input[type="checkbox"], -.navbar-form input[type="radio"] { - margin-top: 3px; -} - -.navbar-form .input-append, -.navbar-form .input-prepend { - margin-top: 5px; - white-space: nowrap; -} - -.navbar-form .input-append input, -.navbar-form .input-prepend input { - margin-top: 0; -} - -.navbar-search { - position: relative; - float: left; - margin-top: 5px; - margin-bottom: 0; -} - -.navbar-search .search-query { - padding: 4px 14px; - margin-bottom: 0; - font-family: QNAPCustomFont,'Lucida Grande','Verdana','Tahoma','Arial','Helvetica','sans-serif','Microsoft JhengHei'; - font-size: 13px; - font-weight: normal; - line-height: 1; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} - -.navbar-static-top { - position: static; - margin-bottom: 0; -} - -.navbar-static-top .navbar-inner { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: 1030; - margin-bottom: 0; -} - -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - border-width: 0 0 1px; -} - -.navbar-fixed-bottom .navbar-inner { - border-width: 1px 0 0; -} - -.navbar-fixed-top .navbar-inner, -.navbar-fixed-bottom .navbar-inner { - padding-right: 0; - padding-left: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -.navbar-static-top .container, -.navbar-fixed-top .container, -.navbar-fixed-bottom .container { - width: 1180px; -} - -.navbar-fixed-top { - top: 0; -} - -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); -} - -.navbar-fixed-bottom { - bottom: 0; -} - -.navbar-fixed-bottom .navbar-inner { - -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); - box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); -} - -.navbar .nav { - position: relative; - left: 0; - display: block; - float: left; - margin: 0 10px 0 0; -} - -.navbar .nav.pull-right { - float: right; - margin-right: 0; -} - -.navbar .nav > li { - float: left; -} - -.navbar .nav > li > a { - float: none; - padding: 10px 15px 10px; - color: #777777; - text-decoration: none; - text-shadow: 0 1px 0 #ffffff; -} - -.navbar .nav .dropdown-toggle .caret { - margin-top: 8px; -} - -.navbar .nav > li > a:focus, -.navbar .nav > li > a:hover { - color: #333333; - text-decoration: none; - background-color: transparent; -} - -.navbar .nav > .active > a, -.navbar .nav > .active > a:hover, -.navbar .nav > .active > a:focus { - color: #555555; - text-decoration: none; - background-color: #e5e5e5; - -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); - -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); -} - -.navbar .btn-navbar { - display: none; - float: right; - padding: 7px 10px; - margin-right: 5px; - margin-left: 5px; - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #ededed; - *background-color: #e5e5e5; - background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); - background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); - background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); - background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); - background-repeat: repeat-x; - border-color: #e5e5e5 #e5e5e5 #bfbfbf; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); - -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); -} - -.navbar .btn-navbar:hover, -.navbar .btn-navbar:active, -.navbar .btn-navbar.active, -.navbar .btn-navbar.disabled, -.navbar .btn-navbar[disabled] { - color: #ffffff; - background-color: #e5e5e5; - *background-color: #d9d9d9; -} - -.navbar .btn-navbar:active, -.navbar .btn-navbar.active { - background-color: #cccccc \9; -} - -.navbar .btn-navbar .icon-bar { - display: block; - width: 18px; - height: 2px; - background-color: #f5f5f5; - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; - -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); - -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); -} - -.btn-navbar .icon-bar + .icon-bar { - margin-top: 3px; -} - -.navbar .nav > li > .dropdown-menu:before { - position: absolute; - top: -7px; - left: 9px; - display: inline-block; - border-right: 7px solid transparent; - border-bottom: 7px solid #ccc; - border-left: 7px solid transparent; - border-bottom-color: rgba(0, 0, 0, 0.2); - content: ''; -} - -.navbar .nav > li > .dropdown-menu:after { - position: absolute; - top: -6px; - left: 10px; - display: inline-block; - border-right: 6px solid transparent; - border-bottom: 6px solid #ffffff; - border-left: 6px solid transparent; - content: ''; -} - -.navbar-fixed-bottom .nav > li > .dropdown-menu:before { - top: auto; - bottom: -7px; - border-top: 7px solid #ccc; - border-bottom: 0; - border-top-color: rgba(0, 0, 0, 0.2); -} - -.navbar-fixed-bottom .nav > li > .dropdown-menu:after { - top: auto; - bottom: -6px; - border-top: 6px solid #ffffff; - border-bottom: 0; -} - -.navbar .nav li.dropdown > a:hover .caret { - border-top-color: #555555; - border-bottom-color: #555555; -} - -.navbar .nav li.dropdown.open > .dropdown-toggle, -.navbar .nav li.dropdown.active > .dropdown-toggle, -.navbar .nav li.dropdown.open.active > .dropdown-toggle { - color: #555555; - background-color: #e5e5e5; -} - -.navbar .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #777777; - border-bottom-color: #777777; -} - -.navbar .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #555555; - border-bottom-color: #555555; -} - -.navbar .pull-right > li > .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right { - right: 0; - left: auto; -} - -.navbar .pull-right > li > .dropdown-menu:before, -.navbar .nav > li > .dropdown-menu.pull-right:before { - right: 12px; - left: auto; -} - -.navbar .pull-right > li > .dropdown-menu:after, -.navbar .nav > li > .dropdown-menu.pull-right:after { - right: 13px; - left: auto; -} - -.navbar .pull-right > li > .dropdown-menu .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { - right: 100%; - left: auto; - margin-right: -1px; - margin-left: 0; - -webkit-border-radius: 6px 0 6px 6px; - -moz-border-radius: 6px 0 6px 6px; - border-radius: 6px 0 6px 6px; -} - -.navbar-inverse .navbar-inner { - background-color: #1b1b1b; - background-image: -moz-linear-gradient(top, #222222, #111111); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); - background-image: -webkit-linear-gradient(top, #222222, #111111); - background-image: -o-linear-gradient(top, #222222, #111111); - background-image: linear-gradient(to bottom, #222222, #111111); - background-repeat: repeat-x; - border-color: #252525; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); -} - -.navbar-inverse .brand, -.navbar-inverse .nav > li > a { - color: #999999; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); -} - -.navbar-inverse .brand:hover, -.navbar-inverse .nav > li > a:hover { - color: #ffffff; -} - -.navbar-inverse .brand { - color: #999999; -} - -.navbar-inverse .navbar-text { - color: #999999; -} - -.navbar-inverse .nav > li > a:focus, -.navbar-inverse .nav > li > a:hover { - color: #ffffff; - background-color: transparent; -} - -.navbar-inverse .nav .active > a, -.navbar-inverse .nav .active > a:hover, -.navbar-inverse .nav .active > a:focus { - color: #ffffff; - background-color: #111111; -} - -.navbar-inverse .navbar-link { - color: #999999; -} - -.navbar-inverse .navbar-link:hover { - color: #ffffff; -} - -.navbar-inverse .divider-vertical { - border-right-color: #222222; - border-left-color: #111111; -} - -.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, -.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, -.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { - color: #ffffff; - background-color: #111111; -} - -.navbar-inverse .nav li.dropdown > a:hover .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #999999; - border-bottom-color: #999999; -} - -.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #ffffff; - border-bottom-color: #ffffff; -} - -.navbar-inverse .navbar-search .search-query { - color: #ffffff; - background-color: #515151; - border-color: #111111; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); - -webkit-transition: none; - -moz-transition: none; - -o-transition: none; - transition: none; -} - -.navbar-inverse .navbar-search .search-query:-moz-placeholder { - color: #cccccc; -} - -.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { - color: #cccccc; -} - -.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { - color: #cccccc; -} - -.navbar-inverse .navbar-search .search-query:focus, -.navbar-inverse .navbar-search .search-query.focused { - padding: 5px 15px; - color: #333333; - text-shadow: 0 1px 0 #ffffff; - background-color: #ffffff; - border: 0; - outline: 0; - -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); - box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); -} - -.navbar-inverse .btn-navbar { - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #0e0e0e; - *background-color: #040404; - background-image: -moz-linear-gradient(top, #151515, #040404); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); - background-image: -webkit-linear-gradient(top, #151515, #040404); - background-image: -o-linear-gradient(top, #151515, #040404); - background-image: linear-gradient(to bottom, #151515, #040404); - background-repeat: repeat-x; - border-color: #040404 #040404 #000000; - border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -} - -.navbar-inverse .btn-navbar:hover, -.navbar-inverse .btn-navbar:active, -.navbar-inverse .btn-navbar.active, -.navbar-inverse .btn-navbar.disabled, -.navbar-inverse .btn-navbar[disabled] { - color: #ffffff; - background-color: #040404; - *background-color: #000000; -} - -.navbar-inverse .btn-navbar:active, -.navbar-inverse .btn-navbar.active { - background-color: #000000 \9; -} - -.breadcrumb { - padding: 8px 15px; - margin: 0 0 20px; - list-style: none; - background-color: #f5f5f5; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.breadcrumb > li { - display: inline-block; - *display: inline; - text-shadow: 0 1px 0 #ffffff; - *zoom: 1; -} - -.breadcrumb > li > .divider { - padding: 0 5px; - color: #ccc; -} - -.breadcrumb > .active { - color: #999999; -} - -.pagination { - margin: 20px 0; -} - -.pagination ul { - display: inline-block; - *display: inline; - margin-bottom: 0; - margin-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - *zoom: 1; - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); -} - -.pagination ul > li { - display: inline; -} - -.pagination ul > li > a, -.pagination ul > li > span { - float: left; - padding: 4px 12px; - line-height: 20px; - text-decoration: none; - background-color: #ffffff; - border: 1px solid #dddddd; - border-left-width: 0; -} - -.pagination ul > li > a:hover, -.pagination ul > .active > a, -.pagination ul > .active > span { - background-color: #f5f5f5; -} - -.pagination ul > .active > a, -.pagination ul > .active > span { - color: #999999; - cursor: default; -} - -.pagination ul > .disabled > span, -.pagination ul > .disabled > a, -.pagination ul > .disabled > a:hover { - color: #999999; - cursor: default; - background-color: transparent; -} - -.pagination ul > li:first-child > a, -.pagination ul > li:first-child > span { - border-left-width: 1px; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - -moz-border-radius-topleft: 4px; -} - -.pagination ul > li:last-child > a, -.pagination ul > li:last-child > span { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-topright: 4px; - -moz-border-radius-bottomright: 4px; -} - -.pagination-centered { - text-align: center; -} - -.pagination-right { - text-align: right; -} - -.pagination-large ul > li > a, -.pagination-large ul > li > span { - padding: 11px 19px; - font-size: 17.5px; -} - -.pagination-large ul > li:first-child > a, -.pagination-large ul > li:first-child > span { - -webkit-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -webkit-border-top-left-radius: 6px; - border-top-left-radius: 6px; - -moz-border-radius-bottomleft: 6px; - -moz-border-radius-topleft: 6px; -} - -.pagination-large ul > li:last-child > a, -.pagination-large ul > li:last-child > span { - -webkit-border-top-right-radius: 6px; - border-top-right-radius: 6px; - -webkit-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - -moz-border-radius-topright: 6px; - -moz-border-radius-bottomright: 6px; -} - -.pagination-mini ul > li:first-child > a, -.pagination-small ul > li:first-child > a, -.pagination-mini ul > li:first-child > span, -.pagination-small ul > li:first-child > span { - -webkit-border-bottom-left-radius: 3px; - border-bottom-left-radius: 3px; - -webkit-border-top-left-radius: 3px; - border-top-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - -moz-border-radius-topleft: 3px; -} - -.pagination-mini ul > li:last-child > a, -.pagination-small ul > li:last-child > a, -.pagination-mini ul > li:last-child > span, -.pagination-small ul > li:last-child > span { - -webkit-border-top-right-radius: 3px; - border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - border-bottom-right-radius: 3px; - -moz-border-radius-topright: 3px; - -moz-border-radius-bottomright: 3px; -} - -.pagination-small ul > li > a, -.pagination-small ul > li > span { - padding: 2px 10px; - font-size: 11.9px; -} - -.pagination-mini ul > li > a, -.pagination-mini ul > li > span { - padding: 0 6px; - font-size: 10.5px; -} - -.pager { - margin: 20px 0; - text-align: center; - list-style: none; - *zoom: 1; -} - -.pager:before, -.pager:after { - display: table; - line-height: 0; - content: ""; -} - -.pager:after { - clear: both; -} - -.pager li { - display: inline; -} - -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #fff; - border: 1px solid #ddd; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} - -.pager li > a:hover { - text-decoration: none; - background-color: #f5f5f5; -} - -.pager .next > a, -.pager .next > span { - float: right; -} - -.pager .previous > a, -.pager .previous > span { - float: left; -} - -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > span { - color: #999999; - cursor: default; - background-color: #fff; -} - -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000000; -} - -.modal-backdrop.fade { - opacity: 0; -} - -.modal-backdrop, -.modal-backdrop.fade.in { - opacity: 0.5; - filter: alpha(opacity=80); -} - -.modal { - position: fixed; - top: 10%; - left: 50%; - z-index: 1050; - width: 560px; - margin-left: -280px; - background-color: #ffffff; - border: 1px solid #999; - border: 1px solid rgba(0, 0, 0, 0.3); - *border: 1px solid #999; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - outline: none; - -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; -} - -.modal.fade { - top: -25%; - -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; - -moz-transition: opacity 0.3s linear, top 0.3s ease-out; - -o-transition: opacity 0.3s linear, top 0.3s ease-out; - transition: opacity 0.3s linear, top 0.3s ease-out; -} - -.modal.fade.in { - top: 10%; -} - -.modal-header { - padding: 0px 15px; - border-bottom: 1px solid #eee; - background-color: #DDDDDD; - background-image: url("/media/img/title_bg.png"); - background-repeat: repeat; - text-align: center; - -webkit-border-radius: 6px 6px 0 0; - -moz-border-radius: 6px 6px 0 0; - border-radius: 6px 6px 0 0; -} - -.modal-header .close { - margin-top: 2px; -} - -.modal-header h3 { - margin: 0; - font-size: 12px; - line-height: 37px; -} - -.modal-body { - position: relative; - max-height: 360px; - padding: 10px; - overflow-y: auto; - -webkit-overflow-scrolling: touch; -} - -.modal-form { - margin-bottom: 0; -} - -.modal-footer { - padding: 9px 15px 10px; - margin-bottom: 0; - text-align: right; - background-color: #E7E7E7; - border-top: 1px solid #ddd; - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; - *zoom: 1; - -webkit-box-shadow: inset 0 1px 0 #ffffff; - -moz-box-shadow: inset 0 1px 0 #ffffff; - box-shadow: inset 0 1px 0 #ffffff; -} - -.modal-footer:before, -.modal-footer:after { - display: table; - line-height: 0; - content: ""; -} - -.modal-footer:after { - clear: both; -} - -.modal-footer .btn + .btn { - margin-bottom: 0; - margin-left: 5px; -} - -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} - -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} - -.tooltip { - position: absolute; - z-index: 1030; - display: block; - padding: 5px; - font-size: 11px; - opacity: 0; - filter: alpha(opacity=0); - visibility: visible; -} - -.tooltip.in { - opacity: 0.8; - filter: alpha(opacity=80); -} - -.tooltip.top { - margin-top: -3px; -} - -.tooltip.right { - margin-left: 3px; -} - -.tooltip.bottom { - margin-top: 3px; -} - -.tooltip.left { - margin-left: -3px; -} - -.tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #ffffff; - text-align: center; - text-decoration: none; - background-color: #000000; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-top-color: #000000; - border-width: 5px 5px 0; -} - -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-right-color: #000000; - border-width: 5px 5px 5px 0; -} - -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-left-color: #000000; - border-width: 5px 0 5px 5px; -} - -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-bottom-color: #000000; - border-width: 0 5px 5px; -} - -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1010; - display: none; - width: 236px; - padding: 1px; - text-align: left; - white-space: normal; - background-color: #ffffff; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} - -.popover.top { - margin-top: -10px; -} - -.popover.right { - margin-left: 10px; -} - -.popover.bottom { - margin-top: 10px; -} - -.popover.left { - margin-left: -10px; -} - -.popover-title { - padding: 8px 14px; - margin: 0; - font-size: 14px; - font-weight: normal; - line-height: 18px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - -webkit-border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - border-radius: 5px 5px 0 0; -} - -.popover-content { - padding: 9px 14px; -} - -.popover .arrow, -.popover .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.popover .arrow { - border-width: 11px; -} - -.popover .arrow:after { - border-width: 10px; - content: ""; -} - -.popover.top .arrow { - bottom: -11px; - left: 50%; - margin-left: -11px; - border-top-color: #999; - border-top-color: rgba(0, 0, 0, 0.25); - border-bottom-width: 0; -} - -.popover.top .arrow:after { - bottom: 1px; - margin-left: -10px; - border-top-color: #ffffff; - border-bottom-width: 0; -} - -.popover.right .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-right-color: #999; - border-right-color: rgba(0, 0, 0, 0.25); - border-left-width: 0; -} - -.popover.right .arrow:after { - bottom: -10px; - left: 1px; - border-right-color: #ffffff; - border-left-width: 0; -} - -.popover.bottom .arrow { - top: -11px; - left: 50%; - margin-left: -11px; - border-bottom-color: #999; - border-bottom-color: rgba(0, 0, 0, 0.25); - border-top-width: 0; -} - -.popover.bottom .arrow:after { - top: 1px; - margin-left: -10px; - border-bottom-color: #ffffff; - border-top-width: 0; -} - -.popover.left .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-left-color: #999; - border-left-color: rgba(0, 0, 0, 0.25); - border-right-width: 0; -} - -.popover.left .arrow:after { - right: 1px; - bottom: -10px; - border-left-color: #ffffff; - border-right-width: 0; -} - -.thumbnails { - margin-left: -20px; - list-style: none; - *zoom: 1; -} - -.thumbnails:before, -.thumbnails:after { - display: table; - line-height: 0; - content: ""; -} - -.thumbnails:after { - clear: both; -} - -.row-fluid .thumbnails { - margin-left: 0; -} - -.thumbnails > li { - float: left; - margin-bottom: 20px; - margin-left: 20px; -} - -.thumbnail { - display: block; - padding: 4px; - line-height: 20px; - border: 1px solid #ddd; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; -} - -a.thumbnail:hover { - border-color: #0088cc; - -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); - -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); - box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); -} - -.thumbnail > img { - display: block; - max-width: 100%; - margin-right: auto; - margin-left: auto; -} - -.thumbnail .caption { - padding: 9px; - color: #555555; -} - -.media, -.media-body { - overflow: hidden; - *overflow: visible; - zoom: 1; -} - -.media, -.media .media { - margin-top: 15px; -} - -.media:first-child { - margin-top: 0; -} - -.media-object { - display: block; -} - -.media-heading { - margin: 0 0 5px; -} - -.media .pull-left { - margin-right: 10px; -} - -.media .pull-right { - margin-left: 10px; -} - -.media-list { - margin-left: 0; - list-style: none; -} - -.label, -.badge { - display: inline-block; - padding: 2px 4px; - font-size: 11.844px; - font-weight: bold; - line-height: 14px; - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - white-space: nowrap; - vertical-align: baseline; - background-color: #999999; -} - -.label { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -.badge { - padding-right: 9px; - padding-left: 9px; - -webkit-border-radius: 9px; - -moz-border-radius: 9px; - border-radius: 9px; -} - -.label:empty, -.badge:empty { - display: none; -} - -a.label:hover, -a.badge:hover { - color: #ffffff; - text-decoration: none; - cursor: pointer; -} - -.label-important, -.badge-important { - background-color: #b94a48; -} - -.label-important[href], -.badge-important[href] { - background-color: #953b39; -} - -.label-warning, -.badge-warning { - background-color: #f89406; -} - -.label-warning[href], -.badge-warning[href] { - background-color: #c67605; -} - -.label-success, -.badge-success { - background-color: #468847; -} - -.label-success[href], -.badge-success[href] { - background-color: #356635; -} - -.label-info, -.badge-info { - background-color: #3a87ad; -} - -.label-info[href], -.badge-info[href] { - background-color: #2d6987; -} - -.label-inverse, -.badge-inverse { - background-color: #333333; -} - -.label-inverse[href], -.badge-inverse[href] { - background-color: #1a1a1a; -} - -.btn .label, -.btn .badge { - position: relative; - top: -1px; -} - -.btn-mini .label, -.btn-mini .badge { - top: 0; -} - -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-moz-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-ms-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -@-o-keyframes progress-bar-stripes { - from { - background-position: 0 0; - } - to { - background-position: 40px 0; - } -} - -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} - -.progress { - height: 16px; - margin-bottom: 20px; - overflow: hidden; - background-color: #f7f7f7; - background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); - background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); - background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); - background-repeat: repeat-x; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -} - -.progress .bar { - float: left; - width: 0; - height: 100%; - font-size: 12px; - color: #ffffff; - text-align: center; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); - background-color: #0e90d2; - background-image: -moz-linear-gradient(top, #149bdf, #0480be); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); - background-image: -webkit-linear-gradient(top, #149bdf, #0480be); - background-image: -o-linear-gradient(top, #149bdf, #0480be); - background-image: linear-gradient(to bottom, #149bdf, #0480be); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: width 0.6s ease; - -moz-transition: width 0.6s ease; - -o-transition: width 0.6s ease; - transition: width 0.6s ease; -} - -.progress .bar + .bar { - -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); -} - -.progress-striped .bar { - background-color: #149bdf; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - -webkit-background-size: 40px 40px; - -moz-background-size: 40px 40px; - -o-background-size: 40px 40px; - background-size: 40px 40px; -} - -.progress.active .bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -moz-animation: progress-bar-stripes 2s linear infinite; - -ms-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} - -.progress-danger .bar, -.progress .bar-danger { - background-color: #dd514c; - background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); - background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); - background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); - background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); -} - -.progress-danger.progress-striped .bar, -.progress-striped .bar-danger { - background-color: #ee5f5b; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-success .bar, -.progress .bar-success { - background-color: #5eb95e; - background-image: -moz-linear-gradient(top, #62c462, #57a957); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); - background-image: -webkit-linear-gradient(top, #62c462, #57a957); - background-image: -o-linear-gradient(top, #62c462, #57a957); - background-image: linear-gradient(to bottom, #62c462, #57a957); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); -} - -.progress-success.progress-striped .bar, -.progress-striped .bar-success { - background-color: #62c462; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-info .bar, -.progress .bar-info { - background-color: #4bb1cf; - background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); - background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); - background-image: -o-linear-gradient(top, #5bc0de, #339bb9); - background-image: linear-gradient(to bottom, #5bc0de, #339bb9); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); -} - -.progress-info.progress-striped .bar, -.progress-striped .bar-info { - background-color: #5bc0de; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.progress-warning .bar, -.progress .bar-warning { - background-color: #faa732; - background-image: -moz-linear-gradient(top, #fbb450, #f89406); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); - background-image: -webkit-linear-gradient(top, #fbb450, #f89406); - background-image: -o-linear-gradient(top, #fbb450, #f89406); - background-image: linear-gradient(to bottom, #fbb450, #f89406); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); -} - -.progress-warning.progress-striped .bar, -.progress-striped .bar-warning { - background-color: #fbb450; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); -} - -.accordion { - margin-bottom: 20px; -} - -.accordion-group { - margin-bottom: 2px; - border: 1px solid #e5e5e5; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} - -.accordion-heading { - border-bottom: 0; -} - -.accordion-heading .accordion-toggle { - display: block; - padding: 8px 15px; -} - -.accordion-toggle { - cursor: pointer; -} - -.accordion-inner { - padding: 9px 15px; - border-top: 1px solid #e5e5e5; -} - -.carousel { - position: relative; - margin-bottom: 20px; - line-height: 1; -} - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden; -} - -.carousel-inner > .item { - position: relative; - display: none; - -webkit-transition: 0.6s ease-in-out left; - -moz-transition: 0.6s ease-in-out left; - -o-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} - -.carousel-inner > .item > img { - display: block; - line-height: 1; -} - -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} - -.carousel-inner > .active { - left: 0; -} - -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} - -.carousel-inner > .next { - left: 100%; -} - -.carousel-inner > .prev { - left: -100%; -} - -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} - -.carousel-inner > .active.left { - left: -100%; -} - -.carousel-inner > .active.right { - left: 100%; -} - -.carousel-control { - position: absolute; - top: 40%; - left: 15px; - width: 40px; - height: 40px; - margin-top: -20px; - font-size: 60px; - font-weight: 100; - line-height: 30px; - color: #ffffff; - text-align: center; - background: #222222; - border: 3px solid #ffffff; - -webkit-border-radius: 23px; - -moz-border-radius: 23px; - border-radius: 23px; - opacity: 0.5; - filter: alpha(opacity=50); -} - -.carousel-control.right { - right: 15px; - left: auto; -} - -.carousel-control:hover { - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} - -.carousel-caption { - position: absolute; - right: 0; - bottom: 0; - left: 0; - padding: 15px; - background: #333333; - background: rgba(0, 0, 0, 0.75); -} - -.carousel-caption h4, -.carousel-caption p { - line-height: 20px; - color: #ffffff; -} - -.carousel-caption h4 { - margin: 0 0 5px; -} - -.carousel-caption p { - margin-bottom: 0; -} - -.hero-unit-wizard { - padding: 0px 96px; - font-size: 12px; - height:100%; - /*line-height: 30px;*/ - color: #000000; - /*background-color: #ffffff;*/ - background-color: transparent; - float:left; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.hero-unit-wizard-left { - width: 96px; - height: auto; - float:left; - position: relative; - left: 0; - top: 0; -} - -.hero-unit-wizard-right { - position: relative; - display: inline-block; - width: 96px; - height: auto; - float:right; - /*position: absolute; - float:right; - left: 686px;*/ - right: 0; - top: 0; -} - -.hero-unit-wizard h2 { - font-size: 20px; - font-weight: bold; - color: #0A5FC8; - text-align: center; - margin-top: 0; - margin-bottom: 10px; -} - -.hero-unit-wizard .content_block { - background-color: #F2F2F2; - width: 560px; - height: auto; - padding: 16px 15px; -} - -.blank_block_step { - font-size: 14px; - width: 250px; - height: 60px; - background-color: #ffffff; -} - -.blank_block_step img { - margin-top: 12px; - margin-left: 17px; -} - -.step_left { - float:left; -} -.step_right { - float:right; -} - -.step_left p { - display: inline-block; - padding-top: 12px; - padding-left: 18px; - width: 164px; - word-break: break-all; -} - -.step_right p { - display: inline-block; - word-break: break-all; - width: 164px; - padding-top: 12px; - padding-left: 18px; - line-height: 16px; -} - -.content-block-bottom { - text-align:center; - margin-top:12px; -} - -.content-block-bottom .dot-enable { - display: inline-block; - vertical-align: text-top; - background-image: url("/media/img/wizard/icon.png"); - background-repeat: no-repeat; - background-color: transparent; - height: 8px; - width: 8px; - background-position: 0 -100px; -} - -.content-block-bottom .dot-disable { - display: inline-block; - vertical-align: text-top; - background-image: url("/media/img/wizard/icon.png"); - background-repeat: no-repeat; - background-color: transparent; - height: 8px; - width: 8px; - background-position: 0 -150px; -} - -.wiz-btn-finish { - display: inline-block; - vertical-align: text-top; - background-image: url("/media/img/wizard/icon.png"); - background-repeat: no-repeat; - background-color: transparent; - height: 36px; - width: 123px; - background-position: 0 -52px; -} - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: #eeeeee; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; -} - -.hero-unit h3 { - margin-bottom: 0; - font-size: 40px; - line-height: 1; - letter-spacing: -1px; - color: inherit; -} - -.hero-unit li { - line-height: 30px; -} - -.pull-right { - float: right; -} - -.pull-left { - float: left; -} - -.hide { - display: none; -} - -.show { - display: block; -} - -.invisible { - visibility: hidden; -} - -.affix { - position: fixed; -} - -.icon-loading { - display: inline-block; - width: 64px; - height: 64px; - background-image: url("../img/loading.gif"); - background-position: 0 -} - -.icons-task-log { - display: inline-block; - width: 16px; - height: 16px; - background-image: url("../img/icons.png?cnt=20140424"); /* just random number */ - background-position: 0 -113px; - margin-top: 9px; - float: right; -} - -.icon-connect { - display: inline-block; - width: 16px; - height: 16px; - background-image: url("../img/icon_connect.png"); - background-position: 0 -} - -.icon-disconnect { - display: inline-block; - width: 16px; - height: 16px; - background-image: url("../img/icon_disconnect.png"); - background-position: 0 -} - -.icon-clone { - display: inline-block; - width: 16px; - height: 16px; - background-image: url("../img/clone.png"); - background-position: 0 -} - -/* used for log page */ -.xtb-sep{ - background-position:center; - background-repeat:no-repeat; - display:inline-block; - font-size:1px; - height:16px; - width:4px; - overflow:hidden; - cursor:default; - margin:0 2px 0; - border:0; - vertical-align:middle; - background:url("../img/grid-split.gif") repeat scroll 0 0 #222222; -} - -.icon-page-first { - display: inline-block; - width: 16px; - height: 16px; - background-image: url("../img/page-first.gif"); - background-position: 0; -} - -.icon-page-first[disabled] { - cursor: default; - background-image: url("../img/page-first-disabled.gif"); -} - -.icon-page-last { - display: inline-block; - width: 16px; - height: 16px; - background-image: url("../img/page-last.gif"); - background-position: 0; -} - -.icon-page-last[disabled] { - cursor: default; - background-image: url("../img/page-last-disabled.gif"); -} - -.icon-page-next { - display: inline-block; - width: 16px; - height: 16px; - background-image: url("../img/page-next.gif"); - background-position: 0; -} - -.icon-page-next[disabled] { - cursor: default; - background-image: url("../img/page-next-disabled.gif"); -} - -.icon-page-prev { - display: inline-block; - width: 16px; - height: 16px; - background-image: url("../img/page-prev.gif"); - background-position: 0; -} - -.icon-page-prev[disabled] { - cursor: default; - background-image: url("../img/page-prev-disabled.gif"); -} - -.icon-page-refresh { - display: inline-block; - width: 16px; - height: 16px; - background-image: url("../img/page-refresh.gif"); - background-position: 0; -} - -div._bullet_arrow_up input { -background:url("../img/_bullet_arrow_up.png") no-repeat; -cursor:pointer; -border: none; -} - -div._bullet_arrow_down input { -background:url("../img/_bullet_arrow_down.png") no-repeat; -cursor:pointer; -border: none; -} - -/*VNC*/ -.vnc-logout{ - background-image: url("../img/vnc/logout.png"); - background-repeat: no-repeat; - display: inline-block; - height: 14px; - width: 14px; - margin-bottom:-3px\9; -} -.vnc-suspend { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/suspend.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-reset { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/reset.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-shutdown { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/shutdown.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-destroy { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/destroy.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-snapshot { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/snapshot.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-quality { - display: inline-block; - width: 18px; - height: 12px; - margin-top: 1.2px; - *margin-right: .3em; - line-height: 12px; - vertical-align: text-top; - /*background-image: url("../img/glyphicons-halflings.png"); - background-repeat: no-repeat; - background-position: -96px -120px;*/ -} - -.eye_h { - background-image: url("../img/eye_h.png"); - background-repeat: no-repeat; -} - -.eye_m { - background-image: url("../img/eye_m.png"); - background-repeat: no-repeat; -} - -.eye_l { - background-image: url("../img/eye_l.png"); - background-repeat: no-repeat; -} - -.eye_u { - background-image: url("../img/eye_u.png"); - background-repeat: no-repeat; -} - -.vnc-resume { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/resume.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-virtio { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/install.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-clearconfig { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/cancel.png"); - background-position: 0; -} - -.vnc-ctrlaltdel { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/c_a_d.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-autofit { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/autofit.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-restore { - background-image: url("../img/vnc/restore.png"); - margin-bottom:-3px\9; -} - -.vnc-fullscreen { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/full_screen.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-fullscreenExit { - background-image: url("../img/vnc/exit_full.png"); - margin-bottom:-3px\9; -} - -.vnc-multikey { - display: inline-block; - width: 14px; - height: 14px; - background-image: url("../img/vnc/com.png"); - background-position: 0; - margin-bottom:-3px\9; -} - -.vnc-autologout { - width: 16px; - height: 14px; - background-image: url("../img/vnc/auto_logout.png"); - background-repeat: no-repeat; - display: inline-block; - background-position: 0 1px; - margin-bottom:-3px\9; -} - -.vnc-autologin { - width: 16px; - height: 14px; - background-image: url("../img/vnc/auto_login.png"); - background-repeat: no-repeat; - display: inline-block; - background-position: 0; - margin-bottom:-3px\9; -} - -.helpTip{ - display:none; -} - -.helpTipHeadBg{ - position: absolute; - width: 0px; - height: 0px; - border-style: solid; - border-width: 0 6px 8px; - border-color: transparent transparent #333 transparent; -} - -.helpTipHead{ - position: absolute; - width: 0px; - height: 0px; - border-style: solid; - border-width: 0 6px 8px; - border-color: transparent transparent #4d4d4d transparent; - z-index:1002; -} - -.helpTipBody{ - z-index:1001; - position: absolute; - background-color:#4D4D4D; - color:#FFF; - border:1px solid #333; - border-radius:5px; - padding:8px 14px; - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); -} - -.tipTitle{ - border-bottom:1px solid #FFF; - font-size:14px; - font-weight:bold; - color:#0FF; -} - -.tipFootnote{ - color: #FF0000; - display: inline-block; - font-size: 8px; - font-weight: bold; - margin-top: -4px; - vertical-align: top; -} - -.tipSubTitle{ - font-size:14px; - color:yellow; -} - -.triangleDown{ - position:relative; - border-color: #FFF transparent transparent transparent; - border-style: solid; - border-width: 6px 4px 0px; - margin-left: 10px; - top:12px; - cursor: pointer; -} - -.triangleUp{ - position:relative; - border-color: transparent transparent #FFF transparent; - border-style: solid; - border-width: 0px 4px 6px; - margin-left: 10px; - bottom: 10px; - cursor: pointer; -} - -.addPermMenuContent{ - position: absolute; - z-index:10001; - background-color: #F0F0F0; - color:#222; - border:1px solid #7D7D7D; - line-height:25px; - background-image: url("../img/nas_default/menu.gif"); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); -} - -.menuContent{ - position: absolute; - z-index:10001; - background-color: #F0F0F0; - color:#222; - border:1px solid #7D7D7D; - line-height:25px; - background-image: url("../img/nas_default/menu.gif"); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); -} - -.menuContent ul{ - padding:2px; - overflow:hidden; - margin:0px; -} - -.menuContent li{ - padding:2px; - overflow:hidden; - line-height:100%; - display: block; - padding: 1px; - white-space: nowrap; - font-size: 12px; - margin: 0 1px; - border: 1px solid transparent; -} - -.menuContent li:hover{ - background-image: url("../img/nas_default/item-over.gif"); - background-color: #F1F1F1; - background-position: left bottom; - background-repeat: repeat-x; - border: 1px solid #ACACAC; - margin: 0 1px; - padding: 1px; -} - -.menuContent li div{ - color: #222222; - cursor: pointer; - display: block; - line-height: 16px; - padding: 3px 21px 3px 27px; - position: relative; - text-decoration: none; - white-space: nowrap; -} - -#closeMask{ - position: absolute; - width:100%; - height:100%; - left: 0; - top: 0; - z-index:1000; -} - -.account { - background-image: url("../img/account/account.png"); - display: inline-block; - width: 28px; - height: 16px; - position:relative; - margin-left:13px; - top:7px; - cursor:pointer; -} - -.account:hover { - background-image: url("../img/account/account_over.png"); -} - -.cancelBtn { - background-image: url("../img/account/cancel.png"); - background-position: 0px 0px; - display: inline-block; - width: 9px; - height: 8px; - vertical-align: middle; - cursor:pointer; -} - -.cancelBtn:hover { - background-position: -9px 0px; -} - -.plusBtn { - background-image: url("../img/account/plus.png"); - background-position: 0px 0px; - display: inline-block; - width: 17px; - height: 17px; - cursor:pointer; - margin-top: 1px; -} - -.plusBtn:hover { - background-position: -17px 0px; -} - -.permissionBtn { - background-image: url("../img/account/permission.png"); - background-repeat: no-repeat; - display: inline-block; - height: 14px; - line-height: 14px; - margin-top: 1px; - vertical-align: text-top; - width: 14px; -} - -.accountContent{ - background-color: #F2F2F2; - border: 1px solid #4D4D4D; - border-radius: 7px; - color: #222222; - line-height: 20px; - position: absolute; - z-index: 10001; - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); -} - -.accountContent ul{ - padding:2px; - overflow:hidden; - margin:0px; -} - -.accountBtn{ - cursor:pointer; - line-height: 27px; - border-radius:0px; - padding: 0 18px; -} - -.accountLastBtn{ - border-radius:0 0 5px 5px; -} - -.accountBtn:hover{ - background-color:#A1C4D6; -} - -.accountHr{ - /*border-bottom:1px solid #B2B2B2;*/ - height:70px; - padding: 0 18px; -} - -.showTime{ - color: #065793; -} - -.accountHeadBg{ - position: absolute; - width: 0px; - height: 0px; - border-style: solid; - border-width: 0 6px 8px; - border-color: transparent transparent #4D4D4D transparent; - z-index:10002; -} - -.accountHead{ - position: absolute; - width: 0px; - height: 0px; - border-style: solid; - border-width: 0 6px 8px; - border-color: transparent transparent #F2F2F2 transparent; - z-index:10003; -} - -.checkbox_check { - display: inline-block; - background-image: url("../img/account/checker.png "); - margin-top: 5px; - width: 21px; - height: 21px; - background-position: 0px 0px; - background-repeat: no-repeat; -} -.checkbox_checked { - display: inline-block; - background-image: url("../img/account/checker.png "); - margin-top: 5px; - width: 21px; - height: 21px; - background-position: -41px 0px; - background-repeat: no-repeat; -} - -.vncSnapshotHeadBg{ - position: absolute; - width: 0px; - height: 0px; - border-style: solid; - border-width: 8px 6px 0; - border-color: #333 transparent transparent transparent; -} - -.vncSnapshotHead{ - position: absolute; - width: 0px; - height: 0px; - border-style: solid; - border-width: 8px 6px 0; - border-color: #4d4d4d transparent transparent transparent; - z-index:1002; -} \ No newline at end of file diff --git a/noVNC/media/css/jquery-ui.css b/noVNC/media/css/jquery-ui.css deleted file mode 100755 index 9a91f46..0000000 --- a/noVNC/media/css/jquery-ui.css +++ /dev/null @@ -1,1177 +0,0 @@ -/*! jQuery UI - v1.10.3 - 2013-05-03 -* http://jqueryui.com -* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px -* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { - display: none; -} -.ui-helper-hidden-accessible { - border: 0; - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; -} -.ui-helper-reset { - margin: 0; - padding: 0; - border: 0; - outline: 0; - line-height: 1.3; - text-decoration: none; - font-size: 100%; - list-style: none; -} -.ui-helper-clearfix:before, -.ui-helper-clearfix:after { - content: ""; - display: table; - border-collapse: collapse; -} -.ui-helper-clearfix:after { - clear: both; -} -.ui-helper-clearfix { - min-height: 0; /* support: IE7 */ -} -.ui-helper-zfix { - width: 100%; - height: 100%; - top: 0; - left: 0; - position: absolute; - opacity: 0; - filter:Alpha(Opacity=0); -} - -.ui-front { - z-index: 100; -} - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { - cursor: default !important; -} - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { - display: block; - text-indent: -99999px; - overflow: hidden; - background-repeat: no-repeat; -} - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; -} -.ui-accordion .ui-accordion-header { - display: block; - cursor: pointer; - position: relative; - margin-top: 2px; - padding: .5em .5em .5em .7em; - min-height: 0; /* support: IE7 */ -} -.ui-accordion .ui-accordion-icons { - padding-left: 2.2em; -} -.ui-accordion .ui-accordion-noicons { - padding-left: .7em; -} -.ui-accordion .ui-accordion-icons .ui-accordion-icons { - padding-left: 2.2em; -} -.ui-accordion .ui-accordion-header .ui-accordion-header-icon { - position: absolute; - left: .5em; - top: 50%; - margin-top: -8px; -} -.ui-accordion .ui-accordion-content { - padding: 1em 2.2em; - border-top: 0; - overflow: auto; -} -.ui-autocomplete { - position: absolute; - top: 0; - left: 0; - cursor: default; -} -.ui-button { - display: inline-block; - position: relative; - padding: 0; - line-height: normal; - margin-right: .1em; - cursor: pointer; - vertical-align: middle; - text-align: center; - overflow: visible; /* removes extra width in IE */ -} -.ui-button, -.ui-button:link, -.ui-button:visited, -.ui-button:hover, -.ui-button:active { - text-decoration: none; -} -/* to make room for the icon, a width needs to be set here */ -.ui-button-icon-only { - width: 2.2em; -} -/* button elements seem to need a little more width */ -button.ui-button-icon-only { - width: 2.4em; -} -.ui-button-icons-only { - width: 3.4em; -} -button.ui-button-icons-only { - width: 3.7em; -} - -/* button text element */ -.ui-button .ui-button-text { - display: block; - line-height: normal; -} -.ui-button-text-only .ui-button-text { - padding: .4em 1em; -} -.ui-button-icon-only .ui-button-text, -.ui-button-icons-only .ui-button-text { - padding: .4em; - text-indent: -9999999px; -} -.ui-button-text-icon-primary .ui-button-text, -.ui-button-text-icons .ui-button-text { - padding: .4em 1em .4em 2.1em; -} -.ui-button-text-icon-secondary .ui-button-text, -.ui-button-text-icons .ui-button-text { - padding: .4em 2.1em .4em 1em; -} -.ui-button-text-icons .ui-button-text { - padding-left: 2.1em; - padding-right: 2.1em; -} -/* no icon support for input elements, provide padding by default */ -input.ui-button { - padding: .4em 1em; -} - -/* button icon element(s) */ -.ui-button-icon-only .ui-icon, -.ui-button-text-icon-primary .ui-icon, -.ui-button-text-icon-secondary .ui-icon, -.ui-button-text-icons .ui-icon, -.ui-button-icons-only .ui-icon { - position: absolute; - top: 50%; - margin-top: -8px; -} -.ui-button-icon-only .ui-icon { - left: 50%; - margin-left: -8px; -} -.ui-button-text-icon-primary .ui-button-icon-primary, -.ui-button-text-icons .ui-button-icon-primary, -.ui-button-icons-only .ui-button-icon-primary { - left: .5em; -} -.ui-button-text-icon-secondary .ui-button-icon-secondary, -.ui-button-text-icons .ui-button-icon-secondary, -.ui-button-icons-only .ui-button-icon-secondary { - right: .5em; -} - -/* button sets */ -.ui-buttonset { - margin-right: 7px; -} -.ui-buttonset .ui-button { - margin-left: 0; - margin-right: -.3em; -} - -/* workarounds */ -/* reset extra padding in Firefox, see h5bp.com/l */ -input.ui-button::-moz-focus-inner, -button.ui-button::-moz-focus-inner { - border: 0; - padding: 0; -} -.ui-datepicker { - width: 17em; - padding: .2em .2em 0; - display: none; -} -.ui-datepicker .ui-datepicker-header { - position: relative; - padding: .2em 0; -} -.ui-datepicker .ui-datepicker-prev, -.ui-datepicker .ui-datepicker-next { - position: absolute; - top: 2px; - width: 1.8em; - height: 1.8em; -} -.ui-datepicker .ui-datepicker-prev-hover, -.ui-datepicker .ui-datepicker-next-hover { - top: 1px; -} -.ui-datepicker .ui-datepicker-prev { - left: 2px; -} -.ui-datepicker .ui-datepicker-next { - right: 2px; -} -.ui-datepicker .ui-datepicker-prev-hover { - left: 1px; -} -.ui-datepicker .ui-datepicker-next-hover { - right: 1px; -} -.ui-datepicker .ui-datepicker-prev span, -.ui-datepicker .ui-datepicker-next span { - display: block; - position: absolute; - left: 50%; - margin-left: -8px; - top: 50%; - margin-top: -8px; -} -.ui-datepicker .ui-datepicker-title { - margin: 0 2.3em; - line-height: 1.8em; - text-align: center; -} -.ui-datepicker .ui-datepicker-title select { - font-size: 1em; - margin: 1px 0; -} -.ui-datepicker select.ui-datepicker-month-year { - width: 100%; -} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { - width: 49%; -} -.ui-datepicker table { - width: 100%; - font-size: .9em; - border-collapse: collapse; - margin: 0 0 .4em; -} -.ui-datepicker th { - padding: .7em .3em; - text-align: center; - font-weight: bold; - border: 0; -} -.ui-datepicker td { - border: 0; - padding: 1px; -} -.ui-datepicker td span, -.ui-datepicker td a { - display: block; - padding: .2em; - text-align: right; - text-decoration: none; -} -.ui-datepicker .ui-datepicker-buttonpane { - background-image: none; - margin: .7em 0 0 0; - padding: 0 .2em; - border-left: 0; - border-right: 0; - border-bottom: 0; -} -.ui-datepicker .ui-datepicker-buttonpane button { - float: right; - margin: .5em .2em .4em; - cursor: pointer; - padding: .2em .6em .3em .6em; - width: auto; - overflow: visible; -} -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { - float: left; -} - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { - width: auto; -} -.ui-datepicker-multi .ui-datepicker-group { - float: left; -} -.ui-datepicker-multi .ui-datepicker-group table { - width: 95%; - margin: 0 auto .4em; -} -.ui-datepicker-multi-2 .ui-datepicker-group { - width: 50%; -} -.ui-datepicker-multi-3 .ui-datepicker-group { - width: 33.3%; -} -.ui-datepicker-multi-4 .ui-datepicker-group { - width: 25%; -} -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { - border-left-width: 0; -} -.ui-datepicker-multi .ui-datepicker-buttonpane { - clear: left; -} -.ui-datepicker-row-break { - clear: both; - width: 100%; - font-size: 0; -} - -/* RTL support */ -.ui-datepicker-rtl { - direction: rtl; -} -.ui-datepicker-rtl .ui-datepicker-prev { - right: 2px; - left: auto; -} -.ui-datepicker-rtl .ui-datepicker-next { - left: 2px; - right: auto; -} -.ui-datepicker-rtl .ui-datepicker-prev:hover { - right: 1px; - left: auto; -} -.ui-datepicker-rtl .ui-datepicker-next:hover { - left: 1px; - right: auto; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane { - clear: right; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane button { - float: left; -} -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, -.ui-datepicker-rtl .ui-datepicker-group { - float: right; -} -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { - border-right-width: 0; - border-left-width: 1px; -} -.ui-dialog { - position: absolute; - top: 0; - left: 0; - padding: .2em; - outline: 0; -} -.ui-dialog .ui-dialog-titlebar { - padding: .4em 1em; - position: relative; -} -.ui-dialog .ui-dialog-title { - float: left; - margin: .1em 0; - white-space: nowrap; - width: 90%; - overflow: hidden; - text-overflow: ellipsis; -} -.ui-dialog .ui-dialog-titlebar-close { - position: absolute; - right: .3em; - top: 50%; - width: 21px; - margin: -10px 0 0 0; - padding: 1px; - height: 20px; -} -.ui-dialog .ui-dialog-content { - position: relative; - border: 0; - padding: .5em 1em; - background: none; - overflow: auto; -} -.ui-dialog .ui-dialog-buttonpane { - text-align: left; - border-width: 1px 0 0 0; - background-image: none; - margin-top: .5em; - padding: .3em 1em .5em .4em; -} -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { - float: right; -} -.ui-dialog .ui-dialog-buttonpane button { - margin: .5em .4em .5em 0; - cursor: pointer; -} -.ui-dialog .ui-resizable-se { - width: 12px; - height: 12px; - right: -5px; - bottom: -5px; - background-position: 16px 16px; -} -.ui-draggable .ui-dialog-titlebar { - cursor: move; -} -.ui-menu { - list-style: none; - padding: 2px; - margin: 0; - display: block; - outline: none; -} -.ui-menu .ui-menu { - margin-top: -3px; - position: absolute; -} -.ui-menu .ui-menu-item { - margin: 0; - padding: 0; - width: 100%; - /* support: IE10, see #8844 */ - list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); -} -.ui-menu .ui-menu-divider { - margin: 5px -2px 5px -2px; - height: 0; - font-size: 0; - line-height: 0; - border-width: 1px 0 0 0; -} -.ui-menu .ui-menu-item a { - text-decoration: none; - display: block; - padding: 2px .4em; - line-height: 1.5; - min-height: 0; /* support: IE7 */ - font-weight: normal; -} -.ui-menu .ui-menu-item a.ui-state-focus, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} - -.ui-menu .ui-state-disabled { - font-weight: normal; - margin: .4em 0 .2em; - line-height: 1.5; -} -.ui-menu .ui-state-disabled a { - cursor: default; -} - -/* icon support */ -.ui-menu-icons { - position: relative; -} -.ui-menu-icons .ui-menu-item a { - position: relative; - padding-left: 2em; -} - -/* left-aligned */ -.ui-menu .ui-icon { - position: absolute; - top: .2em; - left: .2em; -} - -/* right-aligned */ -.ui-menu .ui-menu-icon { - position: static; - float: right; -} -.ui-progressbar { - height: 2em; - text-align: left; - overflow: hidden; -} -.ui-progressbar .ui-progressbar-value { - margin: -1px; - height: 100%; -} -.ui-progressbar .ui-progressbar-overlay { - background: url("images/animated-overlay.gif"); - height: 100%; - filter: alpha(opacity=25); - opacity: 0.25; -} -.ui-progressbar-indeterminate .ui-progressbar-value { - background-image: none; -} -.ui-resizable { - position: relative; -} -.ui-resizable-handle { - position: absolute; - font-size: 0.1px; - display: block; -} -.ui-resizable-disabled .ui-resizable-handle, -.ui-resizable-autohide .ui-resizable-handle { - display: none; -} -.ui-resizable-n { - cursor: n-resize; - height: 7px; - width: 100%; - top: -5px; - left: 0; -} -.ui-resizable-s { - cursor: s-resize; - height: 7px; - width: 100%; - bottom: -5px; - left: 0; -} -.ui-resizable-e { - cursor: e-resize; - width: 7px; - right: -5px; - top: 0; - height: 100%; -} -.ui-resizable-w { - cursor: w-resize; - width: 7px; - left: -5px; - top: 0; - height: 100%; -} -.ui-resizable-se { - cursor: se-resize; - width: 12px; - height: 12px; - right: 1px; - bottom: 1px; -} -.ui-resizable-sw { - cursor: sw-resize; - width: 9px; - height: 9px; - left: -5px; - bottom: -5px; -} -.ui-resizable-nw { - cursor: nw-resize; - width: 9px; - height: 9px; - left: -5px; - top: -5px; -} -.ui-resizable-ne { - cursor: ne-resize; - width: 9px; - height: 9px; - right: -5px; - top: -5px; -} -.ui-selectable-helper { - position: absolute; - z-index: 100; - border: 1px dotted black; -} -.ui-slider { - position: relative; - text-align: left; -} -.ui-slider .ui-slider-handle { - position: absolute; - z-index: 2; - width: 1.2em; - height: 1.2em; - cursor: default; -} -.ui-slider .ui-slider-range { - position: absolute; - z-index: 1; - font-size: .7em; - display: block; - border: 0; - background-position: 0 0; -} - -/* For IE8 - See #6727 */ -.ui-slider.ui-state-disabled .ui-slider-handle, -.ui-slider.ui-state-disabled .ui-slider-range { - filter: inherit; -} - -.ui-slider-horizontal { - height: .8em; -} -.ui-slider-horizontal .ui-slider-handle { - top: -.3em; - margin-left: -.6em; -} -.ui-slider-horizontal .ui-slider-range { - top: 0; - height: 100%; -} -.ui-slider-horizontal .ui-slider-range-min { - left: 0; -} -.ui-slider-horizontal .ui-slider-range-max { - right: 0; -} - -.ui-slider-vertical { - width: .8em; - height: 100px; -} -.ui-slider-vertical .ui-slider-handle { - left: -.3em; - margin-left: 0; - margin-bottom: -.6em; -} -.ui-slider-vertical .ui-slider-range { - left: 0; - width: 100%; -} -.ui-slider-vertical .ui-slider-range-min { - bottom: 0; -} -.ui-slider-vertical .ui-slider-range-max { - top: 0; -} -.ui-spinner { - position: relative; - display: inline-block; - overflow: hidden; - padding: 0; - vertical-align: middle; -} -.ui-spinner-input { - border: none; - background: none; - color: inherit; - padding: 0; - margin: .2em 0; - vertical-align: middle; - margin-left: .4em; - margin-right: 22px; -} -.ui-spinner-button { - width: 16px; - height: 50%; - font-size: .5em; - padding: 0; - margin: 0; - text-align: center; - position: absolute; - cursor: default; - display: block; - overflow: hidden; - right: 0; -} -/* more specificity required here to overide default borders */ -.ui-spinner a.ui-spinner-button { - border-top: none; - border-bottom: none; - border-right: none; -} -/* vertical centre icon */ -.ui-spinner .ui-icon { - position: absolute; - margin-top: -8px; - top: 50%; - left: 0; -} -.ui-spinner-up { - top: 0; -} -.ui-spinner-down { - bottom: 0; -} - -/* TR overrides */ -.ui-spinner .ui-icon-triangle-1-s { - /* need to fix icons sprite */ - background-position: -65px -16px; -} -.ui-tabs { - position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ - padding: .2em; -} -.ui-tabs .ui-tabs-nav { - margin: 0; - padding: .2em .2em 0; -} -.ui-tabs .ui-tabs-nav li { - list-style: none; - float: left; - position: relative; - top: 0; - margin: 1px .2em 0 0; - border-bottom-width: 0; - padding: 0; - white-space: nowrap; -} -.ui-tabs .ui-tabs-nav li a { - float: left; - padding: .5em 1em; - text-decoration: none; -} -.ui-tabs .ui-tabs-nav li.ui-tabs-active { - margin-bottom: -1px; - padding-bottom: 1px; -} -.ui-tabs .ui-tabs-nav li.ui-tabs-active a, -.ui-tabs .ui-tabs-nav li.ui-state-disabled a, -.ui-tabs .ui-tabs-nav li.ui-tabs-loading a { - cursor: text; -} -.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { - cursor: pointer; -} -.ui-tabs .ui-tabs-panel { - display: block; - border-width: 0; - padding: 1em 1.4em; - background: none; -} -.ui-tooltip { - padding: 8px; - position: absolute; - z-index: 9999; - max-width: 300px; - -webkit-box-shadow: 0 0 5px #aaa; - box-shadow: 0 0 5px #aaa; -} -body .ui-tooltip { - border-width: 2px; -} - -/* Component containers -----------------------------------*/ -.ui-widget { - font-family: Verdana,Arial,sans-serif; - font-size: 1.1em; -} -.ui-widget .ui-widget { - font-size: 1em; -} -.ui-widget input, -.ui-widget select, -.ui-widget textarea, -.ui-widget button { - font-family: Verdana,Arial,sans-serif; - font-size: 1em; -} -.ui-widget-content { - border: 1px solid #aaaaaa; - background: #ffffff url(../img/slider/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; - color: #222222; -} -.ui-widget-content a { - color: #222222; -} -.ui-widget-header { - border: 1px solid #aaaaaa; - background: #cccccc url(../img/slider/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; - color: #222222; - font-weight: bold; -} -.ui-widget-header a { - color: #222222; -} - -/* Interaction states -----------------------------------*/ -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default { - border: 1px solid #d3d3d3; - background: #e6e6e6 url(../img/slider/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; - font-weight: normal; - color: #555555; -} -.ui-state-default a, -.ui-state-default a:link, -.ui-state-default a:visited { - color: #555555; - text-decoration: none; -} -.ui-state-hover, -.ui-widget-content .ui-state-hover, -.ui-widget-header .ui-state-hover, -.ui-state-focus, -.ui-widget-content .ui-state-focus, -.ui-widget-header .ui-state-focus { - border: 1px solid #999999; - background: #dadada url(../img/slider/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; - font-weight: normal; - color: #212121; -} -.ui-state-hover a, -.ui-state-hover a:hover, -.ui-state-hover a:link, -.ui-state-hover a:visited { - color: #212121; - text-decoration: none; -} -.ui-state-active, -.ui-widget-content .ui-state-active, -.ui-widget-header .ui-state-active { - border: 1px solid #aaaaaa; - background: #ffffff url(../img/slider/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; - font-weight: normal; - color: #212121; -} -.ui-state-active a, -.ui-state-active a:link, -.ui-state-active a:visited { - color: #212121; - text-decoration: none; -} - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, -.ui-widget-content .ui-state-highlight, -.ui-widget-header .ui-state-highlight { - border: 1px solid #fcefa1; - background: #fbf9ee url(../img/slider/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; - color: #363636; -} -.ui-state-highlight a, -.ui-widget-content .ui-state-highlight a, -.ui-widget-header .ui-state-highlight a { - color: #363636; -} -.ui-state-error, -.ui-widget-content .ui-state-error, -.ui-widget-header .ui-state-error { - border: 1px solid #cd0a0a; - background: #fef1ec url(../img/slider/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; - color: #cd0a0a; -} -.ui-state-error a, -.ui-widget-content .ui-state-error a, -.ui-widget-header .ui-state-error a { - color: #cd0a0a; -} -.ui-state-error-text, -.ui-widget-content .ui-state-error-text, -.ui-widget-header .ui-state-error-text { - color: #cd0a0a; -} -.ui-priority-primary, -.ui-widget-content .ui-priority-primary, -.ui-widget-header .ui-priority-primary { - font-weight: bold; -} -.ui-priority-secondary, -.ui-widget-content .ui-priority-secondary, -.ui-widget-header .ui-priority-secondary { - opacity: .7; - filter:Alpha(Opacity=70); - font-weight: normal; -} -.ui-state-disabled, -.ui-widget-content .ui-state-disabled, -.ui-widget-header .ui-state-disabled { - opacity: .35; - filter:Alpha(Opacity=35); - background-image: none; -} -.ui-state-disabled .ui-icon { - filter:Alpha(Opacity=35); /* For IE8 - See #6059 */ -} - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { - width: 16px; - height: 16px; -} -.ui-icon, -.ui-widget-content .ui-icon { - background-image: url(images/ui-icons_222222_256x240.png); -} -.ui-widget-header .ui-icon { - background-image: url(images/ui-icons_222222_256x240.png); -} -.ui-state-default .ui-icon { - background-image: url(images/ui-icons_888888_256x240.png); -} -.ui-state-hover .ui-icon, -.ui-state-focus .ui-icon { - background-image: url(images/ui-icons_454545_256x240.png); -} -.ui-state-active .ui-icon { - background-image: url(images/ui-icons_454545_256x240.png); -} -.ui-state-highlight .ui-icon { - background-image: url(images/ui-icons_2e83ff_256x240.png); -} -.ui-state-error .ui-icon, -.ui-state-error-text .ui-icon { - background-image: url(images/ui-icons_cd0a0a_256x240.png); -} - -/* positioning */ -.ui-icon-blank { background-position: 16px 16px; } -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-on { background-position: -96px -144px; } -.ui-icon-radio-off { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -.ui-corner-all, -.ui-corner-top, -.ui-corner-left, -.ui-corner-tl { - border-top-left-radius: 4px; -} -.ui-corner-all, -.ui-corner-top, -.ui-corner-right, -.ui-corner-tr { - border-top-right-radius: 4px; -} -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-left, -.ui-corner-bl { - border-bottom-left-radius: 4px; -} -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-right, -.ui-corner-br { - border-bottom-right-radius: 4px; -} - -/* Overlays */ -.ui-widget-overlay { - background: #aaaaaa url(../img/slider/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; - opacity: .3; - filter: Alpha(Opacity=30); -} -.ui-widget-shadow { - margin: -8px 0 0 -8px; - padding: 8px; - background: #aaaaaa url(../img/slider/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; - opacity: .3; - filter: Alpha(Opacity=30); - border-radius: 8px; -} diff --git a/noVNC/media/css/jquery.alerts.css b/noVNC/media/css/jquery.alerts.css deleted file mode 100755 index 5c6ac89..0000000 --- a/noVNC/media/css/jquery.alerts.css +++ /dev/null @@ -1,92 +0,0 @@ -#popup_container { - font-size: 12px; - font-family: QNAPCustomFont,'Lucida Grande','Verdana','Tahoma','Arial','Helvetica','sans-serif','Microsoft JhengHei'; - min-width: 300px; /* Dialog will be no smaller than this */ - max-width: 350px; /* Dialog will wrap after this width */ - background: #FFF; - color: #000; - border: 1px solid rgba(0, 0, 0, 0.3); - *border: 1px solid #999; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.7); - -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.7); - box-shadow: 0 3px 7px rgba(0, 0, 0, 0.7); -} - -#popup_title { - font-size: 12px; - font-weight: bold; - text-align: center; - height: 40px; - color: #666; - background: #FFF url(/media/img/title_bg.png) top repeat; - cursor: default; - margin: 0px; - -webkit-border-radius: 6px 6px 0px 0px; - -moz-border-radius: 6px 6px 0px 0px; - border-radius: 6px 6px 0px 0px; -} - -#popup_content { - background: 16px 16px no-repeat url(images/info.gif); - padding: 1em 0 1em 1.75em; - margin: 0em; - /*height: 60px;*/ -} - -#popup_content.alert { - background-image: url(/media/img/icon-info.png); -} - -#popup_content.confirm { - background-image: url(/media/img/icon-question-b.png); - height: auto; -} - -#popup_content.confirm3 { - background-image: url(/media/img/icon-question-b.png); - height: auto; -} - -#popup_content.prompt { - background-image: url(images/help.gif); -} - -#popup_message { - display: block; - color: #000; - width: auto; - min-height: 50px; - max-height: 400px; - overflow-y: auto; - text-overflow:ellipsis; - word-break: break-word; - padding-left: 60px; - padding-top: 6px; - padding-right: 6px; -} - -#popup_panel input { - width: 76px; - height: 26px; - padding: 0px; - margin-top: 5px; -} - -#popup_panel { - text-align: center; - padding: 6px 0px; - height: 34px; - background-color: #E7E7E7; - border-top: 1px solid #bbb; - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; - *zoom: 1; -} - -#popup_prompt { - margin: .5em 0em; -} diff --git a/noVNC/media/css/jquery.treeview.css b/noVNC/media/css/jquery.treeview.css deleted file mode 100755 index 4af392d..0000000 --- a/noVNC/media/css/jquery.treeview.css +++ /dev/null @@ -1,84 +0,0 @@ -.treeview, .treeview ul { - padding: 0; - margin: 0; - list-style: none; -} - -.treeview ul { - background-color: white; - margin-top: 4px; -} - -.treeview .hitarea { - margin-top: 5px; - background: url(../img/treeview/treeview-default.gif) -64px -25px no-repeat; - height: 16px; - width: 16px; - margin-left: -16px; - float: left; - cursor: pointer; -} -/* fix for IE6 */ -* html .hitarea { - display: inline; - float:none; -} - -.treeview li { - margin: 0; - padding: 3px 0pt 3px 16px; - line-height: 20px; -} - -.treeview a.selected { - background-color: #eee; -} - -#treeviewcontrol { margin: 1em 0; display: none; } - -.treeview .hover { color: red; cursor: pointer; } - -.treeview li { background: url(../img/treeview/treeview-default-line.gif) 0 0 no-repeat; } -.treeview li.collapsable, .treeview li.expandable { background-position: 0 -176px; } - -.treeview .expandable-hitarea { background-position: 0px -3px; } - -.treeview li.last { background-position: 0 -1766px } -.treeview li.lastCollapsable, .treeview li.lastExpandable { background-image: url(../img/treeview/treeview-default.gif); } -.treeview li.lastCollapsable { background-position: 0 -111px } -.treeview li.lastExpandable { background-position: -32px -67px } - -.treeview div.lastCollapsable-hitarea, .treeview .collapsable-hitarea { background-position: -16px -2px; } -.treeview div.lastExpandable-hitarea { background-position: 0px -3px; } - -.treeview-red li { background-image: url(../img/treeview/treeview-red-line.gif); } -.treeview-red .hitarea, .treeview-red li.lastCollapsable, .treeview-red li.lastExpandable { background-image: url(../img/treeview/treeview-red.gif); } - -.treeview-black li { background-image: url(../img/treeview/treeview-black-line.gif); } -.treeview-black .hitarea, .treeview-black li.lastCollapsable, .treeview-black li.lastExpandable { background-image: url(../img/treeview/treeview-black.gif); } - -.treeview-gray li { background-image: url(../img/treeview/treeview-gray-line.gif); } -.treeview-gray .hitarea, .treeview-gray li.lastCollapsable, .treeview-gray li.lastExpandable { background-image: url(../img/treeview/treeview-gray.gif); } - -.treeview-famfamfam li { background-image: url(../img/treeview/treeview-famfamfam-line.gif); } -.treeview-famfamfam .hitarea, .treeview-famfamfam li.lastCollapsable, .treeview-famfamfam li.lastExpandable { background-image: url(../img/treeview/tree_arrows.png); } - - -.filetree li { padding: 3px 0 2px 16px; } -.filetree span.folder, .filetree span.file { padding: 1px 0 1px 19px; display: block;} -.filetree span.folder { background: url(../img/treeview/folder.gif) 0 0 no-repeat; background-position: 0 0px;} -.filetree li.expandable span.folder { background: url(../img/treeview/folder-closed.gif) 0 0 no-repeat;background-position: 0 0px; } -.filetree span.file { background: url(../img/treeview/file.gif) 0 0 no-repeat; } - -/* For Qnap style */ -.qtreeview { - padding: 1em; - font-size: 12px; - background: #fff; - color: #333; - min-height:150px; -} -.qtreeview li { - line-height: 20px; - cursor: pointer; -} \ No newline at end of file diff --git a/noVNC/media/css/radio-checkbox-chrome.css b/noVNC/media/css/radio-checkbox-chrome.css deleted file mode 100755 index c622645..0000000 --- a/noVNC/media/css/radio-checkbox-chrome.css +++ /dev/null @@ -1,72 +0,0 @@ -input[type=radio] { - border-radius: 20px; - border:1px solid rgb(125,125,125); - background: #CCC; - -webkit-appearance: none; - width: 13px; - height: 13px; -} - -input[type="radio"]:after { - background-color: #FFF; - border-radius: 25px; - box-shadow: inset 0 0 0 1px hsla(0,0%,0%,.4), - 0 1px 1px hsla(0,0%,100%,.8); - content: ''; - display: block; - height: 7px; - left: 2px; - position: relative; - top: 2px; - width: 7px; -} - -input[type=radio]:checked:after { - background: #006494; -} - -input[type=radio]:disabled{ - border-radius: 20px; - border:1px solid rgb(175,175,175); - background: #CCC; - -webkit-appearance: none; -} - -input[type="radio"]:disabled:after { - background-color: #CCC; - border-radius: 25px; - box-shadow: inset 0 0 0 1px hsla(0,0%,0%,.2), - 0 1px 1px hsla(0,0%,100%,.8); - content: ''; - display: block; - height: 7px; - left: 2px; - position: relative; - top: 2px; - width: 7px; -} - -input[type=checkbox] { - background: #CCC; - border:1px solid rgb(125,125,125); - -webkit-appearance: none; - width: 15px; - height: 15px; -} - -input[type="checkbox"]:after { - background-color: #FFF; - box-shadow: inset 0 0 0 1px hsla(0,0%,0%,.4), - 0 1px 1px hsla(0,0%,100%,.8); - content: ''; - display: block; - height: 9px; - left: 2px; - position: relative; - top: 2px; - width: 9px; -} - -input[type=checkbox]:checked:after { - background: #006494; -} \ No newline at end of file diff --git a/noVNC/media/css/radio-checkbox.css b/noVNC/media/css/radio-checkbox.css deleted file mode 100755 index 70f3795..0000000 --- a/noVNC/media/css/radio-checkbox.css +++ /dev/null @@ -1,95 +0,0 @@ -input[type=radio] { - border-radius: 20px; - border:1px solid rgb(125,125,125); - background: #CCC; - -webkit-appearance: none; - width: 13px; - height: 13px; -} - -input[type="radio"]:after { - background-color: #FFF; - border-radius: 25px; - box-shadow: inset 0 0 0 1px hsla(0,0%,0%,.4), - 0 1px 1px hsla(0,0%,100%,.8); - content: ''; - display: block; - height: 7px; - left: 2px; - position: relative; - top: 2px; - width: 7px; -} - -input[type=radio]:checked:after { - background: #006494; -} - -input[type=radio]:disabled{ - border-radius: 20px; - border:1px solid rgb(175,175,175); - background: #CCC; - -webkit-appearance: none; -} - -input[type="radio"]:disabled:after { - background-color: #CCC; - border-radius: 25px; - box-shadow: inset 0 0 0 1px hsla(0,0%,0%,.2), - 0 1px 1px hsla(0,0%,100%,.8); - content: ''; - display: block; - height: 7px; - left: 2px; - position: relative; - top: 2px; - width: 7px; -} - -input[type="checkbox"] { - display:none; -} - -input[type="checkbox"] + label { - display:inline-block; - width:13px; - height:13px; - background:url(../img/account/checker.png); - background-repeat:no-repeat; - background-position: -3px -3px; - margin:0 5px -2px 0; -} - -input[type="checkbox"]:checked + label { - display:inline-block; - width:13px; - height:13px; - background:url(../img/account/checker.png); - background-repeat:no-repeat; - background-position: -22px -3px; - margin:0 5px -2px 0; -} - -input[type="checkbox"]:disabled + label { - display:inline-block; - width:13px; - height:13px; - background:url(../img/account/checker.png); - background-repeat:no-repeat; - background-position: -41px -3px; - margin:0 5px -2px 0; -} - -input[type="checkbox"]:disabled:checked + label { - display:inline-block; - width:13px; - height:13px; - background:url(../img/account/checker.png); - background-repeat:no-repeat; - background-position: -60px -3px; - margin:0 5px -2px 0; -} - -input[type=checkbox]:checked:after { - background: #006494; -}*/ \ No newline at end of file diff --git a/noVNC/media/docs/QNAP-Enable_VT-x_SOP.pdf b/noVNC/media/docs/QNAP-Enable_VT-x_SOP.pdf deleted file mode 100755 index 484dd44..0000000 Binary files a/noVNC/media/docs/QNAP-Enable_VT-x_SOP.pdf and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/defaultbtn.gif b/noVNC/media/img/.@__thumb/defaultbtn.gif deleted file mode 100755 index 4820f2d..0000000 Binary files a/noVNC/media/img/.@__thumb/defaultbtn.gif and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/defaultglyphicons-halflings-green.png b/noVNC/media/img/.@__thumb/defaultglyphicons-halflings-green.png deleted file mode 100755 index 4b65031..0000000 Binary files a/noVNC/media/img/.@__thumb/defaultglyphicons-halflings-green.png and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/defaultglyphicons-halflings-white.png b/noVNC/media/img/.@__thumb/defaultglyphicons-halflings-white.png deleted file mode 100755 index 978cf58..0000000 Binary files a/noVNC/media/img/.@__thumb/defaultglyphicons-halflings-white.png and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/defaultglyphicons-halflings.png b/noVNC/media/img/.@__thumb/defaultglyphicons-halflings.png deleted file mode 100755 index 7d03fea..0000000 Binary files a/noVNC/media/img/.@__thumb/defaultglyphicons-halflings.png and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/s100btn.gif b/noVNC/media/img/.@__thumb/s100btn.gif deleted file mode 100755 index 4820f2d..0000000 Binary files a/noVNC/media/img/.@__thumb/s100btn.gif and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/s100glyphicons-halflings-green.png b/noVNC/media/img/.@__thumb/s100glyphicons-halflings-green.png deleted file mode 100755 index 292955e..0000000 Binary files a/noVNC/media/img/.@__thumb/s100glyphicons-halflings-green.png and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/s100glyphicons-halflings-white.png b/noVNC/media/img/.@__thumb/s100glyphicons-halflings-white.png deleted file mode 100755 index e43c4cf..0000000 Binary files a/noVNC/media/img/.@__thumb/s100glyphicons-halflings-white.png and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/s100glyphicons-halflings.png b/noVNC/media/img/.@__thumb/s100glyphicons-halflings.png deleted file mode 100755 index 7570f1e..0000000 Binary files a/noVNC/media/img/.@__thumb/s100glyphicons-halflings.png and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/s800btn.gif b/noVNC/media/img/.@__thumb/s800btn.gif deleted file mode 100755 index 4820f2d..0000000 Binary files a/noVNC/media/img/.@__thumb/s800btn.gif and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/s800glyphicons-halflings-green.png b/noVNC/media/img/.@__thumb/s800glyphicons-halflings-green.png deleted file mode 100755 index 4b65031..0000000 Binary files a/noVNC/media/img/.@__thumb/s800glyphicons-halflings-green.png and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/s800glyphicons-halflings-white.png b/noVNC/media/img/.@__thumb/s800glyphicons-halflings-white.png deleted file mode 100755 index 978cf58..0000000 Binary files a/noVNC/media/img/.@__thumb/s800glyphicons-halflings-white.png and /dev/null differ diff --git a/noVNC/media/img/.@__thumb/s800glyphicons-halflings.png b/noVNC/media/img/.@__thumb/s800glyphicons-halflings.png deleted file mode 100755 index 7d03fea..0000000 Binary files a/noVNC/media/img/.@__thumb/s800glyphicons-halflings.png and /dev/null differ diff --git a/noVNC/media/img/_bullet_arrow_down.png b/noVNC/media/img/_bullet_arrow_down.png deleted file mode 100755 index cdbfa91..0000000 Binary files a/noVNC/media/img/_bullet_arrow_down.png and /dev/null differ diff --git a/noVNC/media/img/_bullet_arrow_up.png b/noVNC/media/img/_bullet_arrow_up.png deleted file mode 100755 index 70a8437..0000000 Binary files a/noVNC/media/img/_bullet_arrow_up.png and /dev/null differ diff --git a/noVNC/media/img/account/account.png b/noVNC/media/img/account/account.png deleted file mode 100755 index 707f7e3..0000000 Binary files a/noVNC/media/img/account/account.png and /dev/null differ diff --git a/noVNC/media/img/account/account_over.png b/noVNC/media/img/account/account_over.png deleted file mode 100755 index b494a6d..0000000 Binary files a/noVNC/media/img/account/account_over.png and /dev/null differ diff --git a/noVNC/media/img/account/cancel.png b/noVNC/media/img/account/cancel.png deleted file mode 100755 index 6a84ab7..0000000 Binary files a/noVNC/media/img/account/cancel.png and /dev/null differ diff --git a/noVNC/media/img/account/checker.png b/noVNC/media/img/account/checker.png deleted file mode 100755 index c90a19b..0000000 Binary files a/noVNC/media/img/account/checker.png and /dev/null differ diff --git a/noVNC/media/img/account/permission.png b/noVNC/media/img/account/permission.png deleted file mode 100755 index f1f9435..0000000 Binary files a/noVNC/media/img/account/permission.png and /dev/null differ diff --git a/noVNC/media/img/account/plus.png b/noVNC/media/img/account/plus.png deleted file mode 100755 index 0d97970..0000000 Binary files a/noVNC/media/img/account/plus.png and /dev/null differ diff --git a/noVNC/media/img/addSSLHint/FF/.@__thumb/defaulten.jpg b/noVNC/media/img/addSSLHint/FF/.@__thumb/defaulten.jpg deleted file mode 100755 index 5cf62ee..0000000 Binary files a/noVNC/media/img/addSSLHint/FF/.@__thumb/defaulten.jpg and /dev/null differ diff --git a/noVNC/media/img/addSSLHint/FF/.@__thumb/s100en.jpg b/noVNC/media/img/addSSLHint/FF/.@__thumb/s100en.jpg deleted file mode 100755 index 20a5830..0000000 Binary files a/noVNC/media/img/addSSLHint/FF/.@__thumb/s100en.jpg and /dev/null differ diff --git a/noVNC/media/img/addSSLHint/FF/.@__thumb/s800en.jpg b/noVNC/media/img/addSSLHint/FF/.@__thumb/s800en.jpg deleted file mode 100755 index 2ad1e66..0000000 Binary files a/noVNC/media/img/addSSLHint/FF/.@__thumb/s800en.jpg and /dev/null differ diff --git a/noVNC/media/img/addSSLHint/FF/en.jpg b/noVNC/media/img/addSSLHint/FF/en.jpg deleted file mode 100755 index 9a01a55..0000000 Binary files a/noVNC/media/img/addSSLHint/FF/en.jpg and /dev/null differ diff --git a/noVNC/media/img/arrowbtns.png b/noVNC/media/img/arrowbtns.png deleted file mode 100755 index 6abced1..0000000 Binary files a/noVNC/media/img/arrowbtns.png and /dev/null differ diff --git a/noVNC/media/img/bar/Thumbs.db b/noVNC/media/img/bar/Thumbs.db deleted file mode 100755 index fdcf590..0000000 Binary files a/noVNC/media/img/bar/Thumbs.db and /dev/null differ diff --git a/noVNC/media/img/bar/bblue.png b/noVNC/media/img/bar/bblue.png deleted file mode 100755 index 06a5808..0000000 Binary files a/noVNC/media/img/bar/bblue.png and /dev/null differ diff --git a/noVNC/media/img/bar/blue.png b/noVNC/media/img/bar/blue.png deleted file mode 100755 index 096c6dc..0000000 Binary files a/noVNC/media/img/bar/blue.png and /dev/null differ diff --git a/noVNC/media/img/bar/green.png b/noVNC/media/img/bar/green.png deleted file mode 100755 index 16aca5f..0000000 Binary files a/noVNC/media/img/bar/green.png and /dev/null differ diff --git a/noVNC/media/img/bar/orange.png b/noVNC/media/img/bar/orange.png deleted file mode 100755 index 5b6bff6..0000000 Binary files a/noVNC/media/img/bar/orange.png and /dev/null differ diff --git a/noVNC/media/img/btn.gif b/noVNC/media/img/btn.gif deleted file mode 100755 index 96ea61a..0000000 Binary files a/noVNC/media/img/btn.gif and /dev/null differ diff --git a/noVNC/media/img/cent_snapshot.jpg b/noVNC/media/img/cent_snapshot.jpg deleted file mode 120000 index eb3607e..0000000 --- a/noVNC/media/img/cent_snapshot.jpg +++ /dev/null @@ -1 +0,0 @@ -/share/CACHEDEV1_DATA/.qpkg/.QKVM/tmp/cent/snapshot.jpg \ No newline at end of file diff --git a/noVNC/media/img/clone.png b/noVNC/media/img/clone.png deleted file mode 100755 index 486586a..0000000 Binary files a/noVNC/media/img/clone.png and /dev/null differ diff --git a/noVNC/media/img/close.png b/noVNC/media/img/close.png deleted file mode 100755 index 540b993..0000000 Binary files a/noVNC/media/img/close.png and /dev/null differ diff --git a/noVNC/media/img/error.png b/noVNC/media/img/error.png deleted file mode 100755 index 042a76c..0000000 Binary files a/noVNC/media/img/error.png and /dev/null differ diff --git a/noVNC/media/img/error/err_bg.jpg b/noVNC/media/img/error/err_bg.jpg deleted file mode 100755 index a7265da..0000000 Binary files a/noVNC/media/img/error/err_bg.jpg and /dev/null differ diff --git a/noVNC/media/img/error/forbidden.png b/noVNC/media/img/error/forbidden.png deleted file mode 100755 index 7224e80..0000000 Binary files a/noVNC/media/img/error/forbidden.png and /dev/null differ diff --git a/noVNC/media/img/eye_h.png b/noVNC/media/img/eye_h.png deleted file mode 100755 index 2c2392b..0000000 Binary files a/noVNC/media/img/eye_h.png and /dev/null differ diff --git a/noVNC/media/img/eye_l.png b/noVNC/media/img/eye_l.png deleted file mode 100755 index f170b0c..0000000 Binary files a/noVNC/media/img/eye_l.png and /dev/null differ diff --git a/noVNC/media/img/eye_m.png b/noVNC/media/img/eye_m.png deleted file mode 100755 index 1ac6fd6..0000000 Binary files a/noVNC/media/img/eye_m.png and /dev/null differ diff --git a/noVNC/media/img/eye_u.png b/noVNC/media/img/eye_u.png deleted file mode 100755 index 5f689c1..0000000 Binary files a/noVNC/media/img/eye_u.png and /dev/null differ diff --git a/noVNC/media/img/favicon.ico b/noVNC/media/img/favicon.ico deleted file mode 100755 index 7947aeb..0000000 Binary files a/noVNC/media/img/favicon.ico and /dev/null differ diff --git a/noVNC/media/img/glyphicons-halflings-green.png b/noVNC/media/img/glyphicons-halflings-green.png deleted file mode 100755 index 50dc911..0000000 Binary files a/noVNC/media/img/glyphicons-halflings-green.png and /dev/null differ diff --git a/noVNC/media/img/glyphicons-halflings-white.png b/noVNC/media/img/glyphicons-halflings-white.png deleted file mode 100755 index a20760b..0000000 Binary files a/noVNC/media/img/glyphicons-halflings-white.png and /dev/null differ diff --git a/noVNC/media/img/glyphicons-halflings.png b/noVNC/media/img/glyphicons-halflings.png deleted file mode 100755 index 92d4445..0000000 Binary files a/noVNC/media/img/glyphicons-halflings.png and /dev/null differ diff --git a/noVNC/media/img/green_light.gif b/noVNC/media/img/green_light.gif deleted file mode 100755 index 1baa9dd..0000000 Binary files a/noVNC/media/img/green_light.gif and /dev/null differ diff --git a/noVNC/media/img/grey_light.gif b/noVNC/media/img/grey_light.gif deleted file mode 100755 index d1169d0..0000000 Binary files a/noVNC/media/img/grey_light.gif and /dev/null differ diff --git a/noVNC/media/img/grid-split.gif b/noVNC/media/img/grid-split.gif deleted file mode 100755 index c76a16e..0000000 Binary files a/noVNC/media/img/grid-split.gif and /dev/null differ diff --git a/noVNC/media/img/icon-info.png b/noVNC/media/img/icon-info.png deleted file mode 100755 index 5e56b0a..0000000 Binary files a/noVNC/media/img/icon-info.png and /dev/null differ diff --git a/noVNC/media/img/icon-question-b.png b/noVNC/media/img/icon-question-b.png deleted file mode 100755 index 7838f6b..0000000 Binary files a/noVNC/media/img/icon-question-b.png and /dev/null differ diff --git a/noVNC/media/img/icon_connect.png b/noVNC/media/img/icon_connect.png deleted file mode 100755 index 7cbf0b8..0000000 Binary files a/noVNC/media/img/icon_connect.png and /dev/null differ diff --git a/noVNC/media/img/icon_disconnect.png b/noVNC/media/img/icon_disconnect.png deleted file mode 100755 index 00deee0..0000000 Binary files a/noVNC/media/img/icon_disconnect.png and /dev/null differ diff --git a/noVNC/media/img/icons.png b/noVNC/media/img/icons.png deleted file mode 100755 index 879ab24..0000000 Binary files a/noVNC/media/img/icons.png and /dev/null differ diff --git a/noVNC/media/img/icons_green.png b/noVNC/media/img/icons_green.png deleted file mode 100755 index 2f5e564..0000000 Binary files a/noVNC/media/img/icons_green.png and /dev/null differ diff --git a/noVNC/media/img/icons_over.png b/noVNC/media/img/icons_over.png deleted file mode 100755 index 7d90ef1..0000000 Binary files a/noVNC/media/img/icons_over.png and /dev/null differ diff --git a/noVNC/media/img/icons_yellow.png b/noVNC/media/img/icons_yellow.png deleted file mode 100755 index c2d3f92..0000000 Binary files a/noVNC/media/img/icons_yellow.png and /dev/null differ diff --git a/noVNC/media/img/line.png b/noVNC/media/img/line.png deleted file mode 100755 index e8ccdb3..0000000 Binary files a/noVNC/media/img/line.png and /dev/null differ diff --git a/noVNC/media/img/list_.png b/noVNC/media/img/list_.png deleted file mode 100755 index e9836a8..0000000 Binary files a/noVNC/media/img/list_.png and /dev/null differ diff --git a/noVNC/media/img/list_hover.png b/noVNC/media/img/list_hover.png deleted file mode 100755 index a04e1a9..0000000 Binary files a/noVNC/media/img/list_hover.png and /dev/null differ diff --git a/noVNC/media/img/loading.gif b/noVNC/media/img/loading.gif deleted file mode 100755 index b36b555..0000000 Binary files a/noVNC/media/img/loading.gif and /dev/null differ diff --git a/noVNC/media/img/login/.@__thumb/defaultmiddleBg.png b/noVNC/media/img/login/.@__thumb/defaultmiddleBg.png deleted file mode 100755 index a3c5aed..0000000 Binary files a/noVNC/media/img/login/.@__thumb/defaultmiddleBg.png and /dev/null differ diff --git a/noVNC/media/img/login/.@__thumb/s100middleBg.png b/noVNC/media/img/login/.@__thumb/s100middleBg.png deleted file mode 100755 index f6d3e35..0000000 Binary files a/noVNC/media/img/login/.@__thumb/s100middleBg.png and /dev/null differ diff --git a/noVNC/media/img/login/.@__thumb/s800middleBg.png b/noVNC/media/img/login/.@__thumb/s800middleBg.png deleted file mode 100755 index 1961ca5..0000000 Binary files a/noVNC/media/img/login/.@__thumb/s800middleBg.png and /dev/null differ diff --git a/noVNC/media/img/login/BgImg.png b/noVNC/media/img/login/BgImg.png deleted file mode 100755 index f00d8d6..0000000 Binary files a/noVNC/media/img/login/BgImg.png and /dev/null differ diff --git a/noVNC/media/img/login/checkBox.png b/noVNC/media/img/login/checkBox.png deleted file mode 100755 index 79c36d2..0000000 Binary files a/noVNC/media/img/login/checkBox.png and /dev/null differ diff --git a/noVNC/media/img/login/dot.png b/noVNC/media/img/login/dot.png deleted file mode 100755 index c54f32a..0000000 Binary files a/noVNC/media/img/login/dot.png and /dev/null differ diff --git a/noVNC/media/img/login/goMore.png b/noVNC/media/img/login/goMore.png deleted file mode 100755 index 176352c..0000000 Binary files a/noVNC/media/img/login/goMore.png and /dev/null differ diff --git a/noVNC/media/img/login/loginBtn.png b/noVNC/media/img/login/loginBtn.png deleted file mode 100755 index 1d7427e..0000000 Binary files a/noVNC/media/img/login/loginBtn.png and /dev/null differ diff --git a/noVNC/media/img/login/loginEnter.png b/noVNC/media/img/login/loginEnter.png deleted file mode 100755 index c3f4a6a..0000000 Binary files a/noVNC/media/img/login/loginEnter.png and /dev/null differ diff --git a/noVNC/media/img/login/loginEnterMobile.png b/noVNC/media/img/login/loginEnterMobile.png deleted file mode 100755 index 655a2c9..0000000 Binary files a/noVNC/media/img/login/loginEnterMobile.png and /dev/null differ diff --git a/noVNC/media/img/login/logo.png b/noVNC/media/img/login/logo.png deleted file mode 100755 index 0ab66bc..0000000 Binary files a/noVNC/media/img/login/logo.png and /dev/null differ diff --git a/noVNC/media/img/login/middleBg.png b/noVNC/media/img/login/middleBg.png deleted file mode 100755 index d27e091..0000000 Binary files a/noVNC/media/img/login/middleBg.png and /dev/null differ diff --git a/noVNC/media/img/login/title.png b/noVNC/media/img/login/title.png deleted file mode 100755 index 02d52e9..0000000 Binary files a/noVNC/media/img/login/title.png and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_0.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_0.jpg deleted file mode 100755 index 32c52c5..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_0.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_1.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_1.jpg deleted file mode 100755 index 35e81d2..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_1.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_2.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_2.jpg deleted file mode 100755 index a7ec6a0..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_2.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_3.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_3.jpg deleted file mode 100755 index cf69665..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_3.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_4.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_4.jpg deleted file mode 100755 index 3ff5923..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_4.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_5.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_5.jpg deleted file mode 100755 index ed0e12e..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_5.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_6.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_6.jpg deleted file mode 100755 index 044d5d5..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_6.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_7.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_7.jpg deleted file mode 100755 index 7418c3e..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultbitnami_7.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultvmware_0.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultvmware_0.jpg deleted file mode 100755 index 5e7b9e2..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultvmware_0.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultvmware_1.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultvmware_1.jpg deleted file mode 100755 index ab8fb68..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultvmware_1.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/defaultvmware_2.jpg b/noVNC/media/img/marketplace/.@__thumb/defaultvmware_2.jpg deleted file mode 100755 index a508ada..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/defaultvmware_2.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_0.jpg b/noVNC/media/img/marketplace/.@__thumb/s100bitnami_0.jpg deleted file mode 100755 index c8b5979..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_0.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_1.jpg b/noVNC/media/img/marketplace/.@__thumb/s100bitnami_1.jpg deleted file mode 100755 index 477e351..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_1.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_2.jpg b/noVNC/media/img/marketplace/.@__thumb/s100bitnami_2.jpg deleted file mode 100755 index d9e05a2..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_2.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_3.jpg b/noVNC/media/img/marketplace/.@__thumb/s100bitnami_3.jpg deleted file mode 100755 index 08a151a..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_3.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_4.jpg b/noVNC/media/img/marketplace/.@__thumb/s100bitnami_4.jpg deleted file mode 100755 index 849b05d..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_4.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_5.jpg b/noVNC/media/img/marketplace/.@__thumb/s100bitnami_5.jpg deleted file mode 100755 index 49e48e6..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_5.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_6.jpg b/noVNC/media/img/marketplace/.@__thumb/s100bitnami_6.jpg deleted file mode 100755 index 41a03be..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_6.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_7.jpg b/noVNC/media/img/marketplace/.@__thumb/s100bitnami_7.jpg deleted file mode 100755 index 296bae6..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100bitnami_7.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100vmware_0.jpg b/noVNC/media/img/marketplace/.@__thumb/s100vmware_0.jpg deleted file mode 100755 index 68658bc..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100vmware_0.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100vmware_1.jpg b/noVNC/media/img/marketplace/.@__thumb/s100vmware_1.jpg deleted file mode 100755 index b3053a1..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100vmware_1.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s100vmware_2.jpg b/noVNC/media/img/marketplace/.@__thumb/s100vmware_2.jpg deleted file mode 100755 index 6b3e380..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s100vmware_2.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_0.jpg b/noVNC/media/img/marketplace/.@__thumb/s800bitnami_0.jpg deleted file mode 100755 index 4bfb1af..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_0.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_1.jpg b/noVNC/media/img/marketplace/.@__thumb/s800bitnami_1.jpg deleted file mode 100755 index 6c8ab67..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_1.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_2.jpg b/noVNC/media/img/marketplace/.@__thumb/s800bitnami_2.jpg deleted file mode 100755 index 0aad7a4..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_2.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_3.jpg b/noVNC/media/img/marketplace/.@__thumb/s800bitnami_3.jpg deleted file mode 100755 index dd58c25..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_3.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_4.jpg b/noVNC/media/img/marketplace/.@__thumb/s800bitnami_4.jpg deleted file mode 100755 index cc92529..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_4.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_5.jpg b/noVNC/media/img/marketplace/.@__thumb/s800bitnami_5.jpg deleted file mode 100755 index caf6d90..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_5.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_6.jpg b/noVNC/media/img/marketplace/.@__thumb/s800bitnami_6.jpg deleted file mode 100755 index c209172..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_6.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_7.jpg b/noVNC/media/img/marketplace/.@__thumb/s800bitnami_7.jpg deleted file mode 100755 index c70b843..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800bitnami_7.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800vmware_0.jpg b/noVNC/media/img/marketplace/.@__thumb/s800vmware_0.jpg deleted file mode 100755 index 7837e7d..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800vmware_0.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800vmware_1.jpg b/noVNC/media/img/marketplace/.@__thumb/s800vmware_1.jpg deleted file mode 100755 index 1bca5b0..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800vmware_1.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/.@__thumb/s800vmware_2.jpg b/noVNC/media/img/marketplace/.@__thumb/s800vmware_2.jpg deleted file mode 100755 index 234532b..0000000 Binary files a/noVNC/media/img/marketplace/.@__thumb/s800vmware_2.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/bitnami_0.jpg b/noVNC/media/img/marketplace/bitnami_0.jpg deleted file mode 100755 index fca3ef9..0000000 Binary files a/noVNC/media/img/marketplace/bitnami_0.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/bitnami_1.jpg b/noVNC/media/img/marketplace/bitnami_1.jpg deleted file mode 100755 index 21be49d..0000000 Binary files a/noVNC/media/img/marketplace/bitnami_1.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/bitnami_2.jpg b/noVNC/media/img/marketplace/bitnami_2.jpg deleted file mode 100755 index 2c907e3..0000000 Binary files a/noVNC/media/img/marketplace/bitnami_2.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/bitnami_3.jpg b/noVNC/media/img/marketplace/bitnami_3.jpg deleted file mode 100755 index 3f2ca08..0000000 Binary files a/noVNC/media/img/marketplace/bitnami_3.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/bitnami_4.jpg b/noVNC/media/img/marketplace/bitnami_4.jpg deleted file mode 100755 index 69eb5a9..0000000 Binary files a/noVNC/media/img/marketplace/bitnami_4.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/bitnami_5.jpg b/noVNC/media/img/marketplace/bitnami_5.jpg deleted file mode 100755 index a9cbbdc..0000000 Binary files a/noVNC/media/img/marketplace/bitnami_5.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/bitnami_6.jpg b/noVNC/media/img/marketplace/bitnami_6.jpg deleted file mode 100755 index d92b45a..0000000 Binary files a/noVNC/media/img/marketplace/bitnami_6.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/bitnami_7.jpg b/noVNC/media/img/marketplace/bitnami_7.jpg deleted file mode 100755 index 8fcd460..0000000 Binary files a/noVNC/media/img/marketplace/bitnami_7.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/close.png b/noVNC/media/img/marketplace/close.png deleted file mode 100755 index 23094f2..0000000 Binary files a/noVNC/media/img/marketplace/close.png and /dev/null differ diff --git a/noVNC/media/img/marketplace/goto.png b/noVNC/media/img/marketplace/goto.png deleted file mode 100755 index d4ae51d..0000000 Binary files a/noVNC/media/img/marketplace/goto.png and /dev/null differ diff --git a/noVNC/media/img/marketplace/page_circle.png b/noVNC/media/img/marketplace/page_circle.png deleted file mode 100755 index 636ed1a..0000000 Binary files a/noVNC/media/img/marketplace/page_circle.png and /dev/null differ diff --git a/noVNC/media/img/marketplace/vmware_0.jpg b/noVNC/media/img/marketplace/vmware_0.jpg deleted file mode 100755 index bcf29ab..0000000 Binary files a/noVNC/media/img/marketplace/vmware_0.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/vmware_1.jpg b/noVNC/media/img/marketplace/vmware_1.jpg deleted file mode 100755 index 6ae3e69..0000000 Binary files a/noVNC/media/img/marketplace/vmware_1.jpg and /dev/null differ diff --git a/noVNC/media/img/marketplace/vmware_2.jpg b/noVNC/media/img/marketplace/vmware_2.jpg deleted file mode 100755 index 71ee3da..0000000 Binary files a/noVNC/media/img/marketplace/vmware_2.jpg and /dev/null differ diff --git a/noVNC/media/img/minus.jpg b/noVNC/media/img/minus.jpg deleted file mode 100755 index 3ec53f2..0000000 Binary files a/noVNC/media/img/minus.jpg and /dev/null differ diff --git a/noVNC/media/img/nas_default/item-over.gif b/noVNC/media/img/nas_default/item-over.gif deleted file mode 100755 index e0dc5f7..0000000 Binary files a/noVNC/media/img/nas_default/item-over.gif and /dev/null differ diff --git a/noVNC/media/img/nas_default/menu.gif b/noVNC/media/img/nas_default/menu.gif deleted file mode 100755 index 30a2c4b..0000000 Binary files a/noVNC/media/img/nas_default/menu.gif and /dev/null differ diff --git a/noVNC/media/img/ok.png b/noVNC/media/img/ok.png deleted file mode 100755 index 463b75e..0000000 Binary files a/noVNC/media/img/ok.png and /dev/null differ diff --git a/noVNC/media/img/open.png b/noVNC/media/img/open.png deleted file mode 100755 index 7862cb1..0000000 Binary files a/noVNC/media/img/open.png and /dev/null differ diff --git a/noVNC/media/img/open2.png b/noVNC/media/img/open2.png deleted file mode 100755 index 09a47c3..0000000 Binary files a/noVNC/media/img/open2.png and /dev/null differ diff --git a/noVNC/media/img/page-first-disabled.gif b/noVNC/media/img/page-first-disabled.gif deleted file mode 100755 index 1e02c41..0000000 Binary files a/noVNC/media/img/page-first-disabled.gif and /dev/null differ diff --git a/noVNC/media/img/page-first.gif b/noVNC/media/img/page-first.gif deleted file mode 100755 index d84f41a..0000000 Binary files a/noVNC/media/img/page-first.gif and /dev/null differ diff --git a/noVNC/media/img/page-last-disabled.gif b/noVNC/media/img/page-last-disabled.gif deleted file mode 100755 index 8697067..0000000 Binary files a/noVNC/media/img/page-last-disabled.gif and /dev/null differ diff --git a/noVNC/media/img/page-last.gif b/noVNC/media/img/page-last.gif deleted file mode 100755 index 3df5c2b..0000000 Binary files a/noVNC/media/img/page-last.gif and /dev/null differ diff --git a/noVNC/media/img/page-next-disabled.gif b/noVNC/media/img/page-next-disabled.gif deleted file mode 100755 index 90a7756..0000000 Binary files a/noVNC/media/img/page-next-disabled.gif and /dev/null differ diff --git a/noVNC/media/img/page-next.gif b/noVNC/media/img/page-next.gif deleted file mode 100755 index 9601635..0000000 Binary files a/noVNC/media/img/page-next.gif and /dev/null differ diff --git a/noVNC/media/img/page-prev-disabled.gif b/noVNC/media/img/page-prev-disabled.gif deleted file mode 100755 index 37154d6..0000000 Binary files a/noVNC/media/img/page-prev-disabled.gif and /dev/null differ diff --git a/noVNC/media/img/page-prev.gif b/noVNC/media/img/page-prev.gif deleted file mode 100755 index eb70cf8..0000000 Binary files a/noVNC/media/img/page-prev.gif and /dev/null differ diff --git a/noVNC/media/img/page-refresh.gif b/noVNC/media/img/page-refresh.gif deleted file mode 100755 index 110f684..0000000 Binary files a/noVNC/media/img/page-refresh.gif and /dev/null differ diff --git a/noVNC/media/img/plus.jpg b/noVNC/media/img/plus.jpg deleted file mode 100755 index cd9e206..0000000 Binary files a/noVNC/media/img/plus.jpg and /dev/null differ diff --git a/noVNC/media/img/qnap-logo-b.png b/noVNC/media/img/qnap-logo-b.png deleted file mode 100755 index 27c13df..0000000 Binary files a/noVNC/media/img/qnap-logo-b.png and /dev/null differ diff --git a/noVNC/media/img/question.png b/noVNC/media/img/question.png deleted file mode 100755 index a1bd8a3..0000000 Binary files a/noVNC/media/img/question.png and /dev/null differ diff --git a/noVNC/media/img/refresh.png b/noVNC/media/img/refresh.png deleted file mode 100755 index 9b935a2..0000000 Binary files a/noVNC/media/img/refresh.png and /dev/null differ diff --git a/noVNC/media/img/refresh2.png b/noVNC/media/img/refresh2.png deleted file mode 100755 index 23c4a02..0000000 Binary files a/noVNC/media/img/refresh2.png and /dev/null differ diff --git a/noVNC/media/img/remove2.png b/noVNC/media/img/remove2.png deleted file mode 100755 index 63350ad..0000000 Binary files a/noVNC/media/img/remove2.png and /dev/null differ diff --git a/noVNC/media/img/slider/ui-bg_flat_0_aaaaaa_40x100.png b/noVNC/media/img/slider/ui-bg_flat_0_aaaaaa_40x100.png deleted file mode 100755 index 4743d09..0000000 Binary files a/noVNC/media/img/slider/ui-bg_flat_0_aaaaaa_40x100.png and /dev/null differ diff --git a/noVNC/media/img/slider/ui-bg_flat_75_ffffff_40x100.png b/noVNC/media/img/slider/ui-bg_flat_75_ffffff_40x100.png deleted file mode 100755 index ca779e3..0000000 Binary files a/noVNC/media/img/slider/ui-bg_flat_75_ffffff_40x100.png and /dev/null differ diff --git a/noVNC/media/img/slider/ui-bg_glass_55_fbf9ee_1x400.png b/noVNC/media/img/slider/ui-bg_glass_55_fbf9ee_1x400.png deleted file mode 100755 index 6640381..0000000 Binary files a/noVNC/media/img/slider/ui-bg_glass_55_fbf9ee_1x400.png and /dev/null differ diff --git a/noVNC/media/img/slider/ui-bg_glass_65_ffffff_1x400.png b/noVNC/media/img/slider/ui-bg_glass_65_ffffff_1x400.png deleted file mode 100755 index d3277b5..0000000 Binary files a/noVNC/media/img/slider/ui-bg_glass_65_ffffff_1x400.png and /dev/null differ diff --git a/noVNC/media/img/slider/ui-bg_glass_75_dadada_1x400.png b/noVNC/media/img/slider/ui-bg_glass_75_dadada_1x400.png deleted file mode 100755 index 7eda20a..0000000 Binary files a/noVNC/media/img/slider/ui-bg_glass_75_dadada_1x400.png and /dev/null differ diff --git a/noVNC/media/img/slider/ui-bg_glass_75_e6e6e6_1x400.png b/noVNC/media/img/slider/ui-bg_glass_75_e6e6e6_1x400.png deleted file mode 100755 index f4d86b9..0000000 Binary files a/noVNC/media/img/slider/ui-bg_glass_75_e6e6e6_1x400.png and /dev/null differ diff --git a/noVNC/media/img/slider/ui-bg_glass_95_fef1ec_1x400.png b/noVNC/media/img/slider/ui-bg_glass_95_fef1ec_1x400.png deleted file mode 100755 index 8500938..0000000 Binary files a/noVNC/media/img/slider/ui-bg_glass_95_fef1ec_1x400.png and /dev/null differ diff --git a/noVNC/media/img/slider/ui-bg_highlight-soft_75_cccccc_1x100.png b/noVNC/media/img/slider/ui-bg_highlight-soft_75_cccccc_1x100.png deleted file mode 100755 index 4795f69..0000000 Binary files a/noVNC/media/img/slider/ui-bg_highlight-soft_75_cccccc_1x100.png and /dev/null differ diff --git a/noVNC/media/img/switch_off.png b/noVNC/media/img/switch_off.png deleted file mode 100755 index 640f6d9..0000000 Binary files a/noVNC/media/img/switch_off.png and /dev/null differ diff --git a/noVNC/media/img/switch_on.png b/noVNC/media/img/switch_on.png deleted file mode 100755 index df18e8d..0000000 Binary files a/noVNC/media/img/switch_on.png and /dev/null differ diff --git a/noVNC/media/img/text-bg.png b/noVNC/media/img/text-bg.png deleted file mode 100755 index e38aed9..0000000 Binary files a/noVNC/media/img/text-bg.png and /dev/null differ diff --git a/noVNC/media/img/title_bg.png b/noVNC/media/img/title_bg.png deleted file mode 100755 index 538802a..0000000 Binary files a/noVNC/media/img/title_bg.png and /dev/null differ diff --git a/noVNC/media/img/tree_root.png b/noVNC/media/img/tree_root.png deleted file mode 100755 index c0eb401..0000000 Binary files a/noVNC/media/img/tree_root.png and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/defaulttreeview-black-line.gif b/noVNC/media/img/treeview/.@__thumb/defaulttreeview-black-line.gif deleted file mode 100755 index 96fe919..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/defaulttreeview-black-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/defaulttreeview-default-line.gif b/noVNC/media/img/treeview/.@__thumb/defaulttreeview-default-line.gif deleted file mode 100755 index 905fb43..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/defaulttreeview-default-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/defaulttreeview-gray-line.gif b/noVNC/media/img/treeview/.@__thumb/defaulttreeview-gray-line.gif deleted file mode 100755 index c5cbe0f..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/defaulttreeview-gray-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/defaulttreeview-red-line.gif b/noVNC/media/img/treeview/.@__thumb/defaulttreeview-red-line.gif deleted file mode 100755 index b084306..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/defaulttreeview-red-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/s100treeview-black-line.gif b/noVNC/media/img/treeview/.@__thumb/s100treeview-black-line.gif deleted file mode 100755 index 96fe919..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/s100treeview-black-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/s100treeview-default-line.gif b/noVNC/media/img/treeview/.@__thumb/s100treeview-default-line.gif deleted file mode 100755 index 905fb43..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/s100treeview-default-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/s100treeview-gray-line.gif b/noVNC/media/img/treeview/.@__thumb/s100treeview-gray-line.gif deleted file mode 100755 index c5cbe0f..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/s100treeview-gray-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/s100treeview-red-line.gif b/noVNC/media/img/treeview/.@__thumb/s100treeview-red-line.gif deleted file mode 100755 index b084306..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/s100treeview-red-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/s800treeview-black-line.gif b/noVNC/media/img/treeview/.@__thumb/s800treeview-black-line.gif deleted file mode 100755 index 96fe919..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/s800treeview-black-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/s800treeview-default-line.gif b/noVNC/media/img/treeview/.@__thumb/s800treeview-default-line.gif deleted file mode 100755 index 905fb43..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/s800treeview-default-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/s800treeview-gray-line.gif b/noVNC/media/img/treeview/.@__thumb/s800treeview-gray-line.gif deleted file mode 100755 index c5cbe0f..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/s800treeview-gray-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/.@__thumb/s800treeview-red-line.gif b/noVNC/media/img/treeview/.@__thumb/s800treeview-red-line.gif deleted file mode 100755 index b084306..0000000 Binary files a/noVNC/media/img/treeview/.@__thumb/s800treeview-red-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/Thumbs.db b/noVNC/media/img/treeview/Thumbs.db deleted file mode 100755 index c9a9e5c..0000000 Binary files a/noVNC/media/img/treeview/Thumbs.db and /dev/null differ diff --git a/noVNC/media/img/treeview/file.gif b/noVNC/media/img/treeview/file.gif deleted file mode 100755 index 77e7ab6..0000000 Binary files a/noVNC/media/img/treeview/file.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/folder-closed.gif b/noVNC/media/img/treeview/folder-closed.gif deleted file mode 100755 index c9ac83d..0000000 Binary files a/noVNC/media/img/treeview/folder-closed.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/folder-expanded.png b/noVNC/media/img/treeview/folder-expanded.png deleted file mode 100755 index 073ee42..0000000 Binary files a/noVNC/media/img/treeview/folder-expanded.png and /dev/null differ diff --git a/noVNC/media/img/treeview/folder.gif b/noVNC/media/img/treeview/folder.gif deleted file mode 100755 index 1bff22b..0000000 Binary files a/noVNC/media/img/treeview/folder.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/folder.png b/noVNC/media/img/treeview/folder.png deleted file mode 100755 index 6949e4f..0000000 Binary files a/noVNC/media/img/treeview/folder.png and /dev/null differ diff --git a/noVNC/media/img/treeview/minus.gif b/noVNC/media/img/treeview/minus.gif deleted file mode 100755 index 47fb7b7..0000000 Binary files a/noVNC/media/img/treeview/minus.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/nas.png b/noVNC/media/img/treeview/nas.png deleted file mode 100755 index fc56aa6..0000000 Binary files a/noVNC/media/img/treeview/nas.png and /dev/null differ diff --git a/noVNC/media/img/treeview/plus.gif b/noVNC/media/img/treeview/plus.gif deleted file mode 100755 index 6906621..0000000 Binary files a/noVNC/media/img/treeview/plus.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/tree_arrows.png b/noVNC/media/img/treeview/tree_arrows.png deleted file mode 100755 index b47c18a..0000000 Binary files a/noVNC/media/img/treeview/tree_arrows.png and /dev/null differ diff --git a/noVNC/media/img/treeview/treeview-black-line.gif b/noVNC/media/img/treeview/treeview-black-line.gif deleted file mode 100755 index e549687..0000000 Binary files a/noVNC/media/img/treeview/treeview-black-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/treeview-black.gif b/noVNC/media/img/treeview/treeview-black.gif deleted file mode 100755 index d549b9f..0000000 Binary files a/noVNC/media/img/treeview/treeview-black.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/treeview-default-line.gif b/noVNC/media/img/treeview/treeview-default-line.gif deleted file mode 100755 index 37114d3..0000000 Binary files a/noVNC/media/img/treeview/treeview-default-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/treeview-default.gif b/noVNC/media/img/treeview/treeview-default.gif deleted file mode 100755 index a12ac52..0000000 Binary files a/noVNC/media/img/treeview/treeview-default.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/treeview-famfamfam-line.gif b/noVNC/media/img/treeview/treeview-famfamfam-line.gif deleted file mode 100755 index 6e289ce..0000000 Binary files a/noVNC/media/img/treeview/treeview-famfamfam-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/treeview-famfamfam.gif b/noVNC/media/img/treeview/treeview-famfamfam.gif deleted file mode 100755 index 0cb178e..0000000 Binary files a/noVNC/media/img/treeview/treeview-famfamfam.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/treeview-gray-line.gif b/noVNC/media/img/treeview/treeview-gray-line.gif deleted file mode 100755 index 3760044..0000000 Binary files a/noVNC/media/img/treeview/treeview-gray-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/treeview-gray.gif b/noVNC/media/img/treeview/treeview-gray.gif deleted file mode 100755 index cfb8a2f..0000000 Binary files a/noVNC/media/img/treeview/treeview-gray.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/treeview-red-line.gif b/noVNC/media/img/treeview/treeview-red-line.gif deleted file mode 100755 index df9e749..0000000 Binary files a/noVNC/media/img/treeview/treeview-red-line.gif and /dev/null differ diff --git a/noVNC/media/img/treeview/treeview-red.gif b/noVNC/media/img/treeview/treeview-red.gif deleted file mode 100755 index 3bbb3a1..0000000 Binary files a/noVNC/media/img/treeview/treeview-red.gif and /dev/null differ diff --git a/noVNC/media/img/ubuntu_snapshot.jpg b/noVNC/media/img/ubuntu_snapshot.jpg deleted file mode 120000 index 8d071d7..0000000 --- a/noVNC/media/img/ubuntu_snapshot.jpg +++ /dev/null @@ -1 +0,0 @@ -/share/CACHEDEV1_DATA/.qpkg/.QKVM/tmp/ubuntu/snapshot.jpg \ No newline at end of file diff --git a/noVNC/media/img/vnc/auto_login.png b/noVNC/media/img/vnc/auto_login.png deleted file mode 100755 index f9f4b09..0000000 Binary files a/noVNC/media/img/vnc/auto_login.png and /dev/null differ diff --git a/noVNC/media/img/vnc/auto_logout.png b/noVNC/media/img/vnc/auto_logout.png deleted file mode 100755 index fc499a3..0000000 Binary files a/noVNC/media/img/vnc/auto_logout.png and /dev/null differ diff --git a/noVNC/media/img/vnc/autofit.png b/noVNC/media/img/vnc/autofit.png deleted file mode 100755 index d370551..0000000 Binary files a/noVNC/media/img/vnc/autofit.png and /dev/null differ diff --git a/noVNC/media/img/vnc/c_a_d.png b/noVNC/media/img/vnc/c_a_d.png deleted file mode 100755 index adfc691..0000000 Binary files a/noVNC/media/img/vnc/c_a_d.png and /dev/null differ diff --git a/noVNC/media/img/vnc/cancel.png b/noVNC/media/img/vnc/cancel.png deleted file mode 100755 index c068a7a..0000000 Binary files a/noVNC/media/img/vnc/cancel.png and /dev/null differ diff --git a/noVNC/media/img/vnc/com.png b/noVNC/media/img/vnc/com.png deleted file mode 100755 index 9ae74ee..0000000 Binary files a/noVNC/media/img/vnc/com.png and /dev/null differ diff --git a/noVNC/media/img/vnc/destroy.png b/noVNC/media/img/vnc/destroy.png deleted file mode 100755 index 3cd0269..0000000 Binary files a/noVNC/media/img/vnc/destroy.png and /dev/null differ diff --git a/noVNC/media/img/vnc/exit_full.png b/noVNC/media/img/vnc/exit_full.png deleted file mode 100755 index 83225f1..0000000 Binary files a/noVNC/media/img/vnc/exit_full.png and /dev/null differ diff --git a/noVNC/media/img/vnc/full_screen.png b/noVNC/media/img/vnc/full_screen.png deleted file mode 100755 index f78e147..0000000 Binary files a/noVNC/media/img/vnc/full_screen.png and /dev/null differ diff --git a/noVNC/media/img/vnc/install.png b/noVNC/media/img/vnc/install.png deleted file mode 100755 index e230f8d..0000000 Binary files a/noVNC/media/img/vnc/install.png and /dev/null differ diff --git a/noVNC/media/img/vnc/logout.png b/noVNC/media/img/vnc/logout.png deleted file mode 100755 index 52019d9..0000000 Binary files a/noVNC/media/img/vnc/logout.png and /dev/null differ diff --git a/noVNC/media/img/vnc/reset.png b/noVNC/media/img/vnc/reset.png deleted file mode 100755 index 4ad615a..0000000 Binary files a/noVNC/media/img/vnc/reset.png and /dev/null differ diff --git a/noVNC/media/img/vnc/restore.png b/noVNC/media/img/vnc/restore.png deleted file mode 100755 index b293432..0000000 Binary files a/noVNC/media/img/vnc/restore.png and /dev/null differ diff --git a/noVNC/media/img/vnc/resume.png b/noVNC/media/img/vnc/resume.png deleted file mode 100755 index 17e6a27..0000000 Binary files a/noVNC/media/img/vnc/resume.png and /dev/null differ diff --git a/noVNC/media/img/vnc/shutdown.png b/noVNC/media/img/vnc/shutdown.png deleted file mode 100755 index bd3471d..0000000 Binary files a/noVNC/media/img/vnc/shutdown.png and /dev/null differ diff --git a/noVNC/media/img/vnc/snapshot.png b/noVNC/media/img/vnc/snapshot.png deleted file mode 100755 index 156b765..0000000 Binary files a/noVNC/media/img/vnc/snapshot.png and /dev/null differ diff --git a/noVNC/media/img/vnc/suspend.png b/noVNC/media/img/vnc/suspend.png deleted file mode 100755 index c8905e1..0000000 Binary files a/noVNC/media/img/vnc/suspend.png and /dev/null differ diff --git a/noVNC/media/img/wait.gif b/noVNC/media/img/wait.gif deleted file mode 100755 index 471c1a4..0000000 Binary files a/noVNC/media/img/wait.gif and /dev/null differ diff --git a/noVNC/media/img/wizard/Thumbs.db b/noVNC/media/img/wizard/Thumbs.db deleted file mode 100755 index 5df4a78..0000000 Binary files a/noVNC/media/img/wizard/Thumbs.db and /dev/null differ diff --git a/noVNC/media/img/wizard/circle.png b/noVNC/media/img/wizard/circle.png deleted file mode 100755 index b651ba4..0000000 Binary files a/noVNC/media/img/wizard/circle.png and /dev/null differ diff --git a/noVNC/media/img/wizard/icon.png b/noVNC/media/img/wizard/icon.png deleted file mode 100755 index 3f4f5b2..0000000 Binary files a/noVNC/media/img/wizard/icon.png and /dev/null differ diff --git a/noVNC/media/img/wizard/n1.png b/noVNC/media/img/wizard/n1.png deleted file mode 100755 index 4105a5f..0000000 Binary files a/noVNC/media/img/wizard/n1.png and /dev/null differ diff --git a/noVNC/media/img/wizard/n2.png b/noVNC/media/img/wizard/n2.png deleted file mode 100755 index 080d3cf..0000000 Binary files a/noVNC/media/img/wizard/n2.png and /dev/null differ diff --git a/noVNC/media/img/wizard/window.png b/noVNC/media/img/wizard/window.png deleted file mode 100755 index 088f083..0000000 Binary files a/noVNC/media/img/wizard/window.png and /dev/null differ diff --git a/noVNC/media/java/tightvnc-jviewer-nossh.jar b/noVNC/media/java/tightvnc-jviewer-nossh.jar deleted file mode 100755 index 28d4770..0000000 Binary files a/noVNC/media/java/tightvnc-jviewer-nossh.jar and /dev/null differ diff --git a/noVNC/media/java/vncviewer.jar b/noVNC/media/java/vncviewer.jar deleted file mode 100755 index f7fad3b..0000000 Binary files a/noVNC/media/java/vncviewer.jar and /dev/null differ diff --git a/noVNC/media/js/QFlot.js b/noVNC/media/js/QFlot.js deleted file mode 100755 index d9e1a23..0000000 --- a/noVNC/media/js/QFlot.js +++ /dev/null @@ -1,121 +0,0 @@ -function QFlot(bodyObjID) -{ - this.bodyObjID = bodyObjID; - this.DataArray = []; - this.PreviousData = []; - this.totalPoints = 180; // 180*5s=15min - - - //public methods - QFlot.prototype.InsertData = InsertData; - QFlot.prototype.Repaint = Repaint; - QFlot.prototype.GetData = GetData; - - // private constructor - __construct = function(that) { - }(this) - - function GetData(idx) { - var maxValue = 0; - var result = []; - var rxData = []; - var txData = []; - for (var i=0; i this.totalPoints) { - this.DataArray[i].rx.shift(); - this.DataArray[i].tx.shift(); - } - break; - } - } - } - - function Repaint() { - var resultData = this.GetData(0); - var maxValue = resultData.maxValue/0.9; - if (maxValue < 400) { - maxValue = 400; - } - var myTicksX = []; - for (var i=0; i<=5; i++) { - var xValue = this.totalPoints/5*i; - if(i == 5) { - myTicksX.push([xValue, String((this.totalPoints-xValue)/12)+' MINs']); - } - else { - myTicksX.push([xValue, String((this.totalPoints-xValue)/12)]); - } - } - var myTicksY = [[0, '0KB/s']]; - for (var i=1; i<5; i++) { - var yValue = maxValue/4*i; - if (yValue >= 1024*1024) { - myTicksY.push([yValue, (yValue/1024/1024).toFixed(0) + 'GB']); - } else if (yValue >= 1024) { - myTicksY.push([yValue, (yValue/1024).toFixed(0) + 'MB']); - } else { - myTicksY.push([yValue, yValue.toFixed(0) + 'KB']); - } - } - - var plot = $.plot($('#'+this.bodyObjID), - resultData.result, - { - colors: ["#5E4D93" , "#FCCD06"], - legend: { - container:$("#legendContainer"), - //position: 'nw', - labelBoxBorderColor: "#FFFFFF" - //noColumns: 0 - }, - xaxis: { - min: 0, - max: this.totalPoints, - ticks: myTicksX - }, - yaxis: { - min: 0, - max: maxValue, - ticks: myTicksY - }, - grid:{ backgroundColor: { colors: ["#ffffff", "#ffffff"] } } - - } - ); - plot.draw(); - } - -} \ No newline at end of file diff --git a/noVNC/media/js/QFolderTree.js b/noVNC/media/js/QFolderTree.js deleted file mode 100755 index 7a63df3..0000000 --- a/noVNC/media/js/QFolderTree.js +++ /dev/null @@ -1,227 +0,0 @@ -var gNodeIdCount = 100; -DEFAULT_POOL_FOLDER_ID = ""; - -MODE_SINGLE_FOLDER = 1; -MODE_SINGLE_FILE = 2; -FILTER_FOLDER = 'folder'; -FILTER_EXPORT = 'export'; -FILTER_ISO = 'iso'; -FILTER_IMG = 'img'; - - -function QFolderTree(mode, filter) -{ - //public methods - QFolderTree.prototype.initTree = initTree; - QFolderTree.prototype.destroy = destroy; - QFolderTree.prototype.expandAll = expandAll; - QFolderTree.prototype.collapseAll = collapseAll; - QFolderTree.prototype.onItemlClick = onItemlClick; - QFolderTree.prototype.getItemInfo = getItemInfo; - QFolderTree.prototype.selectFolder = selectFolder; - - this.FolderList = []; - this.FocusID = ""; - this.Mode = mode ? mode : MODE_SINGLE_FOLDER; - this.Filter = filter ? filter : FILTER_FOLDER; - this.bInit = false; - this.BodyObgID = ''; - this.argDefaultFolders = []; - this.bAutoSelect = false; - - var idTreeViewRoot = 'treeviewroot'; - var idTreeViewControl = 'treeviewcontrol'; - var idTreeViewCollapse = 'treeviewcollapse'; - var idTreeViewExpand = 'treeviewexpand'; - - function initTree(bodyObjID, shareList, rootName) { - gNodeIdCount = 100; - this.FolderList = shareList; - this.BodyObgID = bodyObjID; - - var tmpStr = '' + - '
    '+ - '
  • '+rootName+'
      '; - - for (var i=0; i'+this.FolderList[i].name+''; - } - - tmpStr += '
'; - document.getElementById(bodyObjID).innerHTML = tmpStr; - - var parentElm = this; - $('#'+idTreeViewRoot).treeview({ - control:'#'+idTreeViewControl, - toggle: function() { - var elemID = $(this).find(">span").attr('id'); - if (!parentElm.bInit || elemID == 'node_100') { - return false; - } - parentElm.onItemlClick(elemID); - } - }); - this.collapseAll(); - this.bInit = true; - } - - function destroy() { - if (this.BodyObgID) { - document.getElementById(this.BodyObgID).innerHTML = ''; - } - this.FolderList = []; - } - - function expandAll() { - document.getElementById(idTreeViewExpand).click(); - } - - function collapseAll() { - document.getElementById(idTreeViewCollapse).click(); - document.getElementById('node_100').click(); - } - - function getItemInfo(elemID) { - var item = null; - for (var i=0; i'+newItem.name+''; - gNodeIdCount++; - } - - // list file items - for (var i=0; i'+newItem.name+''; - gNodeIdCount++; - } - - var branches = $(tmpStr).appendTo("#root_"+json.id); - $("#root_"+json.id).treeview({ - add: branches - }); - - if (objTree.bAutoSelect) { - objTree.selectFolder(objTree.argDefaultFolders); - } - } - } -} - -function GetShareShortPath(shareMap, fullpath) -{ - var strRet = fullpath; - - for (var i=0; i this.MaxValue || theValue < this.MinValue || isFinite(theValue) == 0 || String(FixJSFloatBug(theValue)).indexOf('.') !=- 1) { - this.OnValidateError(); - return false; - } else { - //prevent bug when user enters '07' for example in the edit field - this.ObjectRef['Edit'].value = FixJSFloatBug(theValue*1); //little trick to convert to numeric and prevent JS Floating point operation bugs - return true; - } - } - - function AddSubStep(mode) - { - if (this.TimerObj) { - clearTimeout(this.TimerObj); - } - - if (this.ObjectRef['Edit'].disabled) { - return; - } - - var OldValue = this.n; - if (this.Step > 0) { - this.n = FixJSFloatBug((mode == "add") ? this.n+this.Step : this.n-this.Step); - if (this.n < this.MinValue) { - this.n = this.MinValue; - } else if (this.n > this.MaxValue) { - this.n = this.MaxValue; - } - } else { - var i = 0; - for (i=0; i<=5; i++) { - var tmp = Math.pow(2, i)*10; //10,20,40,80,160 - if (this.n == tmp) { - this.n = FixJSFloatBug((mode == "add") ? tmp*2 : tmp/2); - if (this.n < 10) { - this.n = FixJSFloatBug(10); - } else if (this.n > 320) { - this.n = FixJSFloatBug(320); - } - break; - } else if (this.n < tmp) { - if ((tmp == 10) && (mode == "sub")) { - this.n = FixJSFloatBug(this.MinValue); - } else { - this.n = FixJSFloatBug((mode == "add") ? tmp : tmp/2); - } - break; - } - } - } - - if (this.n != OldValue) { - this.ObjectRef['Edit'].value = this.n; - this.OnChange(); - } - - var myObj = this; - this.TimerObj = setTimeout(function(){myObj.AddSubStep(mode)}, 200); - } - - function WriteControl(SpinName) - { - this.n = this.DefaultValue; - var readonly_str = ''; - if (this.ReadOnly) { - readonly_str = 'readonly="readonly"'; - } - - document.write(''); - document.write(''); - - if(this.Style == "vert") { - document.write(''); - document.write(''); - document.write(''); - document.write(''); - document.write(''); - } else { //horizontal - document.write(''); - document.write(''); - document.write(''); - } - document.write(''); - document.write('
'); - - //store objects references for faster access - this.ObjectRef['Edit'] = document.getElementById(this.ObjectId['Edit']); - this.ObjectRef['UpArrow'] = document.getElementById(this.ObjectId['UpArrow']); - this.ObjectRef['DownArrow'] = document.getElementById(this.ObjectId['DownArrow']); - } - - //----------------------------------------------------------------- - //GetValue - function GetValue() - { - return this.n; - } - //----------------------------------------------------------------- - //SetValue - function SetValue(newValue) - { - //validation - if (!this.Validate(newValue) || this.ObjectRef['Edit'].disabled) { - return false; - } - - this.n = newValue * 1; - this.ObjectRef['Edit'].value = this.n; - this.OnChange(); - } - //----------------------------------------------------------------- - //ResetValue - function ResetValue() - { - this.n = this.DefaultValue; - this.ObjectRef['Edit'].value = this.n; - this.OnChange(); - } - - //----------------------------------------------------------------- - function HandleChange(bFromKey) - { - this.ObjectRef['Edit'].style.backgroundColor = this.BackgroundColor; - if (!this.Validate(this.ObjectRef['Edit'].value)) { - if (!bFromKey) { - this.ObjectRef['Edit'].value = this.n; - } else { - this.ObjectRef['Edit'].style.backgroundColor = 'yellow'; - } - this.ObjectRef['Edit'].focus(); //set focus warn user - return false; - } else { - this.ObjectRef['Edit'].style.backgroundColor = 'white'; - this.n = FixJSFloatBug(this.ObjectRef['Edit'].value*1); //little trick to convert to numeric and prevent JS Floating point operation bugs - } - - this.OnChange(); - return true; - } - //----------------------------------------------------------------- - function Disable() - { - this.ObjectRef['Edit'].disabled = true; - this.ObjectRef['UpArrow'].disabled = true; - this.ObjectRef['DownArrow'].disabled = true; - } - //----------------------------------------------------------------- - function Enable() - { - this.ObjectRef['Edit'].disabled = false; - this.ObjectRef['UpArrow'].disabled = false; - this.ObjectRef['DownArrow'].disabled = false; - } -} \ No newline at end of file diff --git a/noVNC/media/js/QUtility.js b/noVNC/media/js/QUtility.js deleted file mode 100755 index 745d957..0000000 --- a/noVNC/media/js/QUtility.js +++ /dev/null @@ -1,1182 +0,0 @@ -NOVNC_PORT = 3388; -IMPORT_VM_EXTENSION_PC = [".ova", ".ovf", '.qvm', '.xml']; -IMPORT_VM_EXTENSION_NAS = [".ova", ".ovf", ".vmx", '.qvm', '.xml']; -PERMISSION_LIMIT_CONTROL = 2; -PERMISSION_LIMIT_VIEWONLY = 2; - -function ShowMask(bShowCancel, elemID, blackMask) { - if(document.getElementById("document-mask")){ - var o = document.getElementById("document-mask"); - o.style.visibility = "visible"; - o.style.zIndex = 10000; - o.style.display = 'block'; - o.style.position = 'absolute'; - o.style.filter = "alpha(opacity:50)"; - o.style.KHTMLOpacity = 0.8; - o.style.MozOpacity = 0.8; - o.style.opacity = 0.8; - o.style.background = '#FFF'; - o.style.height = window.innerHeight + 'px'; - - if (blackMask){ - o.style.opacity = 0.6 - o.style.background = '#000'; - } - - if (elemID) { - var rect = document.getElementById(elemID).getBoundingClientRect(); - //o.style.top = rect.top + 'px'; - o.style.left = rect.left + 'px'; - o.style.width = (window.innerWidth-rect.left) + "px"; - document.getElementById("loading-icon").style.left = ((rect.right-rect.left)/2-32) + 'px'; - } else { - o.style.width = window.innerWidth + "px"; - document.getElementById("loading-icon").style.left = (document.body.clientWidth/2-32) + 'px'; - } - document.getElementById("loading-icon").style.top = ($(window).height()/2-32) + 'px'; - - o = document.getElementById("loading-cancel"); - o.style.zIndex = 20000; - o.style.display = 'block'; - o.style.position = 'absolute'; - o.style.height = document.getElementsByName('importvm_cancel')[0].clientHeight + 'px'; - if (elemID) { - var rect = document.getElementById(elemID).getBoundingClientRect(); - o.style.left = (rect.left-15) + 'px'; - o.style.width = (window.innerWidth-rect.left) + "px"; - } else { - o.style.width = window.innerWidth + "px"; - } - document.getElementById("loading-cancel").style.top = (document.body.clientHeight/2+52) + 'px'; - document.getElementById("loading-cancel").style.visibility = bShowCancel ? 'visible':'hidden'; - } -} - -function CloseMask() { - var o = document.getElementById("document-mask"); - o.style.visibility = "hidden"; - document.getElementById("loading-cancel").style.visibility = 'hidden'; -} -/* -function normalConfirm(msg) -{ - var ret = confirm(msg); - if (ret) { - ShowMask(); - } - return ret; -} -*/ -function SubmitConfirm(msg, msgTitle, submitID, sendValue, blackMask) -{ - jConfirm(msg, msgTitle, function(r) { - if(r) - { - if(submitID) - { - $('#'+submitID).val(sendValue); - $('#'+submitID).click(); - } - } - else - { - if(!blackMask) - CloseMask(); - return; - } - },blackMask); - - if(!blackMask) - ShowMask(); -} - -window.alert = function(str,_callback, blackMask) { - jAlert(str, '', _callback, blackMask); -} - -function SubmitConfirmCustom(msg, msgTitle, formID, sendID, _call_backend) -{ - jConfirm(msg, msgTitle, function(r) { - if(r) - { - if(_call_backend) - { - _call_backend(); - } - else - { - $('#'+sendID).attr("disabled", false); - $('#'+formID).submit(); - } - } - else - CloseMask(); - }); - ShowMask(); -} - -function wait(ms) -{ - var start = +(new Date()); - while (new Date() - start < ms); -} - -function makeRequest(url, data, func, param, sync) { - var http_request = true; - if (sync=="false") - sync = false; - else // (typeof sync == "undefined") - sync = true; - - if (window.XMLHttpRequest) { // Mozilla, Safari,... - http_request = new XMLHttpRequest(); - } else if (window.ActiveXObject) { // IE - try { - http_request = new ActiveXObject("Msxml2.XMLHTTP"); - } catch (e) { - try { - http_request = new ActiveXObject("Microsoft.XMLHTTP"); - } catch (e) {} - } - } - - if (!http_request) { - alert('Giving up :( Cannot create an XMLHTTP instance'); - return false; - } - - http_request.onreadystatechange = function(){ func(http_request, param); }; - - if(data==''){ - http_request.open('GET', url, sync); - http_request.send(null); - } - else{ - http_request.open('POST', url, sync); - http_request.send(data); - } -} - -function UpdateVMState(host_id, vname, vmstate) -{ - clearTimeout(VMStateTimer); - - var bExtendExpire = 0; - if (typeof(bAutoLogin) !== "undefined" && bAutoLogin) { - bExtendExpire = 1; - } - - if($('#div_cpuus_text').length) // Update cpu state - UpdateVMHwState(host_id, vname, vmstate); - url = "/vminfo/" + host_id + "/"+ vname +"/?bExtendExpire="+bExtendExpire+"&r=" + Math.random(); - makeRequest(url, '', _callbk_update_vmstate, {'host_id':host_id, 'vname':vname, 'vmstate':vmstate}); -} - -function _callbk_update_vmstate(http_request, param) -{ - if (http_request.readyState == 4) { - if (http_request.status == 200) { - var json = JSON.parse(http_request.responseText); - if ((!json.success && (json.errors.indexOf('Authentication failed') != -1)) || - (param.vmstate != json.state)) { - window.location.href = window.location.href - return; - } - } - VMStateTimer = setTimeout(function(){UpdateVMState(param.host_id, param.vname, param.vmstate);}, 5000); - } -} - -function UpdateVMHwState(host_id, vname, vmstate) -{ - url = "/vminfo/" + host_id + "/"+ vname +"/cpuus/?r=" + Math.random(); - makeRequest(url, '', _callbk_update_vm_cpuus, vmstate); -} - -function _callbk_update_vm_cpuus(http_request, vmstate) -{ - if (http_request.readyState == 4) { - if (http_request.status == 200) { - var json = JSON.parse(http_request.responseText); - var new_cpu_usg = parseInt(json.percentage,10); - var old_cpu_usg = parseInt(document.getElementById('div_cpuus_text').innerHTML); - if((new_cpu_usg > 10 && old_cpu_usg < 10) || (new_cpu_usg < 10 && old_cpu_usg > 10)) - { - var str = ''; - if(new_cpu_usg > 10) - str = ''+new_cpu_usg+'%'; - else - str = ''+new_cpu_usg+'%'; - document.getElementById('div_cpuus').innerHTML = str; - } - else - { - document.getElementById('div_cpuus_bar').style.width = new_cpu_usg+'%'; - document.getElementById('div_cpuus_text').innerHTML = new_cpu_usg+'%'; - } - } - } -} - -function UpdateTaskInfo(host_id) -{ - clearTimeout(TaskInfoTimer); - makeRequest( "/taskinfo/"+host_id+'/', '', _callbk_update_taskinfo, host_id); -} - -function _callbk_update_taskinfo(http_request, host_id) -{ - if (http_request.readyState == 4) { - if (http_request.status == 200) { - var json = JSON.parse(http_request.responseText); - if (!json.success && (json.errors.indexOf('Authentication failed') != -1)) { - var refreshURL=window.location.href; - refreshURL=refreshURL.substr(0,refreshURL.lastIndexOf('/')); - refreshURL=refreshURL.substr(0,refreshURL.lastIndexOf('/'))+'/'; - window.location.href = refreshURL; - return; - } - - // show/hide export/import icon - var elem = document.getElementById('task-import-icon'); - var title = ""; - if (elem) { - elem.style.display = (json.tasks.import.running || json.tasks.import.queuing) ? '' : 'none'; - if (json.tasks.import.running) { - title += gettext('Running')+' : ' + json.tasks.import.running + '\n'; - } - if (json.tasks.import.queuing) { - title += gettext('Queuing')+' : ' + json.tasks.import.queuing; - } - elem.title = title; - - } - elem = document.getElementById('task-export-icon'); - title = ""; - if (elem) { - elem.style.display = (json.tasks.export.running || json.tasks.export.queuing) ? '' : 'none'; - if (json.tasks.export.running) { - title += gettext('Running')+' : ' + json.tasks.export.running + '\n'; - } - if (json.tasks.export.queuing) { - title += gettext('Queuing')+' : ' + json.tasks.export.queuing; - } - elem.title = title; - } - - // show/hide vm background action icon - var cloningVM = ''; - for (var i=0; i 0) ? false : true; -} - -function GetScrollbarWidth() -{ - var parent, child, width; - if (width === undefined) { - parent = $('
').appendTo('body'); - child = parent.children(); - width = child.innerWidth() - child.height(99).innerWidth(); - parent.remove(); - } - return width; -} - -function MacGenerator(inputID) -{ - var mac = "52:54:00" - for (var i=0; i<3; i++) { - var tmp = Math.floor(Math.random()*256).toString(16).toUpperCase(); - if (tmp.length < 2) { - tmp = '0' + tmp; - } - mac += ':' + tmp; - } - - $('#'+inputID).css({'background-color':'','border':'', 'box-shadow': ''}); - $('#'+inputID).attr('title',''); - - return mac; -} - -function CreateMemSliderElement(elem_id) -{ - var link = [256, MAX_MEMORY_VALUE/4, MAX_MEMORY_VALUE/2, MAX_MEMORY_VALUE*3/4, MAX_MEMORY_VALUE]; - if (MAX_MEMORY_VALUE == 512){ - link = [256, 512]; - } - else if (MAX_MEMORY_VALUE == 768){ - link = [256, 512, 768]; - } - else if (MAX_MEMORY_VALUE == 1024){ - link = [256, 512, 768, 1024]; - } - - var str = ''; - for (var i=0; i'+str2+''; - } - str += '
'; - - document.getElementById("memory_slider_link").innerHTML = str; -} - -function UpdateMemorySlider(elemID, value) -{ - var reg = /^[0-9]*$/; - if (!reg.test(value)) { - value = $("#slider-range-min").slider("value"); - } - - if (value < 256) { - value = 256; - } else if (value > MAX_MEMORY_VALUE) { - value = MAX_MEMORY_VALUE; - } - - $("#slider-range-min").slider("value", value); - if (document.getElementById(elemID).value != value) { - document.getElementById(elemID).value = value; - } -} - -function OnHDDSourceChange(value, id_prefix, total) -{ - for (var i=0; i<=total;i++) { - document.getElementById(id_prefix+i).className = (value == i) ? "active" : ""; - } - - var eleTrs = document.getElementById("hdd_table").getElementsByTagName('tr'); - var cnt = 0; - for (var i=0; i=level_3) - { - link = [level_3, endSize]; - } - else if(startSize>=level_2) - { - link = [level_2, level_3, endSize]; - } - else if(startSize>=level_1) - { - link = [level_1, level_2, level_3, endSize]; - } - else - { - link = [0, level_1, level_2, level_3, endSize]; - } - sliderWidth=305; - } - else - { - style='others'; - } - - var str = ''; - - for (var i=0; i'+str2+''; - } - else - { - str += ''+str2+''; - } - } - - str += ''; - str += '
'; - - document.getElementById("HDD_slider_link").innerHTML = str; -} - -function UpdateHDDSlider(elemID, value, startSize, endSize, style) -{ - var reg = /^[0-9]*$/; - if (!reg.test(value)) { - value = $("#slider-range-HDDmin").slider("value"); - } - - if (value < startSize) { - value = startSize; - } else if (value > endSize) { - value = endSize; - } - - $("#slider-range-HDDmin").slider("value", value); - if (document.getElementById(elemID).value != value) { - document.getElementById(elemID).value = value; - } - - if(style=='exMode'){ - document.getElementById("Hddresize_id").value = value-startSize; - } - -} - -function FL_CreateHDDSliderElement(elem_id,startSize,endSize) -{ - startSize=parseInt(startSize); - endSize=parseInt(endSize); - var sizeRange=endSize-startSize; - var level_1=1024; - var level_2=2048; - var level_3=3072; -/* - var level_1=Math.round((startSize+sizeRange/4)/50)*50; - var level_2=Math.round((startSize+sizeRange/2)/50)*50; - var level_3=Math.round((startSize+sizeRange*3/4)/50)*50; -*/ - var link = [startSize, level_1, level_2, level_3, endSize]; - var str = ''; - for (var i=0; i'+str2+''; - } - - str += ''; - str += '
'; - - document.getElementById("FL_HDD_slider_link").innerHTML = str; -} - -function FL_UpdateHDDSlider(elemID, value, startSize, endSize) -{ - var reg = /^[0-9]*$/; - if (!reg.test(value)) { - value = $("#FL_slider-range-HDDmin").slider("value"); - } - - if (value < startSize) { - value = startSize; - } else if (value > endSize) { - value = endSize; - } - - $("#FL_slider-range-HDDmin").slider("value", value); - if (document.getElementById(elemID).value != value) { - document.getElementById(elemID).value = value; - } - -} - -function ReloadShareList(func, params) -{ - url = "/sharelist/"; - makeRequest(url, '', _callbk_reload_sharelist, {'func':func, 'params':params}); -} - -function _callbk_reload_sharelist(http_request, data) -{ - if (http_request.readyState == 4) { - if (http_request.status == 200) { - var json = JSON.parse(http_request.responseText); - if (json.success) { - if (data.params) { - data.func(json.list_data, data.params); - } else { - data.func(json.list_data); - } - } else { - func(null, []); - } - } else { - func(null, []); - } - } - -} - -function decodeHTMLEntities(text) { - var entities = [ - ['apos', '\''], - ['amp', '&'], - ['lt', '<'], - ['gt', '>'] - ]; - - for (var i = 0, max = entities.length; i < max; ++i) { - text = text.replace(new RegExp('&'+entities[i][0]+';', 'g'), entities[i][1]); - } - - return text; -} - -function FileSizeFormat(bytes) { - var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; - if (bytes == 0) return 'n/a'; - var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); - return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i]; -}; - -function onMultiCkboxChange(elem, prefix, totalCnt,openBtn) -{ - if (elem.id == (prefix+'all')) { - for (var i=0; i').attr('id','helpTip').addClass('helpTip').appendTo($('#rightDiv')); - var helpTipBody = $('
').addClass('helpTipBody').css({'width':baseWidth}).appendTo(helpTip); - var helpTipHeadBg = $('
').addClass('helpTipHeadBg').appendTo(helpTip); - var helpTipHead = $('
').addClass('helpTipHead').appendTo(helpTip); - - $(helpContent).appendTo(helpTipBody); - - var detectUserAgent = navigator.userAgent; - if (detectUserAgent.match(/(iPhone|iPod|iPad|Android)/)){ - $('#help-window').on('touchstart click',function(e){ - e.preventDefault(); - var rect = document.getElementById('help-window').getBoundingClientRect(); - var baseLeft=rect.left+11; - var baseTop=rect.top+30; - helpTipBody.css({'left':baseLeft-baseWidth,'top':baseTop}); - helpTipHeadBg.css({'left':baseLeft-5,'top':baseTop-6}); - helpTipHead.css({'left':baseLeft-5,'top':baseTop-5}); - helpTip.show(); - helpTip.before($('
')); - $('#closeMask').on('touchstart click',closeTip); - }); - - } - else{ - $('#help-window').mouseover(function(){ - var rect = document.getElementById('help-window').getBoundingClientRect(); - var baseLeft=rect.left+11; - var baseTop=rect.top+30; - helpTipBody.css({'left':baseLeft-baseWidth,'top':baseTop}); - helpTipHeadBg.css({'left':baseLeft-5,'top':baseTop-6}); - helpTipHead.css({'left':baseLeft-5,'top':baseTop-5}); - helpTip.show(); - - $('#help-window').click(function(e){ - if(!$('#closeMask').attr('id')) - helpTip.before($('
')); - $('#help-window').off('mouseout'); - $('#closeMask').on('click',closeTip); - }); - - $('#help-window').mouseout(function(){ - $('.helpTip').hide(); - }); - - function closeTip(e){ - e.preventDefault(); - $('.helpTip').hide(); - $('#closeMask').remove(); - } - - }); - } -} - -function closeTip(e){ - e.preventDefault(); - $('.helpTip').hide(); - $('#closeMask').remove(); -} - -//account function start -function accountMenu(userName,lastLoginTime,page){ - if($('#accountMenu').attr('id')!=undefined){ - $('#accountMenu').remove(); - $('#closeMask').remove(); - } - else{ - var rect = $('.account')[0].getBoundingClientRect(); - var baseTop=rect.top+28; - var scrollWidth=18; - - if (oBrowser.isCh){ - scrollWidth=4; - } - - if($('#rightDiv')[0].scrollHeight > $('#rightDiv')[0].clientHeight){ - scrollWidth=0; - } - - if(page=='vm'){ - baseTop = 60; - } - - $('
').appendTo($('#rightDiv')); - var accountMenu = $('
').appendTo($('#rightDiv')); - - if (oBrowser.isCh){ - var accountMenuContent = $('
').addClass('accountContent').css({'right':15-scrollWidth,'top':baseTop}).appendTo(accountMenu); - var accountHeadBg = $('
').addClass('accountHeadBg').css({'right':33-scrollWidth,'top':baseTop-7}).appendTo(accountMenu); - var accountHead = $('
').addClass('accountHead').css({'right':33-scrollWidth,'top':baseTop-5}).appendTo(accountMenu); - } - else{ - var accountMenuContent = $('
').addClass('accountContent').css({'right':30-scrollWidth,'top':baseTop}).appendTo(accountMenu); - var accountHeadBg = $('
').addClass('accountHeadBg').css({'right':48-scrollWidth,'top':baseTop-7}).appendTo(accountMenu); - var accountHead = $('
').addClass('accountHead').css({'right':48-scrollWidth,'top':baseTop-5}).appendTo(accountMenu); - } - - if(userName=='admin'){ - if(window.parent != window.self){ - accountMenuContent.append('
'+userName+'
'+gettext('Last login time')+':
'+ - '
'+lastLoginTime+'
'+ - '
'+gettext('About')+'
'); - } - else{ - accountMenuContent.append('
'+userName+'
'+gettext('Last login time')+':
'+ - '
'+lastLoginTime+'
'+ - '
'+gettext('Logout')+'
'+ - '
'+gettext('About')+'
'); - } - } - else{ - accountMenuContent.append('
'+userName+'
'+gettext('Last login time')+':
'+ - '
'+lastLoginTime+'
'+ - '
'+gettext('Change Password')+'
'+ - '
'+gettext('Logout')+'
'+ - '
'+gettext('About')+'
'); - } - - $('#closeMask').on('touchstart click',closeAccount); - } -} - -function closeAccount(e){ - e.preventDefault(); - $('#accountMenu').remove(); - $('#closeMask').remove(); -} - -function accountControl(choice,blackMask){ - $('.warningStr').hide(); - $('#closeMask').remove(); - $('#accountMenu').remove(); - - if(choice=='logout'){ - ShowMask(); - jConfirm(gettext('Are you sure to log out?'), gettext('Logout Confirm'), function(r) { - if(r) - { - document.location.href='/admin/logout/'; - } - else - { - CloseMask(); - return; - } - },blackMask); - } -} -//account function end - -function getCookie(key) -{ - if( document.cookie.length==0 ) - return false; - - var i=document.cookie.search(key+'='); - if( i==-1 ) - return false; - - i+=key.length+1; - var j=document.cookie.indexOf(';', i); - if( j==-1 ) - j=document.cookie.length; - return document.cookie.slice(i,j); -} - -function fireEvent(element, event) -{ - if (document.createEventObject) { - // dispatch for IE - var evt = document.createEventObject(); - return element.fireEvent('on'+event,evt) - } else { - // dispatch for firefox + others - var evt = document.createEvent("HTMLEvents"); - evt.initEvent(event, true, true ); // event type,bubbling,cancelable - return !element.dispatchEvent(evt); - } -} - -function OnVNCShapshot(host_id, vmname, elem) -{ - url = "/vncsnapshot/"+host_id+"/"+vmname+"/?r=" + Math.random(); - makeRequest(url, '', _callbk_vnc_snapshot, elem.id); -} - -function _callbk_vnc_snapshot(http_request, elemID) -{ - if (http_request.readyState == 4) { - if (http_request.status == 200) { - var json = JSON.parse(http_request.responseText); - console.log(json); - if (!json.success) { - console.log('[Failed]'+json.errors) - return; - } - // update image source path = '/media/img/'+json.vname+'_snapshot.jpg' - showVNCSnapshot(json.vname); - } - } -} - -function creatVNCSnapshot(host_id){ - var helpTip = $('
').attr('id','vncSnapshot').addClass('helpTip').appendTo($('#rightDiv')); - var helpTipBody = $('
').attr('id','vncSnapshotBody').addClass('helpTipBody').appendTo(helpTip); - var helpTipHeadBg = $('
').attr('id','vncSnapshotHeadBg').addClass('helpTipHeadBg').appendTo(helpTip); - var helpTipHead = $('
').attr('id','vncSnapshotHead').addClass('helpTipHead').appendTo(helpTip); - - $('.OnVNCShapshot').on('mouseover',function(e){ - e.preventDefault(); - var vmname = $(this).attr('id').replace('vnc_',''); - - if(oBrowser.isFF){ - OnVNCShapshot(host_id, vmname, $(this)); - } - else if(oBrowser.isCh){ - if(e.relatedTarget.id == $(this).attr('id')) - OnVNCShapshot(host_id, vmname, $(this)); - } - else{ - var sAgent = navigator.userAgent.toLowerCase() - isWin8 = (sAgent.indexOf("windows nt 6.2")!=-1); - - if(isWin8){ - OnVNCShapshot(host_id, vmname, $(this)); - } - else{ - if(e.relatedTarget.id == $(this).attr('id')) - OnVNCShapshot(host_id, vmname, $(this)); - } - } - - $('#rightDiv').on('touchstart click',function(e){ - e.preventDefault(); - $('#vncSnapshot').hide(); - }); - }); - - $('.OnVNCShapshot').mouseout(function(e){ - e.preventDefault(); - $('#vncSnapshot').hide(); - }); -} - -function showVNCSnapshot(vname){ - $('#vncSnapshotBody').children().remove(); - var baseWidth = 400; - var baseHeight = 250; - var dt=new Date(); - var imgPath = '/media/img/'+vname+'_snapshot.jpg?r='+dt.getTime(); - $('').attr('src',imgPath).css('height',250).appendTo($('#vncSnapshotBody')); - - var detectUserAgent = navigator.userAgent; - if($('#btn_console').attr('id')==undefined){ //overview page - $('#vncSnapshotBody').css({'height':baseHeight}); - - var winWidth = window.innerWidth; - var rect = document.getElementById('vnc_'+vname).getBoundingClientRect(); - var baseLeft=rect.left+11; - var baseTop=rect.top-5; - - if((baseTop-272)>0){ - $('#vncSnapshotHeadBg').removeClass().addClass('vncSnapshotHeadBg'); - $('#vncSnapshotHead').removeClass().addClass('vncSnapshotHead'); - $('#vncSnapshotBody').css({'right':winWidth-baseLeft-10,'top':baseTop-272}); - $('#vncSnapshotHeadBg').css({'left':baseLeft-10,'top':baseTop-5}); - $('#vncSnapshotHead').css({'left':baseLeft-10,'top':baseTop-6}); - } - else{ - $('#vncSnapshotHeadBg').removeClass().addClass('helpTipHeadBg'); - $('#vncSnapshotHead').removeClass().addClass('helpTipHead'); - baseTop=rect.top+30; - $('#vncSnapshotBody').css({'right':winWidth-baseLeft-10,'top':baseTop}); - $('#vncSnapshotHeadBg').css({'left':baseLeft-10,'top':baseTop-6}); - $('#vncSnapshotHead').css({'left':baseLeft-10,'top':baseTop-5}); - } - - $('#vncSnapshot').show(); - - } - else{ //VM page - //$('#vncSnapshotBody').css({'width':baseWidth}); - $('#vncSnapshotHeadBg').addClass('helpTipHeadBg'); - $('#vncSnapshotHead').addClass('helpTipHead'); - - var windowHeight = window.innerHeight; - var rect = document.getElementById('btn_console').getBoundingClientRect(); - var baseLeft=rect.left+11; - var baseTop=rect.top+30; - - $('#vncSnapshotBody').css({'left':baseLeft+20,'top':baseTop+7}); - $('#vncSnapshotHeadBg').css({'left':baseLeft-5+40,'top':baseTop-6+5}); - $('#vncSnapshotHead').css({'left':baseLeft-5+40,'top':baseTop-5+5}); - - if($('#conselModal').hasClass('in')){ - $('#vncSnapshot').hide(); - } - else{ - $('#vncSnapshot').show(); - } - - $('#btn_console').on('mouseout click',function(){ - $('#vncSnapshot').hide(); - }); - - $('body').click(function(){ - $('#vncSnapshot').hide(); - }); - - - } -} - -function addSSLHint(){ - var targetVNC = window.location.protocol + "//" + window.location.hostname + ":" + WebUtil.getQueryVar('port', ''); - var SSLbrowser = "FF"; - var hint = ""; - - $('#noVNC_canvas').hide(); - $('body').css('overflow','auto'); - if(oBrowser.isFF){ - SSLbrowser = "FF"; - hint = '
'+gettext("Please add the console's URL to your web browser's [Exception List].")+'
'+ - '
1.'+gettext('Please click to open a new tab.')+'
'+ - '
'+ - '
4.'+gettext('Close the new tab')+'
'+ - '
5.'+gettext('Please click to refresh this page.')+'
'; - $('
').attr('id','addSSLHint').appendTo($('#noVNC_container')); - } - else if(oBrowser.isIE){ - SSLbrowser = "IE"; - hint = '
'+gettext('For security concerns, the HTML5 Console with SSL does not support Internet Explorer.')+'
'+ - '
'+gettext('Click [Redirect] button to open a normal console page.')+'
'+ - '
'; - $('
').attr('id','addSSLHint').css({'height':'150px','width':'800px','margin-left':'-400px','padding':'40px 20px 0 20px'}).appendTo($('#noVNC_container')); - } - - $(hint).appendTo($('#addSSLHint')); - - $('#hintBtn01').on('touchstart click',function(){ - window.open(targetVNC, '_blank'); - }); - - $('#hintBtn02').on('touchstart click',function(){ - location=location; - }); - - $('#hintBtn03').on('touchstart click',function(){ - var port = window.location.port; - var url = window.location.href.replace('https:','http:'); - var r1 = ':'+port+'/'; - var r2 = ':'+(port-1)+'/'; - url = url.replace(r1, r2); - location=url; - }); -} \ No newline at end of file diff --git a/noVNC/media/js/ZeroClipboard.swf b/noVNC/media/js/ZeroClipboard.swf deleted file mode 100755 index 13bf8e3..0000000 Binary files a/noVNC/media/js/ZeroClipboard.swf and /dev/null differ diff --git a/noVNC/media/js/bootstrap-alert.js b/noVNC/media/js/bootstrap-alert.js deleted file mode 100755 index d17f44e..0000000 --- a/noVNC/media/js/bootstrap-alert.js +++ /dev/null @@ -1,94 +0,0 @@ -/* ========================================================== - * bootstrap-alert.js v2.0.2 - * http://twitter.github.com/bootstrap/javascript.html#alerts - * ========================================================== - * Copyright 2012 Twitter, Inc. - * - * 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. - * ========================================================== */ - - -!function( $ ){ - - "use strict" - - /* ALERT CLASS DEFINITION - * ====================== */ - - var dismiss = '[data-dismiss="alert"]' - , Alert = function ( el ) { - $(el).on('click', dismiss, this.close) - } - - Alert.prototype = { - - constructor: Alert - - , close: function ( e ) { - var $this = $(this) - , selector = $this.attr('data-target') - , $parent - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 - } - - $parent = $(selector) - $parent.trigger('close') - - e && e.preventDefault() - - $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) - - $parent - .trigger('close') - .removeClass('in') - - function removeElement() { - $parent - .trigger('closed') - .remove() - } - - $.support.transition && $parent.hasClass('fade') ? - $parent.on($.support.transition.end, removeElement) : - removeElement() - } - - } - - - /* ALERT PLUGIN DEFINITION - * ======================= */ - - $.fn.alert = function ( option ) { - return this.each(function () { - var $this = $(this) - , data = $this.data('alert') - if (!data) $this.data('alert', (data = new Alert(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - $.fn.alert.Constructor = Alert - - - /* ALERT DATA-API - * ============== */ - - $(function () { - $('body').on('click.alert.data-api', dismiss, Alert.prototype.close) - }) - -}( window.jQuery ); \ No newline at end of file diff --git a/noVNC/media/js/bootstrap-button.js b/noVNC/media/js/bootstrap-button.js deleted file mode 100755 index 6b36753..0000000 --- a/noVNC/media/js/bootstrap-button.js +++ /dev/null @@ -1,100 +0,0 @@ -/* ============================================================ - * bootstrap-button.js v2.0.2 - * http://twitter.github.com/bootstrap/javascript.html#buttons - * ============================================================ - * Copyright 2012 Twitter, Inc. - * - * 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. - * ============================================================ */ - -!function( $ ){ - - "use strict" - - /* BUTTON PUBLIC CLASS DEFINITION - * ============================== */ - - var Button = function ( element, options ) { - this.$element = $(element) - this.options = $.extend({}, $.fn.button.defaults, options) - } - - Button.prototype = { - - constructor: Button - - , setState: function ( state ) { - var d = 'disabled' - , $el = this.$element - , data = $el.data() - , val = $el.is('input') ? 'val' : 'html' - - state = state + 'Text' - data.resetText || $el.data('resetText', $el[val]()) - - $el[val](data[state] || this.options[state]) - - // push to event loop to allow forms to submit - setTimeout(function () { - state == 'loadingText' ? - $el.addClass(d).attr(d, d) : - $el.removeClass(d).removeAttr(d) - }, 0) - } - - , toggle: function () { - var $parent = this.$element.parent('[data-toggle="buttons-radio"]') - - $parent && $parent - .find('.active') - .removeClass('active') - - this.$element.toggleClass('active') - } - - } - - - /* BUTTON PLUGIN DEFINITION - * ======================== */ - - $.fn.button = function ( option ) { - return this.each(function () { - var $this = $(this) - , data = $this.data('button') - , options = typeof option == 'object' && option - if (!data) $this.data('button', (data = new Button(this, options))) - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - - $.fn.button.defaults = { - loadingText: 'loading...' - } - - $.fn.button.Constructor = Button - - - /* BUTTON DATA-API - * =============== */ - - $(function () { - $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - $btn.button('toggle') - }) - }) - -}( window.jQuery ); \ No newline at end of file diff --git a/noVNC/media/js/bootstrap-carousel.js b/noVNC/media/js/bootstrap-carousel.js deleted file mode 100755 index 8c0723d..0000000 --- a/noVNC/media/js/bootstrap-carousel.js +++ /dev/null @@ -1,161 +0,0 @@ -/* ========================================================== - * bootstrap-carousel.js v2.0.2 - * http://twitter.github.com/bootstrap/javascript.html#carousel - * ========================================================== - * Copyright 2012 Twitter, Inc. - * - * 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. - * ========================================================== */ - - -!function( $ ){ - - "use strict" - - /* CAROUSEL CLASS DEFINITION - * ========================= */ - - var Carousel = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, $.fn.carousel.defaults, options) - this.options.slide && this.slide(this.options.slide) - this.options.pause == 'hover' && this.$element - .on('mouseenter', $.proxy(this.pause, this)) - .on('mouseleave', $.proxy(this.cycle, this)) - } - - Carousel.prototype = { - - cycle: function () { - this.interval = setInterval($.proxy(this.next, this), this.options.interval) - return this - } - - , to: function (pos) { - var $active = this.$element.find('.active') - , children = $active.parent().children() - , activePos = children.index($active) - , that = this - - if (pos > (children.length - 1) || pos < 0) return - - if (this.sliding) { - return this.$element.one('slid', function () { - that.to(pos) - }) - } - - if (activePos == pos) { - return this.pause().cycle() - } - - return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos])) - } - - , pause: function () { - clearInterval(this.interval) - this.interval = null - return this - } - - , next: function () { - if (this.sliding) return - return this.slide('next') - } - - , prev: function () { - if (this.sliding) return - return this.slide('prev') - } - - , slide: function (type, next) { - var $active = this.$element.find('.active') - , $next = next || $active[type]() - , isCycling = this.interval - , direction = type == 'next' ? 'left' : 'right' - , fallback = type == 'next' ? 'first' : 'last' - , that = this - - this.sliding = true - - isCycling && this.pause() - - $next = $next.length ? $next : this.$element.find('.item')[fallback]() - - if ($next.hasClass('active')) return - - if (!$.support.transition && this.$element.hasClass('slide')) { - this.$element.trigger('slide') - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger('slid') - } else { - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - this.$element.trigger('slide') - this.$element.one($.support.transition.end, function () { - $next.removeClass([type, direction].join(' ')).addClass('active') - $active.removeClass(['active', direction].join(' ')) - that.sliding = false - setTimeout(function () { that.$element.trigger('slid') }, 0) - }) - } - - isCycling && this.cycle() - - return this - } - - } - - - /* CAROUSEL PLUGIN DEFINITION - * ========================== */ - - $.fn.carousel = function ( option ) { - return this.each(function () { - var $this = $(this) - , data = $this.data('carousel') - , options = typeof option == 'object' && option - if (!data) $this.data('carousel', (data = new Carousel(this, options))) - if (typeof option == 'number') data.to(option) - else if (typeof option == 'string' || (option = options.slide)) data[option]() - else data.cycle() - }) - } - - $.fn.carousel.defaults = { - interval: 5000 - , pause: 'hover' - } - - $.fn.carousel.Constructor = Carousel - - - /* CAROUSEL DATA-API - * ================= */ - - $(function () { - $('body').on('click.carousel.data-api', '[data-slide]', function ( e ) { - var $this = $(this), href - , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 - , options = !$target.data('modal') && $.extend({}, $target.data(), $this.data()) - $target.carousel(options) - e.preventDefault() - }) - }) - -}( window.jQuery ); \ No newline at end of file diff --git a/noVNC/media/js/bootstrap-collapse.js b/noVNC/media/js/bootstrap-collapse.js deleted file mode 100755 index 9a36446..0000000 --- a/noVNC/media/js/bootstrap-collapse.js +++ /dev/null @@ -1,138 +0,0 @@ -/* ============================================================= - * bootstrap-collapse.js v2.0.2 - * http://twitter.github.com/bootstrap/javascript.html#collapse - * ============================================================= - * Copyright 2012 Twitter, Inc. - * - * 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. - * ============================================================ */ - -!function( $ ){ - - "use strict" - - var Collapse = function ( element, options ) { - this.$element = $(element) - this.options = $.extend({}, $.fn.collapse.defaults, options) - - if (this.options["parent"]) { - this.$parent = $(this.options["parent"]) - } - - this.options.toggle && this.toggle() - } - - Collapse.prototype = { - - constructor: Collapse - - , dimension: function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - , show: function () { - var dimension = this.dimension() - , scroll = $.camelCase(['scroll', dimension].join('-')) - , actives = this.$parent && this.$parent.find('.in') - , hasData - - if (actives && actives.length) { - hasData = actives.data('collapse') - actives.collapse('hide') - hasData || actives.data('collapse', null) - } - - this.$element[dimension](0) - this.transition('addClass', 'show', 'shown') - this.$element[dimension](this.$element[0][scroll]) - - } - - , hide: function () { - var dimension = this.dimension() - this.reset(this.$element[dimension]()) - this.transition('removeClass', 'hide', 'hidden') - this.$element[dimension](0) - } - - , reset: function ( size ) { - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - [dimension](size || 'auto') - [0].offsetWidth - - this.$element[size ? 'addClass' : 'removeClass']('collapse') - - return this - } - - , transition: function ( method, startEvent, completeEvent ) { - var that = this - , complete = function () { - if (startEvent == 'show') that.reset() - that.$element.trigger(completeEvent) - } - - this.$element - .trigger(startEvent) - [method]('in') - - $.support.transition && this.$element.hasClass('collapse') ? - this.$element.one($.support.transition.end, complete) : - complete() - } - - , toggle: function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } - - } - - /* COLLAPSIBLE PLUGIN DEFINITION - * ============================== */ - - $.fn.collapse = function ( option ) { - return this.each(function () { - var $this = $(this) - , data = $this.data('collapse') - , options = typeof option == 'object' && option - if (!data) $this.data('collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.collapse.defaults = { - toggle: true - } - - $.fn.collapse.Constructor = Collapse - - - /* COLLAPSIBLE DATA-API - * ==================== */ - - $(function () { - $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) { - var $this = $(this), href - , target = $this.attr('data-target') - || e.preventDefault() - || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 - , option = $(target).data('collapse') ? 'toggle' : $this.data() - $(target).collapse(option) - }) - }) - -}( window.jQuery ); \ No newline at end of file diff --git a/noVNC/media/js/bootstrap-dropdown.js b/noVNC/media/js/bootstrap-dropdown.js deleted file mode 100755 index 54b61c5..0000000 --- a/noVNC/media/js/bootstrap-dropdown.js +++ /dev/null @@ -1,92 +0,0 @@ -/* ============================================================ - * bootstrap-dropdown.js v2.0.2 - * http://twitter.github.com/bootstrap/javascript.html#dropdowns - * ============================================================ - * Copyright 2012 Twitter, Inc. - * - * 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. - * ============================================================ */ - - -!function( $ ){ - - "use strict" - - /* DROPDOWN CLASS DEFINITION - * ========================= */ - - var toggle = '[data-toggle="dropdown"]' - , Dropdown = function ( element ) { - var $el = $(element).on('click.dropdown.data-api', this.toggle) - $('html').on('click.dropdown.data-api', function () { - $el.parent().removeClass('open') - }) - } - - Dropdown.prototype = { - - constructor: Dropdown - - , toggle: function ( e ) { - var $this = $(this) - , selector = $this.attr('data-target') - , $parent - , isActive - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 - } - - $parent = $(selector) - $parent.length || ($parent = $this.parent()) - - isActive = $parent.hasClass('open') - - clearMenus() - !isActive && $parent.toggleClass('open') - - return false - } - - } - - function clearMenus() { - $(toggle).parent().removeClass('open') - } - - - /* DROPDOWN PLUGIN DEFINITION - * ========================== */ - - $.fn.dropdown = function ( option ) { - return this.each(function () { - var $this = $(this) - , data = $this.data('dropdown') - if (!data) $this.data('dropdown', (data = new Dropdown(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - $.fn.dropdown.Constructor = Dropdown - - - /* APPLY TO STANDARD DROPDOWN ELEMENTS - * =================================== */ - - $(function () { - $('html').on('click.dropdown.data-api', clearMenus) - $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle) - }) - -}( window.jQuery ); \ No newline at end of file diff --git a/noVNC/media/js/bootstrap-file-input.js b/noVNC/media/js/bootstrap-file-input.js deleted file mode 100755 index 72363dc..0000000 --- a/noVNC/media/js/bootstrap-file-input.js +++ /dev/null @@ -1,113 +0,0 @@ -/* - Bootstrap - File Input - ====================== - - This is meant to convert all file input tags into a set of elements that displays consistently in all browsers. - - Converts all - - into Bootstrap buttons - Browse - -*/ -$(function() { - -$('input[type=file]').each(function(i,elem){ - - // Maybe some fields don't need to be standardized. - if (typeof $(this).attr('data-bfi-disabled') != 'undefined') { - return; - } - - // Set the word to be displayed on the button - var buttonWord = gettext('Browse'); - - if (typeof $(this).attr('title') != 'undefined') { - buttonWord = $(this).attr('title'); - } - - // Start by getting the HTML of the input element. - // Thanks for the tip http://stackoverflow.com/a/1299069 - var $elem = $(elem); - var input = $('
').append( $elem.eq(0).clone() ).html(); - - // Now we're going to replace that input field with a Bootstrap button. - // The input will actually still be there, it will just be float above and transparent (done with the CSS). - $elem.replaceWith(''+buttonWord+input+''); -}) -// After we have found all of the file inputs let's apply a listener for tracking the mouse movement. -// This is important because the in order to give the illusion that this is a button in FF we actually need to move the button from the file input under the cursor. Ugh. -.promise().done( function(){ - - // As the cursor moves over our new Bootstrap button we need to adjust the position of the invisible file input Browse button to be under the cursor. - // This gives us the pointer cursor that FF denies us - $('.file-input-wrapper').mousemove(function(cursor) { - - var input, wrapper, - wrapperX, wrapperY, - inputWidth, inputHeight, - cursorX, cursorY; - - // This wrapper element (the button surround this file input) - wrapper = $(this); - // The invisible file input element - input = wrapper.find("input"); - // The left-most position of the wrapper - wrapperX = wrapper.offset().left; - // The top-most position of the wrapper - wrapperY = wrapper.offset().top; - // The with of the browsers input field - inputWidth= input.width(); - // The height of the browsers input field - inputHeight= input.height(); - //The position of the cursor in the wrapper - cursorX = cursor.pageX; - cursorY = cursor.pageY; - - //The positions we are to move the invisible file input - // The 20 at the end is an arbitrary number of pixels that we can shift the input such that cursor is not pointing at the end of the Browse button but somewhere nearer the middle - moveInputX = cursorX - wrapperX - inputWidth + 20; - // Slides the invisible input Browse button to be positioned middle under the cursor - moveInputY = cursorY- wrapperY - (inputHeight/2); - - // Apply the positioning styles to actually move the invisible file input - input.css({ - left:moveInputX, - top:moveInputY - }); - }); - - $('.file-input-wrapper input[type=file]').change(function(){ - - // Remove any previous file names - $(this).parent().next('.file-input-name').remove(); - if ($(this).prop('files').length > 1) { - count = $(this).prop('files').length; - str = '
' - for (var i=0; i'; - } - str += '
'; - $(this).parent().after(str); - } - else { - $(this).parent().after('
'+$(this).val().replace('C:\\fakepath\\','')+'
'); - } - - }); - - - -}); - -// Add the styles before the first stylesheet -// This ensures they can be easily overridden with developer styles -var cssHtml = ''; -$('link[rel=stylesheet]').eq(0).before(cssHtml); - -}); diff --git a/noVNC/media/js/bootstrap-modal.js b/noVNC/media/js/bootstrap-modal.js deleted file mode 100755 index 8bec6b8..0000000 --- a/noVNC/media/js/bootstrap-modal.js +++ /dev/null @@ -1,211 +0,0 @@ -/* ========================================================= - * bootstrap-modal.js v2.0.2 - * http://twitter.github.com/bootstrap/javascript.html#modals - * ========================================================= - * Copyright 2012 Twitter, Inc. - * - * 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. - * ========================================================= */ - - -!function( $ ){ - - "use strict" - - /* MODAL CLASS DEFINITION - * ====================== */ - - var Modal = function ( content, options ) { - this.options = options - this.$element = $(content) - .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) - } - - Modal.prototype = { - - constructor: Modal - - , toggle: function () { - return this[!this.isShown ? 'show' : 'hide']() - } - - , show: function () { - var that = this - - if (this.isShown) return - - $('body').addClass('modal-open') - - this.isShown = true - this.$element.trigger('show') - - escape.call(this) - backdrop.call(this, function () { - var transition = $.support.transition && that.$element.hasClass('fade') - - !that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position - - that.$element - .show() - - if (transition) { - that.$element[0].offsetWidth // force reflow - } - - that.$element.addClass('in') - - transition ? - that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) : - that.$element.trigger('shown') - - }) - } - - , hide: function ( e ) { - e && e.preventDefault() - - if (!this.isShown) return - - var that = this - this.isShown = false - - $('body').removeClass('modal-open') - - escape.call(this) - - this.$element - .trigger('hide') - .removeClass('in') - - $.support.transition && this.$element.hasClass('fade') ? - hideWithTransition.call(this) : - hideModal.call(this) - } - - } - - - /* MODAL PRIVATE METHODS - * ===================== */ - - function hideWithTransition() { - var that = this - , timeout = setTimeout(function () { - that.$element.off($.support.transition.end) - hideModal.call(that) - }, 500) - - this.$element.one($.support.transition.end, function () { - clearTimeout(timeout) - hideModal.call(that) - }) - } - - function hideModal( that ) { - this.$element - .hide() - .trigger('hidden') - - backdrop.call(this) - } - - function backdrop( callback ) { - var that = this - , animate = this.$element.hasClass('fade') ? 'fade' : '' - - if (this.isShown && this.options.backdrop) { - var doAnimate = $.support.transition && animate - - this.$backdrop = $('