update noVNC component
							
								
								
									
										5
									
								
								php/composer.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,5 @@ | ||||
| { | ||||
|     "require": { | ||||
|         "sentry/sdk": "^3.2" | ||||
|     } | ||||
| } | ||||
							
								
								
									
										13
									
								
								public/novnc/AUTHORS
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,13 @@ | ||||
| maintainers: | ||||
| - Joel Martin (@kanaka) | ||||
| - Solly Ross (@directxman12) | ||||
| - Samuel Mannehed for Cendio AB (@samhed) | ||||
| - Pierre Ossman for Cendio AB (@CendioOssman) | ||||
| maintainersEmeritus: | ||||
| - @astrand  | ||||
| contributors: | ||||
| # There are a bunch of people that should be here. | ||||
| # If you want to be on this list, feel free send a PR | ||||
| # to add yourself. | ||||
| - jalf <git@jalf.dk> | ||||
| - NTT corp. | ||||
| @@ -1,22 +1,14 @@ | ||||
| noVNC is Copyright (C) 2011 Joel Martin <github@martintribe.org> | ||||
| noVNC is Copyright (C) 2019 The noVNC Authors | ||||
| (./AUTHORS) | ||||
|  | ||||
| The noVNC core library files are licensed under the MPL 2.0 (Mozilla | ||||
| 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/keysym.js | ||||
|     include/logo.js | ||||
|     include/playback.js | ||||
|     include/rfb.js | ||||
|     include/ui.js | ||||
|     include/util.js | ||||
|     include/websock.js | ||||
|     include/webutil.js | ||||
|     core/**/*.js | ||||
|     app/*.js | ||||
|     test/playback.js | ||||
|  | ||||
| The HTML, CSS, font and images files that included with the noVNC | ||||
| source distibution (or repository) are not considered part of the | ||||
| @@ -28,34 +20,27 @@ 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. | ||||
| Please refer to the individual source files and/or to the noVNC commit | ||||
| history: https://github.com/kanaka/noVNC/commits/master | ||||
| history: https://github.com/novnc/noVNC/commits/master | ||||
|  | ||||
| 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 | ||||
|     core/base64.js          : MPL 2.0 | ||||
|  | ||||
|     include/des.js             : Various BSD style licenses | ||||
|     core/des.js             : Various BSD style licenses | ||||
|  | ||||
|     include/chrome-app/tcp-stream.js | ||||
|                                : Apache 2.0 license | ||||
|  | ||||
|     utils/websockify | ||||
|     utils/websocket.py         : LGPL 3 | ||||
|      | ||||
|     utils/inflator.partial.js | ||||
|     include/inflator.js        : MIT (for pako) | ||||
|     vendor/pako/            : MIT | ||||
|  | ||||
| Any other files not mentioned above are typically marked with | ||||
| a copyright/license header at the top of the file. The default noVNC | ||||
| @@ -64,21 +49,14 @@ license is MPL-2.0. | ||||
| The following license texts are included: | ||||
|  | ||||
|     docs/LICENSE.MPL-2.0 | ||||
|     docs/LICENSE.LGPL-3 and | ||||
|     docs/LICENSE.GPL-3 | ||||
|     docs/LICENSE.OFL-1.1 | ||||
|     docs/LICENSE.BSD-3-Clause (New BSD) | ||||
|     docs/LICENSE.BSD-2-Clause (Simplified BSD / FreeBSD) | ||||
|     docs/LICENSE.zlib | ||||
|     docs/LICENSE.Apache-2.0 | ||||
|     docs/LICENSE.pako | ||||
|     vendor/pako/LICENSE (MIT) | ||||
|  | ||||
| Or alternatively the license texts may be found here: | ||||
|  | ||||
|     http://www.mozilla.org/MPL/2.0/ | ||||
|     http://www.gnu.org/licenses/lgpl.html and | ||||
|     http://www.gnu.org/licenses/gpl.html | ||||
|     http://scripts.sil.org/OFL | ||||
|     http://en.wikipedia.org/wiki/BSD_licenses | ||||
|     http://www.gzip.org/zlib/zlib_license.html | ||||
|     http://www.apache.org/licenses/LICENSE-2.0.html | ||||
|     https://opensource.org/licenses/MIT | ||||
|   | ||||
| @@ -1,132 +1,214 @@ | ||||
| ## noVNC: HTML5 VNC Client | ||||
| ## noVNC: HTML VNC Client Library and Application | ||||
|  | ||||
| [](https://travis-ci.org/kanaka/noVNC) | ||||
| [](https://github.com/novnc/noVNC/actions?query=workflow%3ATest) | ||||
| [](https://github.com/novnc/noVNC/actions?query=workflow%3ALint) | ||||
|  | ||||
| ### Description | ||||
|  | ||||
| noVNC is a HTML5 VNC client that runs well in any modern browser | ||||
| including mobile browsers (iPhone/iPad and Android). | ||||
| noVNC is both a HTML VNC client JavaScript library and an application built on | ||||
| top of that library. noVNC 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 | ||||
| [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. | ||||
|  | ||||
| ### Table of Contents | ||||
|  | ||||
| - [News/help/contact](#newshelpcontact) | ||||
| - [Features](#features) | ||||
| - [Screenshots](#screenshots) | ||||
| - [Browser Requirements](#browser-requirements) | ||||
| - [Server Requirements](#server-requirements) | ||||
| - [Quick Start](#quick-start) | ||||
| - [Installation from Snap Package](#installation-from-snap-package) | ||||
| - [Integration and Deployment](#integration-and-deployment) | ||||
| - [Authors/Contributors](#authorscontributors) | ||||
|  | ||||
| ### News/help/contact | ||||
|  | ||||
| The project website is found at [novnc.com](http://novnc.com). | ||||
| Notable commits, announcements and news are posted to | ||||
| <a href="http://www.twitter.com/noVNC">@noVNC</a> | ||||
| [@noVNC](http://www.twitter.com/noVNC). | ||||
|  | ||||
| If you are a noVNC developer/integrator/user (or want to be) please | ||||
| join the <a | ||||
| href="https://groups.google.com/forum/?fromgroups#!forum/novnc">noVNC | ||||
| discussion group</a> | ||||
| If you are a noVNC developer/integrator/user (or want to be) please join the | ||||
| [noVNC discussion group](https://groups.google.com/forum/?fromgroups#!forum/novnc). | ||||
|  | ||||
| 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 have questions | ||||
| about using noVNC then please first use the | ||||
| [discussion group](https://groups.google.com/forum/?fromgroups#!forum/novnc). | ||||
| We also have a [wiki](https://github.com/novnc/noVNC/wiki/) with lots of | ||||
| helpful information. | ||||
|  | ||||
| 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 <a | ||||
| href="http://www.twitter.com/noVNC">@noVNC</a> if you do. | ||||
| 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). | ||||
| Please check our | ||||
| [contribution guide](https://github.com/novnc/noVNC/wiki/Contributing) though. | ||||
|  | ||||
| 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](http://www.twitter.com/noVNC) if you do. | ||||
|  | ||||
|  | ||||
| ### Features | ||||
|  | ||||
| * Supports all modern browsers including mobile (iOS, Android) | ||||
| * Supported VNC encodings: raw, copyrect, rre, hextile, tight, tightPNG | ||||
| * WebSocket SSL/TLS encryption (i.e. "wss://") support | ||||
| * 24-bit true color and 8 bit colour mapped | ||||
| * Supports desktop resize notification/pseudo-encoding | ||||
| * Local or remote cursor | ||||
| * Supports scaling, clipping and resizing the desktop | ||||
| * Local cursor rendering | ||||
| * Clipboard copy/paste | ||||
| * Clipping or scolling modes for large remote screens | ||||
| * Easy site integration and theming (3 example themes included) | ||||
| * Licensed under the [MPL 2.0](http://www.mozilla.org/MPL/2.0/) | ||||
| * Translations | ||||
| * Touch gestures for emulating common mouse actions | ||||
| * Licensed mainly under the [MPL 2.0](http://www.mozilla.org/MPL/2.0/), see | ||||
|   [the license document](LICENSE.txt) for details | ||||
|  | ||||
| ### Screenshots | ||||
|  | ||||
| Running in Chrome before and after connecting: | ||||
| Running in Firefox before and after connecting: | ||||
|  | ||||
| <img src="http://kanaka.github.com/noVNC/img/noVNC-5.png" width=400> <img src="http://kanaka.github.com/noVNC/img/noVNC-7.jpg" width=400> | ||||
| <img src="http://novnc.com/img/noVNC-1-login.png" width=400>  | ||||
| <img src="http://novnc.com/img/noVNC-3-connected.png" width=400> | ||||
|  | ||||
| See more screenshots <a href="http://kanaka.github.com/noVNC/screenshots.html">here</a>. | ||||
| See more screenshots | ||||
| [here](http://novnc.com/screenshots.html). | ||||
|  | ||||
|  | ||||
| ### Browser Requirements | ||||
|  | ||||
| * HTML5 Canvas (with createImageData): Chrome, Firefox 3.6+, iOS | ||||
|   Safari, Opera 11+, Internet Explorer 9+, etc. | ||||
| noVNC uses many modern web technologies so a formal requirement list is | ||||
| not available. However these are the minimum versions we are currently | ||||
| aware of: | ||||
|  | ||||
| * HTML5 WebSockets and Typed Arrays | ||||
|  | ||||
| * 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). | ||||
| * Chrome 64, Firefox 79, Safari 13.4, Opera 51, Edge 79 | ||||
|  | ||||
|  | ||||
| ### Server Requirements | ||||
|  | ||||
| Unless you are using a VNC server with support for WebSockets | ||||
| connections (such as | ||||
| noVNC follows the standard VNC protocol, but unlike other VNC clients it does | ||||
| require WebSockets support. Many servers include support (e.g. | ||||
| [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 | ||||
| ('websockify'). | ||||
| [QEMU](http://www.qemu.org/), and | ||||
| [MobileVNC](http://www.smartlab.at/mobilevnc/)), but for the others you need to | ||||
| use a WebSockets to TCP socket proxy. noVNC has a sister project | ||||
| [websockify](https://github.com/novnc/websockify) that provides a simple such | ||||
| proxy. | ||||
|  | ||||
|  | ||||
| ### 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 `novnc_proxy` script to automatically download and start websockify, which | ||||
|   includes a mini-webserver and the WebSockets proxy. The `--vnc` option is | ||||
|   used to specify the location of a running VNC server: | ||||
|  | ||||
|     `./utils/launch.sh --vnc localhost:5901` | ||||
|     `./utils/novnc_proxy --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 `novnc_procy` | ||||
|   script. Hit the Connect button, enter a password if the VNC server has one | ||||
|   configured, and enjoy! | ||||
|  | ||||
| ### Installation from Snap Package | ||||
| Running the command below will install the latest release of noVNC from Snap: | ||||
|  | ||||
| ### Other Pages | ||||
| `sudo snap install novnc` | ||||
|  | ||||
| * [Encrypted Connections](https://github.com/kanaka/websockify/wiki/Encrypted-Connections). How to setup websockify so that you can use encrypted connections from noVNC. | ||||
| #### Running noVNC | ||||
|  | ||||
| * [Advanced Usage](https://github.com/kanaka/noVNC/wiki/Advanced-usage). Starting a VNC server, advanced websockify usage, etc. | ||||
| You can run the Snap-package installed novnc directly with, for example: | ||||
|  | ||||
| * [Integrating noVNC](https://github.com/kanaka/noVNC/wiki/Integration) into existing projects. | ||||
| `novnc --listen 6081 --vnc localhost:5901 # /snap/bin/novnc if /snap/bin is not in your PATH` | ||||
|  | ||||
| * [Troubleshooting noVNC](https://github.com/kanaka/noVNC/wiki/Troubleshooting) problems. | ||||
| #### Running as a Service (Daemon) | ||||
| The Snap package also has the capability to run a 'novnc' service which can be  | ||||
| configured to listen on multiple ports connecting to multiple VNC servers  | ||||
| (effectively a service runing multiple instances of novnc). | ||||
| Instructions (with example values): | ||||
|  | ||||
| List current services (out-of-box this will be blank): | ||||
|  | ||||
| ``` | ||||
| sudo snap get novnc services | ||||
| Key             Value | ||||
| services.n6080  {...} | ||||
| services.n6081  {...} | ||||
| ``` | ||||
|  | ||||
| Create a new service that listens on port 6082 and connects to the VNC server  | ||||
| running on port 5902 on localhost: | ||||
|  | ||||
| `sudo snap set novnc services.n6082.listen=6082 services.n6082.vnc=localhost:5902` | ||||
|  | ||||
| (Any services you define with 'snap set' will be automatically started) | ||||
| Note that the name of the service, 'n6082' in this example, can be anything  | ||||
| as long as it doesn't start with a number or contain spaces/special characters. | ||||
|  | ||||
| View the configuration of the service just created: | ||||
|  | ||||
| ``` | ||||
| sudo snap get novnc services.n6082 | ||||
| Key                    Value | ||||
| services.n6082.listen  6082 | ||||
| services.n6082.vnc     localhost:5902 | ||||
| ``` | ||||
|  | ||||
| Disable a service (note that because of a limitation in  Snap it's currently not  | ||||
| possible to unset config variables, setting them to blank values is the way  | ||||
| to disable a service): | ||||
|  | ||||
| `sudo snap set novnc services.n6082.listen='' services.n6082.vnc=''` | ||||
|  | ||||
| (Any services you set to blank with 'snap set' like this will be automatically stopped) | ||||
|  | ||||
| Verify that the service is disabled (blank values): | ||||
|  | ||||
| ``` | ||||
| sudo snap get novnc services.n6082 | ||||
| Key                    Value | ||||
| services.n6082.listen   | ||||
| services.n6082.vnc | ||||
| ``` | ||||
|  | ||||
| ### Integration and Deployment | ||||
|  | ||||
| Please see our other documents for how to integrate noVNC in your own software, | ||||
| or deploying the noVNC application in production environments: | ||||
|  | ||||
| * [Embedding](docs/EMBEDDING.md) - For the noVNC application | ||||
| * [Library](docs/LIBRARY.md) - For the noVNC JavaScript library | ||||
|  | ||||
|  | ||||
| ### Authors/Contributors | ||||
|  | ||||
| See [AUTHORS](AUTHORS) for a (full-ish) list of authors.  If you're not on | ||||
| that list and you think you should be, feel free to send a PR to fix that. | ||||
|  | ||||
| * Core team: | ||||
|     * [Joel Martin](https://github.com/kanaka) | ||||
|     * [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: | ||||
|     * as3crypto : Henri Torgemane (code.google.com/p/as3crypto) | ||||
|     * base64 : Martijn Pieters (Digital Creations 2), Samuel Sieb (sieb.net) | ||||
|     * DES : Dave Zimmerman (Widget Workshop), Jef Poskanzer (ACME Labs) | ||||
|     * Pako : Vitaly Puzrin (https://github.com/nodeca/pako) | ||||
|  | ||||
| Do you want to be on this list? Check out our | ||||
| [contribution guide](https://github.com/novnc/noVNC/wiki/Contributing) and | ||||
| start hacking! | ||||
|   | ||||
							
								
								
									
										66
									
								
								public/novnc/app/error-handler.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,66 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| // NB: this should *not* be included as a module until we have | ||||
| // native support in the browsers, so that our error handler | ||||
| // can catch script-loading errors. | ||||
|  | ||||
| // No ES6 can be used in this file since it's used for the translation | ||||
| /* eslint-disable prefer-arrow-callback */ | ||||
|  | ||||
| (function _scope() { | ||||
|     "use strict"; | ||||
|  | ||||
|     // Fallback for all uncought errors | ||||
|     function handleError(event, err) { | ||||
|         try { | ||||
|             const msg = document.getElementById('noVNC_fallback_errormsg'); | ||||
|  | ||||
|             // Only show the initial error | ||||
|             if (msg.hasChildNodes()) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             let div = document.createElement("div"); | ||||
|             div.classList.add('noVNC_message'); | ||||
|             div.appendChild(document.createTextNode(event.message)); | ||||
|             msg.appendChild(div); | ||||
|  | ||||
|             if (event.filename) { | ||||
|                 div = document.createElement("div"); | ||||
|                 div.className = 'noVNC_location'; | ||||
|                 let text = event.filename; | ||||
|                 if (event.lineno !== undefined) { | ||||
|                     text += ":" + event.lineno; | ||||
|                     if (event.colno !== undefined) { | ||||
|                         text += ":" + event.colno; | ||||
|                     } | ||||
|                 } | ||||
|                 div.appendChild(document.createTextNode(text)); | ||||
|                 msg.appendChild(div); | ||||
|             } | ||||
|  | ||||
|             if (err && err.stack) { | ||||
|                 div = document.createElement("div"); | ||||
|                 div.className = 'noVNC_stack'; | ||||
|                 div.appendChild(document.createTextNode(err.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; | ||||
|     } | ||||
|     window.addEventListener('error', function onerror(evt) { handleError(evt, evt.error); }); | ||||
|     window.addEventListener('unhandledrejection', function onreject(evt) { handleError(evt.reason, evt.reason); }); | ||||
| })(); | ||||
							
								
								
									
										92
									
								
								public/novnc/app/images/alt.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,92 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="alt.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="16" | ||||
|      inkscape:cx="18.205425" | ||||
|      inkscape:cy="17.531398" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <g | ||||
|        style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|        id="text5290"> | ||||
|       <path | ||||
|          d="m 9.9560547,1042.3329 -2.9394531,0 -0.4638672,1.3281 -1.8896485,0 2.7001953,-7.29 2.241211,0 2.7001958,7.29 -1.889649,0 -0.4589843,-1.3281 z m -2.4707031,-1.3526 1.9970703,0 -0.9960938,-2.9003 -1.0009765,2.9003 z" | ||||
|          style="font-size:10px;fill:#ffffff;fill-opacity:1" | ||||
|          id="path5340" /> | ||||
|       <path | ||||
|          d="m 13.188477,1036.0634 1.748046,0 0,7.5976 -1.748046,0 0,-7.5976 z" | ||||
|          style="font-size:10px;fill:#ffffff;fill-opacity:1" | ||||
|          id="path5342" /> | ||||
|       <path | ||||
|          d="m 18.535156,1036.6395 0,1.5528 1.801758,0 0,1.25 -1.801758,0 0,2.3193 q 0,0.3809 0.151367,0.5176 0.151368,0.1318 0.600586,0.1318 l 0.898438,0 0,1.25 -1.499024,0 q -1.035156,0 -1.469726,-0.4297 -0.429688,-0.4345 -0.429688,-1.4697 l 0,-2.3193 -0.86914,0 0,-1.25 0.86914,0 0,-1.5528 1.748047,0 z" | ||||
|          style="font-size:10px;fill:#ffffff;fill-opacity:1" | ||||
|          id="path5344" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.5 KiB | 
							
								
								
									
										106
									
								
								public/novnc/app/images/clipboard.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,106 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="clipboard.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="15.366606" | ||||
|      inkscape:cy="16.42981" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <path | ||||
|        style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        d="M 9,6 6,6 C 5.4459889,6 5,6.4459889 5,7 l 0,13 c 0,0.554011 0.4459889,1 1,1 l 13,0 c 0.554011,0 1,-0.445989 1,-1 L 20,7 C 20,6.4459889 19.554011,6 19,6 l -3,0" | ||||
|        transform="translate(0,1027.3622)" | ||||
|        id="rect6083" | ||||
|        inkscape:connector-curvature="0" | ||||
|        sodipodi:nodetypes="cssssssssc" /> | ||||
|     <rect | ||||
|        style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect6085" | ||||
|        width="7" | ||||
|        height="4" | ||||
|        x="9" | ||||
|        y="1031.3622" | ||||
|        ry="1.00002" /> | ||||
|     <path | ||||
|        style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081" | ||||
|        d="m 8.5071212,1038.8622 7.9999998,0" | ||||
|        id="path6087" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|     <path | ||||
|        style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081" | ||||
|        d="m 8.5071212,1041.8622 3.9999998,0" | ||||
|        id="path6089" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|     <path | ||||
|        style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.50196081" | ||||
|        d="m 8.5071212,1044.8622 5.9999998,0" | ||||
|        id="path6091" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.9 KiB | 
							
								
								
									
										96
									
								
								public/novnc/app/images/connect.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,96 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="connect.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="37.14834" | ||||
|      inkscape:cy="1.9525926" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <g | ||||
|        id="g5103" | ||||
|        transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,-729.15757,315.8823)"> | ||||
|       <path | ||||
|          sodipodi:nodetypes="cssssc" | ||||
|          inkscape:connector-curvature="0" | ||||
|          id="rect5096" | ||||
|          d="m 11,1040.3622 -5,0 c -1.108,0 -2,-0.892 -2,-2 l 0,-4 c 0,-1.108 0.892,-2 2,-2 l 5,0" | ||||
|          style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | ||||
|       <path | ||||
|          style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|          d="m 14,1032.3622 5,0 c 1.108,0 2,0.892 2,2 l 0,4 c 0,1.108 -0.892,2 -2,2 l -5,0" | ||||
|          id="path5099" | ||||
|          inkscape:connector-curvature="0" | ||||
|          sodipodi:nodetypes="cssssc" /> | ||||
|       <path | ||||
|          inkscape:connector-curvature="0" | ||||
|          id="path5101" | ||||
|          d="m 9,1036.3622 7,0" | ||||
|          style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.3 KiB | 
							
								
								
									
										96
									
								
								public/novnc/app/images/ctrl.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,96 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="ctrl.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="16" | ||||
|      inkscape:cx="18.205425" | ||||
|      inkscape:cy="17.531398" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <g | ||||
|        style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|        id="text5290"> | ||||
|       <path | ||||
|          d="m 9.1210938,1043.1898 q -0.5175782,0.2686 -1.0791016,0.4053 -0.5615235,0.1367 -1.171875,0.1367 -1.8212891,0 -2.8857422,-1.0156 -1.0644531,-1.0205 -1.0644531,-2.7637 0,-1.748 1.0644531,-2.7637 1.0644531,-1.0205 2.8857422,-1.0205 0.6103515,0 1.171875,0.1368 0.5615234,0.1367 1.0791016,0.4052 l 0,1.5088 q -0.522461,-0.3564 -1.0302735,-0.5224 -0.5078125,-0.1661 -1.0693359,-0.1661 -1.0058594,0 -1.5820313,0.6446 -0.5761719,0.6445 -0.5761719,1.7773 0,1.1279 0.5761719,1.7725 0.5761719,0.6445 1.5820313,0.6445 0.5615234,0 1.0693359,-0.166 0.5078125,-0.166 1.0302735,-0.5225 l 0,1.5088 z" | ||||
|          style="font-size:10px;fill:#ffffff;fill-opacity:1" | ||||
|          id="path5370" /> | ||||
|       <path | ||||
|          d="m 12.514648,1036.5687 0,1.5528 1.801758,0 0,1.25 -1.801758,0 0,2.3193 q 0,0.3809 0.151368,0.5176 0.151367,0.1318 0.600586,0.1318 l 0.898437,0 0,1.25 -1.499023,0 q -1.035157,0 -1.469727,-0.4297 -0.429687,-0.4345 -0.429687,-1.4697 l 0,-2.3193 -0.8691411,0 0,-1.25 0.8691411,0 0,-1.5528 1.748046,0 z" | ||||
|          style="font-size:10px;fill:#ffffff;fill-opacity:1" | ||||
|          id="path5372" /> | ||||
|       <path | ||||
|          d="m 19.453125,1039.6107 q -0.229492,-0.1074 -0.458984,-0.1562 -0.22461,-0.054 -0.454102,-0.054 -0.673828,0 -1.040039,0.4345 -0.361328,0.4297 -0.361328,1.2354 l 0,2.5195 -1.748047,0 0,-5.4687 1.748047,0 0,0.8984 q 0.336914,-0.5371 0.771484,-0.7813 0.439453,-0.249 1.049805,-0.249 0.08789,0 0.19043,0.01 0.102539,0 0.297851,0.029 l 0.0049,1.582 z" | ||||
|          style="font-size:10px;fill:#ffffff;fill-opacity:1" | ||||
|          id="path5374" /> | ||||
|       <path | ||||
|          d="m 20.332031,1035.9926 1.748047,0 0,7.5976 -1.748047,0 0,-7.5976 z" | ||||
|          style="font-size:10px;fill:#ffffff;fill-opacity:1" | ||||
|          id="path5376" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.3 KiB | 
							
								
								
									
										100
									
								
								public/novnc/app/images/ctrlaltdel.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,100 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="ctrlaltdel.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="8" | ||||
|      inkscape:cx="11.135667" | ||||
|      inkscape:cy="16.407428" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <rect | ||||
|        style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect5253" | ||||
|        width="5" | ||||
|        height="5.0000172" | ||||
|        x="16" | ||||
|        y="1031.3622" | ||||
|        ry="1.0000174" /> | ||||
|     <rect | ||||
|        y="1043.3622" | ||||
|        x="4" | ||||
|        height="5.0000172" | ||||
|        width="5" | ||||
|        id="rect5255" | ||||
|        style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        ry="1.0000174" /> | ||||
|     <rect | ||||
|        style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect5257" | ||||
|        width="5" | ||||
|        height="5.0000172" | ||||
|        x="13" | ||||
|        y="1043.3622" | ||||
|        ry="1.0000174" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.2 KiB | 
							
								
								
									
										94
									
								
								public/novnc/app/images/disconnect.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,94 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="disconnect.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="16" | ||||
|      inkscape:cx="25.05707" | ||||
|      inkscape:cy="11.594858" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="false"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <g | ||||
|        id="g5171" | ||||
|        transform="translate(-24.062499,-6.15775e-4)"> | ||||
|       <path | ||||
|          id="path5110" | ||||
|          transform="translate(0,1027.3622)" | ||||
|          d="m 39.744141,3.4960938 c -0.769923,0 -1.539607,0.2915468 -2.121094,0.8730468 l -2.566406,2.5664063 1.414062,1.4140625 2.566406,-2.5664063 c 0.403974,-0.404 1.010089,-0.404 1.414063,0 l 2.828125,2.828125 c 0.40398,0.4039 0.403907,1.0101621 0,1.4140629 l -2.566406,2.566406 1.414062,1.414062 2.566406,-2.566406 c 1.163041,-1.1629 1.162968,-3.0791874 0,-4.2421874 L 41.865234,4.3691406 C 41.283747,3.7876406 40.514063,3.4960937 39.744141,3.4960938 Z M 39.017578,9.015625 a 1.0001,1.0001 0 0 0 -0.6875,0.3027344 l -0.445312,0.4453125 1.414062,1.4140621 0.445313,-0.445312 A 1.0001,1.0001 0 0 0 39.017578,9.015625 Z m -6.363281,0.7070312 a 1.0001,1.0001 0 0 0 -0.6875,0.3027348 L 28.431641,13.5625 c -1.163042,1.163 -1.16297,3.079187 0,4.242188 l 2.828125,2.828124 c 1.162974,1.163101 3.079213,1.163101 4.242187,0 l 3.535156,-3.535156 a 1.0001,1.0001 0 1 0 -1.414062,-1.414062 l -3.535156,3.535156 c -0.403974,0.404 -1.010089,0.404 -1.414063,0 l -2.828125,-2.828125 c -0.403981,-0.404 -0.403908,-1.010162 0,-1.414063 l 3.535156,-3.537109 A 1.0001,1.0001 0 0 0 32.654297,9.7226562 Z m 3.109375,2.1621098 -2.382813,2.384765 a 1.0001,1.0001 0 1 0 1.414063,1.414063 l 2.382812,-2.384766 -1.414062,-1.414062 z" | ||||
|          style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" | ||||
|          inkscape:connector-curvature="0" /> | ||||
|       <rect | ||||
|          transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,0,0)" | ||||
|          y="752.29541" | ||||
|          x="-712.31262" | ||||
|          height="18.000017" | ||||
|          width="3" | ||||
|          id="rect5116" | ||||
|          style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.9 KiB | 
							
								
								
									
										76
									
								
								public/novnc/app/images/drag.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,76 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="drag.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="22.627417" | ||||
|      inkscape:cx="9.8789407" | ||||
|      inkscape:cy="9.5008608" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="true" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="false" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <path | ||||
|        style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        d="m 7.039733,1049.3037 c -0.4309106,-0.1233 -0.7932634,-0.4631 -0.9705434,-0.9103 -0.04922,-0.1241 -0.057118,-0.2988 -0.071321,-1.5771 l -0.015972,-1.4375 -0.328125,-0.082 c -0.7668138,-0.1927 -1.1897046,-0.4275 -1.7031253,-0.9457 -0.4586773,-0.4629 -0.6804297,-0.8433 -0.867034,-1.4875 -0.067215,-0.232 -0.068001,-0.2642 -0.078682,-3.2188 -0.012078,-3.341 -0.020337,-3.2012 0.2099452,-3.5555 0.2246623,-0.3458 0.5798271,-0.5892 0.9667343,-0.6626 0.092506,-0.017 0.531898,-0.032 0.9764271,-0.032 l 0.8082347,0 1.157e-4,1.336 c 1.125e-4,1.2779 0.00281,1.3403 0.062214,1.4378 0.091785,0.1505 0.2357707,0.226 0.4314082,0.2261 0.285389,2e-4 0.454884,-0.1352 0.5058962,-0.4042 0.019355,-0.102 0.031616,-0.982 0.031616,-2.269 0,-1.9756 0.00357,-2.1138 0.059205,-2.2926 0.1645475,-0.5287 0.6307616,-0.9246 1.19078,-1.0113 0.8000572,-0.1238 1.5711277,0.4446 1.6860387,1.2429 0.01732,0.1203 0.03177,0.8248 0.03211,1.5657 6.19e-4,1.3449 7.22e-4,1.347 0.07093,1.4499 0.108355,0.1587 0.255268,0.2248 0.46917,0.2108 0.204069,-0.013 0.316116,-0.08 0.413642,-0.2453 0.06028,-0.1024 0.06307,-0.1778 0.07862,-2.1218 0.01462,-1.8283 0.02124,-2.0285 0.07121,-2.1549 0.260673,-0.659 0.934894,-1.0527 1.621129,-0.9465 0.640523,0.099 1.152269,0.6104 1.243187,1.2421 0.01827,0.1269 0.03175,0.9943 0.03211,2.0657 l 6.19e-4,1.8469 0.07031,0.103 c 0.108355,0.1587 0.255267,0.2248 0.46917,0.2108 0.204069,-0.013 0.316115,-0.08 0.413642,-0.2453 0.05951,-0.1011 0.06329,-0.1786 0.07907,-1.6218 0.01469,-1.3438 0.02277,-1.5314 0.07121,-1.6549 0.257975,-0.6576 0.934425,-1.0527 1.620676,-0.9465 0.640522,0.099 1.152269,0.6104 1.243186,1.2421 0.0186,0.1292 0.03179,1.0759 0.03222,2.3125 7.15e-4,2.0335 0.0025,2.0966 0.06283,2.1956 0.09178,0.1505 0.235771,0.226 0.431409,0.2261 0.285388,2e-4 0.454884,-0.1352 0.505897,-0.4042 0.01874,-0.099 0.03161,-0.8192 0.03161,-1.769 0,-1.4848 0.0043,-1.6163 0.0592,-1.7926 0.164548,-0.5287 0.630762,-0.9246 1.19078,-1.0113 0.800057,-0.1238 1.571128,0.4446 1.686039,1.2429 0.04318,0.2999 0.04372,9.1764 5.78e-4,9.4531 -0.04431,0.2841 -0.217814,0.6241 -0.420069,0.8232 -0.320102,0.315 -0.63307,0.4268 -1.194973,0.4268 l -0.35281,0 -2.51e-4,1.2734 c -1.25e-4,0.7046 -0.01439,1.3642 -0.03191,1.4766 -0.06665,0.4274 -0.372966,0.8704 -0.740031,1.0702 -0.349999,0.1905 0.01748,0.18 -6.242199,0.1776 -5.3622439,0 -5.7320152,-0.01 -5.9121592,-0.057 l 1.4e-5,0 z" | ||||
|        id="path4379" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.6 KiB | 
							
								
								
									
										81
									
								
								public/novnc/app/images/error.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,81 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="error.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="14.00357" | ||||
|      inkscape:cy="12.443398" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title /> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <path | ||||
|        style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        d="M 7 3 C 4.7839905 3 3 4.7839905 3 7 L 3 18 C 3 20.21601 4.7839905 22 7 22 L 18 22 C 20.21601 22 22 20.21601 22 18 L 22 7 C 22 4.7839905 20.21601 3 18 3 L 7 3 z M 7.6992188 6 A 1.6916875 1.6924297 0 0 1 8.9121094 6.5117188 L 12.5 10.101562 L 16.087891 6.5117188 A 1.6916875 1.6924297 0 0 1 17.251953 6 A 1.6916875 1.6924297 0 0 1 18.480469 8.90625 L 14.892578 12.496094 L 18.480469 16.085938 A 1.6916875 1.6924297 0 1 1 16.087891 18.478516 L 12.5 14.888672 L 8.9121094 18.478516 A 1.6916875 1.6924297 0 1 1 6.5214844 16.085938 L 10.109375 12.496094 L 6.5214844 8.90625 A 1.6916875 1.6924297 0 0 1 7.6992188 6 z " | ||||
|        transform="translate(0,1027.3622)" | ||||
|        id="rect4135" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.0 KiB | 
							
								
								
									
										92
									
								
								public/novnc/app/images/esc.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,92 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="esc.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="16" | ||||
|      inkscape:cx="18.205425" | ||||
|      inkscape:cy="17.531398" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="text5290" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <g | ||||
|        style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|        id="text5290"> | ||||
|       <path | ||||
|          d="m 3.9331055,1036.1464 5.0732422,0 0,1.4209 -3.1933594,0 0,1.3574 3.0029297,0 0,1.4209 -3.0029297,0 0,1.6699 3.3007812,0 0,1.4209 -5.180664,0 0,-7.29 z" | ||||
|          style="font-size:10px;fill:#ffffff;fill-opacity:1" | ||||
|          id="path5314" /> | ||||
|       <path | ||||
|          d="m 14.963379,1038.1385 0,1.3282 q -0.561524,-0.2344 -1.083984,-0.3516 -0.522461,-0.1172 -0.986329,-0.1172 -0.498046,0 -0.742187,0.127 -0.239258,0.122 -0.239258,0.3808 0,0.21 0.180664,0.3223 0.185547,0.1123 0.65918,0.166 l 0.307617,0.044 q 1.342773,0.1709 1.806641,0.5615 0.463867,0.3906 0.463867,1.2256 0,0.874 -0.644531,1.3134 -0.644532,0.4395 -1.923829,0.4395 -0.541992,0 -1.123046,-0.088 -0.576172,-0.083 -1.186524,-0.2539 l 0,-1.3281 q 0.522461,0.2539 1.069336,0.3808 0.551758,0.127 1.118164,0.127 0.512695,0 0.771485,-0.1416 0.258789,-0.1416 0.258789,-0.4199 0,-0.2344 -0.180664,-0.3467 -0.175782,-0.1172 -0.708008,-0.1807 l -0.307617,-0.039 q -1.166993,-0.1465 -1.635743,-0.542 -0.46875,-0.3955 -0.46875,-1.2012 0,-0.8691 0.595703,-1.2891 0.595704,-0.4199 1.826172,-0.4199 0.483399,0 1.015625,0.073 0.532227,0.073 1.157227,0.2294 z" | ||||
|          style="font-size:10px;fill:#ffffff;fill-opacity:1" | ||||
|          id="path5316" /> | ||||
|       <path | ||||
|          d="m 21.066895,1038.1385 0,1.4258 q -0.356446,-0.2441 -0.717774,-0.3613 -0.356445,-0.1172 -0.742187,-0.1172 -0.732422,0 -1.142579,0.4297 -0.405273,0.4248 -0.405273,1.1914 0,0.7666 0.405273,1.1963 0.410157,0.4248 1.142579,0.4248 0.410156,0 0.776367,-0.1221 0.371094,-0.122 0.683594,-0.3613 l 0,1.4307 q -0.410157,0.1513 -0.834961,0.2246 -0.419922,0.078 -0.844727,0.078 -1.479492,0 -2.314453,-0.7568 -0.834961,-0.7618 -0.834961,-2.1143 0,-1.3525 0.834961,-2.1094 0.834961,-0.7617 2.314453,-0.7617 0.429688,0 0.844727,0.078 0.419921,0.073 0.834961,0.2246 z" | ||||
|          style="font-size:10px;fill:#ffffff;fill-opacity:1" | ||||
|          id="path5318" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.4 KiB | 
							
								
								
									
										69
									
								
								public/novnc/app/images/expander.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,69 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="9" | ||||
|    height="10" | ||||
|    viewBox="0 0 9 10" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="expander.svg"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0.0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="45.254834" | ||||
|      inkscape:cx="9.8737281" | ||||
|      inkscape:cy="6.4583132" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="true" | ||||
|      units="px" | ||||
|      inkscape:snap-object-midpoints="false" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="0" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1042.3622)"> | ||||
|     <path | ||||
|        style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" | ||||
|        d="M 2.0800781,1042.3633 A 2.0002,2.0002 0 0 0 0,1044.3613 l 0,6 a 2.0002,2.0002 0 0 0 3.0292969,1.7168 l 5,-3 a 2.0002,2.0002 0 0 0 0,-3.4316 l -5,-3 a 2.0002,2.0002 0 0 0 -0.9492188,-0.2832 z" | ||||
|        id="path4138" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.0 KiB | 
							
								
								
									
										93
									
								
								public/novnc/app/images/fullscreen.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,93 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="fullscreen.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="16.400723" | ||||
|      inkscape:cy="15.083758" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="false" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="false"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <rect | ||||
|        style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect5006" | ||||
|        width="17" | ||||
|        height="17.000017" | ||||
|        x="4" | ||||
|        y="1031.3622" | ||||
|        ry="3.0000174" /> | ||||
|     <path | ||||
|        style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" | ||||
|        d="m 7.5,1044.8622 4,0 -1.5,-1.5 1.5,-1.5 -1,-1 -1.5,1.5 -1.5,-1.5 0,4 z" | ||||
|        id="path5017" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|     <path | ||||
|        inkscape:connector-curvature="0" | ||||
|        id="path5025" | ||||
|        d="m 17.5,1034.8622 -4,0 1.5,1.5 -1.5,1.5 1,1 1.5,-1.5 1.5,1.5 0,-4 z" | ||||
|        style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.1 KiB | 
							
								
								
									
										82
									
								
								public/novnc/app/images/handle.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,82 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="5" | ||||
|    height="6" | ||||
|    viewBox="0 0 5 6" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="handle.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="32" | ||||
|      inkscape:cx="1.3551778" | ||||
|      inkscape:cy="8.7800329" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="true" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="false" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1046.3622)"> | ||||
|     <path | ||||
|        style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" | ||||
|        d="m 4.0000803,1049.3622 -3,-2 0,4 z" | ||||
|        id="path4247" | ||||
|        inkscape:connector-curvature="0" | ||||
|        sodipodi:nodetypes="cccc" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.5 KiB | 
							
								
								
									
										172
									
								
								public/novnc/app/images/handle_bg.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,172 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="15" | ||||
|    height="50" | ||||
|    viewBox="0 0 15 50" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="handle_bg.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="16" | ||||
|      inkscape:cx="-10.001409" | ||||
|      inkscape:cy="24.512566" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="true" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="false" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1002.3622)"> | ||||
|     <rect | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect4249" | ||||
|        width="1" | ||||
|        height="1.0000174" | ||||
|        x="9.5" | ||||
|        y="1008.8622" | ||||
|        ry="1.7382812e-05" /> | ||||
|     <rect | ||||
|        ry="1.7382812e-05" | ||||
|        y="1013.8622" | ||||
|        x="9.5" | ||||
|        height="1.0000174" | ||||
|        width="1" | ||||
|        id="rect4255" | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | ||||
|     <rect | ||||
|        ry="1.7382812e-05" | ||||
|        y="1008.8622" | ||||
|        x="4.5" | ||||
|        height="1.0000174" | ||||
|        width="1" | ||||
|        id="rect4261" | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | ||||
|     <rect | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect4263" | ||||
|        width="1" | ||||
|        height="1.0000174" | ||||
|        x="4.5" | ||||
|        y="1013.8622" | ||||
|        ry="1.7382812e-05" /> | ||||
|     <rect | ||||
|        ry="1.7382812e-05" | ||||
|        y="1039.8622" | ||||
|        x="9.5" | ||||
|        height="1.0000174" | ||||
|        width="1" | ||||
|        id="rect4265" | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | ||||
|     <rect | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect4267" | ||||
|        width="1" | ||||
|        height="1.0000174" | ||||
|        x="9.5" | ||||
|        y="1044.8622" | ||||
|        ry="1.7382812e-05" /> | ||||
|     <rect | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect4269" | ||||
|        width="1" | ||||
|        height="1.0000174" | ||||
|        x="4.5" | ||||
|        y="1039.8622" | ||||
|        ry="1.7382812e-05" /> | ||||
|     <rect | ||||
|        ry="1.7382812e-05" | ||||
|        y="1044.8622" | ||||
|        x="4.5" | ||||
|        height="1.0000174" | ||||
|        width="1" | ||||
|        id="rect4271" | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | ||||
|     <rect | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect4273" | ||||
|        width="1" | ||||
|        height="1.0000174" | ||||
|        x="9.5" | ||||
|        y="1018.8622" | ||||
|        ry="1.7382812e-05" /> | ||||
|     <rect | ||||
|        ry="1.7382812e-05" | ||||
|        y="1018.8622" | ||||
|        x="4.5" | ||||
|        height="1.0000174" | ||||
|        width="1" | ||||
|        id="rect4275" | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | ||||
|     <rect | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect4277" | ||||
|        width="1" | ||||
|        height="1.0000174" | ||||
|        x="9.5" | ||||
|        y="1034.8622" | ||||
|        ry="1.7382812e-05" /> | ||||
|     <rect | ||||
|        ry="1.7382812e-05" | ||||
|        y="1034.8622" | ||||
|        x="4.5" | ||||
|        height="1.0000174" | ||||
|        width="1" | ||||
|        id="rect4279" | ||||
|        style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 6.2 KiB | 
							
								
								
									
										42
									
								
								public/novnc/app/images/icons/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -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 | ||||
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-120x120.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.9 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-144x144.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 4.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-152x152.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 5.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-16x16.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 675 B | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-192x192.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 5.7 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-24x24.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1000 B | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-32x32.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.0 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-48x48.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.4 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-60x60.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.9 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-64x64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.9 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-72x72.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 2.6 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-76x76.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 2.8 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/images/icons/novnc-96x96.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 2.3 KiB | 
							
								
								
									
										163
									
								
								public/novnc/app/images/icons/novnc-icon-sm.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,163 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="16" | ||||
|    height="16" | ||||
|    viewBox="0 0 16 16" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="novnc-icon-sm.svg"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0.0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="45.254834" | ||||
|      inkscape:cx="9.722703" | ||||
|      inkscape:cy="5.5311896" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:snap-midpoints="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4169" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1036.3621)"> | ||||
|     <rect | ||||
|        style="opacity:1;fill:#494949;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect4167" | ||||
|        width="16" | ||||
|        height="15.999992" | ||||
|        x="0" | ||||
|        y="1036.3622" | ||||
|        ry="2.6666584" /> | ||||
|     <path | ||||
|        style="opacity:1;fill:#313131;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        d="M 2.6666667,1036.3621 C 1.1893373,1036.3621 0,1037.5515 0,1039.0288 l 0,10.6666 c 0,1.4774 1.1893373,2.6667 2.6666667,2.6667 l 4,0 C 11.837333,1052.3621 16,1046.7128 16,1039.6955 l 0,-0.6667 c 0,-1.4773 -1.189337,-2.6667 -2.666667,-2.6667 l -10.6666663,0 z" | ||||
|        id="rect4173" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|     <g | ||||
|        id="g4381"> | ||||
|       <g | ||||
|          transform="translate(0.25,0.25)" | ||||
|          style="fill:#000000;fill-opacity:1" | ||||
|          id="g4365"> | ||||
|         <g | ||||
|            style="fill:#000000;fill-opacity:1" | ||||
|            id="g4367"> | ||||
|           <path | ||||
|              inkscape:connector-curvature="0" | ||||
|              id="path4369" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|              d="m 4.3289754,1039.3621 c 0.1846149,0 0.3419956,0.071 0.4716623,0.2121 C 4.933546,1039.7121 5,1039.8793 5,1040.0759 l 0,3.2862 -1,0 0,-2.964 c 0,-0.024 -0.011592,-0.036 -0.034038,-0.036 l -1.931924,0 C 2.011349,1040.3621 2,1040.3741 2,1040.3981 l 0,2.964 -1,0 0,-4 z" | ||||
|              sodipodi:nodetypes="scsccsssscccs" /> | ||||
|           <path | ||||
|              inkscape:connector-curvature="0" | ||||
|              id="path4371" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|              d="m 6.6710244,1039.3621 2.6579513,0 c 0.184775,0 0.3419957,0.071 0.471662,0.2121 C 9.933546,1039.7121 10,1039.8793 10,1040.0759 l 0,2.5724 c 0,0.1966 -0.066454,0.3655 -0.1993623,0.5069 -0.1296663,0.1379 -0.286887,0.2069 -0.471662,0.2069 l -2.6579513,0 c -0.184775,0 -0.3436164,-0.069 -0.4765247,-0.2069 C 6.0648334,1043.0138 6,1042.8449 6,1042.6483 l 0,-2.5724 c 0,-0.1966 0.064833,-0.3638 0.1944997,-0.5017 0.1329083,-0.1414 0.2917497,-0.2121 0.4765247,-0.2121 z m 2.2949386,1 -1.931926,0 C 7.011344,1040.3621 7,1040.3741 7,1040.3981 l 0,1.928 c 0,0.024 0.011347,0.036 0.034037,0.036 l 1.931926,0 c 0.02269,0 0.034037,-0.012 0.034037,-0.036 l 0,-1.928 c 0,-0.024 -0.011347,-0.036 -0.034037,-0.036 z" | ||||
|              sodipodi:nodetypes="sscsscsscsscssssssssss" /> | ||||
|         </g> | ||||
|         <g | ||||
|            style="fill:#000000;fill-opacity:1" | ||||
|            id="g4373"> | ||||
|           <path | ||||
|              inkscape:connector-curvature="0" | ||||
|              id="path4375" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|              d="m 3,1047.1121 1,-2.75 1,0 -1.5,4 -1,0 -1.5,-4 1,0 z" | ||||
|              sodipodi:nodetypes="cccccccc" /> | ||||
|           <path | ||||
|              inkscape:connector-curvature="0" | ||||
|              id="path4377" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|              d="m 9,1046.8621 0,-2.5 1,0 0,4 -1,0 -2,-2.5 0,2.5 -1,0 0,-4 1,0 z" | ||||
|              sodipodi:nodetypes="ccccccccccc" /> | ||||
|           <path | ||||
|              inkscape:connector-curvature="0" | ||||
|              id="path4379" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|              d="m 15,1045.3621 -2.96596,0 c -0.02269,0 -0.03404,0.012 -0.03404,0.036 l 0,1.928 c 0,0.024 0.01135,0.036 0.03404,0.036 l 2.96596,0 0,1 -3.324113,0 c -0.188017,0 -0.348479,-0.068 -0.481388,-0.2037 C 11.064833,1048.0192 11,1047.8511 11,1047.6542 l 0,-2.5842 c 0,-0.1969 0.06483,-0.3633 0.194499,-0.4991 0.132909,-0.1392 0.293371,-0.2088 0.481388,-0.2088 l 3.324113,0 z" | ||||
|              sodipodi:nodetypes="cssssccscsscscc" /> | ||||
|         </g> | ||||
|       </g> | ||||
|       <g | ||||
|          id="g4356"> | ||||
|         <g | ||||
|            id="g4347"> | ||||
|           <path | ||||
|              sodipodi:nodetypes="scsccsssscccs" | ||||
|              d="m 4.3289754,1039.3621 c 0.1846149,0 0.3419956,0.071 0.4716623,0.2121 C 4.933546,1039.7121 5,1039.8793 5,1040.0759 l 0,3.2862 -1,0 0,-2.964 c 0,-0.024 -0.011592,-0.036 -0.034038,-0.036 l -1.931924,0 c -0.022689,0 -0.034038,0.012 -0.034038,0.036 l 0,2.964 -1,0 0,-4 z" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|              id="path4143" | ||||
|              inkscape:connector-curvature="0" /> | ||||
|           <path | ||||
|              sodipodi:nodetypes="sscsscsscsscssssssssss" | ||||
|              d="m 6.6710244,1039.3621 2.6579513,0 c 0.184775,0 0.3419957,0.071 0.471662,0.2121 C 9.933546,1039.7121 10,1039.8793 10,1040.0759 l 0,2.5724 c 0,0.1966 -0.066454,0.3655 -0.1993623,0.5069 -0.1296663,0.1379 -0.286887,0.2069 -0.471662,0.2069 l -2.6579513,0 c -0.184775,0 -0.3436164,-0.069 -0.4765247,-0.2069 C 6.0648334,1043.0138 6,1042.8449 6,1042.6483 l 0,-2.5724 c 0,-0.1966 0.064833,-0.3638 0.1944997,-0.5017 0.1329083,-0.1414 0.2917497,-0.2121 0.4765247,-0.2121 z m 2.2949386,1 -1.931926,0 C 7.011344,1040.3621 7,1040.3741 7,1040.3981 l 0,1.928 c 0,0.024 0.011347,0.036 0.034037,0.036 l 1.931926,0 c 0.02269,0 0.034037,-0.012 0.034037,-0.036 l 0,-1.928 c 0,-0.024 -0.011347,-0.036 -0.034037,-0.036 z" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|              id="path4145" | ||||
|              inkscape:connector-curvature="0" /> | ||||
|         </g> | ||||
|         <g | ||||
|            id="g4351"> | ||||
|           <path | ||||
|              sodipodi:nodetypes="cccccccc" | ||||
|              d="m 3,1047.1121 1,-2.75 1,0 -1.5,4 -1,0 -1.5,-4 1,0 z" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|              id="path4147" | ||||
|              inkscape:connector-curvature="0" /> | ||||
|           <path | ||||
|              sodipodi:nodetypes="ccccccccccc" | ||||
|              d="m 9,1046.8621 0,-2.5 1,0 0,4 -1,0 -2,-2.5 0,2.5 -1,0 0,-4 1,0 z" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|              id="path4149" | ||||
|              inkscape:connector-curvature="0" /> | ||||
|           <path | ||||
|              sodipodi:nodetypes="cssssccscsscscc" | ||||
|              d="m 15,1045.3621 -2.96596,0 c -0.02269,0 -0.03404,0.012 -0.03404,0.036 l 0,1.928 c 0,0.024 0.01135,0.036 0.03404,0.036 l 2.96596,0 0,1 -3.324113,0 c -0.188017,0 -0.348479,-0.068 -0.481388,-0.2037 C 11.064833,1048.0192 11,1047.8511 11,1047.6542 l 0,-2.5842 c 0,-0.1969 0.06483,-0.3633 0.194499,-0.4991 0.132909,-0.1392 0.293371,-0.2088 0.481388,-0.2088 l 3.324113,0 z" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|              id="path4151" | ||||
|              inkscape:connector-curvature="0" /> | ||||
|         </g> | ||||
|       </g> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 11 KiB | 
							
								
								
									
										163
									
								
								public/novnc/app/images/icons/novnc-icon.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,163 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="48" | ||||
|    height="48" | ||||
|    viewBox="0 0 48 48.000001" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="novnc-icon.svg"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0.0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="11.313708" | ||||
|      inkscape:cx="27.187245" | ||||
|      inkscape:cy="17.700974" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:snap-midpoints="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4169" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title /> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1004.3621)"> | ||||
|     <rect | ||||
|        style="opacity:1;fill:#494949;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        id="rect4167" | ||||
|        width="48" | ||||
|        height="48" | ||||
|        x="0" | ||||
|        y="1004.3621" | ||||
|        ry="7.9999785" /> | ||||
|     <path | ||||
|        style="opacity:1;fill:#313131;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        d="m 8,1004.3621 c -4.4319881,0 -8,3.568 -8,8 l 0,32 c 0,4.432 3.5680119,8 8,8 l 12,0 c 15.512,0 28,-16.948 28,-38 l 0,-2 c 0,-4.432 -3.568012,-8 -8,-8 l -32,0 z" | ||||
|        id="rect4173" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|     <g | ||||
|        id="g4300" | ||||
|        style="fill:#000000;fill-opacity:1;stroke:none" | ||||
|        transform="translate(0.5,0.5)"> | ||||
|       <g | ||||
|          id="g4302" | ||||
|          style="fill:#000000;fill-opacity:1;stroke:none"> | ||||
|         <path | ||||
|            sodipodi:nodetypes="scsccsssscccs" | ||||
|            d="m 11.986926,1016.3621 c 0.554325,0 1.025987,0.2121 1.414987,0.6362 0.398725,0.4138 0.600909,0.9155 0.598087,1.5052 l 0,6.8586 -2,0 0,-6.8914 c 0,-0.072 -0.03404,-0.1086 -0.102113,-0.1086 l -4.7957745,0 C 7.0340375,1018.3621 7,1018.3983 7,1018.4707 l 0,6.8914 -2,0 0,-9 z" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            id="path4304" | ||||
|            inkscape:connector-curvature="0" /> | ||||
|         <path | ||||
|            sodipodi:nodetypes="sscsscsscsscssssssssss" | ||||
|            d="m 17.013073,1016.3621 4.973854,0 c 0.554325,0 1.025987,0.2121 1.414986,0.6362 0.398725,0.4138 0.598087,0.9155 0.598087,1.5052 l 0,4.7172 c 0,0.5897 -0.199362,1.0966 -0.598087,1.5207 -0.388999,0.4138 -0.860661,0.6207 -1.414986,0.6207 l -4.973854,0 c -0.554325,0 -1.030849,-0.2069 -1.429574,-0.6207 C 15.1945,1024.3173 15,1023.8104 15,1023.2207 l 0,-4.7172 c 0,-0.5897 0.1945,-1.0914 0.583499,-1.5052 0.398725,-0.4241 0.875249,-0.6362 1.429574,-0.6362 z m 4.884815,2 -4.795776,0 c -0.06808,0 -0.102112,0.036 -0.102112,0.1086 l 0,4.7828 c 0,0.072 0.03404,0.1086 0.102112,0.1086 l 4.795776,0 c 0.06807,0 0.102112,-0.036 0.102112,-0.1086 l 0,-4.7828 c 0,-0.072 -0.03404,-0.1086 -0.102112,-0.1086 z" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            id="path4306" | ||||
|            inkscape:connector-curvature="0" /> | ||||
|       </g> | ||||
|       <g | ||||
|          id="g4308" | ||||
|          style="fill:#000000;fill-opacity:1;stroke:none"> | ||||
|         <path | ||||
|            sodipodi:nodetypes="cccccccc" | ||||
|            d="m 12,1036.9177 4.768114,-8.5556 2.231886,0 -6,11 -2,0 -6,-11 2.2318854,0 z" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            id="path4310" | ||||
|            inkscape:connector-curvature="0" /> | ||||
|         <path | ||||
|            sodipodi:nodetypes="ccccccccccc" | ||||
|            d="m 29,1036.3621 0,-8 2,0 0,11 -2,0 -7,-8 0,8 -2,0 0,-11 2,0 z" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            id="path4312" | ||||
|            inkscape:connector-curvature="0" /> | ||||
|         <path | ||||
|            sodipodi:nodetypes="cssssccscsscscc" | ||||
|            d="m 43,1030.3621 -8.897887,0 c -0.06808,0 -0.102113,0.036 -0.102113,0.1069 l 0,6.7862 c 0,0.071 0.03404,0.1069 0.102113,0.1069 l 8.897887,0 0,2 -8.972339,0 c -0.56405,0 -1.045437,-0.2037 -1.444162,-0.6111 C 32.1945,1038.3334 32,1037.8292 32,1037.2385 l 0,-6.7528 c 0,-0.5907 0.1945,-1.0898 0.583499,-1.4972 0.398725,-0.4176 0.880112,-0.6264 1.444162,-0.6264 l 8.972339,0 z" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            id="path4314" | ||||
|            inkscape:connector-curvature="0" /> | ||||
|       </g> | ||||
|     </g> | ||||
|     <g | ||||
|        id="g4291" | ||||
|        style="stroke:none"> | ||||
|       <g | ||||
|          id="g4282" | ||||
|          style="stroke:none"> | ||||
|         <path | ||||
|            inkscape:connector-curvature="0" | ||||
|            id="path4143" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            d="m 11.986926,1016.3621 c 0.554325,0 1.025987,0.2121 1.414987,0.6362 0.398725,0.4138 0.600909,0.9155 0.598087,1.5052 l 0,6.8586 -2,0 0,-6.8914 c 0,-0.072 -0.03404,-0.1086 -0.102113,-0.1086 l -4.7957745,0 C 7.0340375,1018.3621 7,1018.3983 7,1018.4707 l 0,6.8914 -2,0 0,-9 z" | ||||
|            sodipodi:nodetypes="scsccsssscccs" /> | ||||
|         <path | ||||
|            inkscape:connector-curvature="0" | ||||
|            id="path4145" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#008000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            d="m 17.013073,1016.3621 4.973854,0 c 0.554325,0 1.025987,0.2121 1.414986,0.6362 0.398725,0.4138 0.598087,0.9155 0.598087,1.5052 l 0,4.7172 c 0,0.5897 -0.199362,1.0966 -0.598087,1.5207 -0.388999,0.4138 -0.860661,0.6207 -1.414986,0.6207 l -4.973854,0 c -0.554325,0 -1.030849,-0.2069 -1.429574,-0.6207 C 15.1945,1024.3173 15,1023.8104 15,1023.2207 l 0,-4.7172 c 0,-0.5897 0.1945,-1.0914 0.583499,-1.5052 0.398725,-0.4241 0.875249,-0.6362 1.429574,-0.6362 z m 4.884815,2 -4.795776,0 c -0.06808,0 -0.102112,0.036 -0.102112,0.1086 l 0,4.7828 c 0,0.072 0.03404,0.1086 0.102112,0.1086 l 4.795776,0 c 0.06807,0 0.102112,-0.036 0.102112,-0.1086 l 0,-4.7828 c 0,-0.072 -0.03404,-0.1086 -0.102112,-0.1086 z" | ||||
|            sodipodi:nodetypes="sscsscsscsscssssssssss" /> | ||||
|       </g> | ||||
|       <g | ||||
|          id="g4286" | ||||
|          style="stroke:none"> | ||||
|         <path | ||||
|            inkscape:connector-curvature="0" | ||||
|            id="path4147" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            d="m 12,1036.9177 4.768114,-8.5556 2.231886,0 -6,11 -2,0 -6,-11 2.2318854,0 z" | ||||
|            sodipodi:nodetypes="cccccccc" /> | ||||
|         <path | ||||
|            inkscape:connector-curvature="0" | ||||
|            id="path4149" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            d="m 29,1036.3621 0,-8 2,0 0,11 -2,0 -7,-8 0,8 -2,0 0,-11 2,0 z" | ||||
|            sodipodi:nodetypes="ccccccccccc" /> | ||||
|         <path | ||||
|            inkscape:connector-curvature="0" | ||||
|            id="path4151" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:medium;line-height:125%;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            d="m 43,1030.3621 -8.897887,0 c -0.06808,0 -0.102113,0.036 -0.102113,0.1069 l 0,6.7862 c 0,0.071 0.03404,0.1069 0.102113,0.1069 l 8.897887,0 0,2 -8.972339,0 c -0.56405,0 -1.045437,-0.2037 -1.444162,-0.6111 C 32.1945,1038.3334 32,1037.8292 32,1037.2385 l 0,-6.7528 c 0,-0.5907 0.1945,-1.0898 0.583499,-1.4972 0.398725,-0.4176 0.880112,-0.6264 1.444162,-0.6264 l 8.972339,0 z" | ||||
|            sodipodi:nodetypes="cssssccscsscscc" /> | ||||
|       </g> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 11 KiB | 
							
								
								
									
										81
									
								
								public/novnc/app/images/info.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,81 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="info.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="15.720838" | ||||
|      inkscape:cy="8.9111233" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="false" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title /> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <path | ||||
|        style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        d="M 12.5 3 A 9.5 9.4999914 0 0 0 3 12.5 A 9.5 9.4999914 0 0 0 12.5 22 A 9.5 9.4999914 0 0 0 22 12.5 A 9.5 9.4999914 0 0 0 12.5 3 z M 12.5 5 A 1.5 1.5000087 0 0 1 14 6.5 A 1.5 1.5000087 0 0 1 12.5 8 A 1.5 1.5000087 0 0 1 11 6.5 A 1.5 1.5000087 0 0 1 12.5 5 z M 10.521484 8.9785156 L 12.521484 8.9785156 A 1.50015 1.50015 0 0 1 14.021484 10.478516 L 14.021484 15.972656 A 1.50015 1.50015 0 0 1 14.498047 18.894531 C 14.498047 18.894531 13.74301 19.228309 12.789062 18.912109 C 12.312092 18.754109 11.776235 18.366625 11.458984 17.828125 C 11.141734 17.289525 11.021484 16.668469 11.021484 15.980469 L 11.021484 11.980469 L 10.521484 11.980469 A 1.50015 1.50015 0 1 1 10.521484 8.9804688 L 10.521484 8.9785156 z " | ||||
|        transform="translate(0,1027.3622)" | ||||
|        id="path4136" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.1 KiB | 
							
								
								
									
										88
									
								
								public/novnc/app/images/keyboard.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,88 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="keyboard.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/keyboard.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#717171" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="31.285341" | ||||
|      inkscape:cy="8.8028469" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:snap-bbox-midpoints="false" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:object-paths="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-midpoints="true" | ||||
|      inkscape:snap-smooth-nodes="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title /> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <path | ||||
|        style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" | ||||
|        d="M 7,3 C 4.8012876,3 3,4.8013 3,7 3,11.166667 3,15.333333 3,19.5 3,20.8764 4.1236413,22 5.5,22 l 14,0 C 20.876358,22 22,20.8764 22,19.5 22,15.333333 22,11.166667 22,7 22,4.8013 20.198712,3 18,3 Z m 0,2 11,0 c 1.125307,0 2,0.8747 2,2 L 20,12 5,12 5,7 C 5,5.8747 5.8746931,5 7,5 Z M 6.5,14 C 6.777,14 7,14.223 7,14.5 7,14.777 6.777,15 6.5,15 6.223,15 6,14.777 6,14.5 6,14.223 6.223,14 6.5,14 Z m 2,0 C 8.777,14 9,14.223 9,14.5 9,14.777 8.777,15 8.5,15 8.223,15 8,14.777 8,14.5 8,14.223 8.223,14 8.5,14 Z m 2,0 C 10.777,14 11,14.223 11,14.5 11,14.777 10.777,15 10.5,15 10.223,15 10,14.777 10,14.5 10,14.223 10.223,14 10.5,14 Z m 2,0 C 12.777,14 13,14.223 13,14.5 13,14.777 12.777,15 12.5,15 12.223,15 12,14.777 12,14.5 12,14.223 12.223,14 12.5,14 Z m 2,0 C 14.777,14 15,14.223 15,14.5 15,14.777 14.777,15 14.5,15 14.223,15 14,14.777 14,14.5 14,14.223 14.223,14 14.5,14 Z m 2,0 C 16.777,14 17,14.223 17,14.5 17,14.777 16.777,15 16.5,15 16.223,15 16,14.777 16,14.5 16,14.223 16.223,14 16.5,14 Z m 2,0 C 18.777,14 19,14.223 19,14.5 19,14.777 18.777,15 18.5,15 18.223,15 18,14.777 18,14.5 18,14.223 18.223,14 18.5,14 Z m -13,2 C 5.777,16 6,16.223 6,16.5 6,16.777 5.777,17 5.5,17 5.223,17 5,16.777 5,16.5 5,16.223 5.223,16 5.5,16 Z m 2,0 C 7.777,16 8,16.223 8,16.5 8,16.777 7.777,17 7.5,17 7.223,17 7,16.777 7,16.5 7,16.223 7.223,16 7.5,16 Z m 2,0 C 9.777,16 10,16.223 10,16.5 10,16.777 9.777,17 9.5,17 9.223,17 9,16.777 9,16.5 9,16.223 9.223,16 9.5,16 Z m 2,0 C 11.777,16 12,16.223 12,16.5 12,16.777 11.777,17 11.5,17 11.223,17 11,16.777 11,16.5 11,16.223 11.223,16 11.5,16 Z m 2,0 C 13.777,16 14,16.223 14,16.5 14,16.777 13.777,17 13.5,17 13.223,17 13,16.777 13,16.5 13,16.223 13.223,16 13.5,16 Z m 2,0 C 15.777,16 16,16.223 16,16.5 16,16.777 15.777,17 15.5,17 15.223,17 15,16.777 15,16.5 15,16.223 15.223,16 15.5,16 Z m 2,0 C 17.777,16 18,16.223 18,16.5 18,16.777 17.777,17 17.5,17 17.223,17 17,16.777 17,16.5 17,16.223 17.223,16 17.5,16 Z m 2,0 C 19.777,16 20,16.223 20,16.5 20,16.777 19.777,17 19.5,17 19.223,17 19,16.777 19,16.5 19,16.223 19.223,16 19.5,16 Z M 6,18 c 0.554,0 1,0.446 1,1 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 0,-0.554 0.446,-1 1,-1 z m 2.8261719,0 7.3476561,0 C 16.631643,18 17,18.368372 17,18.826172 l 0,0.347656 C 17,19.631628 16.631643,20 16.173828,20 L 8.8261719,20 C 8.3683573,20 8,19.631628 8,19.173828 L 8,18.826172 C 8,18.368372 8.3683573,18 8.8261719,18 Z m 10.1113281,0 0.125,0 C 19.581551,18 20,18.4184 20,18.9375 l 0,0.125 C 20,19.5816 19.581551,20 19.0625,20 l -0.125,0 C 18.418449,20 18,19.5816 18,19.0625 l 0,-0.125 C 18,18.4184 18.418449,18 18.9375,18 Z" | ||||
|        transform="translate(0,1027.3622)" | ||||
|        id="rect4160" | ||||
|        inkscape:connector-curvature="0" | ||||
|        sodipodi:nodetypes="sccssccsssssccssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss" /> | ||||
|     <path | ||||
|        style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" | ||||
|        d="m 12.499929,1033.8622 -2,2 1.500071,0 0,2 1,0 0,-2 1.499929,0 z" | ||||
|        id="path4150" | ||||
|        inkscape:connector-curvature="0" | ||||
|        sodipodi:nodetypes="cccccccc" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 6.3 KiB | 
							
								
								
									
										87
									
								
								public/novnc/app/images/power.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,87 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="power.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="9.3159849" | ||||
|      inkscape:cy="13.436208" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <path | ||||
|        style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" | ||||
|        d="M 9 6.8183594 C 6.3418164 8.1213032 4.5 10.849161 4.5 14 C 4.5 18.4065 8.0935666 22 12.5 22 C 16.906433 22 20.5 18.4065 20.5 14 C 20.5 10.849161 18.658184 8.1213032 16 6.8183594 L 16 9.125 C 17.514327 10.211757 18.5 11.984508 18.5 14 C 18.5 17.3256 15.825553 20 12.5 20 C 9.1744469 20 6.5 17.3256 6.5 14 C 6.5 11.984508 7.4856727 10.211757 9 9.125 L 9 6.8183594 z " | ||||
|        transform="translate(0,1027.3622)" | ||||
|        id="path6140" /> | ||||
|     <path | ||||
|        style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" | ||||
|        d="m 12.5,1031.8836 0,6.4786" | ||||
|        id="path6142" | ||||
|        inkscape:connector-curvature="0" | ||||
|        sodipodi:nodetypes="cc" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.9 KiB | 
							
								
								
									
										76
									
								
								public/novnc/app/images/settings.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,76 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="settings.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="22.627417" | ||||
|      inkscape:cx="14.69683" | ||||
|      inkscape:cy="8.8039511" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="true" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="false" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <path | ||||
|        style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        d="M 11 3 L 11 5.1601562 A 7.5 7.5 0 0 0 8.3671875 6.2460938 L 6.84375 4.7226562 L 4.7226562 6.84375 L 6.2480469 8.3691406 A 7.5 7.5 0 0 0 5.1523438 11 L 3 11 L 3 14 L 5.1601562 14 A 7.5 7.5 0 0 0 6.2460938 16.632812 L 4.7226562 18.15625 L 6.84375 20.277344 L 8.3691406 18.751953 A 7.5 7.5 0 0 0 11 19.847656 L 11 22 L 14 22 L 14 19.839844 A 7.5 7.5 0 0 0 16.632812 18.753906 L 18.15625 20.277344 L 20.277344 18.15625 L 18.751953 16.630859 A 7.5 7.5 0 0 0 19.847656 14 L 22 14 L 22 11 L 19.839844 11 A 7.5 7.5 0 0 0 18.753906 8.3671875 L 20.277344 6.84375 L 18.15625 4.7226562 L 16.630859 6.2480469 A 7.5 7.5 0 0 0 14 5.1523438 L 14 3 L 11 3 z M 12.5 10 A 2.5 2.5 0 0 1 15 12.5 A 2.5 2.5 0 0 1 12.5 15 A 2.5 2.5 0 0 1 10 12.5 A 2.5 2.5 0 0 1 12.5 10 z " | ||||
|        transform="translate(0,1027.3622)" | ||||
|        id="rect4967" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.0 KiB | 
							
								
								
									
										86
									
								
								public/novnc/app/images/tab.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,86 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="tab.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="16" | ||||
|      inkscape:cx="11.67335" | ||||
|      inkscape:cy="17.881696" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <path | ||||
|        style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        d="m 3,1031.3622 0,8 2,0 0,-4 0,-4 -2,0 z m 2,4 4,4 0,-3 13,0 0,-2 -13,0 0,-3 -4,4 z" | ||||
|        id="rect5194" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|     <path | ||||
|        id="path5211" | ||||
|        d="m 22,1048.3622 0,-8 -2,0 0,4 0,4 2,0 z m -2,-4 -4,-4 0,3 -13,0 0,2 13,0 0,3 4,-4 z" | ||||
|        style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 2.9 KiB | 
							
								
								
									
										90
									
								
								public/novnc/app/images/toggleextrakeys.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,90 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="extrakeys.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="15.234555" | ||||
|      inkscape:cy="9.9710826" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="false" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="false"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <path | ||||
|        style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" | ||||
|        d="m 8,1031.3622 c -2.1987124,0 -4,1.8013 -4,4 l 0,8.9996 c 0,2.1987 1.8012876,4 4,4 l 9,0 c 2.198712,0 4,-1.8013 4,-4 l 0,-8.9996 c 0,-2.1987 -1.801288,-4 -4,-4 z m 0,2 9,0 c 1.125307,0 2,0.8747 2,2 l 0,7.0005 c 0,1.1253 -0.874693,2 -2,2 l -9,0 c -1.1253069,0 -2,-0.8747 -2,-2 l 0,-7.0005 c 0,-1.1253 0.8746931,-2 2,-2 z" | ||||
|        id="rect5006" | ||||
|        inkscape:connector-curvature="0" | ||||
|        sodipodi:nodetypes="ssssssssssssssssss" /> | ||||
|     <g | ||||
|        style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:10px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|        id="text4167" | ||||
|        transform="matrix(0.96021948,0,0,0.96021948,0.18921715,41.80659)"> | ||||
|       <path | ||||
|          d="m 14.292969,1040.6791 -2.939453,0 -0.463868,1.3281 -1.889648,0 2.700195,-7.29 2.241211,0 2.700196,7.29 -1.889649,0 -0.458984,-1.3281 z m -2.470703,-1.3526 1.99707,0 -0.996094,-2.9004 -1.000976,2.9004 z" | ||||
|          id="path4172" | ||||
|          inkscape:connector-curvature="0" /> | ||||
|     </g> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 4.3 KiB | 
							
								
								
									
										81
									
								
								public/novnc/app/images/warning.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,81 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="25" | ||||
|    height="25" | ||||
|    viewBox="0 0 25 25" | ||||
|    id="svg2" | ||||
|    version="1.1" | ||||
|    inkscape:version="0.91 r13725" | ||||
|    sodipodi:docname="warning.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:export-xdpi="90" | ||||
|    inkscape:export-ydpi="90"> | ||||
|   <defs | ||||
|      id="defs4" /> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#959595" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1" | ||||
|      inkscape:cx="16.457343" | ||||
|      inkscape:cy="12.179552" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="layer1" | ||||
|      showgrid="false" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-paths="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      showguides="false" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1136" | ||||
|      inkscape:window-x="1920" | ||||
|      inkscape:window-y="27" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:object-nodes="true" | ||||
|      inkscape:snap-intersection-paths="true" | ||||
|      inkscape:snap-nodes="true" | ||||
|      inkscape:snap-global="true"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4136" /> | ||||
|   </sodipodi:namedview> | ||||
|   <metadata | ||||
|      id="metadata7"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="Layer 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(0,-1027.3622)"> | ||||
|     <path | ||||
|        style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" | ||||
|        d="M 12.513672 3.0019531 C 11.751609 2.9919531 11.052563 3.4242687 10.710938 4.1054688 L 3.2109375 19.105469 C 2.5461937 20.435369 3.5132277 21.9999 5 22 L 20 22 C 21.486772 21.9999 22.453806 20.435369 21.789062 19.105469 L 14.289062 4.1054688 C 13.951849 3.4330688 13.265888 3.0066531 12.513672 3.0019531 z M 12.478516 6.9804688 A 1.50015 1.50015 0 0 1 14 8.5 L 14 14.5 A 1.50015 1.50015 0 1 1 11 14.5 L 11 8.5 A 1.50015 1.50015 0 0 1 12.478516 6.9804688 z M 12.5 17 A 1.5 1.5 0 0 1 14 18.5 A 1.5 1.5 0 0 1 12.5 20 A 1.5 1.5 0 0 1 11 18.5 A 1.5 1.5 0 0 1 12.5 17 z " | ||||
|        transform="translate(0,1027.3622)" | ||||
|        id="path4208" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 3.8 KiB | 
							
								
								
									
										65
									
								
								public/novnc/app/images/windows.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,65 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||
|  | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    version="1.1" | ||||
|    id="svg2" | ||||
|    inkscape:export-ydpi="90" | ||||
|    inkscape:export-xdpi="90" | ||||
|    sodipodi:docname="windows.svg" | ||||
|    inkscape:export-filename="/home/ossman/devel/noVNC/images/drag.png" | ||||
|    inkscape:version="0.92.4 (unknown)" | ||||
|    x="0px" | ||||
|    y="0px" | ||||
|    viewBox="-293 384 25 25" | ||||
|    xml:space="preserve" | ||||
|    width="25" | ||||
|    height="25"><metadata | ||||
|    id="metadata21"><rdf:RDF><cc:Work | ||||
|        rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type | ||||
|          rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs | ||||
|    id="defs19" /><sodipodi:namedview | ||||
|    pagecolor="#959595" | ||||
|    bordercolor="#666666" | ||||
|    borderopacity="1" | ||||
|    objecttolerance="10" | ||||
|    gridtolerance="10" | ||||
|    guidetolerance="10" | ||||
|    inkscape:pageopacity="0" | ||||
|    inkscape:pageshadow="2" | ||||
|    inkscape:window-width="1920" | ||||
|    inkscape:window-height="1136" | ||||
|    id="namedview17" | ||||
|    showgrid="true" | ||||
|    inkscape:pagecheckerboard="false" | ||||
|    inkscape:zoom="32" | ||||
|    inkscape:cx="3.926913" | ||||
|    inkscape:cy="13.255959" | ||||
|    inkscape:window-x="1920" | ||||
|    inkscape:window-y="27" | ||||
|    inkscape:window-maximized="1" | ||||
|    inkscape:current-layer="svg2"><inkscape:grid | ||||
|      type="xygrid" | ||||
|      id="grid818" /></sodipodi:namedview> | ||||
| <style | ||||
|    type="text/css" | ||||
|    id="style2"> | ||||
| 	.st0{fill:#FFFFFF;} | ||||
| </style> | ||||
|  | ||||
| <path | ||||
|    style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" | ||||
|    d="M 21 4 L 11 5.1757812 L 11 12 L 21 12 L 21 4 z M 10 5.2949219 L 4 6 L 4 12 L 10 12 L 10 5.2949219 z " | ||||
|    transform="translate(-293,384)" | ||||
|    id="path853" /><path | ||||
|    id="path858" | ||||
|    d="m -272,405 -10,-1.17578 V 397 h 10 z M -283,403.70508 -289,403 v -6 h 6 z" | ||||
|    style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|    inkscape:connector-curvature="0" /></svg> | ||||
| After Width: | Height: | Size: 2.4 KiB | 
							
								
								
									
										1
									
								
								public/novnc/app/locale/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| DO NOT MODIFY THE FILES IN THIS FOLDER, THEY ARE AUTOMATICALLY GENERATED FROM THE PO-FILES. | ||||
							
								
								
									
										71
									
								
								public/novnc/app/locale/cs.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,71 @@ | ||||
| { | ||||
|     "Connecting...": "Připojení...", | ||||
|     "Disconnecting...": "Odpojení...", | ||||
|     "Reconnecting...": "Obnova připojení...", | ||||
|     "Internal error": "Vnitřní chyba", | ||||
|     "Must set host": "Hostitel musí být nastavení", | ||||
|     "Connected (encrypted) to ": "Připojení (šifrované) k ", | ||||
|     "Connected (unencrypted) to ": "Připojení (nešifrované) k ", | ||||
|     "Something went wrong, connection is closed": "Něco se pokazilo, odpojeno", | ||||
|     "Failed to connect to server": "Chyba připojení k serveru", | ||||
|     "Disconnected": "Odpojeno", | ||||
|     "New connection has been rejected with reason: ": "Nové připojení bylo odmítnuto s odůvodněním: ", | ||||
|     "New connection has been rejected": "Nové připojení bylo odmítnuto", | ||||
|     "Password is required": "Je vyžadováno heslo", | ||||
|     "noVNC encountered an error:": "noVNC narazilo na chybu:", | ||||
|     "Hide/Show the control bar": "Skrýt/zobrazit ovládací panel", | ||||
|     "Move/Drag Viewport": "Přesunout/přetáhnout výřez", | ||||
|     "viewport drag": "přesun výřezu", | ||||
|     "Active Mouse Button": "Aktivní tlačítka myši", | ||||
|     "No mousebutton": "Žádné", | ||||
|     "Left mousebutton": "Levé tlačítko myši", | ||||
|     "Middle mousebutton": "Prostřední tlačítko myši", | ||||
|     "Right mousebutton": "Pravé tlačítko myši", | ||||
|     "Keyboard": "Klávesnice", | ||||
|     "Show Keyboard": "Zobrazit klávesnici", | ||||
|     "Extra keys": "Extra klávesy", | ||||
|     "Show Extra Keys": "Zobrazit extra klávesy", | ||||
|     "Ctrl": "Ctrl", | ||||
|     "Toggle Ctrl": "Přepnout Ctrl", | ||||
|     "Alt": "Alt", | ||||
|     "Toggle Alt": "Přepnout Alt", | ||||
|     "Send Tab": "Odeslat tabulátor", | ||||
|     "Tab": "Tab", | ||||
|     "Esc": "Esc", | ||||
|     "Send Escape": "Odeslat Esc", | ||||
|     "Ctrl+Alt+Del": "Ctrl+Alt+Del", | ||||
|     "Send Ctrl-Alt-Del": "Poslat Ctrl-Alt-Del", | ||||
|     "Shutdown/Reboot": "Vypnutí/Restart", | ||||
|     "Shutdown/Reboot...": "Vypnutí/Restart...", | ||||
|     "Power": "Napájení", | ||||
|     "Shutdown": "Vypnout", | ||||
|     "Reboot": "Restart", | ||||
|     "Reset": "Reset", | ||||
|     "Clipboard": "Schránka", | ||||
|     "Clear": "Vymazat", | ||||
|     "Fullscreen": "Celá obrazovka", | ||||
|     "Settings": "Nastavení", | ||||
|     "Shared Mode": "Sdílený režim", | ||||
|     "View Only": "Pouze prohlížení", | ||||
|     "Clip to Window": "Přizpůsobit oknu", | ||||
|     "Scaling Mode:": "Přizpůsobení velikosti", | ||||
|     "None": "Žádné", | ||||
|     "Local Scaling": "Místní", | ||||
|     "Remote Resizing": "Vzdálené", | ||||
|     "Advanced": "Pokročilé", | ||||
|     "Repeater ID:": "ID opakovače", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "Šifrování:", | ||||
|     "Host:": "Hostitel:", | ||||
|     "Port:": "Port:", | ||||
|     "Path:": "Cesta", | ||||
|     "Automatic Reconnect": "Automatická obnova připojení", | ||||
|     "Reconnect Delay (ms):": "Zpoždění připojení (ms)", | ||||
|     "Show Dot when No Cursor": "Tečka místo chybějícího kurzoru myši", | ||||
|     "Logging:": "Logování:", | ||||
|     "Disconnect": "Odpojit", | ||||
|     "Connect": "Připojit", | ||||
|     "Password:": "Heslo", | ||||
|     "Send Password": "Odeslat heslo", | ||||
|     "Cancel": "Zrušit" | ||||
| } | ||||
							
								
								
									
										69
									
								
								public/novnc/app/locale/de.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,69 @@ | ||||
| { | ||||
|     "Connecting...": "Verbinden...", | ||||
|     "Disconnecting...": "Verbindung trennen...", | ||||
|     "Reconnecting...": "Verbindung wiederherstellen...", | ||||
|     "Internal error": "Interner Fehler", | ||||
|     "Must set host": "Richten Sie den Server ein", | ||||
|     "Connected (encrypted) to ": "Verbunden mit (verschlüsselt) ", | ||||
|     "Connected (unencrypted) to ": "Verbunden mit (unverschlüsselt) ", | ||||
|     "Something went wrong, connection is closed": "Etwas lief schief, Verbindung wurde getrennt", | ||||
|     "Disconnected": "Verbindung zum Server getrennt", | ||||
|     "New connection has been rejected with reason: ": "Verbindung wurde aus folgendem Grund abgelehnt: ", | ||||
|     "New connection has been rejected": "Verbindung wurde abgelehnt", | ||||
|     "Password is required": "Passwort ist erforderlich", | ||||
|     "noVNC encountered an error:": "Ein Fehler ist aufgetreten:", | ||||
|     "Hide/Show the control bar": "Kontrollleiste verstecken/anzeigen", | ||||
|     "Move/Drag Viewport": "Ansichtsfenster verschieben/ziehen", | ||||
|     "viewport drag": "Ansichtsfenster ziehen", | ||||
|     "Active Mouse Button": "Aktive Maustaste", | ||||
|     "No mousebutton": "Keine Maustaste", | ||||
|     "Left mousebutton": "Linke Maustaste", | ||||
|     "Middle mousebutton": "Mittlere Maustaste", | ||||
|     "Right mousebutton": "Rechte Maustaste", | ||||
|     "Keyboard": "Tastatur", | ||||
|     "Show Keyboard": "Tastatur anzeigen", | ||||
|     "Extra keys": "Zusatztasten", | ||||
|     "Show Extra Keys": "Zusatztasten anzeigen", | ||||
|     "Ctrl": "Strg", | ||||
|     "Toggle Ctrl": "Strg umschalten", | ||||
|     "Alt": "Alt", | ||||
|     "Toggle Alt": "Alt umschalten", | ||||
|     "Send Tab": "Tab senden", | ||||
|     "Tab": "Tab", | ||||
|     "Esc": "Esc", | ||||
|     "Send Escape": "Escape senden", | ||||
|     "Ctrl+Alt+Del": "Strg+Alt+Entf", | ||||
|     "Send Ctrl-Alt-Del": "Strg+Alt+Entf senden", | ||||
|     "Shutdown/Reboot": "Herunterfahren/Neustarten", | ||||
|     "Shutdown/Reboot...": "Herunterfahren/Neustarten...", | ||||
|     "Power": "Energie", | ||||
|     "Shutdown": "Herunterfahren", | ||||
|     "Reboot": "Neustarten", | ||||
|     "Reset": "Zurücksetzen", | ||||
|     "Clipboard": "Zwischenablage", | ||||
|     "Clear": "Löschen", | ||||
|     "Fullscreen": "Vollbild", | ||||
|     "Settings": "Einstellungen", | ||||
|     "Shared Mode": "Geteilter Modus", | ||||
|     "View Only": "Nur betrachten", | ||||
|     "Clip to Window": "Auf Fenster begrenzen", | ||||
|     "Scaling Mode:": "Skalierungsmodus:", | ||||
|     "None": "Keiner", | ||||
|     "Local Scaling": "Lokales skalieren", | ||||
|     "Remote Resizing": "Serverseitiges skalieren", | ||||
|     "Advanced": "Erweitert", | ||||
|     "Repeater ID:": "Repeater ID:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "Verschlüsselt", | ||||
|     "Host:": "Server:", | ||||
|     "Port:": "Port:", | ||||
|     "Path:": "Pfad:", | ||||
|     "Automatic Reconnect": "Automatisch wiederverbinden", | ||||
|     "Reconnect Delay (ms):": "Wiederverbindungsverzögerung (ms):", | ||||
|     "Logging:": "Protokollierung:", | ||||
|     "Disconnect": "Verbindung trennen", | ||||
|     "Connect": "Verbinden", | ||||
|     "Password:": "Passwort:", | ||||
|     "Cancel": "Abbrechen", | ||||
|     "Canvas not supported.": "Canvas nicht unterstützt." | ||||
| } | ||||
							
								
								
									
										69
									
								
								public/novnc/app/locale/el.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,69 @@ | ||||
| { | ||||
|     "Connecting...": "Συνδέεται...", | ||||
|     "Disconnecting...": "Aποσυνδέεται...", | ||||
|     "Reconnecting...": "Επανασυνδέεται...", | ||||
|     "Internal error": "Εσωτερικό σφάλμα", | ||||
|     "Must set host": "Πρέπει να οριστεί ο διακομιστής", | ||||
|     "Connected (encrypted) to ": "Συνδέθηκε (κρυπτογραφημένα) με το ", | ||||
|     "Connected (unencrypted) to ": "Συνδέθηκε (μη κρυπτογραφημένα) με το ", | ||||
|     "Something went wrong, connection is closed": "Κάτι πήγε στραβά, η σύνδεση διακόπηκε", | ||||
|     "Disconnected": "Αποσυνδέθηκε", | ||||
|     "New connection has been rejected with reason: ": "Η νέα σύνδεση απορρίφθηκε διότι: ", | ||||
|     "New connection has been rejected": "Η νέα σύνδεση απορρίφθηκε ", | ||||
|     "Password is required": "Απαιτείται ο κωδικός πρόσβασης", | ||||
|     "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": "Ρυθμίσεις", | ||||
|     "Shared Mode": "Κοινόχρηστη Λειτουργία", | ||||
|     "View Only": "Μόνο Θέαση", | ||||
|     "Clip to Window": "Αποκοπή στο όριο του Παράθυρου", | ||||
|     "Scaling Mode:": "Λειτουργία Κλιμάκωσης:", | ||||
|     "None": "Καμία", | ||||
|     "Local Scaling": "Τοπική Κλιμάκωση", | ||||
|     "Remote Resizing": "Απομακρυσμένη Αλλαγή μεγέθους", | ||||
|     "Advanced": "Για προχωρημένους", | ||||
|     "Repeater ID:": "Repeater ID:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "Κρυπτογράφηση", | ||||
|     "Host:": "Όνομα διακομιστή:", | ||||
|     "Port:": "Πόρτα διακομιστή:", | ||||
|     "Path:": "Διαδρομή:", | ||||
|     "Automatic Reconnect": "Αυτόματη επανασύνδεση", | ||||
|     "Reconnect Delay (ms):": "Καθυστέρηση επανασύνδεσης (ms):", | ||||
|     "Logging:": "Καταγραφή:", | ||||
|     "Disconnect": "Αποσύνδεση", | ||||
|     "Connect": "Σύνδεση", | ||||
|     "Password:": "Κωδικός Πρόσβασης:", | ||||
|     "Cancel": "Ακύρωση", | ||||
|     "Canvas not supported.": "Δεν υποστηρίζεται το στοιχείο Canvas" | ||||
| } | ||||
							
								
								
									
										68
									
								
								public/novnc/app/locale/es.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,68 @@ | ||||
| { | ||||
|     "Connecting...": "Conectando...", | ||||
|     "Connected (encrypted) to ": "Conectado (con encriptación) a", | ||||
|     "Connected (unencrypted) to ": "Conectado (sin encriptación) a", | ||||
|     "Disconnecting...": "Desconectando...", | ||||
|     "Disconnected": "Desconectado", | ||||
|     "Must set host": "Se debe configurar el host", | ||||
|     "Reconnecting...": "Reconectando...", | ||||
|     "Password is required": "La contraseña es obligatoria", | ||||
|     "Disconnect timeout": "Tiempo de desconexión agotado", | ||||
|     "noVNC encountered an error:": "noVNC ha encontrado un error:", | ||||
|     "Hide/Show the control bar": "Ocultar/Mostrar la barra de control", | ||||
|     "Move/Drag Viewport": "Mover/Arrastrar la ventana", | ||||
|     "viewport drag": "Arrastrar la ventana", | ||||
|     "Active Mouse Button": "Botón activo del ratón", | ||||
|     "No mousebutton": "Ningún botón del ratón", | ||||
|     "Left mousebutton": "Botón izquierdo del ratón", | ||||
|     "Middle mousebutton": "Botón central del ratón", | ||||
|     "Right mousebutton": "Botón derecho del ratón", | ||||
|     "Keyboard": "Teclado", | ||||
|     "Show Keyboard": "Mostrar teclado", | ||||
|     "Extra keys": "Teclas adicionales", | ||||
|     "Show Extra Keys": "Mostrar Teclas Adicionales", | ||||
|     "Ctrl": "Ctrl", | ||||
|     "Toggle Ctrl": "Pulsar/Soltar Ctrl", | ||||
|     "Alt": "Alt", | ||||
|     "Toggle Alt": "Pulsar/Soltar Alt", | ||||
|     "Send Tab": "Enviar Tabulación", | ||||
|     "Tab": "Tabulación", | ||||
|     "Esc": "Esc", | ||||
|     "Send Escape": "Enviar Escape", | ||||
|     "Ctrl+Alt+Del": "Ctrl+Alt+Del", | ||||
|     "Send Ctrl-Alt-Del": "Enviar Ctrl+Alt+Del", | ||||
|     "Shutdown/Reboot": "Apagar/Reiniciar", | ||||
|     "Shutdown/Reboot...": "Apagar/Reiniciar...", | ||||
|     "Power": "Encender", | ||||
|     "Shutdown": "Apagar", | ||||
|     "Reboot": "Reiniciar", | ||||
|     "Reset": "Restablecer", | ||||
|     "Clipboard": "Portapapeles", | ||||
|     "Clear": "Vaciar", | ||||
|     "Fullscreen": "Pantalla Completa", | ||||
|     "Settings": "Configuraciones", | ||||
|     "Encrypt": "Encriptar", | ||||
|     "Shared Mode": "Modo Compartido", | ||||
|     "View Only": "Solo visualización", | ||||
|     "Clip to Window": "Recortar al tamaño de la ventana", | ||||
|     "Scaling Mode:": "Modo de escalado:", | ||||
|     "None": "Ninguno", | ||||
|     "Local Scaling": "Escalado Local", | ||||
|     "Local Downscaling": "Reducción de escala local", | ||||
|     "Remote Resizing": "Cambio de tamaño remoto", | ||||
|     "Advanced": "Avanzado", | ||||
|     "Local Cursor": "Cursor Local", | ||||
|     "Repeater ID:": "ID del Repetidor:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Host:": "Host:", | ||||
|     "Port:": "Puerto:", | ||||
|     "Path:": "Ruta:", | ||||
|     "Automatic Reconnect": "Reconexión automática", | ||||
|     "Reconnect Delay (ms):": "Retraso en la reconexión (ms):", | ||||
|     "Logging:": "Registrando:", | ||||
|     "Disconnect": "Desconectar", | ||||
|     "Connect": "Conectar", | ||||
|     "Password:": "Contraseña:", | ||||
|     "Cancel": "Cancelar", | ||||
|     "Canvas not supported.": "Canvas no soportado." | ||||
| } | ||||
							
								
								
									
										72
									
								
								public/novnc/app/locale/fr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,72 @@ | ||||
| { | ||||
|     "Connecting...": "En cours de connexion...", | ||||
|     "Disconnecting...": "Déconnexion en cours...", | ||||
|     "Reconnecting...": "Reconnexion en cours...", | ||||
|     "Internal error": "Erreur interne", | ||||
|     "Must set host": "Doit définir l'hôte", | ||||
|     "Connected (encrypted) to ": "Connecté (crypté) à ", | ||||
|     "Connected (unencrypted) to ": "Connecté (non crypté) à ", | ||||
|     "Something went wrong, connection is closed": "Quelque chose est arrivé, la connexion est fermée", | ||||
|     "Failed to connect to server": "Échec de connexion au serveur", | ||||
|     "Disconnected": "Déconnecté", | ||||
|     "New connection has been rejected with reason: ": "Une nouvelle connexion a été rejetée avec raison: ", | ||||
|     "New connection has been rejected": "Une nouvelle connexion a été rejetée", | ||||
|     "Credentials are required": "Les identifiants sont requis", | ||||
|     "noVNC encountered an error:": "noVNC a rencontré une erreur:", | ||||
|     "Hide/Show the control bar": "Masquer/Afficher la barre de contrôle", | ||||
|     "Drag": "Faire glisser", | ||||
|     "Move/Drag Viewport": "Déplacer/faire glisser Viewport", | ||||
|     "Keyboard": "Clavier", | ||||
|     "Show Keyboard": "Afficher le clavier", | ||||
|     "Extra keys": "Touches supplémentaires", | ||||
|     "Show Extra Keys": "Afficher les touches supplémentaires", | ||||
|     "Ctrl": "Ctrl", | ||||
|     "Toggle Ctrl": "Basculer Ctrl", | ||||
|     "Alt": "Alt", | ||||
|     "Toggle Alt": "Basculer Alt", | ||||
|     "Toggle Windows": "Basculer Windows", | ||||
|     "Windows": "Windows", | ||||
|     "Send Tab": "Envoyer l'onglet", | ||||
|     "Tab": "l'onglet", | ||||
|     "Esc": "Esc", | ||||
|     "Send Escape": "Envoyer Escape", | ||||
|     "Ctrl+Alt+Del": "Ctrl+Alt+Del", | ||||
|     "Send Ctrl-Alt-Del": "Envoyer Ctrl-Alt-Del", | ||||
|     "Shutdown/Reboot": "Arrêter/Redémarrer", | ||||
|     "Shutdown/Reboot...": "Arrêter/Redémarrer...", | ||||
|     "Power": "Alimentation", | ||||
|     "Shutdown": "Arrêter", | ||||
|     "Reboot": "Redémarrer", | ||||
|     "Reset": "Réinitialiser", | ||||
|     "Clipboard": "Presse-papiers", | ||||
|     "Clear": "Effacer", | ||||
|     "Fullscreen": "Plein écran", | ||||
|     "Settings": "Paramètres", | ||||
|     "Shared Mode": "Mode partagé", | ||||
|     "View Only": "Afficher uniquement", | ||||
|     "Clip to Window": "Clip à fenêtre", | ||||
|     "Scaling Mode:": "Mode mise à l'échelle:", | ||||
|     "None": "Aucun", | ||||
|     "Local Scaling": "Mise à l'échelle locale", | ||||
|     "Remote Resizing": "Redimensionnement à distance", | ||||
|     "Advanced": "Avancé", | ||||
|     "Quality:": "Qualité:", | ||||
|     "Compression level:": "Niveau de compression:", | ||||
|     "Repeater ID:": "ID Répéteur:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "Crypter", | ||||
|     "Host:": "Hôte:", | ||||
|     "Port:": "Port:", | ||||
|     "Path:": "Chemin:", | ||||
|     "Automatic Reconnect": "Reconnecter automatiquemen", | ||||
|     "Reconnect Delay (ms):": "Délai de reconnexion (ms):", | ||||
|     "Show Dot when No Cursor": "Afficher le point lorsqu'il n'y a pas de curseur", | ||||
|     "Logging:": "Se connecter:", | ||||
|     "Version:": "Version:", | ||||
|     "Disconnect": "Déconnecter", | ||||
|     "Connect": "Connecter", | ||||
|     "Username:": "Nom d'utilisateur:", | ||||
|     "Password:": "Mot de passe:", | ||||
|     "Send Credentials": "Envoyer les identifiants", | ||||
|     "Cancel": "Annuler" | ||||
| } | ||||
							
								
								
									
										72
									
								
								public/novnc/app/locale/ja.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,72 @@ | ||||
| { | ||||
|     "Connecting...": "接続しています...", | ||||
|     "Disconnecting...": "切断しています...", | ||||
|     "Reconnecting...": "再接続しています...", | ||||
|     "Internal error": "内部エラー", | ||||
|     "Must set host": "ホストを設定する必要があります", | ||||
|     "Connected (encrypted) to ": "接続しました (暗号化済み): ", | ||||
|     "Connected (unencrypted) to ": "接続しました (暗号化されていません): ", | ||||
|     "Something went wrong, connection is closed": "何らかの問題で、接続が閉じられました", | ||||
|     "Failed to connect to server": "サーバーへの接続に失敗しました", | ||||
|     "Disconnected": "切断しました", | ||||
|     "New connection has been rejected with reason: ": "新規接続は次の理由で拒否されました: ", | ||||
|     "New connection has been rejected": "新規接続は拒否されました", | ||||
|     "Credentials are required": "資格情報が必要です", | ||||
|     "noVNC encountered an error:": "noVNC でエラーが発生しました:", | ||||
|     "Hide/Show the control bar": "コントロールバーを隠す/表示する", | ||||
|     "Drag": "ドラッグ", | ||||
|     "Move/Drag Viewport": "ビューポートを移動/ドラッグ", | ||||
|     "Keyboard": "キーボード", | ||||
|     "Show Keyboard": "キーボードを表示", | ||||
|     "Extra keys": "追加キー", | ||||
|     "Show Extra Keys": "追加キーを表示", | ||||
|     "Ctrl": "Ctrl", | ||||
|     "Toggle Ctrl": "Ctrl キーを切り替え", | ||||
|     "Alt": "Alt", | ||||
|     "Toggle Alt": "Alt キーを切り替え", | ||||
|     "Toggle Windows": "Windows キーを切り替え", | ||||
|     "Windows": "Windows", | ||||
|     "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": "設定", | ||||
|     "Shared Mode": "共有モード", | ||||
|     "View Only": "表示のみ", | ||||
|     "Clip to Window": "ウィンドウにクリップ", | ||||
|     "Scaling Mode:": "スケーリングモード:", | ||||
|     "None": "なし", | ||||
|     "Local Scaling": "ローカルスケーリング", | ||||
|     "Remote Resizing": "リモートでリサイズ", | ||||
|     "Advanced": "高度", | ||||
|     "Quality:": "品質:", | ||||
|     "Compression level:": "圧縮レベル:", | ||||
|     "Repeater ID:": "リピーター ID:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "暗号化", | ||||
|     "Host:": "ホスト:", | ||||
|     "Port:": "ポート:", | ||||
|     "Path:": "パス:", | ||||
|     "Automatic Reconnect": "自動再接続", | ||||
|     "Reconnect Delay (ms):": "再接続する遅延 (ミリ秒):", | ||||
|     "Show Dot when No Cursor": "カーソルがないときにドットを表示", | ||||
|     "Logging:": "ロギング:", | ||||
|     "Version:": "バージョン:", | ||||
|     "Disconnect": "切断", | ||||
|     "Connect": "接続", | ||||
|     "Username:": "ユーザー名:", | ||||
|     "Password:": "パスワード:", | ||||
|     "Send Credentials": "資格情報を送信", | ||||
|     "Cancel": "キャンセル" | ||||
| } | ||||
							
								
								
									
										70
									
								
								public/novnc/app/locale/ko.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,70 @@ | ||||
| { | ||||
|     "Connecting...": "연결중...", | ||||
|     "Disconnecting...": "연결 해제중...", | ||||
|     "Reconnecting...": "재연결중...", | ||||
|     "Internal error": "내부 오류", | ||||
|     "Must set host": "호스트는 설정되어야 합니다.", | ||||
|     "Connected (encrypted) to ": "다음과 (암호화되어) 연결되었습니다:", | ||||
|     "Connected (unencrypted) to ": "다음과 (암호화 없이) 연결되었습니다:", | ||||
|     "Something went wrong, connection is closed": "무언가 잘못되었습니다, 연결이 닫혔습니다.", | ||||
|     "Failed to connect to server": "서버에 연결하지 못했습니다.", | ||||
|     "Disconnected": "연결이 해제되었습니다.", | ||||
|     "New connection has been rejected with reason: ": "새 연결이 다음 이유로 거부되었습니다:", | ||||
|     "New connection has been rejected": "새 연결이 거부되었습니다.", | ||||
|     "Password is required": "비밀번호가 필요합니다.", | ||||
|     "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": "Esc 보내기", | ||||
|     "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": "설정", | ||||
|     "Shared Mode": "공유 모드", | ||||
|     "View Only": "보기 전용", | ||||
|     "Clip to Window": "창에 클립", | ||||
|     "Scaling Mode:": "스케일링 모드:", | ||||
|     "None": "없음", | ||||
|     "Local Scaling": "로컬 스케일링", | ||||
|     "Remote Resizing": "원격 크기 조절", | ||||
|     "Advanced": "고급", | ||||
|     "Repeater ID:": "중계 ID", | ||||
|     "WebSocket": "웹소켓", | ||||
|     "Encrypt": "암호화", | ||||
|     "Host:": "호스트:", | ||||
|     "Port:": "포트:", | ||||
|     "Path:": "위치:", | ||||
|     "Automatic Reconnect": "자동 재연결", | ||||
|     "Reconnect Delay (ms):": "재연결 지연 시간 (ms)", | ||||
|     "Logging:": "로깅", | ||||
|     "Disconnect": "연결 해제", | ||||
|     "Connect": "연결", | ||||
|     "Password:": "비밀번호:", | ||||
|     "Send Password": "비밀번호 전송", | ||||
|     "Cancel": "취소" | ||||
| } | ||||
							
								
								
									
										73
									
								
								public/novnc/app/locale/nl.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,73 @@ | ||||
| { | ||||
|     "Connecting...": "Verbinden...", | ||||
|     "Disconnecting...": "Verbinding verbreken...", | ||||
|     "Reconnecting...": "Opnieuw verbinding maken...", | ||||
|     "Internal error": "Interne fout", | ||||
|     "Must set host": "Host moeten worden ingesteld", | ||||
|     "Connected (encrypted) to ": "Verbonden (versleuteld) met ", | ||||
|     "Connected (unencrypted) to ": "Verbonden (onversleuteld) met ", | ||||
|     "Something went wrong, connection is closed": "Er iets fout gelopen, verbinding werd verbroken", | ||||
|     "Failed to connect to server": "Verbinding maken met server is mislukt", | ||||
|     "Disconnected": "Verbinding verbroken", | ||||
|     "New connection has been rejected with reason: ": "Nieuwe verbinding is geweigerd omwille van de volgende reden: ", | ||||
|     "New connection has been rejected": "Nieuwe verbinding is geweigerd", | ||||
|     "Password is required": "Wachtwoord is vereist", | ||||
|     "noVNC encountered an error:": "noVNC heeft een fout bemerkt:", | ||||
|     "Hide/Show the control bar": "Verberg/Toon de bedieningsbalk", | ||||
|     "Move/Drag Viewport": "Verplaats/Versleep Kijkvenster", | ||||
|     "viewport drag": "kijkvenster slepen", | ||||
|     "Active Mouse Button": "Actieve Muisknop", | ||||
|     "No mousebutton": "Geen muisknop", | ||||
|     "Left mousebutton": "Linker muisknop", | ||||
|     "Middle mousebutton": "Middelste muisknop", | ||||
|     "Right mousebutton": "Rechter muisknop", | ||||
|     "Keyboard": "Toetsenbord", | ||||
|     "Show Keyboard": "Toon Toetsenbord", | ||||
|     "Extra keys": "Extra toetsen", | ||||
|     "Show Extra Keys": "Toon Extra Toetsen", | ||||
|     "Ctrl": "Ctrl", | ||||
|     "Toggle Ctrl": "Ctrl omschakelen", | ||||
|     "Alt": "Alt", | ||||
|     "Toggle Alt": "Alt omschakelen", | ||||
|     "Toggle Windows": "Windows omschakelen", | ||||
|     "Windows": "Windows", | ||||
|     "Send Tab": "Tab Sturen", | ||||
|     "Tab": "Tab", | ||||
|     "Esc": "Esc", | ||||
|     "Send Escape": "Escape Sturen", | ||||
|     "Ctrl+Alt+Del": "Ctrl-Alt-Del", | ||||
|     "Send Ctrl-Alt-Del": "Ctrl-Alt-Del Sturen", | ||||
|     "Shutdown/Reboot": "Uitschakelen/Herstarten", | ||||
|     "Shutdown/Reboot...": "Uitschakelen/Herstarten...", | ||||
|     "Power": "Systeem", | ||||
|     "Shutdown": "Uitschakelen", | ||||
|     "Reboot": "Herstarten", | ||||
|     "Reset": "Resetten", | ||||
|     "Clipboard": "Klembord", | ||||
|     "Clear": "Wissen", | ||||
|     "Fullscreen": "Volledig Scherm", | ||||
|     "Settings": "Instellingen", | ||||
|     "Shared Mode": "Gedeelde Modus", | ||||
|     "View Only": "Alleen Kijken", | ||||
|     "Clip to Window": "Randen buiten venster afsnijden", | ||||
|     "Scaling Mode:": "Schaalmodus:", | ||||
|     "None": "Geen", | ||||
|     "Local Scaling": "Lokaal Schalen", | ||||
|     "Remote Resizing": "Op Afstand Formaat Wijzigen", | ||||
|     "Advanced": "Geavanceerd", | ||||
|     "Repeater ID:": "Repeater ID:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "Versleutelen", | ||||
|     "Host:": "Host:", | ||||
|     "Port:": "Poort:", | ||||
|     "Path:": "Pad:", | ||||
|     "Automatic Reconnect": "Automatisch Opnieuw Verbinden", | ||||
|     "Reconnect Delay (ms):": "Vertraging voor Opnieuw Verbinden (ms):", | ||||
|     "Show Dot when No Cursor": "Geef stip weer indien geen cursor", | ||||
|     "Logging:": "Logmeldingen:", | ||||
|     "Disconnect": "Verbinding verbreken", | ||||
|     "Connect": "Verbinden", | ||||
|     "Password:": "Wachtwoord:", | ||||
|     "Send Password": "Verzend Wachtwoord:", | ||||
|     "Cancel": "Annuleren" | ||||
| } | ||||
							
								
								
									
										69
									
								
								public/novnc/app/locale/pl.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,69 @@ | ||||
| { | ||||
|     "Connecting...": "Łączenie...", | ||||
|     "Disconnecting...": "Rozłączanie...", | ||||
|     "Reconnecting...": "Łączenie...", | ||||
|     "Internal error": "Błąd wewnętrzny", | ||||
|     "Must set host": "Host i port są wymagane", | ||||
|     "Connected (encrypted) to ": "Połączenie (szyfrowane) z ", | ||||
|     "Connected (unencrypted) to ": "Połączenie (nieszyfrowane) z ", | ||||
|     "Something went wrong, connection is closed": "Coś poszło źle, połączenie zostało zamknięte", | ||||
|     "Disconnected": "Rozłączony", | ||||
|     "New connection has been rejected with reason: ": "Nowe połączenie zostało odrzucone z powodu: ", | ||||
|     "New connection has been rejected": "Nowe połączenie zostało odrzucone", | ||||
|     "Password is required": "Hasło jest wymagane", | ||||
|     "noVNC encountered an error:": "noVNC napotkało błąd:", | ||||
|     "Hide/Show the control bar": "Pokaż/Ukryj pasek ustawień", | ||||
|     "Move/Drag Viewport": "Ruszaj/Przeciągaj Viewport", | ||||
|     "viewport drag": "przeciągnij viewport", | ||||
|     "Active Mouse Button": "Aktywny Przycisk Myszy", | ||||
|     "No mousebutton": "Brak przycisku myszy", | ||||
|     "Left mousebutton": "Lewy przycisk myszy", | ||||
|     "Middle mousebutton": "Środkowy przycisk myszy", | ||||
|     "Right mousebutton": "Prawy przycisk myszy", | ||||
|     "Keyboard": "Klawiatura", | ||||
|     "Show Keyboard": "Pokaż klawiaturę", | ||||
|     "Extra keys": "Przyciski dodatkowe", | ||||
|     "Show Extra Keys": "Pokaż przyciski dodatkowe", | ||||
|     "Ctrl": "Ctrl", | ||||
|     "Toggle Ctrl": "Przełącz Ctrl", | ||||
|     "Alt": "Alt", | ||||
|     "Toggle Alt": "Przełącz Alt", | ||||
|     "Send Tab": "Wyślij Tab", | ||||
|     "Tab": "Tab", | ||||
|     "Esc": "Esc", | ||||
|     "Send Escape": "Wyślij Escape", | ||||
|     "Ctrl+Alt+Del": "Ctrl+Alt+Del", | ||||
|     "Send Ctrl-Alt-Del": "Wyślij Ctrl-Alt-Del", | ||||
|     "Shutdown/Reboot": "Wyłącz/Uruchom ponownie", | ||||
|     "Shutdown/Reboot...": "Wyłącz/Uruchom ponownie...", | ||||
|     "Power": "Włączony", | ||||
|     "Shutdown": "Wyłącz", | ||||
|     "Reboot": "Uruchom ponownie", | ||||
|     "Reset": "Resetuj", | ||||
|     "Clipboard": "Schowek", | ||||
|     "Clear": "Wyczyść", | ||||
|     "Fullscreen": "Pełny ekran", | ||||
|     "Settings": "Ustawienia", | ||||
|     "Shared Mode": "Tryb Współdzielenia", | ||||
|     "View Only": "Tylko Podgląd", | ||||
|     "Clip to Window": "Przytnij do Okna", | ||||
|     "Scaling Mode:": "Tryb Skalowania:", | ||||
|     "None": "Brak", | ||||
|     "Local Scaling": "Skalowanie lokalne", | ||||
|     "Remote Resizing": "Skalowanie zdalne", | ||||
|     "Advanced": "Zaawansowane", | ||||
|     "Repeater ID:": "ID Repeatera:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "Szyfrowanie", | ||||
|     "Host:": "Host:", | ||||
|     "Port:": "Port:", | ||||
|     "Path:": "Ścieżka:", | ||||
|     "Automatic Reconnect": "Automatycznie wznawiaj połączenie", | ||||
|     "Reconnect Delay (ms):": "Opóźnienie wznawiania (ms):", | ||||
|     "Logging:": "Poziom logowania:", | ||||
|     "Disconnect": "Rozłącz", | ||||
|     "Connect": "Połącz", | ||||
|     "Password:": "Hasło:", | ||||
|     "Cancel": "Anuluj", | ||||
|     "Canvas not supported.": "Element Canvas nie jest wspierany." | ||||
| } | ||||
							
								
								
									
										72
									
								
								public/novnc/app/locale/pt_BR.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,72 @@ | ||||
| { | ||||
|     "Connecting...": "Conectando...", | ||||
|     "Disconnecting...": "Desconectando...", | ||||
|     "Reconnecting...": "Reconectando...", | ||||
|     "Internal error": "Erro interno", | ||||
|     "Must set host": "É necessário definir o host", | ||||
|     "Connected (encrypted) to ": "Conectado (com criptografia) a ", | ||||
|     "Connected (unencrypted) to ": "Conectado (sem criptografia) a ", | ||||
|     "Something went wrong, connection is closed": "Algo deu errado. A conexão foi encerrada.", | ||||
|     "Failed to connect to server": "Falha ao conectar-se ao servidor", | ||||
|     "Disconnected": "Desconectado", | ||||
|     "New connection has been rejected with reason: ": "A nova conexão foi rejeitada pelo motivo: ", | ||||
|     "New connection has been rejected": "A nova conexão foi rejeitada", | ||||
|     "Credentials are required": "Credenciais são obrigatórias", | ||||
|     "noVNC encountered an error:": "O noVNC encontrou um erro:", | ||||
|     "Hide/Show the control bar": "Esconder/mostrar a barra de controles", | ||||
|     "Drag": "Arrastar", | ||||
|     "Move/Drag Viewport": "Mover/arrastar a janela", | ||||
|     "Keyboard": "Teclado", | ||||
|     "Show Keyboard": "Mostrar teclado", | ||||
|     "Extra keys": "Teclas adicionais", | ||||
|     "Show Extra Keys": "Mostar teclas adicionais", | ||||
|     "Ctrl": "Ctrl", | ||||
|     "Toggle Ctrl": "Pressionar/soltar Ctrl", | ||||
|     "Alt": "Alt", | ||||
|     "Toggle Alt": "Pressionar/soltar Alt", | ||||
|     "Toggle Windows": "Pressionar/soltar Windows", | ||||
|     "Windows": "Windows", | ||||
|     "Send Tab": "Enviar Tab", | ||||
|     "Tab": "Tab", | ||||
|     "Esc": "Esc", | ||||
|     "Send Escape": "Enviar Esc", | ||||
|     "Ctrl+Alt+Del": "Ctrl+Alt+Del", | ||||
|     "Send Ctrl-Alt-Del": "Enviar Ctrl-Alt-Del", | ||||
|     "Shutdown/Reboot": "Desligar/reiniciar", | ||||
|     "Shutdown/Reboot...": "Desligar/reiniciar...", | ||||
|     "Power": "Ligar", | ||||
|     "Shutdown": "Desligar", | ||||
|     "Reboot": "Reiniciar", | ||||
|     "Reset": "Reiniciar (forçado)", | ||||
|     "Clipboard": "Área de transferência", | ||||
|     "Clear": "Limpar", | ||||
|     "Fullscreen": "Tela cheia", | ||||
|     "Settings": "Configurações", | ||||
|     "Shared Mode": "Modo compartilhado", | ||||
|     "View Only": "Apenas visualizar", | ||||
|     "Clip to Window": "Recortar à janela", | ||||
|     "Scaling Mode:": "Modo de dimensionamento:", | ||||
|     "None": "Nenhum", | ||||
|     "Local Scaling": "Local", | ||||
|     "Remote Resizing": "Remoto", | ||||
|     "Advanced": "Avançado", | ||||
|     "Quality:": "Qualidade:", | ||||
|     "Compression level:": "Nível de compressão:", | ||||
|     "Repeater ID:": "ID do repetidor:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "Criptografar", | ||||
|     "Host:": "Host:", | ||||
|     "Port:": "Porta:", | ||||
|     "Path:": "Caminho:", | ||||
|     "Automatic Reconnect": "Reconexão automática", | ||||
|     "Reconnect Delay (ms):": "Atraso da reconexão (ms)", | ||||
|     "Show Dot when No Cursor": "Mostrar ponto quando não há cursor", | ||||
|     "Logging:": "Registros:", | ||||
|     "Version:": "Versão:", | ||||
|     "Disconnect": "Desconectar", | ||||
|     "Connect": "Conectar", | ||||
|     "Username:": "Nome de usuário:", | ||||
|     "Password:": "Senha:", | ||||
|     "Send Credentials": "Enviar credenciais", | ||||
|     "Cancel": "Cancelar" | ||||
| } | ||||
							
								
								
									
										72
									
								
								public/novnc/app/locale/ru.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,72 @@ | ||||
| { | ||||
|     "Connecting...": "Подключение...", | ||||
|     "Disconnecting...": "Отключение...", | ||||
|     "Reconnecting...": "Переподключение...", | ||||
|     "Internal error": "Внутренняя ошибка", | ||||
|     "Must set host": "Задайте имя сервера или IP", | ||||
|     "Connected (encrypted) to ": "Подключено (с шифрованием) к ", | ||||
|     "Connected (unencrypted) to ": "Подключено (без шифрования) к ", | ||||
|     "Something went wrong, connection is closed": "Что-то пошло не так, подключение разорвано", | ||||
|     "Failed to connect to server": "Ошибка подключения к серверу", | ||||
|     "Disconnected": "Отключено", | ||||
|     "New connection has been rejected with reason: ": "Новое соединение отклонено по причине: ", | ||||
|     "New connection has been rejected": "Новое соединение отклонено", | ||||
|     "Credentials are required": "Требуются учетные данные", | ||||
|     "noVNC encountered an error:": "Ошибка noVNC: ", | ||||
|     "Hide/Show the control bar": "Скрыть/Показать контрольную панель", | ||||
|     "Drag": "Переместить", | ||||
|     "Move/Drag Viewport": "Переместить окно", | ||||
|     "Keyboard": "Клавиатура", | ||||
|     "Show Keyboard": "Показать клавиатуру", | ||||
|     "Extra keys": "Дополнительные Кнопки", | ||||
|     "Show Extra Keys": "Показать Дополнительные Кнопки", | ||||
|     "Ctrl": "Ctrl", | ||||
|     "Toggle Ctrl": "Переключение нажатия Ctrl", | ||||
|     "Alt": "Alt", | ||||
|     "Toggle Alt": "Переключение нажатия Alt", | ||||
|     "Toggle Windows": "Переключение вкладок", | ||||
|     "Windows": "Вкладка", | ||||
|     "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": "Настройки", | ||||
|     "Shared Mode": "Общий режим", | ||||
|     "View Only": "Только Просмотр", | ||||
|     "Clip to Window": "В окно", | ||||
|     "Scaling Mode:": "Масштаб:", | ||||
|     "None": "Нет", | ||||
|     "Local Scaling": "Локльный масштаб", | ||||
|     "Remote Resizing": "Удаленная перенастройка размера", | ||||
|     "Advanced": "Дополнительно", | ||||
|     "Quality:": "Качество", | ||||
|     "Compression level:": "Уровень Сжатия", | ||||
|     "Repeater ID:": "Идентификатор ID:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "Шифрование", | ||||
|     "Host:": "Сервер:", | ||||
|     "Port:": "Порт:", | ||||
|     "Path:": "Путь:", | ||||
|     "Automatic Reconnect": "Автоматическое переподключение", | ||||
|     "Reconnect Delay (ms):": "Задержка переподключения (мс):", | ||||
|     "Show Dot when No Cursor": "Показать точку вместо курсора", | ||||
|     "Logging:": "Лог:", | ||||
|     "Version:": "Версия", | ||||
|     "Disconnect": "Отключение", | ||||
|     "Connect": "Подключение", | ||||
|     "Username:": "Имя Пользователя", | ||||
|     "Password:": "Пароль:", | ||||
|     "Send Credentials": "Передача Учетных Данных", | ||||
|     "Cancel": "Выход" | ||||
| } | ||||
							
								
								
									
										72
									
								
								public/novnc/app/locale/sv.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,72 @@ | ||||
| { | ||||
|     "Connecting...": "Ansluter...", | ||||
|     "Disconnecting...": "Kopplar ner...", | ||||
|     "Reconnecting...": "Återansluter...", | ||||
|     "Internal error": "Internt fel", | ||||
|     "Must set host": "Du måste specifiera en värd", | ||||
|     "Connected (encrypted) to ": "Ansluten (krypterat) till ", | ||||
|     "Connected (unencrypted) to ": "Ansluten (okrypterat) till ", | ||||
|     "Something went wrong, connection is closed": "Något gick fel, anslutningen avslutades", | ||||
|     "Failed to connect to server": "Misslyckades att ansluta till servern", | ||||
|     "Disconnected": "Frånkopplad", | ||||
|     "New connection has been rejected with reason: ": "Ny anslutning har blivit nekad med följande skäl: ", | ||||
|     "New connection has been rejected": "Ny anslutning har blivit nekad", | ||||
|     "Credentials are required": "Användaruppgifter krävs", | ||||
|     "noVNC encountered an error:": "noVNC stötte på ett problem:", | ||||
|     "Hide/Show the control bar": "Göm/Visa kontrollbaren", | ||||
|     "Drag": "Dra", | ||||
|     "Move/Drag Viewport": "Flytta/Dra Vyn", | ||||
|     "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", | ||||
|     "Toggle Windows": "Växla Windows", | ||||
|     "Windows": "Windows", | ||||
|     "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", | ||||
|     "Shared Mode": "Delat Läge", | ||||
|     "View Only": "Endast Visning", | ||||
|     "Clip to Window": "Begränsa till Fönster", | ||||
|     "Scaling Mode:": "Skalningsläge:", | ||||
|     "None": "Ingen", | ||||
|     "Local Scaling": "Lokal Skalning", | ||||
|     "Remote Resizing": "Ändra Storlek", | ||||
|     "Advanced": "Avancerat", | ||||
|     "Quality:": "Kvalitet:", | ||||
|     "Compression level:": "Kompressionsnivå:", | ||||
|     "Repeater ID:": "Repeater-ID:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "Kryptera", | ||||
|     "Host:": "Värd:", | ||||
|     "Port:": "Port:", | ||||
|     "Path:": "Sökväg:", | ||||
|     "Automatic Reconnect": "Automatisk Återanslutning", | ||||
|     "Reconnect Delay (ms):": "Fördröjning (ms):", | ||||
|     "Show Dot when No Cursor": "Visa prick när ingen muspekare finns", | ||||
|     "Logging:": "Loggning:", | ||||
|     "Version:": "Version:", | ||||
|     "Disconnect": "Koppla från", | ||||
|     "Connect": "Anslut", | ||||
|     "Username:": "Användarnamn:", | ||||
|     "Password:": "Lösenord:", | ||||
|     "Send Credentials": "Skicka Användaruppgifter", | ||||
|     "Cancel": "Avbryt" | ||||
| } | ||||
							
								
								
									
										69
									
								
								public/novnc/app/locale/tr.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,69 @@ | ||||
| { | ||||
|     "Connecting...": "Bağlanıyor...", | ||||
|     "Disconnecting...": "Bağlantı kesiliyor...", | ||||
|     "Reconnecting...": "Yeniden bağlantı kuruluyor...", | ||||
|     "Internal error": "İç hata", | ||||
|     "Must set host": "Sunucuyu kur", | ||||
|     "Connected (encrypted) to ": "Bağlı (şifrelenmiş)", | ||||
|     "Connected (unencrypted) to ": "Bağlandı (şifrelenmemiş)", | ||||
|     "Something went wrong, connection is closed": "Bir şeyler ters gitti, bağlantı kesildi", | ||||
|     "Disconnected": "Bağlantı kesildi", | ||||
|     "New connection has been rejected with reason: ": "Bağlantı aşağıdaki nedenlerden dolayı reddedildi: ", | ||||
|     "New connection has been rejected": "Bağlantı reddedildi", | ||||
|     "Password is required": "Şifre gerekli", | ||||
|     "noVNC encountered an error:": "Bir hata oluştu:", | ||||
|     "Hide/Show the control bar": "Denetim masasını Gizle/Göster", | ||||
|     "Move/Drag Viewport": "Görünümü Taşı/Sürükle", | ||||
|     "viewport drag": "Görüntü penceresini sürükle", | ||||
|     "Active Mouse Button": "Aktif Fare Düğmesi", | ||||
|     "No mousebutton": "Fare düğmesi yok", | ||||
|     "Left mousebutton": "Farenin sol düğmesi", | ||||
|     "Middle mousebutton": "Farenin orta düğmesi", | ||||
|     "Right mousebutton": "Farenin sağ düğmesi", | ||||
|     "Keyboard": "Klavye", | ||||
|     "Show Keyboard": "Klavye Düzenini Göster", | ||||
|     "Extra keys": "Ekstra tuşlar", | ||||
|     "Show Extra Keys": "Ekstra tuşları göster", | ||||
|     "Ctrl": "Ctrl", | ||||
|     "Toggle Ctrl": "Ctrl Değiştir ", | ||||
|     "Alt": "Alt", | ||||
|     "Toggle Alt": "Alt Değiştir", | ||||
|     "Send Tab": "Sekme Gönder", | ||||
|     "Tab": "Sekme", | ||||
|     "Esc": "Esc", | ||||
|     "Send Escape": "Boşluk Gönder", | ||||
|     "Ctrl+Alt+Del": "Ctrl + Alt + Del", | ||||
|     "Send Ctrl-Alt-Del": "Ctrl-Alt-Del Gönder", | ||||
|     "Shutdown/Reboot": "Kapat/Yeniden Başlat", | ||||
|     "Shutdown/Reboot...": "Kapat/Yeniden Başlat...", | ||||
|     "Power": "Güç", | ||||
|     "Shutdown": "Kapat", | ||||
|     "Reboot": "Yeniden Başlat", | ||||
|     "Reset": "Sıfırla", | ||||
|     "Clipboard": "Pano", | ||||
|     "Clear": "Temizle", | ||||
|     "Fullscreen": "Tam Ekran", | ||||
|     "Settings": "Ayarlar", | ||||
|     "Shared Mode": "Paylaşım Modu", | ||||
|     "View Only": "Sadece Görüntüle", | ||||
|     "Clip to Window": "Pencereye Tıkla", | ||||
|     "Scaling Mode:": "Ölçekleme Modu:", | ||||
|     "None": "Bilinmeyen", | ||||
|     "Local Scaling": "Yerel Ölçeklendirme", | ||||
|     "Remote Resizing": "Uzaktan Yeniden Boyutlandırma", | ||||
|     "Advanced": "Gelişmiş", | ||||
|     "Repeater ID:": "Tekralayıcı ID:", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "Şifrele", | ||||
|     "Host:": "Ana makine:", | ||||
|     "Port:": "Port:", | ||||
|     "Path:": "Yol:", | ||||
|     "Automatic Reconnect": "Otomatik Yeniden Bağlan", | ||||
|     "Reconnect Delay (ms):": "Yeniden Bağlanma Süreci (ms):", | ||||
|     "Logging:": "Giriş yapılıyor:", | ||||
|     "Disconnect": "Bağlantıyı Kes", | ||||
|     "Connect": "Bağlan", | ||||
|     "Password:": "Parola:", | ||||
|     "Cancel": "Vazgeç", | ||||
|     "Canvas not supported.": "Tuval desteklenmiyor." | ||||
| } | ||||
							
								
								
									
										69
									
								
								public/novnc/app/locale/zh_CN.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,69 @@ | ||||
| { | ||||
|     "Connecting...": "连接中...", | ||||
|     "Disconnecting...": "正在断开连接...", | ||||
|     "Reconnecting...": "重新连接中...", | ||||
|     "Internal error": "内部错误", | ||||
|     "Must set host": "请提供主机名", | ||||
|     "Connected (encrypted) to ": "已连接到(加密)", | ||||
|     "Connected (unencrypted) to ": "已连接到(未加密)", | ||||
|     "Something went wrong, connection is closed": "发生错误,连接已关闭", | ||||
|     "Failed to connect to server": "无法连接到服务器", | ||||
|     "Disconnected": "已断开连接", | ||||
|     "New connection has been rejected with reason: ": "连接被拒绝,原因:", | ||||
|     "New connection has been rejected": "连接被拒绝", | ||||
|     "Password is required": "请提供密码", | ||||
|     "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": "设置", | ||||
|     "Shared Mode": "分享模式", | ||||
|     "View Only": "仅查看", | ||||
|     "Clip to Window": "限制/裁切窗口大小", | ||||
|     "Scaling Mode:": "缩放模式:", | ||||
|     "None": "无", | ||||
|     "Local Scaling": "本地缩放", | ||||
|     "Remote Resizing": "远程调整大小", | ||||
|     "Advanced": "高级", | ||||
|     "Repeater ID:": "中继站 ID", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "加密", | ||||
|     "Host:": "主机:", | ||||
|     "Port:": "端口:", | ||||
|     "Path:": "路径:", | ||||
|     "Automatic Reconnect": "自动重新连接", | ||||
|     "Reconnect Delay (ms):": "重新连接间隔 (ms):", | ||||
|     "Logging:": "日志级别:", | ||||
|     "Disconnect": "中断连接", | ||||
|     "Connect": "连接", | ||||
|     "Password:": "密码:", | ||||
|     "Cancel": "取消" | ||||
| } | ||||
							
								
								
									
										69
									
								
								public/novnc/app/locale/zh_TW.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,69 @@ | ||||
| { | ||||
|     "Connecting...": "連線中...", | ||||
|     "Disconnecting...": "正在中斷連線...", | ||||
|     "Reconnecting...": "重新連線中...", | ||||
|     "Internal error": "內部錯誤", | ||||
|     "Must set host": "請提供主機資訊", | ||||
|     "Connected (encrypted) to ": "已加密連線到", | ||||
|     "Connected (unencrypted) to ": "未加密連線到", | ||||
|     "Something went wrong, connection is closed": "發生錯誤,連線已關閉", | ||||
|     "Failed to connect to server": "無法連線到伺服器", | ||||
|     "Disconnected": "連線已中斷", | ||||
|     "New connection has been rejected with reason: ": "連線被拒絕,原因:", | ||||
|     "New connection has been rejected": "連線被拒絕", | ||||
|     "Password is required": "請提供密碼", | ||||
|     "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": "設定", | ||||
|     "Shared Mode": "分享模式", | ||||
|     "View Only": "僅檢視", | ||||
|     "Clip to Window": "限制/裁切視窗大小", | ||||
|     "Scaling Mode:": "縮放模式:", | ||||
|     "None": "無", | ||||
|     "Local Scaling": "本機縮放", | ||||
|     "Remote Resizing": "遠端調整大小", | ||||
|     "Advanced": "進階", | ||||
|     "Repeater ID:": "中繼站 ID", | ||||
|     "WebSocket": "WebSocket", | ||||
|     "Encrypt": "加密", | ||||
|     "Host:": "主機:", | ||||
|     "Port:": "連接埠:", | ||||
|     "Path:": "路徑:", | ||||
|     "Automatic Reconnect": "自動重新連線", | ||||
|     "Reconnect Delay (ms):": "重新連線間隔 (ms):", | ||||
|     "Logging:": "日誌級別:", | ||||
|     "Disconnect": "中斷連線", | ||||
|     "Connect": "連線", | ||||
|     "Password:": "密碼:", | ||||
|     "Cancel": "取消" | ||||
| } | ||||
							
								
								
									
										172
									
								
								public/novnc/app/localization.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,172 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2018 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Localization Utilities | ||||
|  */ | ||||
|  | ||||
| export class Localizer { | ||||
|     constructor() { | ||||
|         // Currently configured language | ||||
|         this.language = 'en'; | ||||
|  | ||||
|         // Current dictionary of translations | ||||
|         this.dictionary = undefined; | ||||
|     } | ||||
|  | ||||
|     // Configure suitable language based on user preferences | ||||
|     setup(supportedLanguages) { | ||||
|         this.language = 'en'; // Default: US English | ||||
|  | ||||
|         /* | ||||
|          * Navigator.languages only available in Chrome (32+) and FireFox (32+) | ||||
|          * Fall back to navigator.language for other browsers | ||||
|          */ | ||||
|         let userLanguages; | ||||
|         if (typeof window.navigator.languages == 'object') { | ||||
|             userLanguages = window.navigator.languages; | ||||
|         } else { | ||||
|             userLanguages = [navigator.language || navigator.userLanguage]; | ||||
|         } | ||||
|  | ||||
|         for (let i = 0;i < userLanguages.length;i++) { | ||||
|             const userLang = userLanguages[i] | ||||
|                 .toLowerCase() | ||||
|                 .replace("_", "-") | ||||
|                 .split("-"); | ||||
|  | ||||
|             // Built-in default? | ||||
|             if ((userLang[0] === 'en') && | ||||
|                 ((userLang[1] === undefined) || (userLang[1] === 'us'))) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // First pass: perfect match | ||||
|             for (let j = 0; j < supportedLanguages.length; j++) { | ||||
|                 const supLang = supportedLanguages[j] | ||||
|                     .toLowerCase() | ||||
|                     .replace("_", "-") | ||||
|                     .split("-"); | ||||
|  | ||||
|                 if (userLang[0] !== supLang[0]) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 if (userLang[1] !== supLang[1]) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 this.language = supportedLanguages[j]; | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Second pass: fallback | ||||
|             for (let j = 0;j < supportedLanguages.length;j++) { | ||||
|                 const supLang = supportedLanguages[j] | ||||
|                     .toLowerCase() | ||||
|                     .replace("_", "-") | ||||
|                     .split("-"); | ||||
|  | ||||
|                 if (userLang[0] !== supLang[0]) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 if (supLang[1] !== undefined) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 this.language = supportedLanguages[j]; | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Retrieve localised text | ||||
|     get(id) { | ||||
|         if (typeof this.dictionary !== 'undefined' && this.dictionary[id]) { | ||||
|             return this.dictionary[id]; | ||||
|         } else { | ||||
|             return id; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Traverses the DOM and translates relevant fields | ||||
|     // See https://html.spec.whatwg.org/multipage/dom.html#attr-translate | ||||
|     translateDOM() { | ||||
|         const self = this; | ||||
|  | ||||
|         function process(elem, enabled) { | ||||
|             function isAnyOf(searchElement, items) { | ||||
|                 return items.indexOf(searchElement) !== -1; | ||||
|             } | ||||
|  | ||||
|             function translateAttribute(elem, attr) { | ||||
|                 const str = self.get(elem.getAttribute(attr)); | ||||
|                 elem.setAttribute(attr, str); | ||||
|             } | ||||
|  | ||||
|             function translateTextNode(node) { | ||||
|                 const str = self.get(node.data.trim()); | ||||
|                 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", "submit"])) { | ||||
|                     translateAttribute(elem, "value"); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             for (let i = 0; i < elem.childNodes.length; i++) { | ||||
|                 const 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); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export const l10n = new Localizer(); | ||||
| export default l10n.get.bind(l10n); | ||||
							
								
								
									
										4
									
								
								public/novnc/app/sounds/CREDITS
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -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 | ||||
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/sounds/bell.mp3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/sounds/bell.oga
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/styles/Orbitron700.ttf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								public/novnc/app/styles/Orbitron700.woff
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										970
									
								
								public/novnc/app/styles/base.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,970 @@ | ||||
| /* | ||||
|  * noVNC base CSS | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * 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; | ||||
|   box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); | ||||
|   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:not([type]), | ||||
| input[type=date], | ||||
| input[type=datetime-local], | ||||
| input[type=email], | ||||
| input[type=month], | ||||
| input[type=number], | ||||
| input[type=password], | ||||
| input[type=search], | ||||
| input[type=tel], | ||||
| input[type=text], | ||||
| input[type=time], | ||||
| input[type=url], | ||||
| input[type=week], | ||||
| 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=color], | ||||
| input[type=reset], | ||||
| 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=color], | ||||
| input[type=reset], | ||||
| input[type=submit] { | ||||
|   padding-left: 20px; | ||||
|   padding-right: 20px; | ||||
| } | ||||
|  | ||||
| option { | ||||
|   color: black; | ||||
|   background: white; | ||||
| } | ||||
|  | ||||
| input:not([type]):focus, | ||||
| input[type=button]:focus, | ||||
| input[type=color]:focus, | ||||
| input[type=date]:focus, | ||||
| input[type=datetime-local]:focus, | ||||
| input[type=email]:focus, | ||||
| input[type=month]:focus, | ||||
| input[type=number]:focus, | ||||
| input[type=password]:focus, | ||||
| input[type=reset]:focus, | ||||
| input[type=search]:focus, | ||||
| input[type=submit]:focus, | ||||
| input[type=tel]:focus, | ||||
| input[type=text]:focus, | ||||
| input[type=time]:focus, | ||||
| input[type=url]:focus, | ||||
| input[type=week]:focus, | ||||
| select:focus, | ||||
| textarea: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=color]::-moz-focus-inner, | ||||
| input[type=reset]::-moz-focus-inner, | ||||
| input[type=submit]::-moz-focus-inner { | ||||
|   border: none; | ||||
| } | ||||
|  | ||||
| input:not([type]):disabled, | ||||
| input[type=button]:disabled, | ||||
| input[type=color]:disabled, | ||||
| input[type=date]:disabled, | ||||
| input[type=datetime-local]:disabled, | ||||
| input[type=email]:disabled, | ||||
| input[type=month]:disabled, | ||||
| input[type=number]:disabled, | ||||
| input[type=password]:disabled, | ||||
| input[type=reset]:disabled, | ||||
| input[type=search]:disabled, | ||||
| input[type=submit]:disabled, | ||||
| input[type=tel]:disabled, | ||||
| input[type=text]:disabled, | ||||
| input[type=time]:disabled, | ||||
| input[type=url]:disabled, | ||||
| input[type=week]:disabled, | ||||
| select:disabled, | ||||
| textarea:disabled { | ||||
|   color: rgb(128, 128, 128); | ||||
|   background: rgb(240, 240, 240); | ||||
| } | ||||
|  | ||||
| input[type=button]:active, | ||||
| input[type=color]:active, | ||||
| input[type=reset]: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=color]:hover:not(:disabled), | ||||
| :root:not(.noVNC_touch) input[type=reset]: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 { | ||||
|   z-index: 1000; | ||||
|   visibility: hidden; | ||||
| } | ||||
| #noVNC_fallback_error.noVNC_open { | ||||
|   visibility: visible; | ||||
| } | ||||
|  | ||||
| #noVNC_fallback_error > div { | ||||
|   max-width: 90%; | ||||
|   padding: 15px; | ||||
|  | ||||
|   transition: 0.5s ease-in-out; | ||||
|  | ||||
|   transform: translateY(-50px); | ||||
|   opacity: 0; | ||||
|  | ||||
|   text-align: center; | ||||
|   font-weight: bold; | ||||
|   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 > div { | ||||
|   transform: translateY(0); | ||||
|   opacity: 1; | ||||
| } | ||||
|  | ||||
| #noVNC_fallback_errormsg { | ||||
|   font-weight: normal; | ||||
| } | ||||
|  | ||||
| #noVNC_fallback_errormsg .noVNC_message { | ||||
|   display: inline-block; | ||||
|   text-align: left; | ||||
|   font-family: monospace; | ||||
|   white-space: pre-wrap; | ||||
| } | ||||
|  | ||||
| #noVNC_fallback_error .noVNC_location { | ||||
|   font-style: italic; | ||||
|   font-size: 0.8em; | ||||
|   color: rgba(255, 255, 255, 0.8); | ||||
| } | ||||
|  | ||||
| #noVNC_fallback_error .noVNC_stack { | ||||
|   max-height: 50vh; | ||||
|   padding: 10px; | ||||
|   margin: 10px; | ||||
|   font-size: 0.8em; | ||||
|   text-align: left; | ||||
|   font-family: monospace; | ||||
|   white-space: pre; | ||||
|   border: 1px solid rgba(0, 0, 0, 0.5); | ||||
|   background: rgba(0, 0, 0, 0.2); | ||||
|   overflow: auto; | ||||
| } | ||||
|  | ||||
| /* ---------------------------------------- | ||||
|  * 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; | ||||
| } | ||||
|  | ||||
| /* Control bar hint */ | ||||
| #noVNC_control_bar_hint { | ||||
|   position: fixed; | ||||
|   left: calc(100vw - 50px); | ||||
|   right: auto; | ||||
|   top: 50%; | ||||
|   transform: translateY(-50%) scale(0); | ||||
|   width: 100px; | ||||
|   height: 50%; | ||||
|   max-height: 600px; | ||||
|  | ||||
|   visibility: hidden; | ||||
|   opacity: 0; | ||||
|   transition: 0.2s ease-in-out; | ||||
|   background: transparent; | ||||
|   box-shadow: 0 0 10px black, inset 0 0 10px 10px rgba(110, 132, 163, 0.8); | ||||
|   border-radius: 10px; | ||||
|   transition-delay: 0s; | ||||
| } | ||||
| #noVNC_control_bar_anchor.noVNC_right #noVNC_control_bar_hint{ | ||||
|   left: auto; | ||||
|   right: calc(100vw - 50px); | ||||
| } | ||||
| #noVNC_control_bar_hint.noVNC_active { | ||||
|   visibility: visible; | ||||
|   opacity: 1; | ||||
|   transition-delay: 0.2s; | ||||
|   transform: translateY(-50%) scale(1); | ||||
| } | ||||
|  | ||||
| /* 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; | ||||
| } | ||||
| /* Android browsers don't properly update hover state if touch events | ||||
|  * are intercepted, but focus should be safe to display */ | ||||
| :root:not(.noVNC_touch) .noVNC_button.noVNC_selected:hover, | ||||
| .noVNC_button.noVNC_selected:focus { | ||||
|   border-color: rgba(0, 0, 0, 0.4); | ||||
|   background: rgba(0, 0, 0, 0.2); | ||||
| } | ||||
| :root:not(.noVNC_touch) .noVNC_button:hover, | ||||
| .noVNC_button:focus { | ||||
|   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_toggle_extra_keys_button { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| #noVNC_modifiers { | ||||
|   background-color: rgb(92, 92, 92); | ||||
|   border: none; | ||||
|   padding: 0 10px; | ||||
| } | ||||
|  | ||||
| /* Shutdown/Reboot */ | ||||
| :root:not(.noVNC_connected) #noVNC_power_button { | ||||
|   display: none; | ||||
| } | ||||
| #noVNC_power { | ||||
| } | ||||
| #noVNC_power_buttons { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| #noVNC_power 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; | ||||
| } | ||||
|  | ||||
| /* Version */ | ||||
|  | ||||
| .noVNC_version_wrapper { | ||||
|   font-size: small; | ||||
| } | ||||
|  | ||||
| .noVNC_version { | ||||
|   margin-left: 1rem; | ||||
| } | ||||
|  | ||||
| /* 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_credentials_dlg { | ||||
|   position: relative; | ||||
|  | ||||
|   transform: translateY(-50px); | ||||
| } | ||||
| #noVNC_credentials_dlg.noVNC_open { | ||||
|   transform: translateY(0); | ||||
| } | ||||
| #noVNC_credentials_dlg ul { | ||||
|   list-style: none; | ||||
|   margin: 0px; | ||||
|   padding: 0px; | ||||
| } | ||||
| .noVNC_hidden { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ---------------------------------------- | ||||
|  * 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_loading #noVNC_transition, | ||||
| :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; | ||||
| } | ||||
|  | ||||
| /*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; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										1715
									
								
								public/novnc/app/ui.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										186
									
								
								public/novnc/app/webutil.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,186 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| import { initLogging as mainInitLogging } from '../core/util/logging.js'; | ||||
|  | ||||
| // init log level reading the logging HTTP param | ||||
| export function initLogging(level) { | ||||
|     "use strict"; | ||||
|     if (typeof level !== "undefined") { | ||||
|         mainInitLogging(level); | ||||
|     } else { | ||||
|         const param = document.location.href.match(/logging=([A-Za-z0-9._-]*)/); | ||||
|         mainInitLogging(param || undefined); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Read a query string variable | ||||
| // A URL with a query parameter can look like this (But will most probably get logged on the http server): | ||||
| // https://www.example.com?myqueryparam=myvalue | ||||
| // | ||||
| // For privacy (Using a hastag #, the parameters will not be sent to the server) | ||||
| // the url can be requested in the following way: | ||||
| // https://www.example.com#myqueryparam=myvalue&password=secreatvalue | ||||
| // | ||||
| // Even Mixing public and non public parameters will work: | ||||
| // https://www.example.com?nonsecretparam=example.com#password=secreatvalue | ||||
| export function getQueryVar(name, defVal) { | ||||
|     "use strict"; | ||||
|     const re = new RegExp('.*[?&]' + name + '=([^&#]*)'), | ||||
|         match = ''.concat(document.location.href, window.location.hash).match(re); | ||||
|     if (typeof defVal === 'undefined') { defVal = null; } | ||||
|  | ||||
|     if (match) { | ||||
|         return decodeURIComponent(match[1]); | ||||
|     } | ||||
|  | ||||
|     return defVal; | ||||
| } | ||||
|  | ||||
| // Read a hash fragment variable | ||||
| export function getHashVar(name, defVal) { | ||||
|     "use strict"; | ||||
|     const re = new RegExp('.*[&#]' + name + '=([^&]*)'), | ||||
|         match = document.location.hash.match(re); | ||||
|     if (typeof defVal === 'undefined') { defVal = null; } | ||||
|  | ||||
|     if (match) { | ||||
|         return decodeURIComponent(match[1]); | ||||
|     } | ||||
|  | ||||
|     return defVal; | ||||
| } | ||||
|  | ||||
| // Read a variable from the fragment or the query string | ||||
| // Fragment takes precedence | ||||
| export function getConfigVar(name, defVal) { | ||||
|     "use strict"; | ||||
|     const val = getHashVar(name); | ||||
|  | ||||
|     if (val === null) { | ||||
|         return getQueryVar(name, defVal); | ||||
|     } | ||||
|  | ||||
|     return val; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html | ||||
|  */ | ||||
|  | ||||
| // No days means only for this browser session | ||||
| export function createCookie(name, value, days) { | ||||
|     "use strict"; | ||||
|     let date, expires; | ||||
|     if (days) { | ||||
|         date = new Date(); | ||||
|         date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); | ||||
|         expires = "; expires=" + date.toGMTString(); | ||||
|     } else { | ||||
|         expires = ""; | ||||
|     } | ||||
|  | ||||
|     let secure; | ||||
|     if (document.location.protocol === "https:") { | ||||
|         secure = "; secure"; | ||||
|     } else { | ||||
|         secure = ""; | ||||
|     } | ||||
|     document.cookie = name + "=" + value + expires + "; path=/" + secure; | ||||
| } | ||||
|  | ||||
| export function readCookie(name, defaultValue) { | ||||
|     "use strict"; | ||||
|     const nameEQ = name + "="; | ||||
|     const ca = document.cookie.split(';'); | ||||
|  | ||||
|     for (let i = 0; i < ca.length; i += 1) { | ||||
|         let c = ca[i]; | ||||
|         while (c.charAt(0) === ' ') { | ||||
|             c = c.substring(1, c.length); | ||||
|         } | ||||
|         if (c.indexOf(nameEQ) === 0) { | ||||
|             return c.substring(nameEQ.length, c.length); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return (typeof defaultValue !== 'undefined') ? defaultValue : null; | ||||
| } | ||||
|  | ||||
| export function eraseCookie(name) { | ||||
|     "use strict"; | ||||
|     createCookie(name, "", -1); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Setting handling. | ||||
|  */ | ||||
|  | ||||
| let settings = {}; | ||||
|  | ||||
| export function initSettings() { | ||||
|     if (!window.chrome || !window.chrome.storage) { | ||||
|         settings = {}; | ||||
|         return Promise.resolve(); | ||||
|     } | ||||
|  | ||||
|     return new Promise(resolve => window.chrome.storage.sync.get(resolve)) | ||||
|         .then((cfg) => { settings = cfg; }); | ||||
| } | ||||
|  | ||||
| // Update the settings cache, but do not write to permanent storage | ||||
| export function setSetting(name, value) { | ||||
|     settings[name] = value; | ||||
| } | ||||
|  | ||||
| // No days means only for this browser session | ||||
| export function writeSetting(name, value) { | ||||
|     "use strict"; | ||||
|     if (settings[name] === value) return; | ||||
|     settings[name] = value; | ||||
|     if (window.chrome && window.chrome.storage) { | ||||
|         window.chrome.storage.sync.set(settings); | ||||
|     } else { | ||||
|         localStorage.setItem(name, value); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export function readSetting(name, defaultValue) { | ||||
|     "use strict"; | ||||
|     let value; | ||||
|     if ((name in settings) || (window.chrome && window.chrome.storage)) { | ||||
|         value = settings[name]; | ||||
|     } else { | ||||
|         value = localStorage.getItem(name); | ||||
|         settings[name] = value; | ||||
|     } | ||||
|     if (typeof value === "undefined") { | ||||
|         value = null; | ||||
|     } | ||||
|  | ||||
|     if (value === null && typeof defaultValue !== "undefined") { | ||||
|         return defaultValue; | ||||
|     } | ||||
|  | ||||
|     return value; | ||||
| } | ||||
|  | ||||
| export function eraseSetting(name) { | ||||
|     "use strict"; | ||||
|     // Deleting here means that next time the setting is read when using local | ||||
|     // storage, it will be pulled from local storage again. | ||||
|     // If the setting in local storage is changed (e.g. in another tab) | ||||
|     // between this delete and the next read, it could lead to an unexpected | ||||
|     // value change. | ||||
|     delete settings[name]; | ||||
|     if (window.chrome && window.chrome.storage) { | ||||
|         window.chrome.storage.sync.remove(name); | ||||
|     } else { | ||||
|         localStorage.removeItem(name); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										104
									
								
								public/novnc/core/base64.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,104 @@ | ||||
| /* This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||||
|  | ||||
| // From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js | ||||
|  | ||||
| import * as Log from './util/logging.js'; | ||||
|  | ||||
| export default { | ||||
|     /* Convert data (an array of integers) to a Base64 string. */ | ||||
|     toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''), | ||||
|     base64Pad: '=', | ||||
|  | ||||
|     encode(data) { | ||||
|         "use strict"; | ||||
|         let result = ''; | ||||
|         const length = data.length; | ||||
|         const lengthpad = (length % 3); | ||||
|         // Convert every three bytes to 4 ascii characters. | ||||
|  | ||||
|         for (let i = 0; i < (length - 2); i += 3) { | ||||
|             result += this.toBase64Table[data[i] >> 2]; | ||||
|             result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)]; | ||||
|             result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)]; | ||||
|             result += this.toBase64Table[data[i + 2] & 0x3f]; | ||||
|         } | ||||
|  | ||||
|         // Convert the remaining 1 or 2 bytes, pad out to 4 characters. | ||||
|         const j = length - lengthpad; | ||||
|         if (lengthpad === 2) { | ||||
|             result += this.toBase64Table[data[j] >> 2]; | ||||
|             result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)]; | ||||
|             result += this.toBase64Table[(data[j + 1] & 0x0f) << 2]; | ||||
|             result += this.toBase64Table[64]; | ||||
|         } else if (lengthpad === 1) { | ||||
|             result += this.toBase64Table[data[j] >> 2]; | ||||
|             result += this.toBase64Table[(data[j] & 0x03) << 4]; | ||||
|             result += this.toBase64Table[64]; | ||||
|             result += this.toBase64Table[64]; | ||||
|         } | ||||
|  | ||||
|         return result; | ||||
|     }, | ||||
|  | ||||
|     /* Convert Base64 data to a string */ | ||||
|     /* eslint-disable comma-spacing */ | ||||
|     toBinaryTable: [ | ||||
|         -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, | ||||
|         -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, | ||||
|         -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, | ||||
|         52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, | ||||
|         -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14, | ||||
|         15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, | ||||
|         -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, | ||||
|         41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 | ||||
|     ], | ||||
|     /* eslint-enable comma-spacing */ | ||||
|  | ||||
|     decode(data, offset = 0) { | ||||
|         let dataLength = data.indexOf('=') - offset; | ||||
|         if (dataLength < 0) { dataLength = data.length - offset; } | ||||
|  | ||||
|         /* Every four characters is 3 resulting numbers */ | ||||
|         const resultLength = (dataLength >> 2) * 3 + Math.floor((dataLength % 4) / 1.5); | ||||
|         const result = new Array(resultLength); | ||||
|  | ||||
|         // Convert one by one. | ||||
|  | ||||
|         let leftbits = 0; // number of bits decoded, but yet to be appended | ||||
|         let leftdata = 0; // bits decoded, but yet to be appended | ||||
|         for (let idx = 0, i = offset; i < data.length; i++) { | ||||
|             const c = this.toBinaryTable[data.charCodeAt(i) & 0x7f]; | ||||
|             const padding = (data.charAt(i) === this.base64Pad); | ||||
|             // Skip illegal characters and whitespace | ||||
|             if (c === -1) { | ||||
|                 Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i); | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // Collect data into leftdata, update bitcount | ||||
|             leftdata = (leftdata << 6) | c; | ||||
|             leftbits += 6; | ||||
|  | ||||
|             // If we have 8 or more bits, append 8 bits to the result | ||||
|             if (leftbits >= 8) { | ||||
|                 leftbits -= 8; | ||||
|                 // Append if not padding. | ||||
|                 if (!padding) { | ||||
|                     result[idx++] = (leftdata >> leftbits) & 0xff; | ||||
|                 } | ||||
|                 leftdata &= (1 << leftbits) - 1; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // If there are any bits left, the base64 string was corrupted | ||||
|         if (leftbits) { | ||||
|             const err = new Error('Corrupted base64 string'); | ||||
|             err.name = 'Base64-Error'; | ||||
|             throw err; | ||||
|         } | ||||
|  | ||||
|         return result; | ||||
|     } | ||||
| }; /* End of Base64 namespace */ | ||||
							
								
								
									
										27
									
								
								public/novnc/core/decoders/copyrect.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,27 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| export default class CopyRectDecoder { | ||||
|     decodeRect(x, y, width, height, sock, display, depth) { | ||||
|         if (sock.rQwait("COPYRECT", 4)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         let deltaX = sock.rQshift16(); | ||||
|         let deltaY = sock.rQshift16(); | ||||
|  | ||||
|         if ((width === 0) || (height === 0)) { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         display.copyImage(deltaX, deltaY, x, y, width, height); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										191
									
								
								public/novnc/core/decoders/hextile.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,191 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| import * as Log from '../util/logging.js'; | ||||
|  | ||||
| export default class HextileDecoder { | ||||
|     constructor() { | ||||
|         this._tiles = 0; | ||||
|         this._lastsubencoding = 0; | ||||
|         this._tileBuffer = new Uint8Array(16 * 16 * 4); | ||||
|     } | ||||
|  | ||||
|     decodeRect(x, y, width, height, sock, display, depth) { | ||||
|         if (this._tiles === 0) { | ||||
|             this._tilesX = Math.ceil(width / 16); | ||||
|             this._tilesY = Math.ceil(height / 16); | ||||
|             this._totalTiles = this._tilesX * this._tilesY; | ||||
|             this._tiles = this._totalTiles; | ||||
|         } | ||||
|  | ||||
|         while (this._tiles > 0) { | ||||
|             let bytes = 1; | ||||
|  | ||||
|             if (sock.rQwait("HEXTILE", bytes)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             let rQ = sock.rQ; | ||||
|             let rQi = sock.rQi; | ||||
|  | ||||
|             let subencoding = rQ[rQi];  // Peek | ||||
|             if (subencoding > 30) {  // Raw | ||||
|                 throw new Error("Illegal hextile subencoding (subencoding: " + | ||||
|                             subencoding + ")"); | ||||
|             } | ||||
|  | ||||
|             const currTile = this._totalTiles - this._tiles; | ||||
|             const tileX = currTile % this._tilesX; | ||||
|             const tileY = Math.floor(currTile / this._tilesX); | ||||
|             const tx = x + tileX * 16; | ||||
|             const ty = y + tileY * 16; | ||||
|             const tw = Math.min(16, (x + width) - tx); | ||||
|             const th = Math.min(16, (y + height) - ty); | ||||
|  | ||||
|             // Figure out how much we are expecting | ||||
|             if (subencoding & 0x01) {  // Raw | ||||
|                 bytes += tw * th * 4; | ||||
|             } else { | ||||
|                 if (subencoding & 0x02) {  // Background | ||||
|                     bytes += 4; | ||||
|                 } | ||||
|                 if (subencoding & 0x04) {  // Foreground | ||||
|                     bytes += 4; | ||||
|                 } | ||||
|                 if (subencoding & 0x08) {  // AnySubrects | ||||
|                     bytes++;  // Since we aren't shifting it off | ||||
|  | ||||
|                     if (sock.rQwait("HEXTILE", bytes)) { | ||||
|                         return false; | ||||
|                     } | ||||
|  | ||||
|                     let subrects = rQ[rQi + bytes - 1];  // Peek | ||||
|                     if (subencoding & 0x10) {  // SubrectsColoured | ||||
|                         bytes += subrects * (4 + 2); | ||||
|                     } else { | ||||
|                         bytes += subrects * 2; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (sock.rQwait("HEXTILE", bytes)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             // We know the encoding and have a whole tile | ||||
|             rQi++; | ||||
|             if (subencoding === 0) { | ||||
|                 if (this._lastsubencoding & 0x01) { | ||||
|                     // Weird: ignore blanks are RAW | ||||
|                     Log.Debug("     Ignoring blank after RAW"); | ||||
|                 } else { | ||||
|                     display.fillRect(tx, ty, tw, th, this._background); | ||||
|                 } | ||||
|             } else if (subencoding & 0x01) {  // Raw | ||||
|                 let pixels = tw * th; | ||||
|                 // Max sure the image is fully opaque | ||||
|                 for (let i = 0;i <  pixels;i++) { | ||||
|                     rQ[rQi + i * 4 + 3] = 255; | ||||
|                 } | ||||
|                 display.blitImage(tx, ty, tw, th, rQ, rQi); | ||||
|                 rQi += bytes - 1; | ||||
|             } else { | ||||
|                 if (subencoding & 0x02) {  // Background | ||||
|                     this._background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | ||||
|                     rQi += 4; | ||||
|                 } | ||||
|                 if (subencoding & 0x04) {  // Foreground | ||||
|                     this._foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | ||||
|                     rQi += 4; | ||||
|                 } | ||||
|  | ||||
|                 this._startTile(tx, ty, tw, th, this._background); | ||||
|                 if (subencoding & 0x08) {  // AnySubrects | ||||
|                     let subrects = rQ[rQi]; | ||||
|                     rQi++; | ||||
|  | ||||
|                     for (let s = 0; s < subrects; s++) { | ||||
|                         let color; | ||||
|                         if (subencoding & 0x10) {  // SubrectsColoured | ||||
|                             color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | ||||
|                             rQi += 4; | ||||
|                         } else { | ||||
|                             color = this._foreground; | ||||
|                         } | ||||
|                         const xy = rQ[rQi]; | ||||
|                         rQi++; | ||||
|                         const sx = (xy >> 4); | ||||
|                         const sy = (xy & 0x0f); | ||||
|  | ||||
|                         const wh = rQ[rQi]; | ||||
|                         rQi++; | ||||
|                         const sw = (wh >> 4) + 1; | ||||
|                         const sh = (wh & 0x0f) + 1; | ||||
|  | ||||
|                         this._subTile(sx, sy, sw, sh, color); | ||||
|                     } | ||||
|                 } | ||||
|                 this._finishTile(display); | ||||
|             } | ||||
|             sock.rQi = rQi; | ||||
|             this._lastsubencoding = subencoding; | ||||
|             this._tiles--; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     // start updating a tile | ||||
|     _startTile(x, y, width, height, color) { | ||||
|         this._tileX = x; | ||||
|         this._tileY = y; | ||||
|         this._tileW = width; | ||||
|         this._tileH = height; | ||||
|  | ||||
|         const red = color[0]; | ||||
|         const green = color[1]; | ||||
|         const blue = color[2]; | ||||
|  | ||||
|         const data = this._tileBuffer; | ||||
|         for (let i = 0; i < width * height * 4; i += 4) { | ||||
|             data[i]     = red; | ||||
|             data[i + 1] = green; | ||||
|             data[i + 2] = blue; | ||||
|             data[i + 3] = 255; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // update sub-rectangle of the current tile | ||||
|     _subTile(x, y, w, h, color) { | ||||
|         const red = color[0]; | ||||
|         const green = color[1]; | ||||
|         const blue = color[2]; | ||||
|         const xend = x + w; | ||||
|         const yend = y + h; | ||||
|  | ||||
|         const data = this._tileBuffer; | ||||
|         const width = this._tileW; | ||||
|         for (let j = y; j < yend; j++) { | ||||
|             for (let i = x; i < xend; i++) { | ||||
|                 const p = (i + (j * width)) * 4; | ||||
|                 data[p]     = red; | ||||
|                 data[p + 1] = green; | ||||
|                 data[p + 2] = blue; | ||||
|                 data[p + 3] = 255; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // draw the current tile to the screen | ||||
|     _finishTile(display) { | ||||
|         display.blitImage(this._tileX, this._tileY, | ||||
|                           this._tileW, this._tileH, | ||||
|                           this._tileBuffer, 0); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										66
									
								
								public/novnc/core/decoders/raw.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,66 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| export default class RawDecoder { | ||||
|     constructor() { | ||||
|         this._lines = 0; | ||||
|     } | ||||
|  | ||||
|     decodeRect(x, y, width, height, sock, display, depth) { | ||||
|         if ((width === 0) || (height === 0)) { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         if (this._lines === 0) { | ||||
|             this._lines = height; | ||||
|         } | ||||
|  | ||||
|         const pixelSize = depth == 8 ? 1 : 4; | ||||
|         const bytesPerLine = width * pixelSize; | ||||
|  | ||||
|         if (sock.rQwait("RAW", bytesPerLine)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         const curY = y + (height - this._lines); | ||||
|         const currHeight = Math.min(this._lines, | ||||
|                                     Math.floor(sock.rQlen / bytesPerLine)); | ||||
|         const pixels = width * currHeight; | ||||
|  | ||||
|         let data = sock.rQ; | ||||
|         let index = sock.rQi; | ||||
|  | ||||
|         // Convert data if needed | ||||
|         if (depth == 8) { | ||||
|             const newdata = new Uint8Array(pixels * 4); | ||||
|             for (let i = 0; i < pixels; i++) { | ||||
|                 newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3; | ||||
|                 newdata[i * 4 + 1] = ((data[index + i] >> 2) & 0x3) * 255 / 3; | ||||
|                 newdata[i * 4 + 2] = ((data[index + i] >> 4) & 0x3) * 255 / 3; | ||||
|                 newdata[i * 4 + 3] = 255; | ||||
|             } | ||||
|             data = newdata; | ||||
|             index = 0; | ||||
|         } | ||||
|  | ||||
|         // Max sure the image is fully opaque | ||||
|         for (let i = 0; i < pixels; i++) { | ||||
|             data[i * 4 + 3] = 255; | ||||
|         } | ||||
|  | ||||
|         display.blitImage(x, curY, width, currHeight, data, index); | ||||
|         sock.rQskipBytes(currHeight * bytesPerLine); | ||||
|         this._lines -= currHeight; | ||||
|         if (this._lines > 0) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										44
									
								
								public/novnc/core/decoders/rre.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,44 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| export default class RREDecoder { | ||||
|     constructor() { | ||||
|         this._subrects = 0; | ||||
|     } | ||||
|  | ||||
|     decodeRect(x, y, width, height, sock, display, depth) { | ||||
|         if (this._subrects === 0) { | ||||
|             if (sock.rQwait("RRE", 4 + 4)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             this._subrects = sock.rQshift32(); | ||||
|  | ||||
|             let color = sock.rQshiftBytes(4);  // Background | ||||
|             display.fillRect(x, y, width, height, color); | ||||
|         } | ||||
|  | ||||
|         while (this._subrects > 0) { | ||||
|             if (sock.rQwait("RRE", 4 + 8)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             let color = sock.rQshiftBytes(4); | ||||
|             let sx = sock.rQshift16(); | ||||
|             let sy = sock.rQshift16(); | ||||
|             let swidth = sock.rQshift16(); | ||||
|             let sheight = sock.rQshift16(); | ||||
|             display.fillRect(x + sx, y + sy, swidth, sheight, color); | ||||
|  | ||||
|             this._subrects--; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										331
									
								
								public/novnc/core/decoders/tight.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,331 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca) | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| import * as Log from '../util/logging.js'; | ||||
| import Inflator from "../inflator.js"; | ||||
|  | ||||
| export default class TightDecoder { | ||||
|     constructor() { | ||||
|         this._ctl = null; | ||||
|         this._filter = null; | ||||
|         this._numColors = 0; | ||||
|         this._palette = new Uint8Array(1024);  // 256 * 4 (max palette size * max bytes-per-pixel) | ||||
|         this._len = 0; | ||||
|  | ||||
|         this._zlibs = []; | ||||
|         for (let i = 0; i < 4; i++) { | ||||
|             this._zlibs[i] = new Inflator(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     decodeRect(x, y, width, height, sock, display, depth) { | ||||
|         if (this._ctl === null) { | ||||
|             if (sock.rQwait("TIGHT compression-control", 1)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             this._ctl = sock.rQshift8(); | ||||
|  | ||||
|             // Reset streams if the server requests it | ||||
|             for (let i = 0; i < 4; i++) { | ||||
|                 if ((this._ctl >> i) & 1) { | ||||
|                     this._zlibs[i].reset(); | ||||
|                     Log.Info("Reset zlib stream " + i); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Figure out filter | ||||
|             this._ctl = this._ctl >> 4; | ||||
|         } | ||||
|  | ||||
|         let ret; | ||||
|  | ||||
|         if (this._ctl === 0x08) { | ||||
|             ret = this._fillRect(x, y, width, height, | ||||
|                                  sock, display, depth); | ||||
|         } else if (this._ctl === 0x09) { | ||||
|             ret = this._jpegRect(x, y, width, height, | ||||
|                                  sock, display, depth); | ||||
|         } else if (this._ctl === 0x0A) { | ||||
|             ret = this._pngRect(x, y, width, height, | ||||
|                                 sock, display, depth); | ||||
|         } else if ((this._ctl & 0x08) == 0) { | ||||
|             ret = this._basicRect(this._ctl, x, y, width, height, | ||||
|                                   sock, display, depth); | ||||
|         } else { | ||||
|             throw new Error("Illegal tight compression received (ctl: " + | ||||
|                                    this._ctl + ")"); | ||||
|         } | ||||
|  | ||||
|         if (ret) { | ||||
|             this._ctl = null; | ||||
|         } | ||||
|  | ||||
|         return ret; | ||||
|     } | ||||
|  | ||||
|     _fillRect(x, y, width, height, sock, display, depth) { | ||||
|         if (sock.rQwait("TIGHT", 3)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         const rQi = sock.rQi; | ||||
|         const rQ = sock.rQ; | ||||
|  | ||||
|         display.fillRect(x, y, width, height, | ||||
|                          [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2]], false); | ||||
|         sock.rQskipBytes(3); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     _jpegRect(x, y, width, height, sock, display, depth) { | ||||
|         let data = this._readData(sock); | ||||
|         if (data === null) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         display.imageRect(x, y, width, height, "image/jpeg", data); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     _pngRect(x, y, width, height, sock, display, depth) { | ||||
|         throw new Error("PNG received in standard Tight rect"); | ||||
|     } | ||||
|  | ||||
|     _basicRect(ctl, x, y, width, height, sock, display, depth) { | ||||
|         if (this._filter === null) { | ||||
|             if (ctl & 0x4) { | ||||
|                 if (sock.rQwait("TIGHT", 1)) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 this._filter = sock.rQshift8(); | ||||
|             } else { | ||||
|                 // Implicit CopyFilter | ||||
|                 this._filter = 0; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         let streamId = ctl & 0x3; | ||||
|  | ||||
|         let ret; | ||||
|  | ||||
|         switch (this._filter) { | ||||
|             case 0: // CopyFilter | ||||
|                 ret = this._copyFilter(streamId, x, y, width, height, | ||||
|                                        sock, display, depth); | ||||
|                 break; | ||||
|             case 1: // PaletteFilter | ||||
|                 ret = this._paletteFilter(streamId, x, y, width, height, | ||||
|                                           sock, display, depth); | ||||
|                 break; | ||||
|             case 2: // GradientFilter | ||||
|                 ret = this._gradientFilter(streamId, x, y, width, height, | ||||
|                                            sock, display, depth); | ||||
|                 break; | ||||
|             default: | ||||
|                 throw new Error("Illegal tight filter received (ctl: " + | ||||
|                                        this._filter + ")"); | ||||
|         } | ||||
|  | ||||
|         if (ret) { | ||||
|             this._filter = null; | ||||
|         } | ||||
|  | ||||
|         return ret; | ||||
|     } | ||||
|  | ||||
|     _copyFilter(streamId, x, y, width, height, sock, display, depth) { | ||||
|         const uncompressedSize = width * height * 3; | ||||
|         let data; | ||||
|  | ||||
|         if (uncompressedSize === 0) { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         if (uncompressedSize < 12) { | ||||
|             if (sock.rQwait("TIGHT", uncompressedSize)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             data = sock.rQshiftBytes(uncompressedSize); | ||||
|         } else { | ||||
|             data = this._readData(sock); | ||||
|             if (data === null) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             this._zlibs[streamId].setInput(data); | ||||
|             data = this._zlibs[streamId].inflate(uncompressedSize); | ||||
|             this._zlibs[streamId].setInput(null); | ||||
|         } | ||||
|  | ||||
|         let rgbx = new Uint8Array(width * height * 4); | ||||
|         for (let i = 0, j = 0; i < width * height * 4; i += 4, j += 3) { | ||||
|             rgbx[i]     = data[j]; | ||||
|             rgbx[i + 1] = data[j + 1]; | ||||
|             rgbx[i + 2] = data[j + 2]; | ||||
|             rgbx[i + 3] = 255;  // Alpha | ||||
|         } | ||||
|  | ||||
|         display.blitImage(x, y, width, height, rgbx, 0, false); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     _paletteFilter(streamId, x, y, width, height, sock, display, depth) { | ||||
|         if (this._numColors === 0) { | ||||
|             if (sock.rQwait("TIGHT palette", 1)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             const numColors = sock.rQpeek8() + 1; | ||||
|             const paletteSize = numColors * 3; | ||||
|  | ||||
|             if (sock.rQwait("TIGHT palette", 1 + paletteSize)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             this._numColors = numColors; | ||||
|             sock.rQskipBytes(1); | ||||
|  | ||||
|             sock.rQshiftTo(this._palette, paletteSize); | ||||
|         } | ||||
|  | ||||
|         const bpp = (this._numColors <= 2) ? 1 : 8; | ||||
|         const rowSize = Math.floor((width * bpp + 7) / 8); | ||||
|         const uncompressedSize = rowSize * height; | ||||
|  | ||||
|         let data; | ||||
|  | ||||
|         if (uncompressedSize === 0) { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         if (uncompressedSize < 12) { | ||||
|             if (sock.rQwait("TIGHT", uncompressedSize)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             data = sock.rQshiftBytes(uncompressedSize); | ||||
|         } else { | ||||
|             data = this._readData(sock); | ||||
|             if (data === null) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             this._zlibs[streamId].setInput(data); | ||||
|             data = this._zlibs[streamId].inflate(uncompressedSize); | ||||
|             this._zlibs[streamId].setInput(null); | ||||
|         } | ||||
|  | ||||
|         // Convert indexed (palette based) image data to RGB | ||||
|         if (this._numColors == 2) { | ||||
|             this._monoRect(x, y, width, height, data, this._palette, display); | ||||
|         } else { | ||||
|             this._paletteRect(x, y, width, height, data, this._palette, display); | ||||
|         } | ||||
|  | ||||
|         this._numColors = 0; | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     _monoRect(x, y, width, height, data, palette, display) { | ||||
|         // Convert indexed (palette based) image data to RGB | ||||
|         // TODO: reduce number of calculations inside loop | ||||
|         const dest = this._getScratchBuffer(width * height * 4); | ||||
|         const w = Math.floor((width + 7) / 8); | ||||
|         const w1 = Math.floor(width / 8); | ||||
|  | ||||
|         for (let y = 0; y < height; y++) { | ||||
|             let dp, sp, x; | ||||
|             for (x = 0; x < w1; x++) { | ||||
|                 for (let 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 (let 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; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         display.blitImage(x, y, width, height, dest, 0, false); | ||||
|     } | ||||
|  | ||||
|     _paletteRect(x, y, width, height, data, palette, display) { | ||||
|         // Convert indexed (palette based) image data to RGB | ||||
|         const dest = this._getScratchBuffer(width * height * 4); | ||||
|         const total = width * height * 4; | ||||
|         for (let i = 0, j = 0; i < total; i += 4, j++) { | ||||
|             const sp = data[j] * 3; | ||||
|             dest[i]     = palette[sp]; | ||||
|             dest[i + 1] = palette[sp + 1]; | ||||
|             dest[i + 2] = palette[sp + 2]; | ||||
|             dest[i + 3] = 255; | ||||
|         } | ||||
|  | ||||
|         display.blitImage(x, y, width, height, dest, 0, false); | ||||
|     } | ||||
|  | ||||
|     _gradientFilter(streamId, x, y, width, height, sock, display, depth) { | ||||
|         throw new Error("Gradient filter not implemented"); | ||||
|     } | ||||
|  | ||||
|     _readData(sock) { | ||||
|         if (this._len === 0) { | ||||
|             if (sock.rQwait("TIGHT", 3)) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             let byte; | ||||
|  | ||||
|             byte = sock.rQshift8(); | ||||
|             this._len = byte & 0x7f; | ||||
|             if (byte & 0x80) { | ||||
|                 byte = sock.rQshift8(); | ||||
|                 this._len |= (byte & 0x7f) << 7; | ||||
|                 if (byte & 0x80) { | ||||
|                     byte = sock.rQshift8(); | ||||
|                     this._len |= byte << 14; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (sock.rQwait("TIGHT", this._len)) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         let data = sock.rQshiftBytes(this._len); | ||||
|         this._len = 0; | ||||
|  | ||||
|         return data; | ||||
|     } | ||||
|  | ||||
|     _getScratchBuffer(size) { | ||||
|         if (!this._scratchBuffer || (this._scratchBuffer.length < size)) { | ||||
|             this._scratchBuffer = new Uint8Array(size); | ||||
|         } | ||||
|         return this._scratchBuffer; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										27
									
								
								public/novnc/core/decoders/tightpng.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,27 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| import TightDecoder from './tight.js'; | ||||
|  | ||||
| export default class TightPNGDecoder extends TightDecoder { | ||||
|     _pngRect(x, y, width, height, sock, display, depth) { | ||||
|         let data = this._readData(sock); | ||||
|         if (data === null) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         display.imageRect(x, y, width, height, "image/png", data); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     _basicRect(ctl, x, y, width, height, sock, display, depth) { | ||||
|         throw new Error("BasicCompression received in TightPNG rect"); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										85
									
								
								public/novnc/core/deflator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,85 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2020 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| import { deflateInit, deflate } from "../vendor/pako/lib/zlib/deflate.js"; | ||||
| import { Z_FULL_FLUSH } from "../vendor/pako/lib/zlib/deflate.js"; | ||||
| import ZStream from "../vendor/pako/lib/zlib/zstream.js"; | ||||
|  | ||||
| export default class Deflator { | ||||
|     constructor() { | ||||
|         this.strm = new ZStream(); | ||||
|         this.chunkSize = 1024 * 10 * 10; | ||||
|         this.outputBuffer = new Uint8Array(this.chunkSize); | ||||
|         this.windowBits = 5; | ||||
|  | ||||
|         deflateInit(this.strm, this.windowBits); | ||||
|     } | ||||
|  | ||||
|     deflate(inData) { | ||||
|         /* eslint-disable camelcase */ | ||||
|         this.strm.input = inData; | ||||
|         this.strm.avail_in = this.strm.input.length; | ||||
|         this.strm.next_in = 0; | ||||
|         this.strm.output = this.outputBuffer; | ||||
|         this.strm.avail_out = this.chunkSize; | ||||
|         this.strm.next_out = 0; | ||||
|         /* eslint-enable camelcase */ | ||||
|  | ||||
|         let lastRet = deflate(this.strm, Z_FULL_FLUSH); | ||||
|         let outData = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); | ||||
|  | ||||
|         if (lastRet < 0) { | ||||
|             throw new Error("zlib deflate failed"); | ||||
|         } | ||||
|  | ||||
|         if (this.strm.avail_in > 0) { | ||||
|             // Read chunks until done | ||||
|  | ||||
|             let chunks = [outData]; | ||||
|             let totalLen = outData.length; | ||||
|             do { | ||||
|                 /* eslint-disable camelcase */ | ||||
|                 this.strm.output = new Uint8Array(this.chunkSize); | ||||
|                 this.strm.next_out = 0; | ||||
|                 this.strm.avail_out = this.chunkSize; | ||||
|                 /* eslint-enable camelcase */ | ||||
|  | ||||
|                 lastRet = deflate(this.strm, Z_FULL_FLUSH); | ||||
|  | ||||
|                 if (lastRet < 0) { | ||||
|                     throw new Error("zlib deflate failed"); | ||||
|                 } | ||||
|  | ||||
|                 let chunk = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); | ||||
|                 totalLen += chunk.length; | ||||
|                 chunks.push(chunk); | ||||
|             } while (this.strm.avail_in > 0); | ||||
|  | ||||
|             // Combine chunks into a single data | ||||
|  | ||||
|             let newData = new Uint8Array(totalLen); | ||||
|             let offset = 0; | ||||
|  | ||||
|             for (let i = 0; i < chunks.length; i++) { | ||||
|                 newData.set(chunks[i], offset); | ||||
|                 offset += chunks[i].length; | ||||
|             } | ||||
|  | ||||
|             outData = newData; | ||||
|         } | ||||
|  | ||||
|         /* eslint-disable camelcase */ | ||||
|         this.strm.input = null; | ||||
|         this.strm.avail_in = 0; | ||||
|         this.strm.next_in = 0; | ||||
|         /* eslint-enable camelcase */ | ||||
|  | ||||
|         return outData; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										266
									
								
								public/novnc/core/des.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,266 @@ | ||||
| /* | ||||
|  * Ported from Flashlight VNC ActionScript implementation: | ||||
|  *     http://www.wizhelp.com/flashlight-vnc/ | ||||
|  * | ||||
|  * Full attribution follows: | ||||
|  * | ||||
|  * ------------------------------------------------------------------------- | ||||
|  * | ||||
|  * This DES class has been extracted from package Acme.Crypto for use in VNC. | ||||
|  * The unnecessary odd parity code has been removed. | ||||
|  * | ||||
|  * These changes are: | ||||
|  *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved. | ||||
|  * | ||||
|  * This software is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  * | ||||
|  | ||||
|  * DesCipher - the DES encryption method | ||||
|  * | ||||
|  * The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is: | ||||
|  * | ||||
|  * Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * 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 | ||||
|  * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE | ||||
|  * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE | ||||
|  * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE | ||||
|  * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  WIDGET WORKSHOP | ||||
|  * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR | ||||
|  * HIGH RISK ACTIVITIES. | ||||
|  * | ||||
|  * | ||||
|  * The rest is: | ||||
|  * | ||||
|  * Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>.  All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  * | ||||
|  * Visit the ACME Labs Java page for up-to-date versions of this and other | ||||
|  * fine Java utilities: http://www.acme.com/java/ | ||||
|  */ | ||||
|  | ||||
| /* eslint-disable comma-spacing */ | ||||
|  | ||||
| // Tables, permutations, S-boxes, etc. | ||||
| const PC2 = [13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3, | ||||
|              25, 7,15, 6,26,19,12, 1,40,51,30,36,46,54,29,39, | ||||
|              50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31 ], | ||||
|     totrot = [ 1, 2, 4, 6, 8,10,12,14,15,17,19,21,23,25,27,28]; | ||||
|  | ||||
| const z = 0x0; | ||||
| let a,b,c,d,e,f; | ||||
| a=1<<16; b=1<<24; c=a|b; d=1<<2; e=1<<10; f=d|e; | ||||
| const SP1 = [c|e,z|z,a|z,c|f,c|d,a|f,z|d,a|z,z|e,c|e,c|f,z|e,b|f,c|d,b|z,z|d, | ||||
|              z|f,b|e,b|e,a|e,a|e,c|z,c|z,b|f,a|d,b|d,b|d,a|d,z|z,z|f,a|f,b|z, | ||||
|              a|z,c|f,z|d,c|z,c|e,b|z,b|z,z|e,c|d,a|z,a|e,b|d,z|e,z|d,b|f,a|f, | ||||
|              c|f,a|d,c|z,b|f,b|d,z|f,a|f,c|e,z|f,b|e,b|e,z|z,a|d,a|e,z|z,c|d]; | ||||
| a=1<<20; b=1<<31; c=a|b; d=1<<5; e=1<<15; f=d|e; | ||||
| const SP2 = [c|f,b|e,z|e,a|f,a|z,z|d,c|d,b|f,b|d,c|f,c|e,b|z,b|e,a|z,z|d,c|d, | ||||
|              a|e,a|d,b|f,z|z,b|z,z|e,a|f,c|z,a|d,b|d,z|z,a|e,z|f,c|e,c|z,z|f, | ||||
|              z|z,a|f,c|d,a|z,b|f,c|z,c|e,z|e,c|z,b|e,z|d,c|f,a|f,z|d,z|e,b|z, | ||||
|              z|f,c|e,a|z,b|d,a|d,b|f,b|d,a|d,a|e,z|z,b|e,z|f,b|z,c|d,c|f,a|e]; | ||||
| a=1<<17; b=1<<27; c=a|b; d=1<<3; e=1<<9; f=d|e; | ||||
| const SP3 = [z|f,c|e,z|z,c|d,b|e,z|z,a|f,b|e,a|d,b|d,b|d,a|z,c|f,a|d,c|z,z|f, | ||||
|              b|z,z|d,c|e,z|e,a|e,c|z,c|d,a|f,b|f,a|e,a|z,b|f,z|d,c|f,z|e,b|z, | ||||
|              c|e,b|z,a|d,z|f,a|z,c|e,b|e,z|z,z|e,a|d,c|f,b|e,b|d,z|e,z|z,c|d, | ||||
|              b|f,a|z,b|z,c|f,z|d,a|f,a|e,b|d,c|z,b|f,z|f,c|z,a|f,z|d,c|d,a|e]; | ||||
| a=1<<13; b=1<<23; c=a|b; d=1<<0; e=1<<7; f=d|e; | ||||
| const SP4 = [c|d,a|f,a|f,z|e,c|e,b|f,b|d,a|d,z|z,c|z,c|z,c|f,z|f,z|z,b|e,b|d, | ||||
|              z|d,a|z,b|z,c|d,z|e,b|z,a|d,a|e,b|f,z|d,a|e,b|e,a|z,c|e,c|f,z|f, | ||||
|              b|e,b|d,c|z,c|f,z|f,z|z,z|z,c|z,a|e,b|e,b|f,z|d,c|d,a|f,a|f,z|e, | ||||
|              c|f,z|f,z|d,a|z,b|d,a|d,c|e,b|f,a|d,a|e,b|z,c|d,z|e,b|z,a|z,c|e]; | ||||
| a=1<<25; b=1<<30; c=a|b; d=1<<8; e=1<<19; f=d|e; | ||||
| const SP5 = [z|d,a|f,a|e,c|d,z|e,z|d,b|z,a|e,b|f,z|e,a|d,b|f,c|d,c|e,z|f,b|z, | ||||
|              a|z,b|e,b|e,z|z,b|d,c|f,c|f,a|d,c|e,b|d,z|z,c|z,a|f,a|z,c|z,z|f, | ||||
|              z|e,c|d,z|d,a|z,b|z,a|e,c|d,b|f,a|d,b|z,c|e,a|f,b|f,z|d,a|z,c|e, | ||||
|              c|f,z|f,c|z,c|f,a|e,z|z,b|e,c|z,z|f,a|d,b|d,z|e,z|z,b|e,a|f,b|d]; | ||||
| a=1<<22; b=1<<29; c=a|b; d=1<<4; e=1<<14; f=d|e; | ||||
| const SP6 = [b|d,c|z,z|e,c|f,c|z,z|d,c|f,a|z,b|e,a|f,a|z,b|d,a|d,b|e,b|z,z|f, | ||||
|              z|z,a|d,b|f,z|e,a|e,b|f,z|d,c|d,c|d,z|z,a|f,c|e,z|f,a|e,c|e,b|z, | ||||
|              b|e,z|d,c|d,a|e,c|f,a|z,z|f,b|d,a|z,b|e,b|z,z|f,b|d,c|f,a|e,c|z, | ||||
|              a|f,c|e,z|z,c|d,z|d,z|e,c|z,a|f,z|e,a|d,b|f,z|z,c|e,b|z,a|d,b|f]; | ||||
| a=1<<21; b=1<<26; c=a|b; d=1<<1; e=1<<11; f=d|e; | ||||
| const SP7 = [a|z,c|d,b|f,z|z,z|e,b|f,a|f,c|e,c|f,a|z,z|z,b|d,z|d,b|z,c|d,z|f, | ||||
|              b|e,a|f,a|d,b|e,b|d,c|z,c|e,a|d,c|z,z|e,z|f,c|f,a|e,z|d,b|z,a|e, | ||||
|              b|z,a|e,a|z,b|f,b|f,c|d,c|d,z|d,a|d,b|z,b|e,a|z,c|e,z|f,a|f,c|e, | ||||
|              z|f,b|d,c|f,c|z,a|e,z|z,z|d,c|f,z|z,a|f,c|z,z|e,b|d,b|e,z|e,a|d]; | ||||
| a=1<<18; b=1<<28; c=a|b; d=1<<6; e=1<<12; f=d|e; | ||||
| const SP8 = [b|f,z|e,a|z,c|f,b|z,b|f,z|d,b|z,a|d,c|z,c|f,a|e,c|e,a|f,z|e,z|d, | ||||
|              c|z,b|d,b|e,z|f,a|e,a|d,c|d,c|e,z|f,z|z,z|z,c|d,b|d,b|e,a|f,a|z, | ||||
|              a|f,a|z,c|e,z|e,z|d,c|d,z|e,a|f,b|e,z|d,b|d,c|z,c|d,b|z,a|z,b|f, | ||||
|              z|z,c|f,a|d,b|d,c|z,b|e,b|f,z|z,c|f,a|e,a|e,z|f,z|f,a|d,b|z,c|e]; | ||||
|  | ||||
| /* eslint-enable comma-spacing */ | ||||
|  | ||||
| export default class DES { | ||||
|     constructor(password) { | ||||
|         this.keys = []; | ||||
|  | ||||
|         // Set the key. | ||||
|         const pc1m = [], pcr = [], kn = []; | ||||
|  | ||||
|         for (let j = 0, l = 56; j < 56; ++j, l -= 8) { | ||||
|             l += l < -5 ? 65 : l < -3 ? 31 : l < -1 ? 63 : l === 27 ? 35 : 0; // PC1 | ||||
|             const m = l & 0x7; | ||||
|             pc1m[j] = ((password[l >>> 3] & (1<<m)) !== 0) ? 1: 0; | ||||
|         } | ||||
|  | ||||
|         for (let i = 0; i < 16; ++i) { | ||||
|             const m = i << 1; | ||||
|             const n = m + 1; | ||||
|             kn[m] = kn[n] = 0; | ||||
|             for (let o = 28; o < 59; o += 28) { | ||||
|                 for (let j = o - 28; j < o; ++j) { | ||||
|                     const l = j + totrot[i]; | ||||
|                     pcr[j] = l < o ? pc1m[l] : pc1m[l - 28]; | ||||
|                 } | ||||
|             } | ||||
|             for (let j = 0; j < 24; ++j) { | ||||
|                 if (pcr[PC2[j]] !== 0) { | ||||
|                     kn[m] |= 1 << (23 - j); | ||||
|                 } | ||||
|                 if (pcr[PC2[j + 24]] !== 0) { | ||||
|                     kn[n] |= 1 << (23 - j); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // cookey | ||||
|         for (let i = 0, rawi = 0, KnLi = 0; i < 16; ++i) { | ||||
|             const raw0 = kn[rawi++]; | ||||
|             const raw1 = kn[rawi++]; | ||||
|             this.keys[KnLi] = (raw0 & 0x00fc0000) << 6; | ||||
|             this.keys[KnLi] |= (raw0 & 0x00000fc0) << 10; | ||||
|             this.keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10; | ||||
|             this.keys[KnLi] |= (raw1 & 0x00000fc0) >>> 6; | ||||
|             ++KnLi; | ||||
|             this.keys[KnLi] = (raw0 & 0x0003f000) << 12; | ||||
|             this.keys[KnLi] |= (raw0 & 0x0000003f) << 16; | ||||
|             this.keys[KnLi] |= (raw1 & 0x0003f000) >>> 4; | ||||
|             this.keys[KnLi] |= (raw1 & 0x0000003f); | ||||
|             ++KnLi; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Encrypt 8 bytes of text | ||||
|     enc8(text) { | ||||
|         const b = text.slice(); | ||||
|         let i = 0, l, r, x; // left, right, accumulator | ||||
|  | ||||
|         // Squash 8 bytes to 2 ints | ||||
|         l = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++]; | ||||
|         r = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++]; | ||||
|  | ||||
|         x = ((l >>> 4) ^ r) & 0x0f0f0f0f; | ||||
|         r ^= x; | ||||
|         l ^= (x << 4); | ||||
|         x = ((l >>> 16) ^ r) & 0x0000ffff; | ||||
|         r ^= x; | ||||
|         l ^= (x << 16); | ||||
|         x = ((r >>> 2) ^ l) & 0x33333333; | ||||
|         l ^= x; | ||||
|         r ^= (x << 2); | ||||
|         x = ((r >>> 8) ^ l) & 0x00ff00ff; | ||||
|         l ^= x; | ||||
|         r ^= (x << 8); | ||||
|         r = (r << 1) | ((r >>> 31) & 1); | ||||
|         x = (l ^ r) & 0xaaaaaaaa; | ||||
|         l ^= x; | ||||
|         r ^= x; | ||||
|         l = (l << 1) | ((l >>> 31) & 1); | ||||
|  | ||||
|         for (let i = 0, keysi = 0; i < 8; ++i) { | ||||
|             x = (r << 28) | (r >>> 4); | ||||
|             x ^= this.keys[keysi++]; | ||||
|             let fval =  SP7[x & 0x3f]; | ||||
|             fval |= SP5[(x >>> 8) & 0x3f]; | ||||
|             fval |= SP3[(x >>> 16) & 0x3f]; | ||||
|             fval |= SP1[(x >>> 24) & 0x3f]; | ||||
|             x = r ^ this.keys[keysi++]; | ||||
|             fval |= SP8[x & 0x3f]; | ||||
|             fval |= SP6[(x >>> 8) & 0x3f]; | ||||
|             fval |= SP4[(x >>> 16) & 0x3f]; | ||||
|             fval |= SP2[(x >>> 24) & 0x3f]; | ||||
|             l ^= fval; | ||||
|             x = (l << 28) | (l >>> 4); | ||||
|             x ^= this.keys[keysi++]; | ||||
|             fval =  SP7[x & 0x3f]; | ||||
|             fval |= SP5[(x >>> 8) & 0x3f]; | ||||
|             fval |= SP3[(x >>> 16) & 0x3f]; | ||||
|             fval |= SP1[(x >>> 24) & 0x3f]; | ||||
|             x = l ^ this.keys[keysi++]; | ||||
|             fval |= SP8[x & 0x0000003f]; | ||||
|             fval |= SP6[(x >>> 8) & 0x3f]; | ||||
|             fval |= SP4[(x >>> 16) & 0x3f]; | ||||
|             fval |= SP2[(x >>> 24) & 0x3f]; | ||||
|             r ^= fval; | ||||
|         } | ||||
|  | ||||
|         r = (r << 31) | (r >>> 1); | ||||
|         x = (l ^ r) & 0xaaaaaaaa; | ||||
|         l ^= x; | ||||
|         r ^= x; | ||||
|         l = (l << 31) | (l >>> 1); | ||||
|         x = ((l >>> 8) ^ r) & 0x00ff00ff; | ||||
|         r ^= x; | ||||
|         l ^= (x << 8); | ||||
|         x = ((l >>> 2) ^ r) & 0x33333333; | ||||
|         r ^= x; | ||||
|         l ^= (x << 2); | ||||
|         x = ((r >>> 16) ^ l) & 0x0000ffff; | ||||
|         l ^= x; | ||||
|         r ^= (x << 16); | ||||
|         x = ((r >>> 4) ^ l) & 0x0f0f0f0f; | ||||
|         l ^= x; | ||||
|         r ^= (x << 4); | ||||
|  | ||||
|         // Spread ints to bytes | ||||
|         x = [r, l]; | ||||
|         for (i = 0; i < 8; i++) { | ||||
|             b[i] = (x[i>>>2] >>> (8 * (3 - (i % 4)))) % 256; | ||||
|             if (b[i] < 0) { b[i] += 256; } // unsigned | ||||
|         } | ||||
|         return b; | ||||
|     } | ||||
|  | ||||
|     // Encrypt 16 bytes of text using passwd as key | ||||
|     encrypt(t) { | ||||
|         return this.enc8(t.slice(0, 8)).concat(this.enc8(t.slice(8, 16))); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										513
									
								
								public/novnc/core/display.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,513 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| import * as Log from './util/logging.js'; | ||||
| import Base64 from "./base64.js"; | ||||
| import { toSigned32bit } from './util/int.js'; | ||||
|  | ||||
| export default class Display { | ||||
|     constructor(target) { | ||||
|         this._drawCtx = null; | ||||
|  | ||||
|         this._renderQ = [];  // queue drawing actions for in-oder rendering | ||||
|         this._flushing = false; | ||||
|  | ||||
|         // the full frame buffer (logical canvas) size | ||||
|         this._fbWidth = 0; | ||||
|         this._fbHeight = 0; | ||||
|  | ||||
|         this._prevDrawStyle = ""; | ||||
|  | ||||
|         Log.Debug(">> Display.constructor"); | ||||
|  | ||||
|         // The visible canvas | ||||
|         this._target = target; | ||||
|  | ||||
|         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 }; | ||||
|  | ||||
|         Log.Debug("User Agent: " + navigator.userAgent); | ||||
|  | ||||
|         Log.Debug("<< Display.constructor"); | ||||
|  | ||||
|         // ===== PROPERTIES ===== | ||||
|  | ||||
|         this._scale = 1.0; | ||||
|         this._clipViewport = false; | ||||
|  | ||||
|         // ===== EVENT HANDLERS ===== | ||||
|  | ||||
|         this.onflush = () => {}; // A flush request has finished | ||||
|     } | ||||
|  | ||||
|     // ===== PROPERTIES ===== | ||||
|  | ||||
|     get scale() { return this._scale; } | ||||
|     set scale(scale) { | ||||
|         this._rescale(scale); | ||||
|     } | ||||
|  | ||||
|     get clipViewport() { return this._clipViewport; } | ||||
|     set clipViewport(viewport) { | ||||
|         this._clipViewport = viewport; | ||||
|         // May need to readjust the viewport dimensions | ||||
|         const vp = this._viewportLoc; | ||||
|         this.viewportChangeSize(vp.w, vp.h); | ||||
|         this.viewportChangePos(0, 0); | ||||
|     } | ||||
|  | ||||
|     get width() { | ||||
|         return this._fbWidth; | ||||
|     } | ||||
|  | ||||
|     get height() { | ||||
|         return this._fbHeight; | ||||
|     } | ||||
|  | ||||
|     // ===== PUBLIC METHODS ===== | ||||
|  | ||||
|     viewportChangePos(deltaX, deltaY) { | ||||
|         const vp = this._viewportLoc; | ||||
|         deltaX = Math.floor(deltaX); | ||||
|         deltaY = Math.floor(deltaY); | ||||
|  | ||||
|         if (!this._clipViewport) { | ||||
|             deltaX = -vp.w;  // clamped later of out of bounds | ||||
|             deltaY = -vp.h; | ||||
|         } | ||||
|  | ||||
|         const vx2 = vp.x + vp.w - 1; | ||||
|         const vy2 = vp.y + vp.h - 1; | ||||
|  | ||||
|         // Position change | ||||
|  | ||||
|         if (deltaX < 0 && vp.x + deltaX < 0) { | ||||
|             deltaX = -vp.x; | ||||
|         } | ||||
|         if (vx2 + deltaX >= this._fbWidth) { | ||||
|             deltaX -= vx2 + deltaX - this._fbWidth + 1; | ||||
|         } | ||||
|  | ||||
|         if (vp.y + deltaY < 0) { | ||||
|             deltaY = -vp.y; | ||||
|         } | ||||
|         if (vy2 + deltaY >= this._fbHeight) { | ||||
|             deltaY -= (vy2 + deltaY - this._fbHeight + 1); | ||||
|         } | ||||
|  | ||||
|         if (deltaX === 0 && deltaY === 0) { | ||||
|             return; | ||||
|         } | ||||
|         Log.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(width, height) { | ||||
|  | ||||
|         if (!this._clipViewport || | ||||
|             typeof(width) === "undefined" || | ||||
|             typeof(height) === "undefined") { | ||||
|  | ||||
|             Log.Debug("Setting viewport to full display region"); | ||||
|             width = this._fbWidth; | ||||
|             height = this._fbHeight; | ||||
|         } | ||||
|  | ||||
|         width = Math.floor(width); | ||||
|         height = Math.floor(height); | ||||
|  | ||||
|         if (width > this._fbWidth) { | ||||
|             width = this._fbWidth; | ||||
|         } | ||||
|         if (height > this._fbHeight) { | ||||
|             height = this._fbHeight; | ||||
|         } | ||||
|  | ||||
|         const vp = this._viewportLoc; | ||||
|         if (vp.w !== width || vp.h !== height) { | ||||
|             vp.w = width; | ||||
|             vp.h = height; | ||||
|  | ||||
|             const 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(x) { | ||||
|         if (this._scale === 0) { | ||||
|             return 0; | ||||
|         } | ||||
|         return toSigned32bit(x / this._scale + this._viewportLoc.x); | ||||
|     } | ||||
|  | ||||
|     absY(y) { | ||||
|         if (this._scale === 0) { | ||||
|             return 0; | ||||
|         } | ||||
|         return toSigned32bit(y / this._scale + this._viewportLoc.y); | ||||
|     } | ||||
|  | ||||
|     resize(width, height) { | ||||
|         this._prevDrawStyle = ""; | ||||
|  | ||||
|         this._fbWidth = width; | ||||
|         this._fbHeight = height; | ||||
|  | ||||
|         const canvas = this._backbuffer; | ||||
|         if (canvas.width !== width || canvas.height !== height) { | ||||
|  | ||||
|             // We have to save the canvas data since changing the size will clear it | ||||
|             let 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 | ||||
|         const vp = this._viewportLoc; | ||||
|         this.viewportChangeSize(vp.w, vp.h); | ||||
|         this.viewportChangePos(0, 0); | ||||
|     } | ||||
|  | ||||
|     // Track what parts of the visible canvas that need updating | ||||
|     _damage(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(fromQueue) { | ||||
|         if (this._renderQ.length !== 0 && !fromQueue) { | ||||
|             this._renderQPush({ | ||||
|                 'type': 'flip' | ||||
|             }); | ||||
|         } else { | ||||
|             let x = this._damageBounds.left; | ||||
|             let y = this._damageBounds.top; | ||||
|             let w = this._damageBounds.right - x; | ||||
|             let h = this._damageBounds.bottom - y; | ||||
|  | ||||
|             let vx = x - this._viewportLoc.x; | ||||
|             let 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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pending() { | ||||
|         return this._renderQ.length > 0; | ||||
|     } | ||||
|  | ||||
|     flush() { | ||||
|         if (this._renderQ.length === 0) { | ||||
|             this.onflush(); | ||||
|         } else { | ||||
|             this._flushing = true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fillRect(x, y, width, height, color, fromQueue) { | ||||
|         if (this._renderQ.length !== 0 && !fromQueue) { | ||||
|             this._renderQPush({ | ||||
|                 '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(oldX, oldY, newX, newY, w, h, fromQueue) { | ||||
|         if (this._renderQ.length !== 0 && !fromQueue) { | ||||
|             this._renderQPush({ | ||||
|                 'type': 'copy', | ||||
|                 'oldX': oldX, | ||||
|                 'oldY': oldY, | ||||
|                 'x': newX, | ||||
|                 'y': newY, | ||||
|                 '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, | ||||
|                                     oldX, oldY, w, h, | ||||
|                                     newX, newY, w, h); | ||||
|             this._damage(newX, newY, w, h); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     imageRect(x, y, width, height, mime, arr) { | ||||
|         /* The internal logic cannot handle empty images, so bail early */ | ||||
|         if ((width === 0) || (height === 0)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         const img = new Image(); | ||||
|         img.src = "data: " + mime + ";base64," + Base64.encode(arr); | ||||
|  | ||||
|         this._renderQPush({ | ||||
|             'type': 'img', | ||||
|             'img': img, | ||||
|             'x': x, | ||||
|             'y': y, | ||||
|             'width': width, | ||||
|             'height': height | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     blitImage(x, y, width, height, arr, offset, fromQueue) { | ||||
|         if (this._renderQ.length !== 0 && !fromQueue) { | ||||
|             // 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 | ||||
|             const newArr = new Uint8Array(width * height * 4); | ||||
|             newArr.set(new Uint8Array(arr.buffer, 0, newArr.length)); | ||||
|             this._renderQPush({ | ||||
|                 'type': 'blit', | ||||
|                 'data': newArr, | ||||
|                 'x': x, | ||||
|                 'y': y, | ||||
|                 'width': width, | ||||
|                 'height': height, | ||||
|             }); | ||||
|         } else { | ||||
|             // NB(directxman12): arr must be an Type Array view | ||||
|             let data = new Uint8ClampedArray(arr.buffer, | ||||
|                                              arr.byteOffset + offset, | ||||
|                                              width * height * 4); | ||||
|             let img = new ImageData(data, width, height); | ||||
|             this._drawCtx.putImageData(img, x, y); | ||||
|             this._damage(x, y, width, height); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     drawImage(img, x, y) { | ||||
|         this._drawCtx.drawImage(img, x, y); | ||||
|         this._damage(x, y, img.width, img.height); | ||||
|     } | ||||
|  | ||||
|     autoscale(containerWidth, containerHeight) { | ||||
|         let scaleRatio; | ||||
|  | ||||
|         if (containerWidth === 0 || containerHeight === 0) { | ||||
|             scaleRatio = 0; | ||||
|  | ||||
|         } else { | ||||
|  | ||||
|             const vp = this._viewportLoc; | ||||
|             const targetAspectRatio = containerWidth / containerHeight; | ||||
|             const fbAspectRatio = vp.w / vp.h; | ||||
|  | ||||
|             if (fbAspectRatio >= targetAspectRatio) { | ||||
|                 scaleRatio = containerWidth / vp.w; | ||||
|             } else { | ||||
|                 scaleRatio = containerHeight / vp.h; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this._rescale(scaleRatio); | ||||
|     } | ||||
|  | ||||
|     // ===== PRIVATE METHODS ===== | ||||
|  | ||||
|     _rescale(factor) { | ||||
|         this._scale = factor; | ||||
|         const 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. | ||||
|         const width = factor * vp.w + 'px'; | ||||
|         const height = 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(color) { | ||||
|         const newStyle = 'rgb(' + color[0] + ',' + color[1] + ',' + color[2] + ')'; | ||||
|         if (newStyle !== this._prevDrawStyle) { | ||||
|             this._drawCtx.fillStyle = newStyle; | ||||
|             this._prevDrawStyle = newStyle; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _renderQPush(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._scanRenderQ(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _resumeRenderQ() { | ||||
|         // "this" is the object that is ready, not the | ||||
|         // display object | ||||
|         this.removeEventListener('load', this._noVNCDisplay._resumeRenderQ); | ||||
|         this._noVNCDisplay._scanRenderQ(); | ||||
|     } | ||||
|  | ||||
|     _scanRenderQ() { | ||||
|         let ready = true; | ||||
|         while (ready && this._renderQ.length > 0) { | ||||
|             const a = this._renderQ[0]; | ||||
|             switch (a.type) { | ||||
|                 case 'flip': | ||||
|                     this.flip(true); | ||||
|                     break; | ||||
|                 case 'copy': | ||||
|                     this.copyImage(a.oldX, a.oldY, 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 'img': | ||||
|                     if (a.img.complete) { | ||||
|                         if (a.img.width !== a.width || a.img.height !== a.height) { | ||||
|                             Log.Error("Decoded image has incorrect dimensions. Got " + | ||||
|                                       a.img.width + "x" + a.img.height + ". Expected " + | ||||
|                                       a.width + "x" + a.height + "."); | ||||
|                             return; | ||||
|                         } | ||||
|                         this.drawImage(a.img, a.x, a.y); | ||||
|                     } else { | ||||
|                         a.img._noVNCDisplay = this; | ||||
|                         a.img.addEventListener('load', this._resumeRenderQ); | ||||
|                         // 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(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										44
									
								
								public/novnc/core/encodings.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,44 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| export const encodings = { | ||||
|     encodingRaw: 0, | ||||
|     encodingCopyRect: 1, | ||||
|     encodingRRE: 2, | ||||
|     encodingHextile: 5, | ||||
|     encodingTight: 7, | ||||
|     encodingTightPNG: -260, | ||||
|  | ||||
|     pseudoEncodingQualityLevel9: -23, | ||||
|     pseudoEncodingQualityLevel0: -32, | ||||
|     pseudoEncodingDesktopSize: -223, | ||||
|     pseudoEncodingLastRect: -224, | ||||
|     pseudoEncodingCursor: -239, | ||||
|     pseudoEncodingQEMUExtendedKeyEvent: -258, | ||||
|     pseudoEncodingDesktopName: -307, | ||||
|     pseudoEncodingExtendedDesktopSize: -308, | ||||
|     pseudoEncodingXvp: -309, | ||||
|     pseudoEncodingFence: -312, | ||||
|     pseudoEncodingContinuousUpdates: -313, | ||||
|     pseudoEncodingCompressLevel9: -247, | ||||
|     pseudoEncodingCompressLevel0: -256, | ||||
|     pseudoEncodingVMwareCursor: 0x574d5664, | ||||
|     pseudoEncodingExtendedClipboard: 0xc0a1e5ce | ||||
| }; | ||||
|  | ||||
| export function encodingName(num) { | ||||
|     switch (num) { | ||||
|         case encodings.encodingRaw:      return "Raw"; | ||||
|         case encodings.encodingCopyRect: return "CopyRect"; | ||||
|         case encodings.encodingRRE:      return "RRE"; | ||||
|         case encodings.encodingHextile:  return "Hextile"; | ||||
|         case encodings.encodingTight:    return "Tight"; | ||||
|         case encodings.encodingTightPNG: return "TightPNG"; | ||||
|         default:                         return "[unknown encoding " + num + "]"; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										66
									
								
								public/novnc/core/inflator.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,66 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2020 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| import { inflateInit, inflate, inflateReset } from "../vendor/pako/lib/zlib/inflate.js"; | ||||
| import ZStream from "../vendor/pako/lib/zlib/zstream.js"; | ||||
|  | ||||
| export default class Inflate { | ||||
|     constructor() { | ||||
|         this.strm = new ZStream(); | ||||
|         this.chunkSize = 1024 * 10 * 10; | ||||
|         this.strm.output = new Uint8Array(this.chunkSize); | ||||
|         this.windowBits = 5; | ||||
|  | ||||
|         inflateInit(this.strm, this.windowBits); | ||||
|     } | ||||
|  | ||||
|     setInput(data) { | ||||
|         if (!data) { | ||||
|             //FIXME: flush remaining data. | ||||
|             /* eslint-disable camelcase */ | ||||
|             this.strm.input = null; | ||||
|             this.strm.avail_in = 0; | ||||
|             this.strm.next_in = 0; | ||||
|         } else { | ||||
|             this.strm.input = data; | ||||
|             this.strm.avail_in = this.strm.input.length; | ||||
|             this.strm.next_in = 0; | ||||
|             /* eslint-enable camelcase */ | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     inflate(expected) { | ||||
|         // 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); | ||||
|         } | ||||
|  | ||||
|         /* eslint-disable camelcase */ | ||||
|         this.strm.next_out = 0; | ||||
|         this.strm.avail_out = expected; | ||||
|         /* eslint-enable camelcase */ | ||||
|  | ||||
|         let ret = inflate(this.strm, 0); // Flush argument not used. | ||||
|         if (ret < 0) { | ||||
|             throw new Error("zlib inflate failed"); | ||||
|         } | ||||
|  | ||||
|         if (this.strm.next_out != expected) { | ||||
|             throw new Error("Incomplete zlib block"); | ||||
|         } | ||||
|  | ||||
|         return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); | ||||
|     } | ||||
|  | ||||
|     reset() { | ||||
|         inflateReset(this.strm); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										311
									
								
								public/novnc/core/input/domkeytable.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,311 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2018 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | ||||
|  */ | ||||
|  | ||||
| import KeyTable from "./keysym.js"; | ||||
|  | ||||
| /* | ||||
|  * Mapping between HTML key values and VNC/X11 keysyms for "special" | ||||
|  * keys that cannot be handled via their Unicode codepoint. | ||||
|  * | ||||
|  * See https://www.w3.org/TR/uievents-key/ for possible values. | ||||
|  */ | ||||
|  | ||||
| const DOMKeyTable = {}; | ||||
|  | ||||
| function addStandard(key, standard) { | ||||
|     if (standard === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | ||||
|     if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\""); | ||||
|     DOMKeyTable[key] = [standard, standard, standard, standard]; | ||||
| } | ||||
|  | ||||
| function addLeftRight(key, left, right) { | ||||
|     if (left === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | ||||
|     if (right === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | ||||
|     if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\""); | ||||
|     DOMKeyTable[key] = [left, left, right, left]; | ||||
| } | ||||
|  | ||||
| function addNumpad(key, standard, numpad) { | ||||
|     if (standard === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | ||||
|     if (numpad === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | ||||
|     if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\""); | ||||
|     DOMKeyTable[key] = [standard, standard, standard, numpad]; | ||||
| } | ||||
|  | ||||
| // 3.2. Modifier Keys | ||||
|  | ||||
| addLeftRight("Alt", KeyTable.XK_Alt_L, KeyTable.XK_Alt_R); | ||||
| addStandard("AltGraph", KeyTable.XK_ISO_Level3_Shift); | ||||
| addStandard("CapsLock", KeyTable.XK_Caps_Lock); | ||||
| addLeftRight("Control", KeyTable.XK_Control_L, KeyTable.XK_Control_R); | ||||
| // - Fn | ||||
| // - FnLock | ||||
| addLeftRight("Meta", KeyTable.XK_Super_L, KeyTable.XK_Super_R); | ||||
| addStandard("NumLock", KeyTable.XK_Num_Lock); | ||||
| addStandard("ScrollLock", KeyTable.XK_Scroll_Lock); | ||||
| addLeftRight("Shift", KeyTable.XK_Shift_L, KeyTable.XK_Shift_R); | ||||
| // - Symbol | ||||
| // - SymbolLock | ||||
| // - Hyper | ||||
| // - Super | ||||
|  | ||||
| // 3.3. Whitespace Keys | ||||
|  | ||||
| addNumpad("Enter", KeyTable.XK_Return, KeyTable.XK_KP_Enter); | ||||
| addStandard("Tab", KeyTable.XK_Tab); | ||||
| addNumpad(" ", KeyTable.XK_space, KeyTable.XK_KP_Space); | ||||
|  | ||||
| // 3.4. Navigation Keys | ||||
|  | ||||
| addNumpad("ArrowDown", KeyTable.XK_Down, KeyTable.XK_KP_Down); | ||||
| addNumpad("ArrowLeft", KeyTable.XK_Left, KeyTable.XK_KP_Left); | ||||
| addNumpad("ArrowRight", KeyTable.XK_Right, KeyTable.XK_KP_Right); | ||||
| addNumpad("ArrowUp", KeyTable.XK_Up, KeyTable.XK_KP_Up); | ||||
| addNumpad("End", KeyTable.XK_End, KeyTable.XK_KP_End); | ||||
| addNumpad("Home", KeyTable.XK_Home, KeyTable.XK_KP_Home); | ||||
| addNumpad("PageDown", KeyTable.XK_Next, KeyTable.XK_KP_Next); | ||||
| addNumpad("PageUp", KeyTable.XK_Prior, KeyTable.XK_KP_Prior); | ||||
|  | ||||
| // 3.5. Editing Keys | ||||
|  | ||||
| addStandard("Backspace", KeyTable.XK_BackSpace); | ||||
| // Browsers send "Clear" for the numpad 5 without NumLock because | ||||
| // Windows uses VK_Clear for that key. But Unix expects KP_Begin for | ||||
| // that scenario. | ||||
| addNumpad("Clear", KeyTable.XK_Clear, KeyTable.XK_KP_Begin); | ||||
| addStandard("Copy", KeyTable.XF86XK_Copy); | ||||
| // - CrSel | ||||
| addStandard("Cut", KeyTable.XF86XK_Cut); | ||||
| addNumpad("Delete", KeyTable.XK_Delete, KeyTable.XK_KP_Delete); | ||||
| // - EraseEof | ||||
| // - ExSel | ||||
| addNumpad("Insert", KeyTable.XK_Insert, KeyTable.XK_KP_Insert); | ||||
| addStandard("Paste", KeyTable.XF86XK_Paste); | ||||
| addStandard("Redo", KeyTable.XK_Redo); | ||||
| addStandard("Undo", KeyTable.XK_Undo); | ||||
|  | ||||
| // 3.6. UI Keys | ||||
|  | ||||
| // - Accept | ||||
| // - Again (could just be XK_Redo) | ||||
| // - Attn | ||||
| addStandard("Cancel", KeyTable.XK_Cancel); | ||||
| addStandard("ContextMenu", KeyTable.XK_Menu); | ||||
| addStandard("Escape", KeyTable.XK_Escape); | ||||
| addStandard("Execute", KeyTable.XK_Execute); | ||||
| addStandard("Find", KeyTable.XK_Find); | ||||
| addStandard("Help", KeyTable.XK_Help); | ||||
| addStandard("Pause", KeyTable.XK_Pause); | ||||
| // - Play | ||||
| // - Props | ||||
| addStandard("Select", KeyTable.XK_Select); | ||||
| addStandard("ZoomIn", KeyTable.XF86XK_ZoomIn); | ||||
| addStandard("ZoomOut", KeyTable.XF86XK_ZoomOut); | ||||
|  | ||||
| // 3.7. Device Keys | ||||
|  | ||||
| addStandard("BrightnessDown", KeyTable.XF86XK_MonBrightnessDown); | ||||
| addStandard("BrightnessUp", KeyTable.XF86XK_MonBrightnessUp); | ||||
| addStandard("Eject", KeyTable.XF86XK_Eject); | ||||
| addStandard("LogOff", KeyTable.XF86XK_LogOff); | ||||
| addStandard("Power", KeyTable.XF86XK_PowerOff); | ||||
| addStandard("PowerOff", KeyTable.XF86XK_PowerDown); | ||||
| addStandard("PrintScreen", KeyTable.XK_Print); | ||||
| addStandard("Hibernate", KeyTable.XF86XK_Hibernate); | ||||
| addStandard("Standby", KeyTable.XF86XK_Standby); | ||||
| addStandard("WakeUp", KeyTable.XF86XK_WakeUp); | ||||
|  | ||||
| // 3.8. IME and Composition Keys | ||||
|  | ||||
| addStandard("AllCandidates", KeyTable.XK_MultipleCandidate); | ||||
| addStandard("Alphanumeric", KeyTable.XK_Eisu_toggle); | ||||
| addStandard("CodeInput", KeyTable.XK_Codeinput); | ||||
| addStandard("Compose", KeyTable.XK_Multi_key); | ||||
| addStandard("Convert", KeyTable.XK_Henkan); | ||||
| // - Dead | ||||
| // - FinalMode | ||||
| addStandard("GroupFirst", KeyTable.XK_ISO_First_Group); | ||||
| addStandard("GroupLast", KeyTable.XK_ISO_Last_Group); | ||||
| addStandard("GroupNext", KeyTable.XK_ISO_Next_Group); | ||||
| addStandard("GroupPrevious", KeyTable.XK_ISO_Prev_Group); | ||||
| // - ModeChange (XK_Mode_switch is often used for AltGr) | ||||
| // - NextCandidate | ||||
| addStandard("NonConvert", KeyTable.XK_Muhenkan); | ||||
| addStandard("PreviousCandidate", KeyTable.XK_PreviousCandidate); | ||||
| // - Process | ||||
| addStandard("SingleCandidate", KeyTable.XK_SingleCandidate); | ||||
| addStandard("HangulMode", KeyTable.XK_Hangul); | ||||
| addStandard("HanjaMode", KeyTable.XK_Hangul_Hanja); | ||||
| addStandard("JunjaMode", KeyTable.XK_Hangul_Jeonja); | ||||
| addStandard("Eisu", KeyTable.XK_Eisu_toggle); | ||||
| addStandard("Hankaku", KeyTable.XK_Hankaku); | ||||
| addStandard("Hiragana", KeyTable.XK_Hiragana); | ||||
| addStandard("HiraganaKatakana", KeyTable.XK_Hiragana_Katakana); | ||||
| addStandard("KanaMode", KeyTable.XK_Kana_Shift); // could also be _Kana_Lock | ||||
| addStandard("KanjiMode", KeyTable.XK_Kanji); | ||||
| addStandard("Katakana", KeyTable.XK_Katakana); | ||||
| addStandard("Romaji", KeyTable.XK_Romaji); | ||||
| addStandard("Zenkaku", KeyTable.XK_Zenkaku); | ||||
| addStandard("ZenkakuHankaku", KeyTable.XK_Zenkaku_Hankaku); | ||||
|  | ||||
| // 3.9. General-Purpose Function Keys | ||||
|  | ||||
| addStandard("F1", KeyTable.XK_F1); | ||||
| addStandard("F2", KeyTable.XK_F2); | ||||
| addStandard("F3", KeyTable.XK_F3); | ||||
| addStandard("F4", KeyTable.XK_F4); | ||||
| addStandard("F5", KeyTable.XK_F5); | ||||
| addStandard("F6", KeyTable.XK_F6); | ||||
| addStandard("F7", KeyTable.XK_F7); | ||||
| addStandard("F8", KeyTable.XK_F8); | ||||
| addStandard("F9", KeyTable.XK_F9); | ||||
| addStandard("F10", KeyTable.XK_F10); | ||||
| addStandard("F11", KeyTable.XK_F11); | ||||
| addStandard("F12", KeyTable.XK_F12); | ||||
| addStandard("F13", KeyTable.XK_F13); | ||||
| addStandard("F14", KeyTable.XK_F14); | ||||
| addStandard("F15", KeyTable.XK_F15); | ||||
| addStandard("F16", KeyTable.XK_F16); | ||||
| addStandard("F17", KeyTable.XK_F17); | ||||
| addStandard("F18", KeyTable.XK_F18); | ||||
| addStandard("F19", KeyTable.XK_F19); | ||||
| addStandard("F20", KeyTable.XK_F20); | ||||
| addStandard("F21", KeyTable.XK_F21); | ||||
| addStandard("F22", KeyTable.XK_F22); | ||||
| addStandard("F23", KeyTable.XK_F23); | ||||
| addStandard("F24", KeyTable.XK_F24); | ||||
| addStandard("F25", KeyTable.XK_F25); | ||||
| addStandard("F26", KeyTable.XK_F26); | ||||
| addStandard("F27", KeyTable.XK_F27); | ||||
| addStandard("F28", KeyTable.XK_F28); | ||||
| addStandard("F29", KeyTable.XK_F29); | ||||
| addStandard("F30", KeyTable.XK_F30); | ||||
| addStandard("F31", KeyTable.XK_F31); | ||||
| addStandard("F32", KeyTable.XK_F32); | ||||
| addStandard("F33", KeyTable.XK_F33); | ||||
| addStandard("F34", KeyTable.XK_F34); | ||||
| addStandard("F35", KeyTable.XK_F35); | ||||
| // - Soft1... | ||||
|  | ||||
| // 3.10. Multimedia Keys | ||||
|  | ||||
| // - ChannelDown | ||||
| // - ChannelUp | ||||
| addStandard("Close", KeyTable.XF86XK_Close); | ||||
| addStandard("MailForward", KeyTable.XF86XK_MailForward); | ||||
| addStandard("MailReply", KeyTable.XF86XK_Reply); | ||||
| addStandard("MailSend", KeyTable.XF86XK_Send); | ||||
| // - MediaClose | ||||
| addStandard("MediaFastForward", KeyTable.XF86XK_AudioForward); | ||||
| addStandard("MediaPause", KeyTable.XF86XK_AudioPause); | ||||
| addStandard("MediaPlay", KeyTable.XF86XK_AudioPlay); | ||||
| // - MediaPlayPause | ||||
| addStandard("MediaRecord", KeyTable.XF86XK_AudioRecord); | ||||
| addStandard("MediaRewind", KeyTable.XF86XK_AudioRewind); | ||||
| addStandard("MediaStop", KeyTable.XF86XK_AudioStop); | ||||
| addStandard("MediaTrackNext", KeyTable.XF86XK_AudioNext); | ||||
| addStandard("MediaTrackPrevious", KeyTable.XF86XK_AudioPrev); | ||||
| addStandard("New", KeyTable.XF86XK_New); | ||||
| addStandard("Open", KeyTable.XF86XK_Open); | ||||
| addStandard("Print", KeyTable.XK_Print); | ||||
| addStandard("Save", KeyTable.XF86XK_Save); | ||||
| addStandard("SpellCheck", KeyTable.XF86XK_Spell); | ||||
|  | ||||
| // 3.11. Multimedia Numpad Keys | ||||
|  | ||||
| // - Key11 | ||||
| // - Key12 | ||||
|  | ||||
| // 3.12. Audio Keys | ||||
|  | ||||
| // - AudioBalanceLeft | ||||
| // - AudioBalanceRight | ||||
| // - AudioBassBoostDown | ||||
| // - AudioBassBoostToggle | ||||
| // - AudioBassBoostUp | ||||
| // - AudioFaderFront | ||||
| // - AudioFaderRear | ||||
| // - AudioSurroundModeNext | ||||
| // - AudioTrebleDown | ||||
| // - AudioTrebleUp | ||||
| addStandard("AudioVolumeDown", KeyTable.XF86XK_AudioLowerVolume); | ||||
| addStandard("AudioVolumeUp", KeyTable.XF86XK_AudioRaiseVolume); | ||||
| addStandard("AudioVolumeMute", KeyTable.XF86XK_AudioMute); | ||||
| // - MicrophoneToggle | ||||
| // - MicrophoneVolumeDown | ||||
| // - MicrophoneVolumeUp | ||||
| addStandard("MicrophoneVolumeMute", KeyTable.XF86XK_AudioMicMute); | ||||
|  | ||||
| // 3.13. Speech Keys | ||||
|  | ||||
| // - SpeechCorrectionList | ||||
| // - SpeechInputToggle | ||||
|  | ||||
| // 3.14. Application Keys | ||||
|  | ||||
| addStandard("LaunchApplication1", KeyTable.XF86XK_MyComputer); | ||||
| addStandard("LaunchApplication2", KeyTable.XF86XK_Calculator); | ||||
| addStandard("LaunchCalendar", KeyTable.XF86XK_Calendar); | ||||
| // - LaunchContacts | ||||
| addStandard("LaunchMail", KeyTable.XF86XK_Mail); | ||||
| addStandard("LaunchMediaPlayer", KeyTable.XF86XK_AudioMedia); | ||||
| addStandard("LaunchMusicPlayer", KeyTable.XF86XK_Music); | ||||
| addStandard("LaunchPhone", KeyTable.XF86XK_Phone); | ||||
| addStandard("LaunchScreenSaver", KeyTable.XF86XK_ScreenSaver); | ||||
| addStandard("LaunchSpreadsheet", KeyTable.XF86XK_Excel); | ||||
| addStandard("LaunchWebBrowser", KeyTable.XF86XK_WWW); | ||||
| addStandard("LaunchWebCam", KeyTable.XF86XK_WebCam); | ||||
| addStandard("LaunchWordProcessor", KeyTable.XF86XK_Word); | ||||
|  | ||||
| // 3.15. Browser Keys | ||||
|  | ||||
| addStandard("BrowserBack", KeyTable.XF86XK_Back); | ||||
| addStandard("BrowserFavorites", KeyTable.XF86XK_Favorites); | ||||
| addStandard("BrowserForward", KeyTable.XF86XK_Forward); | ||||
| addStandard("BrowserHome", KeyTable.XF86XK_HomePage); | ||||
| addStandard("BrowserRefresh", KeyTable.XF86XK_Refresh); | ||||
| addStandard("BrowserSearch", KeyTable.XF86XK_Search); | ||||
| addStandard("BrowserStop", KeyTable.XF86XK_Stop); | ||||
|  | ||||
| // 3.16. Mobile Phone Keys | ||||
|  | ||||
| // - A whole bunch... | ||||
|  | ||||
| // 3.17. TV Keys | ||||
|  | ||||
| // - A whole bunch... | ||||
|  | ||||
| // 3.18. Media Controller Keys | ||||
|  | ||||
| // - A whole bunch... | ||||
| addStandard("Dimmer", KeyTable.XF86XK_BrightnessAdjust); | ||||
| addStandard("MediaAudioTrack", KeyTable.XF86XK_AudioCycleTrack); | ||||
| addStandard("RandomToggle", KeyTable.XF86XK_AudioRandomPlay); | ||||
| addStandard("SplitScreenToggle", KeyTable.XF86XK_SplitScreen); | ||||
| addStandard("Subtitle", KeyTable.XF86XK_Subtitle); | ||||
| addStandard("VideoModeNext", KeyTable.XF86XK_Next_VMode); | ||||
|  | ||||
| // Extra: Numpad | ||||
|  | ||||
| addNumpad("=", KeyTable.XK_equal, KeyTable.XK_KP_Equal); | ||||
| addNumpad("+", KeyTable.XK_plus, KeyTable.XK_KP_Add); | ||||
| addNumpad("-", KeyTable.XK_minus, KeyTable.XK_KP_Subtract); | ||||
| addNumpad("*", KeyTable.XK_asterisk, KeyTable.XK_KP_Multiply); | ||||
| addNumpad("/", KeyTable.XK_slash, KeyTable.XK_KP_Divide); | ||||
| addNumpad(".", KeyTable.XK_period, KeyTable.XK_KP_Decimal); | ||||
| addNumpad(",", KeyTable.XK_comma, KeyTable.XK_KP_Separator); | ||||
| addNumpad("0", KeyTable.XK_0, KeyTable.XK_KP_0); | ||||
| addNumpad("1", KeyTable.XK_1, KeyTable.XK_KP_1); | ||||
| addNumpad("2", KeyTable.XK_2, KeyTable.XK_KP_2); | ||||
| addNumpad("3", KeyTable.XK_3, KeyTable.XK_KP_3); | ||||
| addNumpad("4", KeyTable.XK_4, KeyTable.XK_KP_4); | ||||
| addNumpad("5", KeyTable.XK_5, KeyTable.XK_KP_5); | ||||
| addNumpad("6", KeyTable.XK_6, KeyTable.XK_KP_6); | ||||
| addNumpad("7", KeyTable.XK_7, KeyTable.XK_KP_7); | ||||
| addNumpad("8", KeyTable.XK_8, KeyTable.XK_KP_8); | ||||
| addNumpad("9", KeyTable.XK_9, KeyTable.XK_KP_9); | ||||
|  | ||||
| export default DOMKeyTable; | ||||
							
								
								
									
										129
									
								
								public/novnc/core/input/fixedkeys.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,129 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2018 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Fallback mapping between HTML key codes (physical keys) and | ||||
|  * HTML key values. This only works for keys that don't vary | ||||
|  * between layouts. We also omit those who manage fine by mapping the | ||||
|  * Unicode representation. | ||||
|  * | ||||
|  * See https://www.w3.org/TR/uievents-code/ for possible codes. | ||||
|  * See https://www.w3.org/TR/uievents-key/ for possible values. | ||||
|  */ | ||||
|  | ||||
| /* eslint-disable key-spacing */ | ||||
|  | ||||
| export default { | ||||
|  | ||||
| // 3.1.1.1. Writing System Keys | ||||
|  | ||||
|     'Backspace':        'Backspace', | ||||
|  | ||||
| // 3.1.1.2. Functional Keys | ||||
|  | ||||
|     'AltLeft':          'Alt', | ||||
|     'AltRight':         'Alt', // This could also be 'AltGraph' | ||||
|     'CapsLock':         'CapsLock', | ||||
|     'ContextMenu':      'ContextMenu', | ||||
|     'ControlLeft':      'Control', | ||||
|     'ControlRight':     'Control', | ||||
|     'Enter':            'Enter', | ||||
|     'MetaLeft':         'Meta', | ||||
|     'MetaRight':        'Meta', | ||||
|     'ShiftLeft':        'Shift', | ||||
|     'ShiftRight':       'Shift', | ||||
|     'Tab':              'Tab', | ||||
|     // FIXME: Japanese/Korean keys | ||||
|  | ||||
| // 3.1.2. Control Pad Section | ||||
|  | ||||
|     'Delete':           'Delete', | ||||
|     'End':              'End', | ||||
|     'Help':             'Help', | ||||
|     'Home':             'Home', | ||||
|     'Insert':           'Insert', | ||||
|     'PageDown':         'PageDown', | ||||
|     'PageUp':           'PageUp', | ||||
|  | ||||
| // 3.1.3. Arrow Pad Section | ||||
|  | ||||
|     'ArrowDown':        'ArrowDown', | ||||
|     'ArrowLeft':        'ArrowLeft', | ||||
|     'ArrowRight':       'ArrowRight', | ||||
|     'ArrowUp':          'ArrowUp', | ||||
|  | ||||
| // 3.1.4. Numpad Section | ||||
|  | ||||
|     'NumLock':          'NumLock', | ||||
|     'NumpadBackspace':  'Backspace', | ||||
|     'NumpadClear':      'Clear', | ||||
|  | ||||
| // 3.1.5. Function Section | ||||
|  | ||||
|     'Escape':           'Escape', | ||||
|     'F1':               'F1', | ||||
|     'F2':               'F2', | ||||
|     'F3':               'F3', | ||||
|     'F4':               'F4', | ||||
|     'F5':               'F5', | ||||
|     'F6':               'F6', | ||||
|     'F7':               'F7', | ||||
|     'F8':               'F8', | ||||
|     'F9':               'F9', | ||||
|     'F10':              'F10', | ||||
|     'F11':              'F11', | ||||
|     'F12':              'F12', | ||||
|     'F13':              'F13', | ||||
|     'F14':              'F14', | ||||
|     'F15':              'F15', | ||||
|     'F16':              'F16', | ||||
|     'F17':              'F17', | ||||
|     'F18':              'F18', | ||||
|     'F19':              'F19', | ||||
|     'F20':              'F20', | ||||
|     'F21':              'F21', | ||||
|     'F22':              'F22', | ||||
|     'F23':              'F23', | ||||
|     'F24':              'F24', | ||||
|     'F25':              'F25', | ||||
|     'F26':              'F26', | ||||
|     'F27':              'F27', | ||||
|     'F28':              'F28', | ||||
|     'F29':              'F29', | ||||
|     'F30':              'F30', | ||||
|     'F31':              'F31', | ||||
|     'F32':              'F32', | ||||
|     'F33':              'F33', | ||||
|     'F34':              'F34', | ||||
|     'F35':              'F35', | ||||
|     'PrintScreen':      'PrintScreen', | ||||
|     'ScrollLock':       'ScrollLock', | ||||
|     'Pause':            'Pause', | ||||
|  | ||||
| // 3.1.6. Media Keys | ||||
|  | ||||
|     'BrowserBack':      'BrowserBack', | ||||
|     'BrowserFavorites': 'BrowserFavorites', | ||||
|     'BrowserForward':   'BrowserForward', | ||||
|     'BrowserHome':      'BrowserHome', | ||||
|     'BrowserRefresh':   'BrowserRefresh', | ||||
|     'BrowserSearch':    'BrowserSearch', | ||||
|     'BrowserStop':      'BrowserStop', | ||||
|     'Eject':            'Eject', | ||||
|     'LaunchApp1':       'LaunchMyComputer', | ||||
|     'LaunchApp2':       'LaunchCalendar', | ||||
|     'LaunchMail':       'LaunchMail', | ||||
|     'MediaPlayPause':   'MediaPlay', | ||||
|     'MediaStop':        'MediaStop', | ||||
|     'MediaTrackNext':   'MediaTrackNext', | ||||
|     'MediaTrackPrevious': 'MediaTrackPrevious', | ||||
|     'Power':            'Power', | ||||
|     'Sleep':            'Sleep', | ||||
|     'AudioVolumeDown':  'AudioVolumeDown', | ||||
|     'AudioVolumeMute':  'AudioVolumeMute', | ||||
|     'AudioVolumeUp':    'AudioVolumeUp', | ||||
|     'WakeUp':           'WakeUp', | ||||
| }; | ||||
							
								
								
									
										567
									
								
								public/novnc/core/input/gesturehandler.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,567 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2020 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| const GH_NOGESTURE = 0; | ||||
| const GH_ONETAP    = 1; | ||||
| const GH_TWOTAP    = 2; | ||||
| const GH_THREETAP  = 4; | ||||
| const GH_DRAG      = 8; | ||||
| const GH_LONGPRESS = 16; | ||||
| const GH_TWODRAG   = 32; | ||||
| const GH_PINCH     = 64; | ||||
|  | ||||
| const GH_INITSTATE = 127; | ||||
|  | ||||
| const GH_MOVE_THRESHOLD = 50; | ||||
| const GH_ANGLE_THRESHOLD = 90; // Degrees | ||||
|  | ||||
| // Timeout when waiting for gestures (ms) | ||||
| const GH_MULTITOUCH_TIMEOUT = 250; | ||||
|  | ||||
| // Maximum time between press and release for a tap (ms) | ||||
| const GH_TAP_TIMEOUT = 1000; | ||||
|  | ||||
| // Timeout when waiting for longpress (ms) | ||||
| const GH_LONGPRESS_TIMEOUT = 1000; | ||||
|  | ||||
| // Timeout when waiting to decide between PINCH and TWODRAG (ms) | ||||
| const GH_TWOTOUCH_TIMEOUT = 50; | ||||
|  | ||||
| export default class GestureHandler { | ||||
|     constructor() { | ||||
|         this._target = null; | ||||
|  | ||||
|         this._state = GH_INITSTATE; | ||||
|  | ||||
|         this._tracked = []; | ||||
|         this._ignored = []; | ||||
|  | ||||
|         this._waitingRelease = false; | ||||
|         this._releaseStart = 0.0; | ||||
|  | ||||
|         this._longpressTimeoutId = null; | ||||
|         this._twoTouchTimeoutId = null; | ||||
|  | ||||
|         this._boundEventHandler = this._eventHandler.bind(this); | ||||
|     } | ||||
|  | ||||
|     attach(target) { | ||||
|         this.detach(); | ||||
|  | ||||
|         this._target = target; | ||||
|         this._target.addEventListener('touchstart', | ||||
|                                       this._boundEventHandler); | ||||
|         this._target.addEventListener('touchmove', | ||||
|                                       this._boundEventHandler); | ||||
|         this._target.addEventListener('touchend', | ||||
|                                       this._boundEventHandler); | ||||
|         this._target.addEventListener('touchcancel', | ||||
|                                       this._boundEventHandler); | ||||
|     } | ||||
|  | ||||
|     detach() { | ||||
|         if (!this._target) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this._stopLongpressTimeout(); | ||||
|         this._stopTwoTouchTimeout(); | ||||
|  | ||||
|         this._target.removeEventListener('touchstart', | ||||
|                                          this._boundEventHandler); | ||||
|         this._target.removeEventListener('touchmove', | ||||
|                                          this._boundEventHandler); | ||||
|         this._target.removeEventListener('touchend', | ||||
|                                          this._boundEventHandler); | ||||
|         this._target.removeEventListener('touchcancel', | ||||
|                                          this._boundEventHandler); | ||||
|         this._target = null; | ||||
|     } | ||||
|  | ||||
|     _eventHandler(e) { | ||||
|         let fn; | ||||
|  | ||||
|         e.stopPropagation(); | ||||
|         e.preventDefault(); | ||||
|  | ||||
|         switch (e.type) { | ||||
|             case 'touchstart': | ||||
|                 fn = this._touchStart; | ||||
|                 break; | ||||
|             case 'touchmove': | ||||
|                 fn = this._touchMove; | ||||
|                 break; | ||||
|             case 'touchend': | ||||
|             case 'touchcancel': | ||||
|                 fn = this._touchEnd; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         for (let i = 0; i < e.changedTouches.length; i++) { | ||||
|             let touch = e.changedTouches[i]; | ||||
|             fn.call(this, touch.identifier, touch.clientX, touch.clientY); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _touchStart(id, x, y) { | ||||
|         // Ignore any new touches if there is already an active gesture, | ||||
|         // or we're in a cleanup state | ||||
|         if (this._hasDetectedGesture() || (this._state === GH_NOGESTURE)) { | ||||
|             this._ignored.push(id); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Did it take too long between touches that we should no longer | ||||
|         // consider this a single gesture? | ||||
|         if ((this._tracked.length > 0) && | ||||
|             ((Date.now() - this._tracked[0].started) > GH_MULTITOUCH_TIMEOUT)) { | ||||
|             this._state = GH_NOGESTURE; | ||||
|             this._ignored.push(id); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // If we're waiting for fingers to release then we should no longer | ||||
|         // recognize new touches | ||||
|         if (this._waitingRelease) { | ||||
|             this._state = GH_NOGESTURE; | ||||
|             this._ignored.push(id); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this._tracked.push({ | ||||
|             id: id, | ||||
|             started: Date.now(), | ||||
|             active: true, | ||||
|             firstX: x, | ||||
|             firstY: y, | ||||
|             lastX: x, | ||||
|             lastY: y, | ||||
|             angle: 0 | ||||
|         }); | ||||
|  | ||||
|         switch (this._tracked.length) { | ||||
|             case 1: | ||||
|                 this._startLongpressTimeout(); | ||||
|                 break; | ||||
|  | ||||
|             case 2: | ||||
|                 this._state &= ~(GH_ONETAP | GH_DRAG | GH_LONGPRESS); | ||||
|                 this._stopLongpressTimeout(); | ||||
|                 break; | ||||
|  | ||||
|             case 3: | ||||
|                 this._state &= ~(GH_TWOTAP | GH_TWODRAG | GH_PINCH); | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 this._state = GH_NOGESTURE; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _touchMove(id, x, y) { | ||||
|         let touch = this._tracked.find(t => t.id === id); | ||||
|  | ||||
|         // If this is an update for a touch we're not tracking, ignore it | ||||
|         if (touch === undefined) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Update the touches last position with the event coordinates | ||||
|         touch.lastX = x; | ||||
|         touch.lastY = y; | ||||
|  | ||||
|         let deltaX = x - touch.firstX; | ||||
|         let deltaY = y - touch.firstY; | ||||
|  | ||||
|         // Update angle when the touch has moved | ||||
|         if ((touch.firstX !== touch.lastX) || | ||||
|             (touch.firstY !== touch.lastY)) { | ||||
|             touch.angle = Math.atan2(deltaY, deltaX) * 180 / Math.PI; | ||||
|         } | ||||
|  | ||||
|         if (!this._hasDetectedGesture()) { | ||||
|             // Ignore moves smaller than the minimum threshold | ||||
|             if (Math.hypot(deltaX, deltaY) < GH_MOVE_THRESHOLD) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // Can't be a tap or long press as we've seen movement | ||||
|             this._state &= ~(GH_ONETAP | GH_TWOTAP | GH_THREETAP | GH_LONGPRESS); | ||||
|             this._stopLongpressTimeout(); | ||||
|  | ||||
|             if (this._tracked.length !== 1) { | ||||
|                 this._state &= ~(GH_DRAG); | ||||
|             } | ||||
|             if (this._tracked.length !== 2) { | ||||
|                 this._state &= ~(GH_TWODRAG | GH_PINCH); | ||||
|             } | ||||
|  | ||||
|             // We need to figure out which of our different two touch gestures | ||||
|             // this might be | ||||
|             if (this._tracked.length === 2) { | ||||
|  | ||||
|                 // The other touch is the one where the id doesn't match | ||||
|                 let prevTouch = this._tracked.find(t => t.id !== id); | ||||
|  | ||||
|                 // How far the previous touch point has moved since start | ||||
|                 let prevDeltaMove = Math.hypot(prevTouch.firstX - prevTouch.lastX, | ||||
|                                                prevTouch.firstY - prevTouch.lastY); | ||||
|  | ||||
|                 // We know that the current touch moved far enough, | ||||
|                 // but unless both touches moved further than their | ||||
|                 // threshold we don't want to disqualify any gestures | ||||
|                 if (prevDeltaMove > GH_MOVE_THRESHOLD) { | ||||
|  | ||||
|                     // The angle difference between the direction of the touch points | ||||
|                     let deltaAngle = Math.abs(touch.angle - prevTouch.angle); | ||||
|                     deltaAngle = Math.abs(((deltaAngle + 180) % 360) - 180); | ||||
|  | ||||
|                     // PINCH or TWODRAG can be eliminated depending on the angle | ||||
|                     if (deltaAngle > GH_ANGLE_THRESHOLD) { | ||||
|                         this._state &= ~GH_TWODRAG; | ||||
|                     } else { | ||||
|                         this._state &= ~GH_PINCH; | ||||
|                     } | ||||
|  | ||||
|                     if (this._isTwoTouchTimeoutRunning()) { | ||||
|                         this._stopTwoTouchTimeout(); | ||||
|                     } | ||||
|                 } else if (!this._isTwoTouchTimeoutRunning()) { | ||||
|                     // We can't determine the gesture right now, let's | ||||
|                     // wait and see if more events are on their way | ||||
|                     this._startTwoTouchTimeout(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (!this._hasDetectedGesture()) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             this._pushEvent('gesturestart'); | ||||
|         } | ||||
|  | ||||
|         this._pushEvent('gesturemove'); | ||||
|     } | ||||
|  | ||||
|     _touchEnd(id, x, y) { | ||||
|         // Check if this is an ignored touch | ||||
|         if (this._ignored.indexOf(id) !== -1) { | ||||
|             // Remove this touch from ignored | ||||
|             this._ignored.splice(this._ignored.indexOf(id), 1); | ||||
|  | ||||
|             // And reset the state if there are no more touches | ||||
|             if ((this._ignored.length === 0) && | ||||
|                 (this._tracked.length === 0)) { | ||||
|                 this._state = GH_INITSTATE; | ||||
|                 this._waitingRelease = false; | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // We got a touchend before the timer triggered, | ||||
|         // this cannot result in a gesture anymore. | ||||
|         if (!this._hasDetectedGesture() && | ||||
|             this._isTwoTouchTimeoutRunning()) { | ||||
|             this._stopTwoTouchTimeout(); | ||||
|             this._state = GH_NOGESTURE; | ||||
|         } | ||||
|  | ||||
|         // Some gestures don't trigger until a touch is released | ||||
|         if (!this._hasDetectedGesture()) { | ||||
|             // Can't be a gesture that relies on movement | ||||
|             this._state &= ~(GH_DRAG | GH_TWODRAG | GH_PINCH); | ||||
|             // Or something that relies on more time | ||||
|             this._state &= ~GH_LONGPRESS; | ||||
|             this._stopLongpressTimeout(); | ||||
|  | ||||
|             if (!this._waitingRelease) { | ||||
|                 this._releaseStart = Date.now(); | ||||
|                 this._waitingRelease = true; | ||||
|  | ||||
|                 // Can't be a tap that requires more touches than we current have | ||||
|                 switch (this._tracked.length) { | ||||
|                     case 1: | ||||
|                         this._state &= ~(GH_TWOTAP | GH_THREETAP); | ||||
|                         break; | ||||
|  | ||||
|                     case 2: | ||||
|                         this._state &= ~(GH_ONETAP | GH_THREETAP); | ||||
|                         break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Waiting for all touches to release? (i.e. some tap) | ||||
|         if (this._waitingRelease) { | ||||
|             // Were all touches released at roughly the same time? | ||||
|             if ((Date.now() - this._releaseStart) > GH_MULTITOUCH_TIMEOUT) { | ||||
|                 this._state = GH_NOGESTURE; | ||||
|             } | ||||
|  | ||||
|             // Did too long time pass between press and release? | ||||
|             if (this._tracked.some(t => (Date.now() - t.started) > GH_TAP_TIMEOUT)) { | ||||
|                 this._state = GH_NOGESTURE; | ||||
|             } | ||||
|  | ||||
|             let touch = this._tracked.find(t => t.id === id); | ||||
|             touch.active = false; | ||||
|  | ||||
|             // Are we still waiting for more releases? | ||||
|             if (this._hasDetectedGesture()) { | ||||
|                 this._pushEvent('gesturestart'); | ||||
|             } else { | ||||
|                 // Have we reached a dead end? | ||||
|                 if (this._state !== GH_NOGESTURE) { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (this._hasDetectedGesture()) { | ||||
|             this._pushEvent('gestureend'); | ||||
|         } | ||||
|  | ||||
|         // Ignore any remaining touches until they are ended | ||||
|         for (let i = 0; i < this._tracked.length; i++) { | ||||
|             if (this._tracked[i].active) { | ||||
|                 this._ignored.push(this._tracked[i].id); | ||||
|             } | ||||
|         } | ||||
|         this._tracked = []; | ||||
|  | ||||
|         this._state = GH_NOGESTURE; | ||||
|  | ||||
|         // Remove this touch from ignored if it's in there | ||||
|         if (this._ignored.indexOf(id) !== -1) { | ||||
|             this._ignored.splice(this._ignored.indexOf(id), 1); | ||||
|         } | ||||
|  | ||||
|         // We reset the state if ignored is empty | ||||
|         if ((this._ignored.length === 0)) { | ||||
|             this._state = GH_INITSTATE; | ||||
|             this._waitingRelease = false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _hasDetectedGesture() { | ||||
|         if (this._state === GH_NOGESTURE) { | ||||
|             return false; | ||||
|         } | ||||
|         // Check to see if the bitmask value is a power of 2 | ||||
|         // (i.e. only one bit set). If it is, we have a state. | ||||
|         if (this._state & (this._state - 1)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // For taps we also need to have all touches released | ||||
|         // before we've fully detected the gesture | ||||
|         if (this._state & (GH_ONETAP | GH_TWOTAP | GH_THREETAP)) { | ||||
|             if (this._tracked.some(t => t.active)) { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     _startLongpressTimeout() { | ||||
|         this._stopLongpressTimeout(); | ||||
|         this._longpressTimeoutId = setTimeout(() => this._longpressTimeout(), | ||||
|                                               GH_LONGPRESS_TIMEOUT); | ||||
|     } | ||||
|  | ||||
|     _stopLongpressTimeout() { | ||||
|         clearTimeout(this._longpressTimeoutId); | ||||
|         this._longpressTimeoutId = null; | ||||
|     } | ||||
|  | ||||
|     _longpressTimeout() { | ||||
|         if (this._hasDetectedGesture()) { | ||||
|             throw new Error("A longpress gesture failed, conflict with a different gesture"); | ||||
|         } | ||||
|  | ||||
|         this._state = GH_LONGPRESS; | ||||
|         this._pushEvent('gesturestart'); | ||||
|     } | ||||
|  | ||||
|     _startTwoTouchTimeout() { | ||||
|         this._stopTwoTouchTimeout(); | ||||
|         this._twoTouchTimeoutId = setTimeout(() => this._twoTouchTimeout(), | ||||
|                                              GH_TWOTOUCH_TIMEOUT); | ||||
|     } | ||||
|  | ||||
|     _stopTwoTouchTimeout() { | ||||
|         clearTimeout(this._twoTouchTimeoutId); | ||||
|         this._twoTouchTimeoutId = null; | ||||
|     } | ||||
|  | ||||
|     _isTwoTouchTimeoutRunning() { | ||||
|         return this._twoTouchTimeoutId !== null; | ||||
|     } | ||||
|  | ||||
|     _twoTouchTimeout() { | ||||
|         if (this._tracked.length === 0) { | ||||
|             throw new Error("A pinch or two drag gesture failed, no tracked touches"); | ||||
|         } | ||||
|  | ||||
|         // How far each touch point has moved since start | ||||
|         let avgM = this._getAverageMovement(); | ||||
|         let avgMoveH = Math.abs(avgM.x); | ||||
|         let avgMoveV = Math.abs(avgM.y); | ||||
|  | ||||
|         // The difference in the distance between where | ||||
|         // the touch points started and where they are now | ||||
|         let avgD = this._getAverageDistance(); | ||||
|         let deltaTouchDistance = Math.abs(Math.hypot(avgD.first.x, avgD.first.y) - | ||||
|                                           Math.hypot(avgD.last.x, avgD.last.y)); | ||||
|  | ||||
|         if ((avgMoveV < deltaTouchDistance) && | ||||
|             (avgMoveH < deltaTouchDistance)) { | ||||
|             this._state = GH_PINCH; | ||||
|         } else { | ||||
|             this._state = GH_TWODRAG; | ||||
|         } | ||||
|  | ||||
|         this._pushEvent('gesturestart'); | ||||
|         this._pushEvent('gesturemove'); | ||||
|     } | ||||
|  | ||||
|     _pushEvent(type) { | ||||
|         let detail = { type: this._stateToGesture(this._state) }; | ||||
|  | ||||
|         // For most gesture events the current (average) position is the | ||||
|         // most useful | ||||
|         let avg = this._getPosition(); | ||||
|         let pos = avg.last; | ||||
|  | ||||
|         // However we have a slight distance to detect gestures, so for the | ||||
|         // first gesture event we want to use the first positions we saw | ||||
|         if (type === 'gesturestart') { | ||||
|             pos = avg.first; | ||||
|         } | ||||
|  | ||||
|         // For these gestures, we always want the event coordinates | ||||
|         // to be where the gesture began, not the current touch location. | ||||
|         switch (this._state) { | ||||
|             case GH_TWODRAG: | ||||
|             case GH_PINCH: | ||||
|                 pos = avg.first; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         detail['clientX'] = pos.x; | ||||
|         detail['clientY'] = pos.y; | ||||
|  | ||||
|         // FIXME: other coordinates? | ||||
|  | ||||
|         // Some gestures also have a magnitude | ||||
|         if (this._state === GH_PINCH) { | ||||
|             let distance = this._getAverageDistance(); | ||||
|             if (type === 'gesturestart') { | ||||
|                 detail['magnitudeX'] = distance.first.x; | ||||
|                 detail['magnitudeY'] = distance.first.y; | ||||
|             } else { | ||||
|                 detail['magnitudeX'] = distance.last.x; | ||||
|                 detail['magnitudeY'] = distance.last.y; | ||||
|             } | ||||
|         } else if (this._state === GH_TWODRAG) { | ||||
|             if (type === 'gesturestart') { | ||||
|                 detail['magnitudeX'] = 0.0; | ||||
|                 detail['magnitudeY'] = 0.0; | ||||
|             } else { | ||||
|                 let movement = this._getAverageMovement(); | ||||
|                 detail['magnitudeX'] = movement.x; | ||||
|                 detail['magnitudeY'] = movement.y; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         let gev = new CustomEvent(type, { detail: detail }); | ||||
|         this._target.dispatchEvent(gev); | ||||
|     } | ||||
|  | ||||
|     _stateToGesture(state) { | ||||
|         switch (state) { | ||||
|             case GH_ONETAP: | ||||
|                 return 'onetap'; | ||||
|             case GH_TWOTAP: | ||||
|                 return 'twotap'; | ||||
|             case GH_THREETAP: | ||||
|                 return 'threetap'; | ||||
|             case GH_DRAG: | ||||
|                 return 'drag'; | ||||
|             case GH_LONGPRESS: | ||||
|                 return 'longpress'; | ||||
|             case GH_TWODRAG: | ||||
|                 return 'twodrag'; | ||||
|             case GH_PINCH: | ||||
|                 return 'pinch'; | ||||
|         } | ||||
|  | ||||
|         throw new Error("Unknown gesture state: " + state); | ||||
|     } | ||||
|  | ||||
|     _getPosition() { | ||||
|         if (this._tracked.length === 0) { | ||||
|             throw new Error("Failed to get gesture position, no tracked touches"); | ||||
|         } | ||||
|  | ||||
|         let size = this._tracked.length; | ||||
|         let fx = 0, fy = 0, lx = 0, ly = 0; | ||||
|  | ||||
|         for (let i = 0; i < this._tracked.length; i++) { | ||||
|             fx += this._tracked[i].firstX; | ||||
|             fy += this._tracked[i].firstY; | ||||
|             lx += this._tracked[i].lastX; | ||||
|             ly += this._tracked[i].lastY; | ||||
|         } | ||||
|  | ||||
|         return { first: { x: fx / size, | ||||
|                           y: fy / size }, | ||||
|                  last: { x: lx / size, | ||||
|                          y: ly / size } }; | ||||
|     } | ||||
|  | ||||
|     _getAverageMovement() { | ||||
|         if (this._tracked.length === 0) { | ||||
|             throw new Error("Failed to get gesture movement, no tracked touches"); | ||||
|         } | ||||
|  | ||||
|         let totalH, totalV; | ||||
|         totalH = totalV = 0; | ||||
|         let size = this._tracked.length; | ||||
|  | ||||
|         for (let i = 0; i < this._tracked.length; i++) { | ||||
|             totalH += this._tracked[i].lastX - this._tracked[i].firstX; | ||||
|             totalV += this._tracked[i].lastY - this._tracked[i].firstY; | ||||
|         } | ||||
|  | ||||
|         return { x: totalH / size, | ||||
|                  y: totalV / size }; | ||||
|     } | ||||
|  | ||||
|     _getAverageDistance() { | ||||
|         if (this._tracked.length === 0) { | ||||
|             throw new Error("Failed to get gesture distance, no tracked touches"); | ||||
|         } | ||||
|  | ||||
|         // Distance between the first and last tracked touches | ||||
|  | ||||
|         let first = this._tracked[0]; | ||||
|         let last = this._tracked[this._tracked.length - 1]; | ||||
|  | ||||
|         let fdx = Math.abs(last.firstX - first.firstX); | ||||
|         let fdy = Math.abs(last.firstY - first.firstY); | ||||
|  | ||||
|         let ldx = Math.abs(last.lastX - first.lastX); | ||||
|         let ldy = Math.abs(last.lastY - first.lastY); | ||||
|  | ||||
|         return { first: { x: fdx, y: fdy }, | ||||
|                  last: { x: ldx, y: ldy } }; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										273
									
								
								public/novnc/core/input/keyboard.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,273 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | ||||
|  */ | ||||
|  | ||||
| import * as Log from '../util/logging.js'; | ||||
| import { stopEvent } from '../util/events.js'; | ||||
| import * as KeyboardUtil from "./util.js"; | ||||
| import KeyTable from "./keysym.js"; | ||||
| import * as browser from "../util/browser.js"; | ||||
|  | ||||
| // | ||||
| // Keyboard event handler | ||||
| // | ||||
|  | ||||
| export default class Keyboard { | ||||
|     constructor(target) { | ||||
|         this._target = target || null; | ||||
|  | ||||
|         this._keyDownList = {};         // List of depressed keys | ||||
|                                         // (even if they are happy) | ||||
|         this._altGrArmed = false;       // Windows AltGr detection | ||||
|  | ||||
|         // keep these here so we can refer to them later | ||||
|         this._eventHandlers = { | ||||
|             'keyup': this._handleKeyUp.bind(this), | ||||
|             'keydown': this._handleKeyDown.bind(this), | ||||
|             'blur': this._allKeysUp.bind(this), | ||||
|         }; | ||||
|  | ||||
|         // ===== EVENT HANDLERS ===== | ||||
|  | ||||
|         this.onkeyevent = () => {}; // Handler for key press/release | ||||
|     } | ||||
|  | ||||
|     // ===== PRIVATE METHODS ===== | ||||
|  | ||||
|     _sendKeyEvent(keysym, code, down) { | ||||
|         if (down) { | ||||
|             this._keyDownList[code] = keysym; | ||||
|         } else { | ||||
|             // Do we really think this key is down? | ||||
|             if (!(code in this._keyDownList)) { | ||||
|                 return; | ||||
|             } | ||||
|             delete this._keyDownList[code]; | ||||
|         } | ||||
|  | ||||
|         Log.Debug("onkeyevent " + (down ? "down" : "up") + | ||||
|                   ", keysym: " + keysym, ", code: " + code); | ||||
|         this.onkeyevent(keysym, code, down); | ||||
|     } | ||||
|  | ||||
|     _getKeyCode(e) { | ||||
|         const code = KeyboardUtil.getKeycode(e); | ||||
|         if (code !== 'Unidentified') { | ||||
|             return code; | ||||
|         } | ||||
|  | ||||
|         // Unstable, but we don't have anything else to go on | ||||
|         if (e.keyCode) { | ||||
|             // 229 is used for composition events | ||||
|             if (e.keyCode !== 229) { | ||||
|                 return 'Platform' + e.keyCode; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // A precursor to the final DOM3 standard. Unfortunately it | ||||
|         // is not layout independent, so it is as bad as using keyCode | ||||
|         if (e.keyIdentifier) { | ||||
|             // Non-character key? | ||||
|             if (e.keyIdentifier.substr(0, 2) !== 'U+') { | ||||
|                 return e.keyIdentifier; | ||||
|             } | ||||
|  | ||||
|             const codepoint = parseInt(e.keyIdentifier.substr(2), 16); | ||||
|             const char = String.fromCharCode(codepoint).toUpperCase(); | ||||
|  | ||||
|             return 'Platform' + char.charCodeAt(); | ||||
|         } | ||||
|  | ||||
|         return 'Unidentified'; | ||||
|     } | ||||
|  | ||||
|     _handleKeyDown(e) { | ||||
|         const code = this._getKeyCode(e); | ||||
|         let keysym = KeyboardUtil.getKeysym(e); | ||||
|  | ||||
|         // Windows doesn't have a proper AltGr, but handles it using | ||||
|         // fake Ctrl+Alt. However the remote end might not be Windows, | ||||
|         // so we need to merge those in to a single AltGr event. We | ||||
|         // detect this case by seeing the two key events directly after | ||||
|         // each other with a very short time between them (<50ms). | ||||
|         if (this._altGrArmed) { | ||||
|             this._altGrArmed = false; | ||||
|             clearTimeout(this._altGrTimeout); | ||||
|  | ||||
|             if ((code === "AltRight") && | ||||
|                 ((e.timeStamp - this._altGrCtrlTime) < 50)) { | ||||
|                 // FIXME: We fail to detect this if either Ctrl key is | ||||
|                 //        first manually pressed as Windows then no | ||||
|                 //        longer sends the fake Ctrl down event. It | ||||
|                 //        does however happily send real Ctrl events | ||||
|                 //        even when AltGr is already down. Some | ||||
|                 //        browsers detect this for us though and set the | ||||
|                 //        key to "AltGraph". | ||||
|                 keysym = KeyTable.XK_ISO_Level3_Shift; | ||||
|             } else { | ||||
|                 this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // We cannot handle keys we cannot track, but we also need | ||||
|         // to deal with virtual keyboards which omit key info | ||||
|         if (code === 'Unidentified') { | ||||
|             if (keysym) { | ||||
|                 // If it's a virtual keyboard then it should be | ||||
|                 // sufficient to just send press and release right | ||||
|                 // after each other | ||||
|                 this._sendKeyEvent(keysym, code, true); | ||||
|                 this._sendKeyEvent(keysym, code, false); | ||||
|             } | ||||
|  | ||||
|             stopEvent(e); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Alt behaves more like AltGraph on macOS, so shuffle the | ||||
|         // keys around a bit to make things more sane for the remote | ||||
|         // server. This method is used by RealVNC and TigerVNC (and | ||||
|         // possibly others). | ||||
|         if (browser.isMac() || browser.isIOS()) { | ||||
|             switch (keysym) { | ||||
|                 case KeyTable.XK_Super_L: | ||||
|                     keysym = KeyTable.XK_Alt_L; | ||||
|                     break; | ||||
|                 case KeyTable.XK_Super_R: | ||||
|                     keysym = KeyTable.XK_Super_L; | ||||
|                     break; | ||||
|                 case KeyTable.XK_Alt_L: | ||||
|                     keysym = KeyTable.XK_Mode_switch; | ||||
|                     break; | ||||
|                 case KeyTable.XK_Alt_R: | ||||
|                     keysym = KeyTable.XK_ISO_Level3_Shift; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Is this key already pressed? If so, then we must use the | ||||
|         // same keysym or we'll confuse the server | ||||
|         if (code in this._keyDownList) { | ||||
|             keysym = this._keyDownList[code]; | ||||
|         } | ||||
|  | ||||
|         // macOS doesn't send proper key events for modifiers, only | ||||
|         // state change events. That gets extra confusing for CapsLock | ||||
|         // which toggles on each press, but not on release. So pretend | ||||
|         // it was a quick press and release of the button. | ||||
|         if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) { | ||||
|             this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true); | ||||
|             this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false); | ||||
|             stopEvent(e); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Windows doesn't send proper key releases for a bunch of | ||||
|         // Japanese IM keys so we have to fake the release right away | ||||
|         const jpBadKeys = [ KeyTable.XK_Zenkaku_Hankaku, | ||||
|                             KeyTable.XK_Eisu_toggle, | ||||
|                             KeyTable.XK_Katakana, | ||||
|                             KeyTable.XK_Hiragana, | ||||
|                             KeyTable.XK_Romaji ]; | ||||
|         if (browser.isWindows() && jpBadKeys.includes(keysym)) { | ||||
|             this._sendKeyEvent(keysym, code, true); | ||||
|             this._sendKeyEvent(keysym, code, false); | ||||
|             stopEvent(e); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         stopEvent(e); | ||||
|  | ||||
|         // Possible start of AltGr sequence? (see above) | ||||
|         if ((code === "ControlLeft") && browser.isWindows() && | ||||
|             !("ControlLeft" in this._keyDownList)) { | ||||
|             this._altGrArmed = true; | ||||
|             this._altGrTimeout = setTimeout(this._handleAltGrTimeout.bind(this), 100); | ||||
|             this._altGrCtrlTime = e.timeStamp; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this._sendKeyEvent(keysym, code, true); | ||||
|     } | ||||
|  | ||||
|     _handleKeyUp(e) { | ||||
|         stopEvent(e); | ||||
|  | ||||
|         const code = this._getKeyCode(e); | ||||
|  | ||||
|         // We can't get a release in the middle of an AltGr sequence, so | ||||
|         // abort that detection | ||||
|         if (this._altGrArmed) { | ||||
|             this._altGrArmed = false; | ||||
|             clearTimeout(this._altGrTimeout); | ||||
|             this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true); | ||||
|         } | ||||
|  | ||||
|         // See comment in _handleKeyDown() | ||||
|         if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) { | ||||
|             this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true); | ||||
|             this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this._sendKeyEvent(this._keyDownList[code], code, false); | ||||
|  | ||||
|         // Windows has a rather nasty bug where it won't send key | ||||
|         // release events for a Shift button if the other Shift is still | ||||
|         // pressed | ||||
|         if (browser.isWindows() && ((code === 'ShiftLeft') || | ||||
|                                     (code === 'ShiftRight'))) { | ||||
|             if ('ShiftRight' in this._keyDownList) { | ||||
|                 this._sendKeyEvent(this._keyDownList['ShiftRight'], | ||||
|                                    'ShiftRight', false); | ||||
|             } | ||||
|             if ('ShiftLeft' in this._keyDownList) { | ||||
|                 this._sendKeyEvent(this._keyDownList['ShiftLeft'], | ||||
|                                    'ShiftLeft', false); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _handleAltGrTimeout() { | ||||
|         this._altGrArmed = false; | ||||
|         clearTimeout(this._altGrTimeout); | ||||
|         this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true); | ||||
|     } | ||||
|  | ||||
|     _allKeysUp() { | ||||
|         Log.Debug(">> Keyboard.allKeysUp"); | ||||
|         for (let code in this._keyDownList) { | ||||
|             this._sendKeyEvent(this._keyDownList[code], code, false); | ||||
|         } | ||||
|         Log.Debug("<< Keyboard.allKeysUp"); | ||||
|     } | ||||
|  | ||||
|     // ===== PUBLIC METHODS ===== | ||||
|  | ||||
|     grab() { | ||||
|         //Log.Debug(">> Keyboard.grab"); | ||||
|  | ||||
|         this._target.addEventListener('keydown', this._eventHandlers.keydown); | ||||
|         this._target.addEventListener('keyup', this._eventHandlers.keyup); | ||||
|  | ||||
|         // Release (key up) if window loses focus | ||||
|         window.addEventListener('blur', this._eventHandlers.blur); | ||||
|  | ||||
|         //Log.Debug("<< Keyboard.grab"); | ||||
|     } | ||||
|  | ||||
|     ungrab() { | ||||
|         //Log.Debug(">> Keyboard.ungrab"); | ||||
|  | ||||
|         this._target.removeEventListener('keydown', this._eventHandlers.keydown); | ||||
|         this._target.removeEventListener('keyup', this._eventHandlers.keyup); | ||||
|         window.removeEventListener('blur', this._eventHandlers.blur); | ||||
|  | ||||
|         // Release (key up) all keys that are in a down state | ||||
|         this._allKeysUp(); | ||||
|  | ||||
|         //Log.Debug(">> Keyboard.ungrab"); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										616
									
								
								public/novnc/core/input/keysym.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,616 @@ | ||||
| /* eslint-disable key-spacing */ | ||||
|  | ||||
| export default { | ||||
|     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 */ | ||||
|  | ||||
|     /* International & multi-key character composition */ | ||||
|  | ||||
|     XK_Multi_key:                   0xff20, /* Multi-key character compose */ | ||||
|     XK_Codeinput:                   0xff37, | ||||
|     XK_SingleCandidate:             0xff3c, | ||||
|     XK_MultipleCandidate:           0xff3d, | ||||
|     XK_PreviousCandidate:           0xff3e, | ||||
|  | ||||
|     /* Japanese keyboard support */ | ||||
|  | ||||
|     XK_Kanji:                       0xff21, /* Kanji, Kanji convert */ | ||||
|     XK_Muhenkan:                    0xff22, /* Cancel Conversion */ | ||||
|     XK_Henkan_Mode:                 0xff23, /* Start/Stop Conversion */ | ||||
|     XK_Henkan:                      0xff23, /* Alias for Henkan_Mode */ | ||||
|     XK_Romaji:                      0xff24, /* to Romaji */ | ||||
|     XK_Hiragana:                    0xff25, /* to Hiragana */ | ||||
|     XK_Katakana:                    0xff26, /* to Katakana */ | ||||
|     XK_Hiragana_Katakana:           0xff27, /* Hiragana/Katakana toggle */ | ||||
|     XK_Zenkaku:                     0xff28, /* to Zenkaku */ | ||||
|     XK_Hankaku:                     0xff29, /* to Hankaku */ | ||||
|     XK_Zenkaku_Hankaku:             0xff2a, /* Zenkaku/Hankaku toggle */ | ||||
|     XK_Touroku:                     0xff2b, /* Add to Dictionary */ | ||||
|     XK_Massyo:                      0xff2c, /* Delete from Dictionary */ | ||||
|     XK_Kana_Lock:                   0xff2d, /* Kana Lock */ | ||||
|     XK_Kana_Shift:                  0xff2e, /* Kana Shift */ | ||||
|     XK_Eisu_Shift:                  0xff2f, /* Alphanumeric Shift */ | ||||
|     XK_Eisu_toggle:                 0xff30, /* Alphanumeric toggle */ | ||||
|     XK_Kanji_Bangou:                0xff37, /* Codeinput */ | ||||
|     XK_Zen_Koho:                    0xff3d, /* Multiple/All Candidate(s) */ | ||||
|     XK_Mae_Koho:                    0xff3e, /* Previous Candidate */ | ||||
|  | ||||
|     /* 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 */ | ||||
|  | ||||
|     /* | ||||
|      * Keyboard (XKB) Extension function and modifier keys | ||||
|      * (from Appendix C of "The X Keyboard Extension: Protocol Specification") | ||||
|      * Byte 3 = 0xfe | ||||
|      */ | ||||
|  | ||||
|     XK_ISO_Level3_Shift:            0xfe03, /* AltGr */ | ||||
|     XK_ISO_Next_Group:              0xfe08, | ||||
|     XK_ISO_Prev_Group:              0xfe0a, | ||||
|     XK_ISO_First_Group:             0xfe0c, | ||||
|     XK_ISO_Last_Group:              0xfe0e, | ||||
|  | ||||
|     /* | ||||
|      * 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 */ | ||||
|  | ||||
|     /* | ||||
|      * Korean | ||||
|      * Byte 3 = 0x0e | ||||
|      */ | ||||
|  | ||||
|     XK_Hangul:                      0xff31, /* Hangul start/stop(toggle) */ | ||||
|     XK_Hangul_Hanja:                0xff34, /* Start Hangul->Hanja Conversion */ | ||||
|     XK_Hangul_Jeonja:               0xff38, /* Jeonja mode */ | ||||
|  | ||||
|     /* | ||||
|      * XFree86 vendor specific keysyms. | ||||
|      * | ||||
|      * The XFree86 keysym range is 0x10080001 - 0x1008FFFF. | ||||
|      */ | ||||
|  | ||||
|     XF86XK_ModeLock:                0x1008FF01, | ||||
|     XF86XK_MonBrightnessUp:         0x1008FF02, | ||||
|     XF86XK_MonBrightnessDown:       0x1008FF03, | ||||
|     XF86XK_KbdLightOnOff:           0x1008FF04, | ||||
|     XF86XK_KbdBrightnessUp:         0x1008FF05, | ||||
|     XF86XK_KbdBrightnessDown:       0x1008FF06, | ||||
|     XF86XK_Standby:                 0x1008FF10, | ||||
|     XF86XK_AudioLowerVolume:        0x1008FF11, | ||||
|     XF86XK_AudioMute:               0x1008FF12, | ||||
|     XF86XK_AudioRaiseVolume:        0x1008FF13, | ||||
|     XF86XK_AudioPlay:               0x1008FF14, | ||||
|     XF86XK_AudioStop:               0x1008FF15, | ||||
|     XF86XK_AudioPrev:               0x1008FF16, | ||||
|     XF86XK_AudioNext:               0x1008FF17, | ||||
|     XF86XK_HomePage:                0x1008FF18, | ||||
|     XF86XK_Mail:                    0x1008FF19, | ||||
|     XF86XK_Start:                   0x1008FF1A, | ||||
|     XF86XK_Search:                  0x1008FF1B, | ||||
|     XF86XK_AudioRecord:             0x1008FF1C, | ||||
|     XF86XK_Calculator:              0x1008FF1D, | ||||
|     XF86XK_Memo:                    0x1008FF1E, | ||||
|     XF86XK_ToDoList:                0x1008FF1F, | ||||
|     XF86XK_Calendar:                0x1008FF20, | ||||
|     XF86XK_PowerDown:               0x1008FF21, | ||||
|     XF86XK_ContrastAdjust:          0x1008FF22, | ||||
|     XF86XK_RockerUp:                0x1008FF23, | ||||
|     XF86XK_RockerDown:              0x1008FF24, | ||||
|     XF86XK_RockerEnter:             0x1008FF25, | ||||
|     XF86XK_Back:                    0x1008FF26, | ||||
|     XF86XK_Forward:                 0x1008FF27, | ||||
|     XF86XK_Stop:                    0x1008FF28, | ||||
|     XF86XK_Refresh:                 0x1008FF29, | ||||
|     XF86XK_PowerOff:                0x1008FF2A, | ||||
|     XF86XK_WakeUp:                  0x1008FF2B, | ||||
|     XF86XK_Eject:                   0x1008FF2C, | ||||
|     XF86XK_ScreenSaver:             0x1008FF2D, | ||||
|     XF86XK_WWW:                     0x1008FF2E, | ||||
|     XF86XK_Sleep:                   0x1008FF2F, | ||||
|     XF86XK_Favorites:               0x1008FF30, | ||||
|     XF86XK_AudioPause:              0x1008FF31, | ||||
|     XF86XK_AudioMedia:              0x1008FF32, | ||||
|     XF86XK_MyComputer:              0x1008FF33, | ||||
|     XF86XK_VendorHome:              0x1008FF34, | ||||
|     XF86XK_LightBulb:               0x1008FF35, | ||||
|     XF86XK_Shop:                    0x1008FF36, | ||||
|     XF86XK_History:                 0x1008FF37, | ||||
|     XF86XK_OpenURL:                 0x1008FF38, | ||||
|     XF86XK_AddFavorite:             0x1008FF39, | ||||
|     XF86XK_HotLinks:                0x1008FF3A, | ||||
|     XF86XK_BrightnessAdjust:        0x1008FF3B, | ||||
|     XF86XK_Finance:                 0x1008FF3C, | ||||
|     XF86XK_Community:               0x1008FF3D, | ||||
|     XF86XK_AudioRewind:             0x1008FF3E, | ||||
|     XF86XK_BackForward:             0x1008FF3F, | ||||
|     XF86XK_Launch0:                 0x1008FF40, | ||||
|     XF86XK_Launch1:                 0x1008FF41, | ||||
|     XF86XK_Launch2:                 0x1008FF42, | ||||
|     XF86XK_Launch3:                 0x1008FF43, | ||||
|     XF86XK_Launch4:                 0x1008FF44, | ||||
|     XF86XK_Launch5:                 0x1008FF45, | ||||
|     XF86XK_Launch6:                 0x1008FF46, | ||||
|     XF86XK_Launch7:                 0x1008FF47, | ||||
|     XF86XK_Launch8:                 0x1008FF48, | ||||
|     XF86XK_Launch9:                 0x1008FF49, | ||||
|     XF86XK_LaunchA:                 0x1008FF4A, | ||||
|     XF86XK_LaunchB:                 0x1008FF4B, | ||||
|     XF86XK_LaunchC:                 0x1008FF4C, | ||||
|     XF86XK_LaunchD:                 0x1008FF4D, | ||||
|     XF86XK_LaunchE:                 0x1008FF4E, | ||||
|     XF86XK_LaunchF:                 0x1008FF4F, | ||||
|     XF86XK_ApplicationLeft:         0x1008FF50, | ||||
|     XF86XK_ApplicationRight:        0x1008FF51, | ||||
|     XF86XK_Book:                    0x1008FF52, | ||||
|     XF86XK_CD:                      0x1008FF53, | ||||
|     XF86XK_Calculater:              0x1008FF54, | ||||
|     XF86XK_Clear:                   0x1008FF55, | ||||
|     XF86XK_Close:                   0x1008FF56, | ||||
|     XF86XK_Copy:                    0x1008FF57, | ||||
|     XF86XK_Cut:                     0x1008FF58, | ||||
|     XF86XK_Display:                 0x1008FF59, | ||||
|     XF86XK_DOS:                     0x1008FF5A, | ||||
|     XF86XK_Documents:               0x1008FF5B, | ||||
|     XF86XK_Excel:                   0x1008FF5C, | ||||
|     XF86XK_Explorer:                0x1008FF5D, | ||||
|     XF86XK_Game:                    0x1008FF5E, | ||||
|     XF86XK_Go:                      0x1008FF5F, | ||||
|     XF86XK_iTouch:                  0x1008FF60, | ||||
|     XF86XK_LogOff:                  0x1008FF61, | ||||
|     XF86XK_Market:                  0x1008FF62, | ||||
|     XF86XK_Meeting:                 0x1008FF63, | ||||
|     XF86XK_MenuKB:                  0x1008FF65, | ||||
|     XF86XK_MenuPB:                  0x1008FF66, | ||||
|     XF86XK_MySites:                 0x1008FF67, | ||||
|     XF86XK_New:                     0x1008FF68, | ||||
|     XF86XK_News:                    0x1008FF69, | ||||
|     XF86XK_OfficeHome:              0x1008FF6A, | ||||
|     XF86XK_Open:                    0x1008FF6B, | ||||
|     XF86XK_Option:                  0x1008FF6C, | ||||
|     XF86XK_Paste:                   0x1008FF6D, | ||||
|     XF86XK_Phone:                   0x1008FF6E, | ||||
|     XF86XK_Q:                       0x1008FF70, | ||||
|     XF86XK_Reply:                   0x1008FF72, | ||||
|     XF86XK_Reload:                  0x1008FF73, | ||||
|     XF86XK_RotateWindows:           0x1008FF74, | ||||
|     XF86XK_RotationPB:              0x1008FF75, | ||||
|     XF86XK_RotationKB:              0x1008FF76, | ||||
|     XF86XK_Save:                    0x1008FF77, | ||||
|     XF86XK_ScrollUp:                0x1008FF78, | ||||
|     XF86XK_ScrollDown:              0x1008FF79, | ||||
|     XF86XK_ScrollClick:             0x1008FF7A, | ||||
|     XF86XK_Send:                    0x1008FF7B, | ||||
|     XF86XK_Spell:                   0x1008FF7C, | ||||
|     XF86XK_SplitScreen:             0x1008FF7D, | ||||
|     XF86XK_Support:                 0x1008FF7E, | ||||
|     XF86XK_TaskPane:                0x1008FF7F, | ||||
|     XF86XK_Terminal:                0x1008FF80, | ||||
|     XF86XK_Tools:                   0x1008FF81, | ||||
|     XF86XK_Travel:                  0x1008FF82, | ||||
|     XF86XK_UserPB:                  0x1008FF84, | ||||
|     XF86XK_User1KB:                 0x1008FF85, | ||||
|     XF86XK_User2KB:                 0x1008FF86, | ||||
|     XF86XK_Video:                   0x1008FF87, | ||||
|     XF86XK_WheelButton:             0x1008FF88, | ||||
|     XF86XK_Word:                    0x1008FF89, | ||||
|     XF86XK_Xfer:                    0x1008FF8A, | ||||
|     XF86XK_ZoomIn:                  0x1008FF8B, | ||||
|     XF86XK_ZoomOut:                 0x1008FF8C, | ||||
|     XF86XK_Away:                    0x1008FF8D, | ||||
|     XF86XK_Messenger:               0x1008FF8E, | ||||
|     XF86XK_WebCam:                  0x1008FF8F, | ||||
|     XF86XK_MailForward:             0x1008FF90, | ||||
|     XF86XK_Pictures:                0x1008FF91, | ||||
|     XF86XK_Music:                   0x1008FF92, | ||||
|     XF86XK_Battery:                 0x1008FF93, | ||||
|     XF86XK_Bluetooth:               0x1008FF94, | ||||
|     XF86XK_WLAN:                    0x1008FF95, | ||||
|     XF86XK_UWB:                     0x1008FF96, | ||||
|     XF86XK_AudioForward:            0x1008FF97, | ||||
|     XF86XK_AudioRepeat:             0x1008FF98, | ||||
|     XF86XK_AudioRandomPlay:         0x1008FF99, | ||||
|     XF86XK_Subtitle:                0x1008FF9A, | ||||
|     XF86XK_AudioCycleTrack:         0x1008FF9B, | ||||
|     XF86XK_CycleAngle:              0x1008FF9C, | ||||
|     XF86XK_FrameBack:               0x1008FF9D, | ||||
|     XF86XK_FrameForward:            0x1008FF9E, | ||||
|     XF86XK_Time:                    0x1008FF9F, | ||||
|     XF86XK_Select:                  0x1008FFA0, | ||||
|     XF86XK_View:                    0x1008FFA1, | ||||
|     XF86XK_TopMenu:                 0x1008FFA2, | ||||
|     XF86XK_Red:                     0x1008FFA3, | ||||
|     XF86XK_Green:                   0x1008FFA4, | ||||
|     XF86XK_Yellow:                  0x1008FFA5, | ||||
|     XF86XK_Blue:                    0x1008FFA6, | ||||
|     XF86XK_Suspend:                 0x1008FFA7, | ||||
|     XF86XK_Hibernate:               0x1008FFA8, | ||||
|     XF86XK_TouchpadToggle:          0x1008FFA9, | ||||
|     XF86XK_TouchpadOn:              0x1008FFB0, | ||||
|     XF86XK_TouchpadOff:             0x1008FFB1, | ||||
|     XF86XK_AudioMicMute:            0x1008FFB2, | ||||
|     XF86XK_Switch_VT_1:             0x1008FE01, | ||||
|     XF86XK_Switch_VT_2:             0x1008FE02, | ||||
|     XF86XK_Switch_VT_3:             0x1008FE03, | ||||
|     XF86XK_Switch_VT_4:             0x1008FE04, | ||||
|     XF86XK_Switch_VT_5:             0x1008FE05, | ||||
|     XF86XK_Switch_VT_6:             0x1008FE06, | ||||
|     XF86XK_Switch_VT_7:             0x1008FE07, | ||||
|     XF86XK_Switch_VT_8:             0x1008FE08, | ||||
|     XF86XK_Switch_VT_9:             0x1008FE09, | ||||
|     XF86XK_Switch_VT_10:            0x1008FE0A, | ||||
|     XF86XK_Switch_VT_11:            0x1008FE0B, | ||||
|     XF86XK_Switch_VT_12:            0x1008FE0C, | ||||
|     XF86XK_Ungrab:                  0x1008FE20, | ||||
|     XF86XK_ClearGrab:               0x1008FE21, | ||||
|     XF86XK_Next_VMode:              0x1008FE22, | ||||
|     XF86XK_Prev_VMode:              0x1008FE23, | ||||
|     XF86XK_LogWindowTree:           0x1008FE24, | ||||
|     XF86XK_LogGrabInfo:             0x1008FE25, | ||||
| }; | ||||
							
								
								
									
										688
									
								
								public/novnc/core/input/keysymdef.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,688 @@ | ||||
| /* | ||||
|  * Mapping from Unicode codepoints to X11/RFB keysyms | ||||
|  * | ||||
|  * This file was automatically generated from keysymdef.h | ||||
|  * DO NOT EDIT! | ||||
|  */ | ||||
|  | ||||
| /* Functions at the bottom */ | ||||
|  | ||||
| const codepoints = { | ||||
|     0x0100: 0x03c0, // XK_Amacron | ||||
|     0x0101: 0x03e0, // XK_amacron | ||||
|     0x0102: 0x01c3, // XK_Abreve | ||||
|     0x0103: 0x01e3, // XK_abreve | ||||
|     0x0104: 0x01a1, // XK_Aogonek | ||||
|     0x0105: 0x01b1, // XK_aogonek | ||||
|     0x0106: 0x01c6, // XK_Cacute | ||||
|     0x0107: 0x01e6, // XK_cacute | ||||
|     0x0108: 0x02c6, // XK_Ccircumflex | ||||
|     0x0109: 0x02e6, // XK_ccircumflex | ||||
|     0x010a: 0x02c5, // XK_Cabovedot | ||||
|     0x010b: 0x02e5, // XK_cabovedot | ||||
|     0x010c: 0x01c8, // XK_Ccaron | ||||
|     0x010d: 0x01e8, // XK_ccaron | ||||
|     0x010e: 0x01cf, // XK_Dcaron | ||||
|     0x010f: 0x01ef, // XK_dcaron | ||||
|     0x0110: 0x01d0, // XK_Dstroke | ||||
|     0x0111: 0x01f0, // XK_dstroke | ||||
|     0x0112: 0x03aa, // XK_Emacron | ||||
|     0x0113: 0x03ba, // XK_emacron | ||||
|     0x0116: 0x03cc, // XK_Eabovedot | ||||
|     0x0117: 0x03ec, // XK_eabovedot | ||||
|     0x0118: 0x01ca, // XK_Eogonek | ||||
|     0x0119: 0x01ea, // XK_eogonek | ||||
|     0x011a: 0x01cc, // XK_Ecaron | ||||
|     0x011b: 0x01ec, // XK_ecaron | ||||
|     0x011c: 0x02d8, // XK_Gcircumflex | ||||
|     0x011d: 0x02f8, // XK_gcircumflex | ||||
|     0x011e: 0x02ab, // XK_Gbreve | ||||
|     0x011f: 0x02bb, // XK_gbreve | ||||
|     0x0120: 0x02d5, // XK_Gabovedot | ||||
|     0x0121: 0x02f5, // XK_gabovedot | ||||
|     0x0122: 0x03ab, // XK_Gcedilla | ||||
|     0x0123: 0x03bb, // XK_gcedilla | ||||
|     0x0124: 0x02a6, // XK_Hcircumflex | ||||
|     0x0125: 0x02b6, // XK_hcircumflex | ||||
|     0x0126: 0x02a1, // XK_Hstroke | ||||
|     0x0127: 0x02b1, // XK_hstroke | ||||
|     0x0128: 0x03a5, // XK_Itilde | ||||
|     0x0129: 0x03b5, // XK_itilde | ||||
|     0x012a: 0x03cf, // XK_Imacron | ||||
|     0x012b: 0x03ef, // XK_imacron | ||||
|     0x012e: 0x03c7, // XK_Iogonek | ||||
|     0x012f: 0x03e7, // XK_iogonek | ||||
|     0x0130: 0x02a9, // XK_Iabovedot | ||||
|     0x0131: 0x02b9, // XK_idotless | ||||
|     0x0134: 0x02ac, // XK_Jcircumflex | ||||
|     0x0135: 0x02bc, // XK_jcircumflex | ||||
|     0x0136: 0x03d3, // XK_Kcedilla | ||||
|     0x0137: 0x03f3, // XK_kcedilla | ||||
|     0x0138: 0x03a2, // XK_kra | ||||
|     0x0139: 0x01c5, // XK_Lacute | ||||
|     0x013a: 0x01e5, // XK_lacute | ||||
|     0x013b: 0x03a6, // XK_Lcedilla | ||||
|     0x013c: 0x03b6, // XK_lcedilla | ||||
|     0x013d: 0x01a5, // XK_Lcaron | ||||
|     0x013e: 0x01b5, // XK_lcaron | ||||
|     0x0141: 0x01a3, // XK_Lstroke | ||||
|     0x0142: 0x01b3, // XK_lstroke | ||||
|     0x0143: 0x01d1, // XK_Nacute | ||||
|     0x0144: 0x01f1, // XK_nacute | ||||
|     0x0145: 0x03d1, // XK_Ncedilla | ||||
|     0x0146: 0x03f1, // XK_ncedilla | ||||
|     0x0147: 0x01d2, // XK_Ncaron | ||||
|     0x0148: 0x01f2, // XK_ncaron | ||||
|     0x014a: 0x03bd, // XK_ENG | ||||
|     0x014b: 0x03bf, // XK_eng | ||||
|     0x014c: 0x03d2, // XK_Omacron | ||||
|     0x014d: 0x03f2, // XK_omacron | ||||
|     0x0150: 0x01d5, // XK_Odoubleacute | ||||
|     0x0151: 0x01f5, // XK_odoubleacute | ||||
|     0x0152: 0x13bc, // XK_OE | ||||
|     0x0153: 0x13bd, // XK_oe | ||||
|     0x0154: 0x01c0, // XK_Racute | ||||
|     0x0155: 0x01e0, // XK_racute | ||||
|     0x0156: 0x03a3, // XK_Rcedilla | ||||
|     0x0157: 0x03b3, // XK_rcedilla | ||||
|     0x0158: 0x01d8, // XK_Rcaron | ||||
|     0x0159: 0x01f8, // XK_rcaron | ||||
|     0x015a: 0x01a6, // XK_Sacute | ||||
|     0x015b: 0x01b6, // XK_sacute | ||||
|     0x015c: 0x02de, // XK_Scircumflex | ||||
|     0x015d: 0x02fe, // XK_scircumflex | ||||
|     0x015e: 0x01aa, // XK_Scedilla | ||||
|     0x015f: 0x01ba, // XK_scedilla | ||||
|     0x0160: 0x01a9, // XK_Scaron | ||||
|     0x0161: 0x01b9, // XK_scaron | ||||
|     0x0162: 0x01de, // XK_Tcedilla | ||||
|     0x0163: 0x01fe, // XK_tcedilla | ||||
|     0x0164: 0x01ab, // XK_Tcaron | ||||
|     0x0165: 0x01bb, // XK_tcaron | ||||
|     0x0166: 0x03ac, // XK_Tslash | ||||
|     0x0167: 0x03bc, // XK_tslash | ||||
|     0x0168: 0x03dd, // XK_Utilde | ||||
|     0x0169: 0x03fd, // XK_utilde | ||||
|     0x016a: 0x03de, // XK_Umacron | ||||
|     0x016b: 0x03fe, // XK_umacron | ||||
|     0x016c: 0x02dd, // XK_Ubreve | ||||
|     0x016d: 0x02fd, // XK_ubreve | ||||
|     0x016e: 0x01d9, // XK_Uring | ||||
|     0x016f: 0x01f9, // XK_uring | ||||
|     0x0170: 0x01db, // XK_Udoubleacute | ||||
|     0x0171: 0x01fb, // XK_udoubleacute | ||||
|     0x0172: 0x03d9, // XK_Uogonek | ||||
|     0x0173: 0x03f9, // XK_uogonek | ||||
|     0x0178: 0x13be, // XK_Ydiaeresis | ||||
|     0x0179: 0x01ac, // XK_Zacute | ||||
|     0x017a: 0x01bc, // XK_zacute | ||||
|     0x017b: 0x01af, // XK_Zabovedot | ||||
|     0x017c: 0x01bf, // XK_zabovedot | ||||
|     0x017d: 0x01ae, // XK_Zcaron | ||||
|     0x017e: 0x01be, // XK_zcaron | ||||
|     0x0192: 0x08f6, // XK_function | ||||
|     0x01d2: 0x10001d1, // XK_Ocaron | ||||
|     0x02c7: 0x01b7, // XK_caron | ||||
|     0x02d8: 0x01a2, // XK_breve | ||||
|     0x02d9: 0x01ff, // XK_abovedot | ||||
|     0x02db: 0x01b2, // XK_ogonek | ||||
|     0x02dd: 0x01bd, // XK_doubleacute | ||||
|     0x0385: 0x07ae, // XK_Greek_accentdieresis | ||||
|     0x0386: 0x07a1, // XK_Greek_ALPHAaccent | ||||
|     0x0388: 0x07a2, // XK_Greek_EPSILONaccent | ||||
|     0x0389: 0x07a3, // XK_Greek_ETAaccent | ||||
|     0x038a: 0x07a4, // XK_Greek_IOTAaccent | ||||
|     0x038c: 0x07a7, // XK_Greek_OMICRONaccent | ||||
|     0x038e: 0x07a8, // XK_Greek_UPSILONaccent | ||||
|     0x038f: 0x07ab, // XK_Greek_OMEGAaccent | ||||
|     0x0390: 0x07b6, // XK_Greek_iotaaccentdieresis | ||||
|     0x0391: 0x07c1, // XK_Greek_ALPHA | ||||
|     0x0392: 0x07c2, // XK_Greek_BETA | ||||
|     0x0393: 0x07c3, // XK_Greek_GAMMA | ||||
|     0x0394: 0x07c4, // XK_Greek_DELTA | ||||
|     0x0395: 0x07c5, // XK_Greek_EPSILON | ||||
|     0x0396: 0x07c6, // XK_Greek_ZETA | ||||
|     0x0397: 0x07c7, // XK_Greek_ETA | ||||
|     0x0398: 0x07c8, // XK_Greek_THETA | ||||
|     0x0399: 0x07c9, // XK_Greek_IOTA | ||||
|     0x039a: 0x07ca, // XK_Greek_KAPPA | ||||
|     0x039b: 0x07cb, // XK_Greek_LAMDA | ||||
|     0x039c: 0x07cc, // XK_Greek_MU | ||||
|     0x039d: 0x07cd, // XK_Greek_NU | ||||
|     0x039e: 0x07ce, // XK_Greek_XI | ||||
|     0x039f: 0x07cf, // XK_Greek_OMICRON | ||||
|     0x03a0: 0x07d0, // XK_Greek_PI | ||||
|     0x03a1: 0x07d1, // XK_Greek_RHO | ||||
|     0x03a3: 0x07d2, // XK_Greek_SIGMA | ||||
|     0x03a4: 0x07d4, // XK_Greek_TAU | ||||
|     0x03a5: 0x07d5, // XK_Greek_UPSILON | ||||
|     0x03a6: 0x07d6, // XK_Greek_PHI | ||||
|     0x03a7: 0x07d7, // XK_Greek_CHI | ||||
|     0x03a8: 0x07d8, // XK_Greek_PSI | ||||
|     0x03a9: 0x07d9, // XK_Greek_OMEGA | ||||
|     0x03aa: 0x07a5, // XK_Greek_IOTAdieresis | ||||
|     0x03ab: 0x07a9, // XK_Greek_UPSILONdieresis | ||||
|     0x03ac: 0x07b1, // XK_Greek_alphaaccent | ||||
|     0x03ad: 0x07b2, // XK_Greek_epsilonaccent | ||||
|     0x03ae: 0x07b3, // XK_Greek_etaaccent | ||||
|     0x03af: 0x07b4, // XK_Greek_iotaaccent | ||||
|     0x03b0: 0x07ba, // XK_Greek_upsilonaccentdieresis | ||||
|     0x03b1: 0x07e1, // XK_Greek_alpha | ||||
|     0x03b2: 0x07e2, // XK_Greek_beta | ||||
|     0x03b3: 0x07e3, // XK_Greek_gamma | ||||
|     0x03b4: 0x07e4, // XK_Greek_delta | ||||
|     0x03b5: 0x07e5, // XK_Greek_epsilon | ||||
|     0x03b6: 0x07e6, // XK_Greek_zeta | ||||
|     0x03b7: 0x07e7, // XK_Greek_eta | ||||
|     0x03b8: 0x07e8, // XK_Greek_theta | ||||
|     0x03b9: 0x07e9, // XK_Greek_iota | ||||
|     0x03ba: 0x07ea, // XK_Greek_kappa | ||||
|     0x03bb: 0x07eb, // XK_Greek_lamda | ||||
|     0x03bc: 0x07ec, // XK_Greek_mu | ||||
|     0x03bd: 0x07ed, // XK_Greek_nu | ||||
|     0x03be: 0x07ee, // XK_Greek_xi | ||||
|     0x03bf: 0x07ef, // XK_Greek_omicron | ||||
|     0x03c0: 0x07f0, // XK_Greek_pi | ||||
|     0x03c1: 0x07f1, // XK_Greek_rho | ||||
|     0x03c2: 0x07f3, // XK_Greek_finalsmallsigma | ||||
|     0x03c3: 0x07f2, // XK_Greek_sigma | ||||
|     0x03c4: 0x07f4, // XK_Greek_tau | ||||
|     0x03c5: 0x07f5, // XK_Greek_upsilon | ||||
|     0x03c6: 0x07f6, // XK_Greek_phi | ||||
|     0x03c7: 0x07f7, // XK_Greek_chi | ||||
|     0x03c8: 0x07f8, // XK_Greek_psi | ||||
|     0x03c9: 0x07f9, // XK_Greek_omega | ||||
|     0x03ca: 0x07b5, // XK_Greek_iotadieresis | ||||
|     0x03cb: 0x07b9, // XK_Greek_upsilondieresis | ||||
|     0x03cc: 0x07b7, // XK_Greek_omicronaccent | ||||
|     0x03cd: 0x07b8, // XK_Greek_upsilonaccent | ||||
|     0x03ce: 0x07bb, // XK_Greek_omegaaccent | ||||
|     0x0401: 0x06b3, // XK_Cyrillic_IO | ||||
|     0x0402: 0x06b1, // XK_Serbian_DJE | ||||
|     0x0403: 0x06b2, // XK_Macedonia_GJE | ||||
|     0x0404: 0x06b4, // XK_Ukrainian_IE | ||||
|     0x0405: 0x06b5, // XK_Macedonia_DSE | ||||
|     0x0406: 0x06b6, // XK_Ukrainian_I | ||||
|     0x0407: 0x06b7, // XK_Ukrainian_YI | ||||
|     0x0408: 0x06b8, // XK_Cyrillic_JE | ||||
|     0x0409: 0x06b9, // XK_Cyrillic_LJE | ||||
|     0x040a: 0x06ba, // XK_Cyrillic_NJE | ||||
|     0x040b: 0x06bb, // XK_Serbian_TSHE | ||||
|     0x040c: 0x06bc, // XK_Macedonia_KJE | ||||
|     0x040e: 0x06be, // XK_Byelorussian_SHORTU | ||||
|     0x040f: 0x06bf, // XK_Cyrillic_DZHE | ||||
|     0x0410: 0x06e1, // XK_Cyrillic_A | ||||
|     0x0411: 0x06e2, // XK_Cyrillic_BE | ||||
|     0x0412: 0x06f7, // XK_Cyrillic_VE | ||||
|     0x0413: 0x06e7, // XK_Cyrillic_GHE | ||||
|     0x0414: 0x06e4, // XK_Cyrillic_DE | ||||
|     0x0415: 0x06e5, // XK_Cyrillic_IE | ||||
|     0x0416: 0x06f6, // XK_Cyrillic_ZHE | ||||
|     0x0417: 0x06fa, // XK_Cyrillic_ZE | ||||
|     0x0418: 0x06e9, // XK_Cyrillic_I | ||||
|     0x0419: 0x06ea, // XK_Cyrillic_SHORTI | ||||
|     0x041a: 0x06eb, // XK_Cyrillic_KA | ||||
|     0x041b: 0x06ec, // XK_Cyrillic_EL | ||||
|     0x041c: 0x06ed, // XK_Cyrillic_EM | ||||
|     0x041d: 0x06ee, // XK_Cyrillic_EN | ||||
|     0x041e: 0x06ef, // XK_Cyrillic_O | ||||
|     0x041f: 0x06f0, // XK_Cyrillic_PE | ||||
|     0x0420: 0x06f2, // XK_Cyrillic_ER | ||||
|     0x0421: 0x06f3, // XK_Cyrillic_ES | ||||
|     0x0422: 0x06f4, // XK_Cyrillic_TE | ||||
|     0x0423: 0x06f5, // XK_Cyrillic_U | ||||
|     0x0424: 0x06e6, // XK_Cyrillic_EF | ||||
|     0x0425: 0x06e8, // XK_Cyrillic_HA | ||||
|     0x0426: 0x06e3, // XK_Cyrillic_TSE | ||||
|     0x0427: 0x06fe, // XK_Cyrillic_CHE | ||||
|     0x0428: 0x06fb, // XK_Cyrillic_SHA | ||||
|     0x0429: 0x06fd, // XK_Cyrillic_SHCHA | ||||
|     0x042a: 0x06ff, // XK_Cyrillic_HARDSIGN | ||||
|     0x042b: 0x06f9, // XK_Cyrillic_YERU | ||||
|     0x042c: 0x06f8, // XK_Cyrillic_SOFTSIGN | ||||
|     0x042d: 0x06fc, // XK_Cyrillic_E | ||||
|     0x042e: 0x06e0, // XK_Cyrillic_YU | ||||
|     0x042f: 0x06f1, // XK_Cyrillic_YA | ||||
|     0x0430: 0x06c1, // XK_Cyrillic_a | ||||
|     0x0431: 0x06c2, // XK_Cyrillic_be | ||||
|     0x0432: 0x06d7, // XK_Cyrillic_ve | ||||
|     0x0433: 0x06c7, // XK_Cyrillic_ghe | ||||
|     0x0434: 0x06c4, // XK_Cyrillic_de | ||||
|     0x0435: 0x06c5, // XK_Cyrillic_ie | ||||
|     0x0436: 0x06d6, // XK_Cyrillic_zhe | ||||
|     0x0437: 0x06da, // XK_Cyrillic_ze | ||||
|     0x0438: 0x06c9, // XK_Cyrillic_i | ||||
|     0x0439: 0x06ca, // XK_Cyrillic_shorti | ||||
|     0x043a: 0x06cb, // XK_Cyrillic_ka | ||||
|     0x043b: 0x06cc, // XK_Cyrillic_el | ||||
|     0x043c: 0x06cd, // XK_Cyrillic_em | ||||
|     0x043d: 0x06ce, // XK_Cyrillic_en | ||||
|     0x043e: 0x06cf, // XK_Cyrillic_o | ||||
|     0x043f: 0x06d0, // XK_Cyrillic_pe | ||||
|     0x0440: 0x06d2, // XK_Cyrillic_er | ||||
|     0x0441: 0x06d3, // XK_Cyrillic_es | ||||
|     0x0442: 0x06d4, // XK_Cyrillic_te | ||||
|     0x0443: 0x06d5, // XK_Cyrillic_u | ||||
|     0x0444: 0x06c6, // XK_Cyrillic_ef | ||||
|     0x0445: 0x06c8, // XK_Cyrillic_ha | ||||
|     0x0446: 0x06c3, // XK_Cyrillic_tse | ||||
|     0x0447: 0x06de, // XK_Cyrillic_che | ||||
|     0x0448: 0x06db, // XK_Cyrillic_sha | ||||
|     0x0449: 0x06dd, // XK_Cyrillic_shcha | ||||
|     0x044a: 0x06df, // XK_Cyrillic_hardsign | ||||
|     0x044b: 0x06d9, // XK_Cyrillic_yeru | ||||
|     0x044c: 0x06d8, // XK_Cyrillic_softsign | ||||
|     0x044d: 0x06dc, // XK_Cyrillic_e | ||||
|     0x044e: 0x06c0, // XK_Cyrillic_yu | ||||
|     0x044f: 0x06d1, // XK_Cyrillic_ya | ||||
|     0x0451: 0x06a3, // XK_Cyrillic_io | ||||
|     0x0452: 0x06a1, // XK_Serbian_dje | ||||
|     0x0453: 0x06a2, // XK_Macedonia_gje | ||||
|     0x0454: 0x06a4, // XK_Ukrainian_ie | ||||
|     0x0455: 0x06a5, // XK_Macedonia_dse | ||||
|     0x0456: 0x06a6, // XK_Ukrainian_i | ||||
|     0x0457: 0x06a7, // XK_Ukrainian_yi | ||||
|     0x0458: 0x06a8, // XK_Cyrillic_je | ||||
|     0x0459: 0x06a9, // XK_Cyrillic_lje | ||||
|     0x045a: 0x06aa, // XK_Cyrillic_nje | ||||
|     0x045b: 0x06ab, // XK_Serbian_tshe | ||||
|     0x045c: 0x06ac, // XK_Macedonia_kje | ||||
|     0x045e: 0x06ae, // XK_Byelorussian_shortu | ||||
|     0x045f: 0x06af, // XK_Cyrillic_dzhe | ||||
|     0x0490: 0x06bd, // XK_Ukrainian_GHE_WITH_UPTURN | ||||
|     0x0491: 0x06ad, // XK_Ukrainian_ghe_with_upturn | ||||
|     0x05d0: 0x0ce0, // XK_hebrew_aleph | ||||
|     0x05d1: 0x0ce1, // XK_hebrew_bet | ||||
|     0x05d2: 0x0ce2, // XK_hebrew_gimel | ||||
|     0x05d3: 0x0ce3, // XK_hebrew_dalet | ||||
|     0x05d4: 0x0ce4, // XK_hebrew_he | ||||
|     0x05d5: 0x0ce5, // XK_hebrew_waw | ||||
|     0x05d6: 0x0ce6, // XK_hebrew_zain | ||||
|     0x05d7: 0x0ce7, // XK_hebrew_chet | ||||
|     0x05d8: 0x0ce8, // XK_hebrew_tet | ||||
|     0x05d9: 0x0ce9, // XK_hebrew_yod | ||||
|     0x05da: 0x0cea, // XK_hebrew_finalkaph | ||||
|     0x05db: 0x0ceb, // XK_hebrew_kaph | ||||
|     0x05dc: 0x0cec, // XK_hebrew_lamed | ||||
|     0x05dd: 0x0ced, // XK_hebrew_finalmem | ||||
|     0x05de: 0x0cee, // XK_hebrew_mem | ||||
|     0x05df: 0x0cef, // XK_hebrew_finalnun | ||||
|     0x05e0: 0x0cf0, // XK_hebrew_nun | ||||
|     0x05e1: 0x0cf1, // XK_hebrew_samech | ||||
|     0x05e2: 0x0cf2, // XK_hebrew_ayin | ||||
|     0x05e3: 0x0cf3, // XK_hebrew_finalpe | ||||
|     0x05e4: 0x0cf4, // XK_hebrew_pe | ||||
|     0x05e5: 0x0cf5, // XK_hebrew_finalzade | ||||
|     0x05e6: 0x0cf6, // XK_hebrew_zade | ||||
|     0x05e7: 0x0cf7, // XK_hebrew_qoph | ||||
|     0x05e8: 0x0cf8, // XK_hebrew_resh | ||||
|     0x05e9: 0x0cf9, // XK_hebrew_shin | ||||
|     0x05ea: 0x0cfa, // XK_hebrew_taw | ||||
|     0x060c: 0x05ac, // XK_Arabic_comma | ||||
|     0x061b: 0x05bb, // XK_Arabic_semicolon | ||||
|     0x061f: 0x05bf, // XK_Arabic_question_mark | ||||
|     0x0621: 0x05c1, // XK_Arabic_hamza | ||||
|     0x0622: 0x05c2, // XK_Arabic_maddaonalef | ||||
|     0x0623: 0x05c3, // XK_Arabic_hamzaonalef | ||||
|     0x0624: 0x05c4, // XK_Arabic_hamzaonwaw | ||||
|     0x0625: 0x05c5, // XK_Arabic_hamzaunderalef | ||||
|     0x0626: 0x05c6, // XK_Arabic_hamzaonyeh | ||||
|     0x0627: 0x05c7, // XK_Arabic_alef | ||||
|     0x0628: 0x05c8, // XK_Arabic_beh | ||||
|     0x0629: 0x05c9, // XK_Arabic_tehmarbuta | ||||
|     0x062a: 0x05ca, // XK_Arabic_teh | ||||
|     0x062b: 0x05cb, // XK_Arabic_theh | ||||
|     0x062c: 0x05cc, // XK_Arabic_jeem | ||||
|     0x062d: 0x05cd, // XK_Arabic_hah | ||||
|     0x062e: 0x05ce, // XK_Arabic_khah | ||||
|     0x062f: 0x05cf, // XK_Arabic_dal | ||||
|     0x0630: 0x05d0, // XK_Arabic_thal | ||||
|     0x0631: 0x05d1, // XK_Arabic_ra | ||||
|     0x0632: 0x05d2, // XK_Arabic_zain | ||||
|     0x0633: 0x05d3, // XK_Arabic_seen | ||||
|     0x0634: 0x05d4, // XK_Arabic_sheen | ||||
|     0x0635: 0x05d5, // XK_Arabic_sad | ||||
|     0x0636: 0x05d6, // XK_Arabic_dad | ||||
|     0x0637: 0x05d7, // XK_Arabic_tah | ||||
|     0x0638: 0x05d8, // XK_Arabic_zah | ||||
|     0x0639: 0x05d9, // XK_Arabic_ain | ||||
|     0x063a: 0x05da, // XK_Arabic_ghain | ||||
|     0x0640: 0x05e0, // XK_Arabic_tatweel | ||||
|     0x0641: 0x05e1, // XK_Arabic_feh | ||||
|     0x0642: 0x05e2, // XK_Arabic_qaf | ||||
|     0x0643: 0x05e3, // XK_Arabic_kaf | ||||
|     0x0644: 0x05e4, // XK_Arabic_lam | ||||
|     0x0645: 0x05e5, // XK_Arabic_meem | ||||
|     0x0646: 0x05e6, // XK_Arabic_noon | ||||
|     0x0647: 0x05e7, // XK_Arabic_ha | ||||
|     0x0648: 0x05e8, // XK_Arabic_waw | ||||
|     0x0649: 0x05e9, // XK_Arabic_alefmaksura | ||||
|     0x064a: 0x05ea, // XK_Arabic_yeh | ||||
|     0x064b: 0x05eb, // XK_Arabic_fathatan | ||||
|     0x064c: 0x05ec, // XK_Arabic_dammatan | ||||
|     0x064d: 0x05ed, // XK_Arabic_kasratan | ||||
|     0x064e: 0x05ee, // XK_Arabic_fatha | ||||
|     0x064f: 0x05ef, // XK_Arabic_damma | ||||
|     0x0650: 0x05f0, // XK_Arabic_kasra | ||||
|     0x0651: 0x05f1, // XK_Arabic_shadda | ||||
|     0x0652: 0x05f2, // XK_Arabic_sukun | ||||
|     0x0e01: 0x0da1, // XK_Thai_kokai | ||||
|     0x0e02: 0x0da2, // XK_Thai_khokhai | ||||
|     0x0e03: 0x0da3, // XK_Thai_khokhuat | ||||
|     0x0e04: 0x0da4, // XK_Thai_khokhwai | ||||
|     0x0e05: 0x0da5, // XK_Thai_khokhon | ||||
|     0x0e06: 0x0da6, // XK_Thai_khorakhang | ||||
|     0x0e07: 0x0da7, // XK_Thai_ngongu | ||||
|     0x0e08: 0x0da8, // XK_Thai_chochan | ||||
|     0x0e09: 0x0da9, // XK_Thai_choching | ||||
|     0x0e0a: 0x0daa, // XK_Thai_chochang | ||||
|     0x0e0b: 0x0dab, // XK_Thai_soso | ||||
|     0x0e0c: 0x0dac, // XK_Thai_chochoe | ||||
|     0x0e0d: 0x0dad, // XK_Thai_yoying | ||||
|     0x0e0e: 0x0dae, // XK_Thai_dochada | ||||
|     0x0e0f: 0x0daf, // XK_Thai_topatak | ||||
|     0x0e10: 0x0db0, // XK_Thai_thothan | ||||
|     0x0e11: 0x0db1, // XK_Thai_thonangmontho | ||||
|     0x0e12: 0x0db2, // XK_Thai_thophuthao | ||||
|     0x0e13: 0x0db3, // XK_Thai_nonen | ||||
|     0x0e14: 0x0db4, // XK_Thai_dodek | ||||
|     0x0e15: 0x0db5, // XK_Thai_totao | ||||
|     0x0e16: 0x0db6, // XK_Thai_thothung | ||||
|     0x0e17: 0x0db7, // XK_Thai_thothahan | ||||
|     0x0e18: 0x0db8, // XK_Thai_thothong | ||||
|     0x0e19: 0x0db9, // XK_Thai_nonu | ||||
|     0x0e1a: 0x0dba, // XK_Thai_bobaimai | ||||
|     0x0e1b: 0x0dbb, // XK_Thai_popla | ||||
|     0x0e1c: 0x0dbc, // XK_Thai_phophung | ||||
|     0x0e1d: 0x0dbd, // XK_Thai_fofa | ||||
|     0x0e1e: 0x0dbe, // XK_Thai_phophan | ||||
|     0x0e1f: 0x0dbf, // XK_Thai_fofan | ||||
|     0x0e20: 0x0dc0, // XK_Thai_phosamphao | ||||
|     0x0e21: 0x0dc1, // XK_Thai_moma | ||||
|     0x0e22: 0x0dc2, // XK_Thai_yoyak | ||||
|     0x0e23: 0x0dc3, // XK_Thai_rorua | ||||
|     0x0e24: 0x0dc4, // XK_Thai_ru | ||||
|     0x0e25: 0x0dc5, // XK_Thai_loling | ||||
|     0x0e26: 0x0dc6, // XK_Thai_lu | ||||
|     0x0e27: 0x0dc7, // XK_Thai_wowaen | ||||
|     0x0e28: 0x0dc8, // XK_Thai_sosala | ||||
|     0x0e29: 0x0dc9, // XK_Thai_sorusi | ||||
|     0x0e2a: 0x0dca, // XK_Thai_sosua | ||||
|     0x0e2b: 0x0dcb, // XK_Thai_hohip | ||||
|     0x0e2c: 0x0dcc, // XK_Thai_lochula | ||||
|     0x0e2d: 0x0dcd, // XK_Thai_oang | ||||
|     0x0e2e: 0x0dce, // XK_Thai_honokhuk | ||||
|     0x0e2f: 0x0dcf, // XK_Thai_paiyannoi | ||||
|     0x0e30: 0x0dd0, // XK_Thai_saraa | ||||
|     0x0e31: 0x0dd1, // XK_Thai_maihanakat | ||||
|     0x0e32: 0x0dd2, // XK_Thai_saraaa | ||||
|     0x0e33: 0x0dd3, // XK_Thai_saraam | ||||
|     0x0e34: 0x0dd4, // XK_Thai_sarai | ||||
|     0x0e35: 0x0dd5, // XK_Thai_saraii | ||||
|     0x0e36: 0x0dd6, // XK_Thai_saraue | ||||
|     0x0e37: 0x0dd7, // XK_Thai_sarauee | ||||
|     0x0e38: 0x0dd8, // XK_Thai_sarau | ||||
|     0x0e39: 0x0dd9, // XK_Thai_sarauu | ||||
|     0x0e3a: 0x0dda, // XK_Thai_phinthu | ||||
|     0x0e3f: 0x0ddf, // XK_Thai_baht | ||||
|     0x0e40: 0x0de0, // XK_Thai_sarae | ||||
|     0x0e41: 0x0de1, // XK_Thai_saraae | ||||
|     0x0e42: 0x0de2, // XK_Thai_sarao | ||||
|     0x0e43: 0x0de3, // XK_Thai_saraaimaimuan | ||||
|     0x0e44: 0x0de4, // XK_Thai_saraaimaimalai | ||||
|     0x0e45: 0x0de5, // XK_Thai_lakkhangyao | ||||
|     0x0e46: 0x0de6, // XK_Thai_maiyamok | ||||
|     0x0e47: 0x0de7, // XK_Thai_maitaikhu | ||||
|     0x0e48: 0x0de8, // XK_Thai_maiek | ||||
|     0x0e49: 0x0de9, // XK_Thai_maitho | ||||
|     0x0e4a: 0x0dea, // XK_Thai_maitri | ||||
|     0x0e4b: 0x0deb, // XK_Thai_maichattawa | ||||
|     0x0e4c: 0x0dec, // XK_Thai_thanthakhat | ||||
|     0x0e4d: 0x0ded, // XK_Thai_nikhahit | ||||
|     0x0e50: 0x0df0, // XK_Thai_leksun | ||||
|     0x0e51: 0x0df1, // XK_Thai_leknung | ||||
|     0x0e52: 0x0df2, // XK_Thai_leksong | ||||
|     0x0e53: 0x0df3, // XK_Thai_leksam | ||||
|     0x0e54: 0x0df4, // XK_Thai_leksi | ||||
|     0x0e55: 0x0df5, // XK_Thai_lekha | ||||
|     0x0e56: 0x0df6, // XK_Thai_lekhok | ||||
|     0x0e57: 0x0df7, // XK_Thai_lekchet | ||||
|     0x0e58: 0x0df8, // XK_Thai_lekpaet | ||||
|     0x0e59: 0x0df9, // XK_Thai_lekkao | ||||
|     0x2002: 0x0aa2, // XK_enspace | ||||
|     0x2003: 0x0aa1, // XK_emspace | ||||
|     0x2004: 0x0aa3, // XK_em3space | ||||
|     0x2005: 0x0aa4, // XK_em4space | ||||
|     0x2007: 0x0aa5, // XK_digitspace | ||||
|     0x2008: 0x0aa6, // XK_punctspace | ||||
|     0x2009: 0x0aa7, // XK_thinspace | ||||
|     0x200a: 0x0aa8, // XK_hairspace | ||||
|     0x2012: 0x0abb, // XK_figdash | ||||
|     0x2013: 0x0aaa, // XK_endash | ||||
|     0x2014: 0x0aa9, // XK_emdash | ||||
|     0x2015: 0x07af, // XK_Greek_horizbar | ||||
|     0x2017: 0x0cdf, // XK_hebrew_doublelowline | ||||
|     0x2018: 0x0ad0, // XK_leftsinglequotemark | ||||
|     0x2019: 0x0ad1, // XK_rightsinglequotemark | ||||
|     0x201a: 0x0afd, // XK_singlelowquotemark | ||||
|     0x201c: 0x0ad2, // XK_leftdoublequotemark | ||||
|     0x201d: 0x0ad3, // XK_rightdoublequotemark | ||||
|     0x201e: 0x0afe, // XK_doublelowquotemark | ||||
|     0x2020: 0x0af1, // XK_dagger | ||||
|     0x2021: 0x0af2, // XK_doubledagger | ||||
|     0x2022: 0x0ae6, // XK_enfilledcircbullet | ||||
|     0x2025: 0x0aaf, // XK_doubbaselinedot | ||||
|     0x2026: 0x0aae, // XK_ellipsis | ||||
|     0x2030: 0x0ad5, // XK_permille | ||||
|     0x2032: 0x0ad6, // XK_minutes | ||||
|     0x2033: 0x0ad7, // XK_seconds | ||||
|     0x2038: 0x0afc, // XK_caret | ||||
|     0x203e: 0x047e, // XK_overline | ||||
|     0x20a9: 0x0eff, // XK_Korean_Won | ||||
|     0x20ac: 0x20ac, // XK_EuroSign | ||||
|     0x2105: 0x0ab8, // XK_careof | ||||
|     0x2116: 0x06b0, // XK_numerosign | ||||
|     0x2117: 0x0afb, // XK_phonographcopyright | ||||
|     0x211e: 0x0ad4, // XK_prescription | ||||
|     0x2122: 0x0ac9, // XK_trademark | ||||
|     0x2153: 0x0ab0, // XK_onethird | ||||
|     0x2154: 0x0ab1, // XK_twothirds | ||||
|     0x2155: 0x0ab2, // XK_onefifth | ||||
|     0x2156: 0x0ab3, // XK_twofifths | ||||
|     0x2157: 0x0ab4, // XK_threefifths | ||||
|     0x2158: 0x0ab5, // XK_fourfifths | ||||
|     0x2159: 0x0ab6, // XK_onesixth | ||||
|     0x215a: 0x0ab7, // XK_fivesixths | ||||
|     0x215b: 0x0ac3, // XK_oneeighth | ||||
|     0x215c: 0x0ac4, // XK_threeeighths | ||||
|     0x215d: 0x0ac5, // XK_fiveeighths | ||||
|     0x215e: 0x0ac6, // XK_seveneighths | ||||
|     0x2190: 0x08fb, // XK_leftarrow | ||||
|     0x2191: 0x08fc, // XK_uparrow | ||||
|     0x2192: 0x08fd, // XK_rightarrow | ||||
|     0x2193: 0x08fe, // XK_downarrow | ||||
|     0x21d2: 0x08ce, // XK_implies | ||||
|     0x21d4: 0x08cd, // XK_ifonlyif | ||||
|     0x2202: 0x08ef, // XK_partialderivative | ||||
|     0x2207: 0x08c5, // XK_nabla | ||||
|     0x2218: 0x0bca, // XK_jot | ||||
|     0x221a: 0x08d6, // XK_radical | ||||
|     0x221d: 0x08c1, // XK_variation | ||||
|     0x221e: 0x08c2, // XK_infinity | ||||
|     0x2227: 0x08de, // XK_logicaland | ||||
|     0x2228: 0x08df, // XK_logicalor | ||||
|     0x2229: 0x08dc, // XK_intersection | ||||
|     0x222a: 0x08dd, // XK_union | ||||
|     0x222b: 0x08bf, // XK_integral | ||||
|     0x2234: 0x08c0, // XK_therefore | ||||
|     0x223c: 0x08c8, // XK_approximate | ||||
|     0x2243: 0x08c9, // XK_similarequal | ||||
|     0x2245: 0x1002248, // XK_approxeq | ||||
|     0x2260: 0x08bd, // XK_notequal | ||||
|     0x2261: 0x08cf, // XK_identical | ||||
|     0x2264: 0x08bc, // XK_lessthanequal | ||||
|     0x2265: 0x08be, // XK_greaterthanequal | ||||
|     0x2282: 0x08da, // XK_includedin | ||||
|     0x2283: 0x08db, // XK_includes | ||||
|     0x22a2: 0x0bfc, // XK_righttack | ||||
|     0x22a3: 0x0bdc, // XK_lefttack | ||||
|     0x22a4: 0x0bc2, // XK_downtack | ||||
|     0x22a5: 0x0bce, // XK_uptack | ||||
|     0x2308: 0x0bd3, // XK_upstile | ||||
|     0x230a: 0x0bc4, // XK_downstile | ||||
|     0x2315: 0x0afa, // XK_telephonerecorder | ||||
|     0x2320: 0x08a4, // XK_topintegral | ||||
|     0x2321: 0x08a5, // XK_botintegral | ||||
|     0x2395: 0x0bcc, // XK_quad | ||||
|     0x239b: 0x08ab, // XK_topleftparens | ||||
|     0x239d: 0x08ac, // XK_botleftparens | ||||
|     0x239e: 0x08ad, // XK_toprightparens | ||||
|     0x23a0: 0x08ae, // XK_botrightparens | ||||
|     0x23a1: 0x08a7, // XK_topleftsqbracket | ||||
|     0x23a3: 0x08a8, // XK_botleftsqbracket | ||||
|     0x23a4: 0x08a9, // XK_toprightsqbracket | ||||
|     0x23a6: 0x08aa, // XK_botrightsqbracket | ||||
|     0x23a8: 0x08af, // XK_leftmiddlecurlybrace | ||||
|     0x23ac: 0x08b0, // XK_rightmiddlecurlybrace | ||||
|     0x23b7: 0x08a1, // XK_leftradical | ||||
|     0x23ba: 0x09ef, // XK_horizlinescan1 | ||||
|     0x23bb: 0x09f0, // XK_horizlinescan3 | ||||
|     0x23bc: 0x09f2, // XK_horizlinescan7 | ||||
|     0x23bd: 0x09f3, // XK_horizlinescan9 | ||||
|     0x2409: 0x09e2, // XK_ht | ||||
|     0x240a: 0x09e5, // XK_lf | ||||
|     0x240b: 0x09e9, // XK_vt | ||||
|     0x240c: 0x09e3, // XK_ff | ||||
|     0x240d: 0x09e4, // XK_cr | ||||
|     0x2423: 0x0aac, // XK_signifblank | ||||
|     0x2424: 0x09e8, // XK_nl | ||||
|     0x2500: 0x08a3, // XK_horizconnector | ||||
|     0x2502: 0x08a6, // XK_vertconnector | ||||
|     0x250c: 0x08a2, // XK_topleftradical | ||||
|     0x2510: 0x09eb, // XK_uprightcorner | ||||
|     0x2514: 0x09ed, // XK_lowleftcorner | ||||
|     0x2518: 0x09ea, // XK_lowrightcorner | ||||
|     0x251c: 0x09f4, // XK_leftt | ||||
|     0x2524: 0x09f5, // XK_rightt | ||||
|     0x252c: 0x09f7, // XK_topt | ||||
|     0x2534: 0x09f6, // XK_bott | ||||
|     0x253c: 0x09ee, // XK_crossinglines | ||||
|     0x2592: 0x09e1, // XK_checkerboard | ||||
|     0x25aa: 0x0ae7, // XK_enfilledsqbullet | ||||
|     0x25ab: 0x0ae1, // XK_enopensquarebullet | ||||
|     0x25ac: 0x0adb, // XK_filledrectbullet | ||||
|     0x25ad: 0x0ae2, // XK_openrectbullet | ||||
|     0x25ae: 0x0adf, // XK_emfilledrect | ||||
|     0x25af: 0x0acf, // XK_emopenrectangle | ||||
|     0x25b2: 0x0ae8, // XK_filledtribulletup | ||||
|     0x25b3: 0x0ae3, // XK_opentribulletup | ||||
|     0x25b6: 0x0add, // XK_filledrighttribullet | ||||
|     0x25b7: 0x0acd, // XK_rightopentriangle | ||||
|     0x25bc: 0x0ae9, // XK_filledtribulletdown | ||||
|     0x25bd: 0x0ae4, // XK_opentribulletdown | ||||
|     0x25c0: 0x0adc, // XK_filledlefttribullet | ||||
|     0x25c1: 0x0acc, // XK_leftopentriangle | ||||
|     0x25c6: 0x09e0, // XK_soliddiamond | ||||
|     0x25cb: 0x0ace, // XK_emopencircle | ||||
|     0x25cf: 0x0ade, // XK_emfilledcircle | ||||
|     0x25e6: 0x0ae0, // XK_enopencircbullet | ||||
|     0x2606: 0x0ae5, // XK_openstar | ||||
|     0x260e: 0x0af9, // XK_telephone | ||||
|     0x2613: 0x0aca, // XK_signaturemark | ||||
|     0x261c: 0x0aea, // XK_leftpointer | ||||
|     0x261e: 0x0aeb, // XK_rightpointer | ||||
|     0x2640: 0x0af8, // XK_femalesymbol | ||||
|     0x2642: 0x0af7, // XK_malesymbol | ||||
|     0x2663: 0x0aec, // XK_club | ||||
|     0x2665: 0x0aee, // XK_heart | ||||
|     0x2666: 0x0aed, // XK_diamond | ||||
|     0x266d: 0x0af6, // XK_musicalflat | ||||
|     0x266f: 0x0af5, // XK_musicalsharp | ||||
|     0x2713: 0x0af3, // XK_checkmark | ||||
|     0x2717: 0x0af4, // XK_ballotcross | ||||
|     0x271d: 0x0ad9, // XK_latincross | ||||
|     0x2720: 0x0af0, // XK_maltesecross | ||||
|     0x27e8: 0x0abc, // XK_leftanglebracket | ||||
|     0x27e9: 0x0abe, // XK_rightanglebracket | ||||
|     0x3001: 0x04a4, // XK_kana_comma | ||||
|     0x3002: 0x04a1, // XK_kana_fullstop | ||||
|     0x300c: 0x04a2, // XK_kana_openingbracket | ||||
|     0x300d: 0x04a3, // XK_kana_closingbracket | ||||
|     0x309b: 0x04de, // XK_voicedsound | ||||
|     0x309c: 0x04df, // XK_semivoicedsound | ||||
|     0x30a1: 0x04a7, // XK_kana_a | ||||
|     0x30a2: 0x04b1, // XK_kana_A | ||||
|     0x30a3: 0x04a8, // XK_kana_i | ||||
|     0x30a4: 0x04b2, // XK_kana_I | ||||
|     0x30a5: 0x04a9, // XK_kana_u | ||||
|     0x30a6: 0x04b3, // XK_kana_U | ||||
|     0x30a7: 0x04aa, // XK_kana_e | ||||
|     0x30a8: 0x04b4, // XK_kana_E | ||||
|     0x30a9: 0x04ab, // XK_kana_o | ||||
|     0x30aa: 0x04b5, // XK_kana_O | ||||
|     0x30ab: 0x04b6, // XK_kana_KA | ||||
|     0x30ad: 0x04b7, // XK_kana_KI | ||||
|     0x30af: 0x04b8, // XK_kana_KU | ||||
|     0x30b1: 0x04b9, // XK_kana_KE | ||||
|     0x30b3: 0x04ba, // XK_kana_KO | ||||
|     0x30b5: 0x04bb, // XK_kana_SA | ||||
|     0x30b7: 0x04bc, // XK_kana_SHI | ||||
|     0x30b9: 0x04bd, // XK_kana_SU | ||||
|     0x30bb: 0x04be, // XK_kana_SE | ||||
|     0x30bd: 0x04bf, // XK_kana_SO | ||||
|     0x30bf: 0x04c0, // XK_kana_TA | ||||
|     0x30c1: 0x04c1, // XK_kana_CHI | ||||
|     0x30c3: 0x04af, // XK_kana_tsu | ||||
|     0x30c4: 0x04c2, // XK_kana_TSU | ||||
|     0x30c6: 0x04c3, // XK_kana_TE | ||||
|     0x30c8: 0x04c4, // XK_kana_TO | ||||
|     0x30ca: 0x04c5, // XK_kana_NA | ||||
|     0x30cb: 0x04c6, // XK_kana_NI | ||||
|     0x30cc: 0x04c7, // XK_kana_NU | ||||
|     0x30cd: 0x04c8, // XK_kana_NE | ||||
|     0x30ce: 0x04c9, // XK_kana_NO | ||||
|     0x30cf: 0x04ca, // XK_kana_HA | ||||
|     0x30d2: 0x04cb, // XK_kana_HI | ||||
|     0x30d5: 0x04cc, // XK_kana_FU | ||||
|     0x30d8: 0x04cd, // XK_kana_HE | ||||
|     0x30db: 0x04ce, // XK_kana_HO | ||||
|     0x30de: 0x04cf, // XK_kana_MA | ||||
|     0x30df: 0x04d0, // XK_kana_MI | ||||
|     0x30e0: 0x04d1, // XK_kana_MU | ||||
|     0x30e1: 0x04d2, // XK_kana_ME | ||||
|     0x30e2: 0x04d3, // XK_kana_MO | ||||
|     0x30e3: 0x04ac, // XK_kana_ya | ||||
|     0x30e4: 0x04d4, // XK_kana_YA | ||||
|     0x30e5: 0x04ad, // XK_kana_yu | ||||
|     0x30e6: 0x04d5, // XK_kana_YU | ||||
|     0x30e7: 0x04ae, // XK_kana_yo | ||||
|     0x30e8: 0x04d6, // XK_kana_YO | ||||
|     0x30e9: 0x04d7, // XK_kana_RA | ||||
|     0x30ea: 0x04d8, // XK_kana_RI | ||||
|     0x30eb: 0x04d9, // XK_kana_RU | ||||
|     0x30ec: 0x04da, // XK_kana_RE | ||||
|     0x30ed: 0x04db, // XK_kana_RO | ||||
|     0x30ef: 0x04dc, // XK_kana_WA | ||||
|     0x30f2: 0x04a6, // XK_kana_WO | ||||
|     0x30f3: 0x04dd, // XK_kana_N | ||||
|     0x30fb: 0x04a5, // XK_kana_conjunctive | ||||
|     0x30fc: 0x04b0, // XK_prolongedsound | ||||
| }; | ||||
|  | ||||
| export default { | ||||
|     lookup(u) { | ||||
|         // Latin-1 is one-to-one mapping | ||||
|         if ((u >= 0x20) && (u <= 0xff)) { | ||||
|             return u; | ||||
|         } | ||||
|  | ||||
|         // Lookup table (fairly random) | ||||
|         const keysym = codepoints[u]; | ||||
|         if (keysym !== undefined) { | ||||
|             return keysym; | ||||
|         } | ||||
|  | ||||
|         // General mapping as final fallback | ||||
|         return 0x01000000 | u; | ||||
|     }, | ||||
| }; | ||||
							
								
								
									
										191
									
								
								public/novnc/core/input/util.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,191 @@ | ||||
| import KeyTable from "./keysym.js"; | ||||
| import keysyms from "./keysymdef.js"; | ||||
| import vkeys from "./vkeys.js"; | ||||
| import fixedkeys from "./fixedkeys.js"; | ||||
| import DOMKeyTable from "./domkeytable.js"; | ||||
| import * as browser from "../util/browser.js"; | ||||
|  | ||||
| // Get 'KeyboardEvent.code', handling legacy browsers | ||||
| export function getKeycode(evt) { | ||||
|     // Are we getting proper key identifiers? | ||||
|     // (unfortunately Firefox and Chrome are crappy here and gives | ||||
|     // us an empty string on some platforms, rather than leaving it | ||||
|     // undefined) | ||||
|     if (evt.code) { | ||||
|         // Mozilla isn't fully in sync with the spec yet | ||||
|         switch (evt.code) { | ||||
|             case 'OSLeft': return 'MetaLeft'; | ||||
|             case 'OSRight': return 'MetaRight'; | ||||
|         } | ||||
|  | ||||
|         return evt.code; | ||||
|     } | ||||
|  | ||||
|     // The de-facto standard is to use Windows Virtual-Key codes | ||||
|     // in the 'keyCode' field for non-printable characters | ||||
|     if (evt.keyCode in vkeys) { | ||||
|         let code = vkeys[evt.keyCode]; | ||||
|  | ||||
|         // macOS has messed up this code for some reason | ||||
|         if (browser.isMac() && (code === 'ContextMenu')) { | ||||
|             code = 'MetaRight'; | ||||
|         } | ||||
|  | ||||
|         // The keyCode doesn't distinguish between left and right | ||||
|         // for the standard modifiers | ||||
|         if (evt.location === 2) { | ||||
|             switch (code) { | ||||
|                 case 'ShiftLeft': return 'ShiftRight'; | ||||
|                 case 'ControlLeft': return 'ControlRight'; | ||||
|                 case 'AltLeft': return 'AltRight'; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Nor a bunch of the numpad keys | ||||
|         if (evt.location === 3) { | ||||
|             switch (code) { | ||||
|                 case 'Delete': return 'NumpadDecimal'; | ||||
|                 case 'Insert': return 'Numpad0'; | ||||
|                 case 'End': return 'Numpad1'; | ||||
|                 case 'ArrowDown': return 'Numpad2'; | ||||
|                 case 'PageDown': return 'Numpad3'; | ||||
|                 case 'ArrowLeft': return 'Numpad4'; | ||||
|                 case 'ArrowRight': return 'Numpad6'; | ||||
|                 case 'Home': return 'Numpad7'; | ||||
|                 case 'ArrowUp': return 'Numpad8'; | ||||
|                 case 'PageUp': return 'Numpad9'; | ||||
|                 case 'Enter': return 'NumpadEnter'; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return code; | ||||
|     } | ||||
|  | ||||
|     return 'Unidentified'; | ||||
| } | ||||
|  | ||||
| // Get 'KeyboardEvent.key', handling legacy browsers | ||||
| export function getKey(evt) { | ||||
|     // Are we getting a proper key value? | ||||
|     if (evt.key !== undefined) { | ||||
|         // Mozilla isn't fully in sync with the spec yet | ||||
|         switch (evt.key) { | ||||
|             case 'OS': return 'Meta'; | ||||
|             case 'LaunchMyComputer': return 'LaunchApplication1'; | ||||
|             case 'LaunchCalculator': return 'LaunchApplication2'; | ||||
|         } | ||||
|  | ||||
|         // iOS leaks some OS names | ||||
|         switch (evt.key) { | ||||
|             case 'UIKeyInputUpArrow': return 'ArrowUp'; | ||||
|             case 'UIKeyInputDownArrow': return 'ArrowDown'; | ||||
|             case 'UIKeyInputLeftArrow': return 'ArrowLeft'; | ||||
|             case 'UIKeyInputRightArrow': return 'ArrowRight'; | ||||
|             case 'UIKeyInputEscape': return 'Escape'; | ||||
|         } | ||||
|  | ||||
|         // Broken behaviour in Chrome | ||||
|         if ((evt.key === '\x00') && (evt.code === 'NumpadDecimal')) { | ||||
|             return 'Delete'; | ||||
|         } | ||||
|  | ||||
|         return evt.key; | ||||
|     } | ||||
|  | ||||
|     // Try to deduce it based on the physical key | ||||
|     const code = getKeycode(evt); | ||||
|     if (code in fixedkeys) { | ||||
|         return fixedkeys[code]; | ||||
|     } | ||||
|  | ||||
|     // If that failed, then see if we have a printable character | ||||
|     if (evt.charCode) { | ||||
|         return String.fromCharCode(evt.charCode); | ||||
|     } | ||||
|  | ||||
|     // At this point we have nothing left to go on | ||||
|     return 'Unidentified'; | ||||
| } | ||||
|  | ||||
| // Get the most reliable keysym value we can get from a key event | ||||
| export function getKeysym(evt) { | ||||
|     const key = getKey(evt); | ||||
|  | ||||
|     if (key === 'Unidentified') { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     // First look up special keys | ||||
|     if (key in DOMKeyTable) { | ||||
|         let location = evt.location; | ||||
|  | ||||
|         // Safari screws up location for the right cmd key | ||||
|         if ((key === 'Meta') && (location === 0)) { | ||||
|             location = 2; | ||||
|         } | ||||
|  | ||||
|         // And for Clear | ||||
|         if ((key === 'Clear') && (location === 3)) { | ||||
|             let code = getKeycode(evt); | ||||
|             if (code === 'NumLock') { | ||||
|                 location = 0; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if ((location === undefined) || (location > 3)) { | ||||
|             location = 0; | ||||
|         } | ||||
|  | ||||
|         // The original Meta key now gets confused with the Windows key | ||||
|         // https://bugs.chromium.org/p/chromium/issues/detail?id=1020141 | ||||
|         // https://bugzilla.mozilla.org/show_bug.cgi?id=1232918 | ||||
|         if (key === 'Meta') { | ||||
|             let code = getKeycode(evt); | ||||
|             if (code === 'AltLeft') { | ||||
|                 return KeyTable.XK_Meta_L; | ||||
|             } else if (code === 'AltRight') { | ||||
|                 return KeyTable.XK_Meta_R; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // macOS has Clear instead of NumLock, but the remote system is | ||||
|         // probably not macOS, so lying here is probably best... | ||||
|         if (key === 'Clear') { | ||||
|             let code = getKeycode(evt); | ||||
|             if (code === 'NumLock') { | ||||
|                 return KeyTable.XK_Num_Lock; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Windows sends alternating symbols for some keys when using a | ||||
|         // Japanese layout. We have no way of synchronising with the IM | ||||
|         // running on the remote system, so we send some combined keysym | ||||
|         // instead and hope for the best. | ||||
|         if (browser.isWindows()) { | ||||
|             switch (key) { | ||||
|                 case 'Zenkaku': | ||||
|                 case 'Hankaku': | ||||
|                     return KeyTable.XK_Zenkaku_Hankaku; | ||||
|                 case 'Romaji': | ||||
|                 case 'KanaMode': | ||||
|                     return KeyTable.XK_Romaji; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return DOMKeyTable[key][location]; | ||||
|     } | ||||
|  | ||||
|     // Now we need to look at the Unicode symbol instead | ||||
|  | ||||
|     // Special key? (FIXME: Should have been caught earlier) | ||||
|     if (key.length !== 1) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     const codepoint = key.charCodeAt(); | ||||
|     if (codepoint) { | ||||
|         return keysyms.lookup(codepoint); | ||||
|     } | ||||
|  | ||||
|     return null; | ||||
| } | ||||
							
								
								
									
										116
									
								
								public/novnc/core/input/vkeys.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,116 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2018 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Mapping between Microsoft® Windows® Virtual-Key codes and | ||||
|  * HTML key codes. | ||||
|  */ | ||||
|  | ||||
| export default { | ||||
|     0x08: 'Backspace', | ||||
|     0x09: 'Tab', | ||||
|     0x0a: 'NumpadClear', | ||||
|     0x0d: 'Enter', | ||||
|     0x10: 'ShiftLeft', | ||||
|     0x11: 'ControlLeft', | ||||
|     0x12: 'AltLeft', | ||||
|     0x13: 'Pause', | ||||
|     0x14: 'CapsLock', | ||||
|     0x15: 'Lang1', | ||||
|     0x19: 'Lang2', | ||||
|     0x1b: 'Escape', | ||||
|     0x1c: 'Convert', | ||||
|     0x1d: 'NonConvert', | ||||
|     0x20: 'Space', | ||||
|     0x21: 'PageUp', | ||||
|     0x22: 'PageDown', | ||||
|     0x23: 'End', | ||||
|     0x24: 'Home', | ||||
|     0x25: 'ArrowLeft', | ||||
|     0x26: 'ArrowUp', | ||||
|     0x27: 'ArrowRight', | ||||
|     0x28: 'ArrowDown', | ||||
|     0x29: 'Select', | ||||
|     0x2c: 'PrintScreen', | ||||
|     0x2d: 'Insert', | ||||
|     0x2e: 'Delete', | ||||
|     0x2f: 'Help', | ||||
|     0x30: 'Digit0', | ||||
|     0x31: 'Digit1', | ||||
|     0x32: 'Digit2', | ||||
|     0x33: 'Digit3', | ||||
|     0x34: 'Digit4', | ||||
|     0x35: 'Digit5', | ||||
|     0x36: 'Digit6', | ||||
|     0x37: 'Digit7', | ||||
|     0x38: 'Digit8', | ||||
|     0x39: 'Digit9', | ||||
|     0x5b: 'MetaLeft', | ||||
|     0x5c: 'MetaRight', | ||||
|     0x5d: 'ContextMenu', | ||||
|     0x5f: 'Sleep', | ||||
|     0x60: 'Numpad0', | ||||
|     0x61: 'Numpad1', | ||||
|     0x62: 'Numpad2', | ||||
|     0x63: 'Numpad3', | ||||
|     0x64: 'Numpad4', | ||||
|     0x65: 'Numpad5', | ||||
|     0x66: 'Numpad6', | ||||
|     0x67: 'Numpad7', | ||||
|     0x68: 'Numpad8', | ||||
|     0x69: 'Numpad9', | ||||
|     0x6a: 'NumpadMultiply', | ||||
|     0x6b: 'NumpadAdd', | ||||
|     0x6c: 'NumpadDecimal', | ||||
|     0x6d: 'NumpadSubtract', | ||||
|     0x6e: 'NumpadDecimal', // Duplicate, because buggy on Windows | ||||
|     0x6f: 'NumpadDivide', | ||||
|     0x70: 'F1', | ||||
|     0x71: 'F2', | ||||
|     0x72: 'F3', | ||||
|     0x73: 'F4', | ||||
|     0x74: 'F5', | ||||
|     0x75: 'F6', | ||||
|     0x76: 'F7', | ||||
|     0x77: 'F8', | ||||
|     0x78: 'F9', | ||||
|     0x79: 'F10', | ||||
|     0x7a: 'F11', | ||||
|     0x7b: 'F12', | ||||
|     0x7c: 'F13', | ||||
|     0x7d: 'F14', | ||||
|     0x7e: 'F15', | ||||
|     0x7f: 'F16', | ||||
|     0x80: 'F17', | ||||
|     0x81: 'F18', | ||||
|     0x82: 'F19', | ||||
|     0x83: 'F20', | ||||
|     0x84: 'F21', | ||||
|     0x85: 'F22', | ||||
|     0x86: 'F23', | ||||
|     0x87: 'F24', | ||||
|     0x90: 'NumLock', | ||||
|     0x91: 'ScrollLock', | ||||
|     0xa6: 'BrowserBack', | ||||
|     0xa7: 'BrowserForward', | ||||
|     0xa8: 'BrowserRefresh', | ||||
|     0xa9: 'BrowserStop', | ||||
|     0xaa: 'BrowserSearch', | ||||
|     0xab: 'BrowserFavorites', | ||||
|     0xac: 'BrowserHome', | ||||
|     0xad: 'AudioVolumeMute', | ||||
|     0xae: 'AudioVolumeDown', | ||||
|     0xaf: 'AudioVolumeUp', | ||||
|     0xb0: 'MediaTrackNext', | ||||
|     0xb1: 'MediaTrackPrevious', | ||||
|     0xb2: 'MediaStop', | ||||
|     0xb3: 'MediaPlayPause', | ||||
|     0xb4: 'LaunchMail', | ||||
|     0xb5: 'MediaSelect', | ||||
|     0xb6: 'LaunchApp1', | ||||
|     0xb7: 'LaunchApp2', | ||||
|     0xe1: 'AltRight', // Only when it is AltGraph | ||||
| }; | ||||
							
								
								
									
										173
									
								
								public/novnc/core/input/xtscancodes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,173 @@ | ||||
| /* | ||||
|  * This file is auto-generated from keymaps.csv | ||||
|  * Database checksum sha256(76d68c10e97d37fe2ea459e210125ae41796253fb217e900bf2983ade13a7920) | ||||
|  * To re-generate, run: | ||||
|  *   keymap-gen code-map --lang=js keymaps.csv html atset1 | ||||
| */ | ||||
| export default { | ||||
|   "Again": 0xe005, /* html:Again (Again) -> linux:129 (KEY_AGAIN) -> atset1:57349 */ | ||||
|   "AltLeft": 0x38, /* html:AltLeft (AltLeft) -> linux:56 (KEY_LEFTALT) -> atset1:56 */ | ||||
|   "AltRight": 0xe038, /* html:AltRight (AltRight) -> linux:100 (KEY_RIGHTALT) -> atset1:57400 */ | ||||
|   "ArrowDown": 0xe050, /* html:ArrowDown (ArrowDown) -> linux:108 (KEY_DOWN) -> atset1:57424 */ | ||||
|   "ArrowLeft": 0xe04b, /* html:ArrowLeft (ArrowLeft) -> linux:105 (KEY_LEFT) -> atset1:57419 */ | ||||
|   "ArrowRight": 0xe04d, /* html:ArrowRight (ArrowRight) -> linux:106 (KEY_RIGHT) -> atset1:57421 */ | ||||
|   "ArrowUp": 0xe048, /* html:ArrowUp (ArrowUp) -> linux:103 (KEY_UP) -> atset1:57416 */ | ||||
|   "AudioVolumeDown": 0xe02e, /* html:AudioVolumeDown (AudioVolumeDown) -> linux:114 (KEY_VOLUMEDOWN) -> atset1:57390 */ | ||||
|   "AudioVolumeMute": 0xe020, /* html:AudioVolumeMute (AudioVolumeMute) -> linux:113 (KEY_MUTE) -> atset1:57376 */ | ||||
|   "AudioVolumeUp": 0xe030, /* html:AudioVolumeUp (AudioVolumeUp) -> linux:115 (KEY_VOLUMEUP) -> atset1:57392 */ | ||||
|   "Backquote": 0x29, /* html:Backquote (Backquote) -> linux:41 (KEY_GRAVE) -> atset1:41 */ | ||||
|   "Backslash": 0x2b, /* html:Backslash (Backslash) -> linux:43 (KEY_BACKSLASH) -> atset1:43 */ | ||||
|   "Backspace": 0xe, /* html:Backspace (Backspace) -> linux:14 (KEY_BACKSPACE) -> atset1:14 */ | ||||
|   "BracketLeft": 0x1a, /* html:BracketLeft (BracketLeft) -> linux:26 (KEY_LEFTBRACE) -> atset1:26 */ | ||||
|   "BracketRight": 0x1b, /* html:BracketRight (BracketRight) -> linux:27 (KEY_RIGHTBRACE) -> atset1:27 */ | ||||
|   "BrowserBack": 0xe06a, /* html:BrowserBack (BrowserBack) -> linux:158 (KEY_BACK) -> atset1:57450 */ | ||||
|   "BrowserFavorites": 0xe066, /* html:BrowserFavorites (BrowserFavorites) -> linux:156 (KEY_BOOKMARKS) -> atset1:57446 */ | ||||
|   "BrowserForward": 0xe069, /* html:BrowserForward (BrowserForward) -> linux:159 (KEY_FORWARD) -> atset1:57449 */ | ||||
|   "BrowserHome": 0xe032, /* html:BrowserHome (BrowserHome) -> linux:172 (KEY_HOMEPAGE) -> atset1:57394 */ | ||||
|   "BrowserRefresh": 0xe067, /* html:BrowserRefresh (BrowserRefresh) -> linux:173 (KEY_REFRESH) -> atset1:57447 */ | ||||
|   "BrowserSearch": 0xe065, /* html:BrowserSearch (BrowserSearch) -> linux:217 (KEY_SEARCH) -> atset1:57445 */ | ||||
|   "BrowserStop": 0xe068, /* html:BrowserStop (BrowserStop) -> linux:128 (KEY_STOP) -> atset1:57448 */ | ||||
|   "CapsLock": 0x3a, /* html:CapsLock (CapsLock) -> linux:58 (KEY_CAPSLOCK) -> atset1:58 */ | ||||
|   "Comma": 0x33, /* html:Comma (Comma) -> linux:51 (KEY_COMMA) -> atset1:51 */ | ||||
|   "ContextMenu": 0xe05d, /* html:ContextMenu (ContextMenu) -> linux:127 (KEY_COMPOSE) -> atset1:57437 */ | ||||
|   "ControlLeft": 0x1d, /* html:ControlLeft (ControlLeft) -> linux:29 (KEY_LEFTCTRL) -> atset1:29 */ | ||||
|   "ControlRight": 0xe01d, /* html:ControlRight (ControlRight) -> linux:97 (KEY_RIGHTCTRL) -> atset1:57373 */ | ||||
|   "Convert": 0x79, /* html:Convert (Convert) -> linux:92 (KEY_HENKAN) -> atset1:121 */ | ||||
|   "Copy": 0xe078, /* html:Copy (Copy) -> linux:133 (KEY_COPY) -> atset1:57464 */ | ||||
|   "Cut": 0xe03c, /* html:Cut (Cut) -> linux:137 (KEY_CUT) -> atset1:57404 */ | ||||
|   "Delete": 0xe053, /* html:Delete (Delete) -> linux:111 (KEY_DELETE) -> atset1:57427 */ | ||||
|   "Digit0": 0xb, /* html:Digit0 (Digit0) -> linux:11 (KEY_0) -> atset1:11 */ | ||||
|   "Digit1": 0x2, /* html:Digit1 (Digit1) -> linux:2 (KEY_1) -> atset1:2 */ | ||||
|   "Digit2": 0x3, /* html:Digit2 (Digit2) -> linux:3 (KEY_2) -> atset1:3 */ | ||||
|   "Digit3": 0x4, /* html:Digit3 (Digit3) -> linux:4 (KEY_3) -> atset1:4 */ | ||||
|   "Digit4": 0x5, /* html:Digit4 (Digit4) -> linux:5 (KEY_4) -> atset1:5 */ | ||||
|   "Digit5": 0x6, /* html:Digit5 (Digit5) -> linux:6 (KEY_5) -> atset1:6 */ | ||||
|   "Digit6": 0x7, /* html:Digit6 (Digit6) -> linux:7 (KEY_6) -> atset1:7 */ | ||||
|   "Digit7": 0x8, /* html:Digit7 (Digit7) -> linux:8 (KEY_7) -> atset1:8 */ | ||||
|   "Digit8": 0x9, /* html:Digit8 (Digit8) -> linux:9 (KEY_8) -> atset1:9 */ | ||||
|   "Digit9": 0xa, /* html:Digit9 (Digit9) -> linux:10 (KEY_9) -> atset1:10 */ | ||||
|   "Eject": 0xe07d, /* html:Eject (Eject) -> linux:162 (KEY_EJECTCLOSECD) -> atset1:57469 */ | ||||
|   "End": 0xe04f, /* html:End (End) -> linux:107 (KEY_END) -> atset1:57423 */ | ||||
|   "Enter": 0x1c, /* html:Enter (Enter) -> linux:28 (KEY_ENTER) -> atset1:28 */ | ||||
|   "Equal": 0xd, /* html:Equal (Equal) -> linux:13 (KEY_EQUAL) -> atset1:13 */ | ||||
|   "Escape": 0x1, /* html:Escape (Escape) -> linux:1 (KEY_ESC) -> atset1:1 */ | ||||
|   "F1": 0x3b, /* html:F1 (F1) -> linux:59 (KEY_F1) -> atset1:59 */ | ||||
|   "F10": 0x44, /* html:F10 (F10) -> linux:68 (KEY_F10) -> atset1:68 */ | ||||
|   "F11": 0x57, /* html:F11 (F11) -> linux:87 (KEY_F11) -> atset1:87 */ | ||||
|   "F12": 0x58, /* html:F12 (F12) -> linux:88 (KEY_F12) -> atset1:88 */ | ||||
|   "F13": 0x5d, /* html:F13 (F13) -> linux:183 (KEY_F13) -> atset1:93 */ | ||||
|   "F14": 0x5e, /* html:F14 (F14) -> linux:184 (KEY_F14) -> atset1:94 */ | ||||
|   "F15": 0x5f, /* html:F15 (F15) -> linux:185 (KEY_F15) -> atset1:95 */ | ||||
|   "F16": 0x55, /* html:F16 (F16) -> linux:186 (KEY_F16) -> atset1:85 */ | ||||
|   "F17": 0xe003, /* html:F17 (F17) -> linux:187 (KEY_F17) -> atset1:57347 */ | ||||
|   "F18": 0xe077, /* html:F18 (F18) -> linux:188 (KEY_F18) -> atset1:57463 */ | ||||
|   "F19": 0xe004, /* html:F19 (F19) -> linux:189 (KEY_F19) -> atset1:57348 */ | ||||
|   "F2": 0x3c, /* html:F2 (F2) -> linux:60 (KEY_F2) -> atset1:60 */ | ||||
|   "F20": 0x5a, /* html:F20 (F20) -> linux:190 (KEY_F20) -> atset1:90 */ | ||||
|   "F21": 0x74, /* html:F21 (F21) -> linux:191 (KEY_F21) -> atset1:116 */ | ||||
|   "F22": 0xe079, /* html:F22 (F22) -> linux:192 (KEY_F22) -> atset1:57465 */ | ||||
|   "F23": 0x6d, /* html:F23 (F23) -> linux:193 (KEY_F23) -> atset1:109 */ | ||||
|   "F24": 0x6f, /* html:F24 (F24) -> linux:194 (KEY_F24) -> atset1:111 */ | ||||
|   "F3": 0x3d, /* html:F3 (F3) -> linux:61 (KEY_F3) -> atset1:61 */ | ||||
|   "F4": 0x3e, /* html:F4 (F4) -> linux:62 (KEY_F4) -> atset1:62 */ | ||||
|   "F5": 0x3f, /* html:F5 (F5) -> linux:63 (KEY_F5) -> atset1:63 */ | ||||
|   "F6": 0x40, /* html:F6 (F6) -> linux:64 (KEY_F6) -> atset1:64 */ | ||||
|   "F7": 0x41, /* html:F7 (F7) -> linux:65 (KEY_F7) -> atset1:65 */ | ||||
|   "F8": 0x42, /* html:F8 (F8) -> linux:66 (KEY_F8) -> atset1:66 */ | ||||
|   "F9": 0x43, /* html:F9 (F9) -> linux:67 (KEY_F9) -> atset1:67 */ | ||||
|   "Find": 0xe041, /* html:Find (Find) -> linux:136 (KEY_FIND) -> atset1:57409 */ | ||||
|   "Help": 0xe075, /* html:Help (Help) -> linux:138 (KEY_HELP) -> atset1:57461 */ | ||||
|   "Hiragana": 0x77, /* html:Hiragana (Lang4) -> linux:91 (KEY_HIRAGANA) -> atset1:119 */ | ||||
|   "Home": 0xe047, /* html:Home (Home) -> linux:102 (KEY_HOME) -> atset1:57415 */ | ||||
|   "Insert": 0xe052, /* html:Insert (Insert) -> linux:110 (KEY_INSERT) -> atset1:57426 */ | ||||
|   "IntlBackslash": 0x56, /* html:IntlBackslash (IntlBackslash) -> linux:86 (KEY_102ND) -> atset1:86 */ | ||||
|   "IntlRo": 0x73, /* html:IntlRo (IntlRo) -> linux:89 (KEY_RO) -> atset1:115 */ | ||||
|   "IntlYen": 0x7d, /* html:IntlYen (IntlYen) -> linux:124 (KEY_YEN) -> atset1:125 */ | ||||
|   "KanaMode": 0x70, /* html:KanaMode (KanaMode) -> linux:93 (KEY_KATAKANAHIRAGANA) -> atset1:112 */ | ||||
|   "Katakana": 0x78, /* html:Katakana (Lang3) -> linux:90 (KEY_KATAKANA) -> atset1:120 */ | ||||
|   "KeyA": 0x1e, /* html:KeyA (KeyA) -> linux:30 (KEY_A) -> atset1:30 */ | ||||
|   "KeyB": 0x30, /* html:KeyB (KeyB) -> linux:48 (KEY_B) -> atset1:48 */ | ||||
|   "KeyC": 0x2e, /* html:KeyC (KeyC) -> linux:46 (KEY_C) -> atset1:46 */ | ||||
|   "KeyD": 0x20, /* html:KeyD (KeyD) -> linux:32 (KEY_D) -> atset1:32 */ | ||||
|   "KeyE": 0x12, /* html:KeyE (KeyE) -> linux:18 (KEY_E) -> atset1:18 */ | ||||
|   "KeyF": 0x21, /* html:KeyF (KeyF) -> linux:33 (KEY_F) -> atset1:33 */ | ||||
|   "KeyG": 0x22, /* html:KeyG (KeyG) -> linux:34 (KEY_G) -> atset1:34 */ | ||||
|   "KeyH": 0x23, /* html:KeyH (KeyH) -> linux:35 (KEY_H) -> atset1:35 */ | ||||
|   "KeyI": 0x17, /* html:KeyI (KeyI) -> linux:23 (KEY_I) -> atset1:23 */ | ||||
|   "KeyJ": 0x24, /* html:KeyJ (KeyJ) -> linux:36 (KEY_J) -> atset1:36 */ | ||||
|   "KeyK": 0x25, /* html:KeyK (KeyK) -> linux:37 (KEY_K) -> atset1:37 */ | ||||
|   "KeyL": 0x26, /* html:KeyL (KeyL) -> linux:38 (KEY_L) -> atset1:38 */ | ||||
|   "KeyM": 0x32, /* html:KeyM (KeyM) -> linux:50 (KEY_M) -> atset1:50 */ | ||||
|   "KeyN": 0x31, /* html:KeyN (KeyN) -> linux:49 (KEY_N) -> atset1:49 */ | ||||
|   "KeyO": 0x18, /* html:KeyO (KeyO) -> linux:24 (KEY_O) -> atset1:24 */ | ||||
|   "KeyP": 0x19, /* html:KeyP (KeyP) -> linux:25 (KEY_P) -> atset1:25 */ | ||||
|   "KeyQ": 0x10, /* html:KeyQ (KeyQ) -> linux:16 (KEY_Q) -> atset1:16 */ | ||||
|   "KeyR": 0x13, /* html:KeyR (KeyR) -> linux:19 (KEY_R) -> atset1:19 */ | ||||
|   "KeyS": 0x1f, /* html:KeyS (KeyS) -> linux:31 (KEY_S) -> atset1:31 */ | ||||
|   "KeyT": 0x14, /* html:KeyT (KeyT) -> linux:20 (KEY_T) -> atset1:20 */ | ||||
|   "KeyU": 0x16, /* html:KeyU (KeyU) -> linux:22 (KEY_U) -> atset1:22 */ | ||||
|   "KeyV": 0x2f, /* html:KeyV (KeyV) -> linux:47 (KEY_V) -> atset1:47 */ | ||||
|   "KeyW": 0x11, /* html:KeyW (KeyW) -> linux:17 (KEY_W) -> atset1:17 */ | ||||
|   "KeyX": 0x2d, /* html:KeyX (KeyX) -> linux:45 (KEY_X) -> atset1:45 */ | ||||
|   "KeyY": 0x15, /* html:KeyY (KeyY) -> linux:21 (KEY_Y) -> atset1:21 */ | ||||
|   "KeyZ": 0x2c, /* html:KeyZ (KeyZ) -> linux:44 (KEY_Z) -> atset1:44 */ | ||||
|   "Lang1": 0x72, /* html:Lang1 (Lang1) -> linux:122 (KEY_HANGEUL) -> atset1:114 */ | ||||
|   "Lang2": 0x71, /* html:Lang2 (Lang2) -> linux:123 (KEY_HANJA) -> atset1:113 */ | ||||
|   "Lang3": 0x78, /* html:Lang3 (Lang3) -> linux:90 (KEY_KATAKANA) -> atset1:120 */ | ||||
|   "Lang4": 0x77, /* html:Lang4 (Lang4) -> linux:91 (KEY_HIRAGANA) -> atset1:119 */ | ||||
|   "Lang5": 0x76, /* html:Lang5 (Lang5) -> linux:85 (KEY_ZENKAKUHANKAKU) -> atset1:118 */ | ||||
|   "LaunchApp1": 0xe06b, /* html:LaunchApp1 (LaunchApp1) -> linux:157 (KEY_COMPUTER) -> atset1:57451 */ | ||||
|   "LaunchApp2": 0xe021, /* html:LaunchApp2 (LaunchApp2) -> linux:140 (KEY_CALC) -> atset1:57377 */ | ||||
|   "LaunchMail": 0xe06c, /* html:LaunchMail (LaunchMail) -> linux:155 (KEY_MAIL) -> atset1:57452 */ | ||||
|   "MediaPlayPause": 0xe022, /* html:MediaPlayPause (MediaPlayPause) -> linux:164 (KEY_PLAYPAUSE) -> atset1:57378 */ | ||||
|   "MediaSelect": 0xe06d, /* html:MediaSelect (MediaSelect) -> linux:226 (KEY_MEDIA) -> atset1:57453 */ | ||||
|   "MediaStop": 0xe024, /* html:MediaStop (MediaStop) -> linux:166 (KEY_STOPCD) -> atset1:57380 */ | ||||
|   "MediaTrackNext": 0xe019, /* html:MediaTrackNext (MediaTrackNext) -> linux:163 (KEY_NEXTSONG) -> atset1:57369 */ | ||||
|   "MediaTrackPrevious": 0xe010, /* html:MediaTrackPrevious (MediaTrackPrevious) -> linux:165 (KEY_PREVIOUSSONG) -> atset1:57360 */ | ||||
|   "MetaLeft": 0xe05b, /* html:MetaLeft (MetaLeft) -> linux:125 (KEY_LEFTMETA) -> atset1:57435 */ | ||||
|   "MetaRight": 0xe05c, /* html:MetaRight (MetaRight) -> linux:126 (KEY_RIGHTMETA) -> atset1:57436 */ | ||||
|   "Minus": 0xc, /* html:Minus (Minus) -> linux:12 (KEY_MINUS) -> atset1:12 */ | ||||
|   "NonConvert": 0x7b, /* html:NonConvert (NonConvert) -> linux:94 (KEY_MUHENKAN) -> atset1:123 */ | ||||
|   "NumLock": 0x45, /* html:NumLock (NumLock) -> linux:69 (KEY_NUMLOCK) -> atset1:69 */ | ||||
|   "Numpad0": 0x52, /* html:Numpad0 (Numpad0) -> linux:82 (KEY_KP0) -> atset1:82 */ | ||||
|   "Numpad1": 0x4f, /* html:Numpad1 (Numpad1) -> linux:79 (KEY_KP1) -> atset1:79 */ | ||||
|   "Numpad2": 0x50, /* html:Numpad2 (Numpad2) -> linux:80 (KEY_KP2) -> atset1:80 */ | ||||
|   "Numpad3": 0x51, /* html:Numpad3 (Numpad3) -> linux:81 (KEY_KP3) -> atset1:81 */ | ||||
|   "Numpad4": 0x4b, /* html:Numpad4 (Numpad4) -> linux:75 (KEY_KP4) -> atset1:75 */ | ||||
|   "Numpad5": 0x4c, /* html:Numpad5 (Numpad5) -> linux:76 (KEY_KP5) -> atset1:76 */ | ||||
|   "Numpad6": 0x4d, /* html:Numpad6 (Numpad6) -> linux:77 (KEY_KP6) -> atset1:77 */ | ||||
|   "Numpad7": 0x47, /* html:Numpad7 (Numpad7) -> linux:71 (KEY_KP7) -> atset1:71 */ | ||||
|   "Numpad8": 0x48, /* html:Numpad8 (Numpad8) -> linux:72 (KEY_KP8) -> atset1:72 */ | ||||
|   "Numpad9": 0x49, /* html:Numpad9 (Numpad9) -> linux:73 (KEY_KP9) -> atset1:73 */ | ||||
|   "NumpadAdd": 0x4e, /* html:NumpadAdd (NumpadAdd) -> linux:78 (KEY_KPPLUS) -> atset1:78 */ | ||||
|   "NumpadComma": 0x7e, /* html:NumpadComma (NumpadComma) -> linux:121 (KEY_KPCOMMA) -> atset1:126 */ | ||||
|   "NumpadDecimal": 0x53, /* html:NumpadDecimal (NumpadDecimal) -> linux:83 (KEY_KPDOT) -> atset1:83 */ | ||||
|   "NumpadDivide": 0xe035, /* html:NumpadDivide (NumpadDivide) -> linux:98 (KEY_KPSLASH) -> atset1:57397 */ | ||||
|   "NumpadEnter": 0xe01c, /* html:NumpadEnter (NumpadEnter) -> linux:96 (KEY_KPENTER) -> atset1:57372 */ | ||||
|   "NumpadEqual": 0x59, /* html:NumpadEqual (NumpadEqual) -> linux:117 (KEY_KPEQUAL) -> atset1:89 */ | ||||
|   "NumpadMultiply": 0x37, /* html:NumpadMultiply (NumpadMultiply) -> linux:55 (KEY_KPASTERISK) -> atset1:55 */ | ||||
|   "NumpadParenLeft": 0xe076, /* html:NumpadParenLeft (NumpadParenLeft) -> linux:179 (KEY_KPLEFTPAREN) -> atset1:57462 */ | ||||
|   "NumpadParenRight": 0xe07b, /* html:NumpadParenRight (NumpadParenRight) -> linux:180 (KEY_KPRIGHTPAREN) -> atset1:57467 */ | ||||
|   "NumpadSubtract": 0x4a, /* html:NumpadSubtract (NumpadSubtract) -> linux:74 (KEY_KPMINUS) -> atset1:74 */ | ||||
|   "Open": 0x64, /* html:Open (Open) -> linux:134 (KEY_OPEN) -> atset1:100 */ | ||||
|   "PageDown": 0xe051, /* html:PageDown (PageDown) -> linux:109 (KEY_PAGEDOWN) -> atset1:57425 */ | ||||
|   "PageUp": 0xe049, /* html:PageUp (PageUp) -> linux:104 (KEY_PAGEUP) -> atset1:57417 */ | ||||
|   "Paste": 0x65, /* html:Paste (Paste) -> linux:135 (KEY_PASTE) -> atset1:101 */ | ||||
|   "Pause": 0xe046, /* html:Pause (Pause) -> linux:119 (KEY_PAUSE) -> atset1:57414 */ | ||||
|   "Period": 0x34, /* html:Period (Period) -> linux:52 (KEY_DOT) -> atset1:52 */ | ||||
|   "Power": 0xe05e, /* html:Power (Power) -> linux:116 (KEY_POWER) -> atset1:57438 */ | ||||
|   "PrintScreen": 0x54, /* html:PrintScreen (PrintScreen) -> linux:99 (KEY_SYSRQ) -> atset1:84 */ | ||||
|   "Props": 0xe006, /* html:Props (Props) -> linux:130 (KEY_PROPS) -> atset1:57350 */ | ||||
|   "Quote": 0x28, /* html:Quote (Quote) -> linux:40 (KEY_APOSTROPHE) -> atset1:40 */ | ||||
|   "ScrollLock": 0x46, /* html:ScrollLock (ScrollLock) -> linux:70 (KEY_SCROLLLOCK) -> atset1:70 */ | ||||
|   "Semicolon": 0x27, /* html:Semicolon (Semicolon) -> linux:39 (KEY_SEMICOLON) -> atset1:39 */ | ||||
|   "ShiftLeft": 0x2a, /* html:ShiftLeft (ShiftLeft) -> linux:42 (KEY_LEFTSHIFT) -> atset1:42 */ | ||||
|   "ShiftRight": 0x36, /* html:ShiftRight (ShiftRight) -> linux:54 (KEY_RIGHTSHIFT) -> atset1:54 */ | ||||
|   "Slash": 0x35, /* html:Slash (Slash) -> linux:53 (KEY_SLASH) -> atset1:53 */ | ||||
|   "Sleep": 0xe05f, /* html:Sleep (Sleep) -> linux:142 (KEY_SLEEP) -> atset1:57439 */ | ||||
|   "Space": 0x39, /* html:Space (Space) -> linux:57 (KEY_SPACE) -> atset1:57 */ | ||||
|   "Suspend": 0xe025, /* html:Suspend (Suspend) -> linux:205 (KEY_SUSPEND) -> atset1:57381 */ | ||||
|   "Tab": 0xf, /* html:Tab (Tab) -> linux:15 (KEY_TAB) -> atset1:15 */ | ||||
|   "Undo": 0xe007, /* html:Undo (Undo) -> linux:131 (KEY_UNDO) -> atset1:57351 */ | ||||
|   "WakeUp": 0xe063, /* html:WakeUp (WakeUp) -> linux:143 (KEY_WAKEUP) -> atset1:57443 */ | ||||
| }; | ||||
							
								
								
									
										2988
									
								
								public/novnc/core/rfb.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										103
									
								
								public/novnc/core/util/browser.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,103 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  * | ||||
|  * Browser feature support detection | ||||
|  */ | ||||
|  | ||||
| import * as Log from './logging.js'; | ||||
|  | ||||
| // Touch detection | ||||
| export let isTouchDevice = ('ontouchstart' in document.documentElement) || | ||||
|                                  // requried for Chrome debugger | ||||
|                                  (document.ontouchstart !== undefined) || | ||||
|                                  // required for MS Surface | ||||
|                                  (navigator.maxTouchPoints > 0) || | ||||
|                                  (navigator.msMaxTouchPoints > 0); | ||||
| window.addEventListener('touchstart', function onFirstTouch() { | ||||
|     isTouchDevice = true; | ||||
|     window.removeEventListener('touchstart', onFirstTouch, false); | ||||
| }, false); | ||||
|  | ||||
|  | ||||
| // The goal is to find a certain physical width, the devicePixelRatio | ||||
| // brings us a bit closer but is not optimal. | ||||
| export let dragThreshold = 10 * (window.devicePixelRatio || 1); | ||||
|  | ||||
| let _supportsCursorURIs = false; | ||||
|  | ||||
| try { | ||||
|     const target = document.createElement('canvas'); | ||||
|     target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default'; | ||||
|  | ||||
|     if (target.style.cursor.indexOf("url") === 0) { | ||||
|         Log.Info("Data URI scheme cursor supported"); | ||||
|         _supportsCursorURIs = true; | ||||
|     } else { | ||||
|         Log.Warn("Data URI scheme cursor not supported"); | ||||
|     } | ||||
| } catch (exc) { | ||||
|     Log.Error("Data URI scheme cursor test exception: " + exc); | ||||
| } | ||||
|  | ||||
| export const supportsCursorURIs = _supportsCursorURIs; | ||||
|  | ||||
| let _hasScrollbarGutter = true; | ||||
| try { | ||||
|     // Create invisible container | ||||
|     const container = document.createElement('div'); | ||||
|     container.style.visibility = 'hidden'; | ||||
|     container.style.overflow = 'scroll'; // forcing scrollbars | ||||
|     document.body.appendChild(container); | ||||
|  | ||||
|     // Create a div and place it in the container | ||||
|     const child = document.createElement('div'); | ||||
|     container.appendChild(child); | ||||
|  | ||||
|     // Calculate the difference between the container's full width | ||||
|     // and the child's width - the difference is the scrollbars | ||||
|     const scrollbarWidth = (container.offsetWidth - child.offsetWidth); | ||||
|  | ||||
|     // Clean up | ||||
|     container.parentNode.removeChild(container); | ||||
|  | ||||
|     _hasScrollbarGutter = scrollbarWidth != 0; | ||||
| } catch (exc) { | ||||
|     Log.Error("Scrollbar test exception: " + exc); | ||||
| } | ||||
| export const hasScrollbarGutter = _hasScrollbarGutter; | ||||
|  | ||||
| /* | ||||
|  * The functions for detection of platforms and browsers below are exported | ||||
|  * but the use of these should be minimized as much as possible. | ||||
|  * | ||||
|  * It's better to use feature detection than platform detection. | ||||
|  */ | ||||
|  | ||||
| export function isMac() { | ||||
|     return navigator && !!(/mac/i).exec(navigator.platform); | ||||
| } | ||||
|  | ||||
| export function isWindows() { | ||||
|     return navigator && !!(/win/i).exec(navigator.platform); | ||||
| } | ||||
|  | ||||
| export function isIOS() { | ||||
|     return navigator && | ||||
|            (!!(/ipad/i).exec(navigator.platform) || | ||||
|             !!(/iphone/i).exec(navigator.platform) || | ||||
|             !!(/ipod/i).exec(navigator.platform)); | ||||
| } | ||||
|  | ||||
| export function isSafari() { | ||||
|     return navigator && (navigator.userAgent.indexOf('Safari') !== -1 && | ||||
|                          navigator.userAgent.indexOf('Chrome') === -1); | ||||
| } | ||||
|  | ||||
| export function isFirefox() { | ||||
|     return navigator && !!(/firefox/i).exec(navigator.userAgent); | ||||
| } | ||||
|  | ||||
							
								
								
									
										243
									
								
								public/novnc/core/util/cursor.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,243 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | ||||
|  */ | ||||
|  | ||||
| import { supportsCursorURIs, isTouchDevice } from './browser.js'; | ||||
|  | ||||
| const useFallback = !supportsCursorURIs || isTouchDevice; | ||||
|  | ||||
| export default class Cursor { | ||||
|     constructor() { | ||||
|         this._target = null; | ||||
|  | ||||
|         this._canvas = document.createElement('canvas'); | ||||
|  | ||||
|         if (useFallback) { | ||||
|             this._canvas.style.position = 'fixed'; | ||||
|             this._canvas.style.zIndex = '65535'; | ||||
|             this._canvas.style.pointerEvents = 'none'; | ||||
|             // Can't use "display" because of Firefox bug #1445997 | ||||
|             this._canvas.style.visibility = 'hidden'; | ||||
|         } | ||||
|  | ||||
|         this._position = { x: 0, y: 0 }; | ||||
|         this._hotSpot = { x: 0, y: 0 }; | ||||
|  | ||||
|         this._eventHandlers = { | ||||
|             'mouseover': this._handleMouseOver.bind(this), | ||||
|             'mouseleave': this._handleMouseLeave.bind(this), | ||||
|             'mousemove': this._handleMouseMove.bind(this), | ||||
|             'mouseup': this._handleMouseUp.bind(this), | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     attach(target) { | ||||
|         if (this._target) { | ||||
|             this.detach(); | ||||
|         } | ||||
|  | ||||
|         this._target = target; | ||||
|  | ||||
|         if (useFallback) { | ||||
|             document.body.appendChild(this._canvas); | ||||
|  | ||||
|             const options = { capture: true, passive: true }; | ||||
|             this._target.addEventListener('mouseover', this._eventHandlers.mouseover, options); | ||||
|             this._target.addEventListener('mouseleave', this._eventHandlers.mouseleave, options); | ||||
|             this._target.addEventListener('mousemove', this._eventHandlers.mousemove, options); | ||||
|             this._target.addEventListener('mouseup', this._eventHandlers.mouseup, options); | ||||
|         } | ||||
|  | ||||
|         this.clear(); | ||||
|     } | ||||
|  | ||||
|     detach() { | ||||
|         if (!this._target) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (useFallback) { | ||||
|             const options = { capture: true, passive: true }; | ||||
|             this._target.removeEventListener('mouseover', this._eventHandlers.mouseover, options); | ||||
|             this._target.removeEventListener('mouseleave', this._eventHandlers.mouseleave, options); | ||||
|             this._target.removeEventListener('mousemove', this._eventHandlers.mousemove, options); | ||||
|             this._target.removeEventListener('mouseup', this._eventHandlers.mouseup, options); | ||||
|  | ||||
|             document.body.removeChild(this._canvas); | ||||
|         } | ||||
|  | ||||
|         this._target = null; | ||||
|     } | ||||
|  | ||||
|     change(rgba, hotx, hoty, w, h) { | ||||
|         if ((w === 0) || (h === 0)) { | ||||
|             this.clear(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         this._position.x = this._position.x + this._hotSpot.x - hotx; | ||||
|         this._position.y = this._position.y + this._hotSpot.y - hoty; | ||||
|         this._hotSpot.x = hotx; | ||||
|         this._hotSpot.y = hoty; | ||||
|  | ||||
|         let ctx = this._canvas.getContext('2d'); | ||||
|  | ||||
|         this._canvas.width = w; | ||||
|         this._canvas.height = h; | ||||
|  | ||||
|         let img = new ImageData(new Uint8ClampedArray(rgba), w, h); | ||||
|         ctx.clearRect(0, 0, w, h); | ||||
|         ctx.putImageData(img, 0, 0); | ||||
|  | ||||
|         if (useFallback) { | ||||
|             this._updatePosition(); | ||||
|         } else { | ||||
|             let url = this._canvas.toDataURL(); | ||||
|             this._target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default'; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     clear() { | ||||
|         this._target.style.cursor = 'none'; | ||||
|         this._canvas.width = 0; | ||||
|         this._canvas.height = 0; | ||||
|         this._position.x = this._position.x + this._hotSpot.x; | ||||
|         this._position.y = this._position.y + this._hotSpot.y; | ||||
|         this._hotSpot.x = 0; | ||||
|         this._hotSpot.y = 0; | ||||
|     } | ||||
|  | ||||
|     // Mouse events might be emulated, this allows | ||||
|     // moving the cursor in such cases | ||||
|     move(clientX, clientY) { | ||||
|         if (!useFallback) { | ||||
|             return; | ||||
|         } | ||||
|         // clientX/clientY are relative the _visual viewport_, | ||||
|         // but our position is relative the _layout viewport_, | ||||
|         // so try to compensate when we can | ||||
|         if (window.visualViewport) { | ||||
|             this._position.x = clientX + window.visualViewport.offsetLeft; | ||||
|             this._position.y = clientY + window.visualViewport.offsetTop; | ||||
|         } else { | ||||
|             this._position.x = clientX; | ||||
|             this._position.y = clientY; | ||||
|         } | ||||
|         this._updatePosition(); | ||||
|         let target = document.elementFromPoint(clientX, clientY); | ||||
|         this._updateVisibility(target); | ||||
|     } | ||||
|  | ||||
|     _handleMouseOver(event) { | ||||
|         // This event could be because we're entering the target, or | ||||
|         // moving around amongst its sub elements. Let the move handler | ||||
|         // sort things out. | ||||
|         this._handleMouseMove(event); | ||||
|     } | ||||
|  | ||||
|     _handleMouseLeave(event) { | ||||
|         // Check if we should show the cursor on the element we are leaving to | ||||
|         this._updateVisibility(event.relatedTarget); | ||||
|     } | ||||
|  | ||||
|     _handleMouseMove(event) { | ||||
|         this._updateVisibility(event.target); | ||||
|  | ||||
|         this._position.x = event.clientX - this._hotSpot.x; | ||||
|         this._position.y = event.clientY - this._hotSpot.y; | ||||
|  | ||||
|         this._updatePosition(); | ||||
|     } | ||||
|  | ||||
|     _handleMouseUp(event) { | ||||
|         // We might get this event because of a drag operation that | ||||
|         // moved outside of the target. Check what's under the cursor | ||||
|         // now and adjust visibility based on that. | ||||
|         let target = document.elementFromPoint(event.clientX, event.clientY); | ||||
|         this._updateVisibility(target); | ||||
|  | ||||
|         // Captures end with a mouseup but we can't know the event order of | ||||
|         // mouseup vs releaseCapture. | ||||
|         // | ||||
|         // In the cases when releaseCapture comes first, the code above is | ||||
|         // enough. | ||||
|         // | ||||
|         // In the cases when the mouseup comes first, we need wait for the | ||||
|         // browser to flush all events and then check again if the cursor | ||||
|         // should be visible. | ||||
|         if (this._captureIsActive()) { | ||||
|             window.setTimeout(() => { | ||||
|                 // We might have detached at this point | ||||
|                 if (!this._target) { | ||||
|                     return; | ||||
|                 } | ||||
|                 // Refresh the target from elementFromPoint since queued events | ||||
|                 // might have altered the DOM | ||||
|                 target = document.elementFromPoint(event.clientX, | ||||
|                                                    event.clientY); | ||||
|                 this._updateVisibility(target); | ||||
|             }, 0); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _showCursor() { | ||||
|         if (this._canvas.style.visibility === 'hidden') { | ||||
|             this._canvas.style.visibility = ''; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _hideCursor() { | ||||
|         if (this._canvas.style.visibility !== 'hidden') { | ||||
|             this._canvas.style.visibility = 'hidden'; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Should we currently display the cursor? | ||||
|     // (i.e. are we over the target, or a child of the target without a | ||||
|     // different cursor set) | ||||
|     _shouldShowCursor(target) { | ||||
|         if (!target) { | ||||
|             return false; | ||||
|         } | ||||
|         // Easy case | ||||
|         if (target === this._target) { | ||||
|             return true; | ||||
|         } | ||||
|         // Other part of the DOM? | ||||
|         if (!this._target.contains(target)) { | ||||
|             return false; | ||||
|         } | ||||
|         // Has the child its own cursor? | ||||
|         // FIXME: How can we tell that a sub element has an | ||||
|         //        explicit "cursor: none;"? | ||||
|         if (window.getComputedStyle(target).cursor !== 'none') { | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     _updateVisibility(target) { | ||||
|         // When the cursor target has capture we want to show the cursor. | ||||
|         // So, if a capture is active - look at the captured element instead. | ||||
|         if (this._captureIsActive()) { | ||||
|             target = document.captureElement; | ||||
|         } | ||||
|         if (this._shouldShowCursor(target)) { | ||||
|             this._showCursor(); | ||||
|         } else { | ||||
|             this._hideCursor(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     _updatePosition() { | ||||
|         this._canvas.style.left = this._position.x + "px"; | ||||
|         this._canvas.style.top = this._position.y + "px"; | ||||
|     } | ||||
|  | ||||
|     _captureIsActive() { | ||||
|         return document.captureElement && | ||||
|             document.documentElement.contains(document.captureElement); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										32
									
								
								public/novnc/core/util/element.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,32 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2020 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * HTML element utility functions | ||||
|  */ | ||||
|  | ||||
| export function clientToElement(x, y, elem) { | ||||
|     const bounds = elem.getBoundingClientRect(); | ||||
|     let pos = { x: 0, y: 0 }; | ||||
|     // Clip to target bounds | ||||
|     if (x < bounds.left) { | ||||
|         pos.x = 0; | ||||
|     } else if (x >= bounds.right) { | ||||
|         pos.x = bounds.width - 1; | ||||
|     } else { | ||||
|         pos.x = x - bounds.left; | ||||
|     } | ||||
|     if (y < bounds.top) { | ||||
|         pos.y = 0; | ||||
|     } else if (y >= bounds.bottom) { | ||||
|         pos.y = bounds.height - 1; | ||||
|     } else { | ||||
|         pos.y = y - bounds.top; | ||||
|     } | ||||
|     return pos; | ||||
| } | ||||
							
								
								
									
										138
									
								
								public/novnc/core/util/events.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,138 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2018 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Cross-browser event and position routines | ||||
|  */ | ||||
|  | ||||
| export function getPointerEvent(e) { | ||||
|     return e.changedTouches ? e.changedTouches[0] : e.touches ? e.touches[0] : e; | ||||
| } | ||||
|  | ||||
| export function stopEvent(e) { | ||||
|     e.stopPropagation(); | ||||
|     e.preventDefault(); | ||||
| } | ||||
|  | ||||
| // Emulate Element.setCapture() when not supported | ||||
| let _captureRecursion = false; | ||||
| let _elementForUnflushedEvents = null; | ||||
| document.captureElement = null; | ||||
| function _captureProxy(e) { | ||||
|     // Recursion protection as we'll see our own event | ||||
|     if (_captureRecursion) return; | ||||
|  | ||||
|     // Clone the event as we cannot dispatch an already dispatched event | ||||
|     const newEv = new e.constructor(e.type, e); | ||||
|  | ||||
|     _captureRecursion = true; | ||||
|     if (document.captureElement) { | ||||
|         document.captureElement.dispatchEvent(newEv); | ||||
|     } else { | ||||
|         _elementForUnflushedEvents.dispatchEvent(newEv); | ||||
|     } | ||||
|     _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") { | ||||
|         releaseCapture(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Follow cursor style of target element | ||||
| function _capturedElemChanged() { | ||||
|     const proxyElem = document.getElementById("noVNC_mouse_capture_elem"); | ||||
|     proxyElem.style.cursor = window.getComputedStyle(document.captureElement).cursor; | ||||
| } | ||||
|  | ||||
| const _captureObserver = new MutationObserver(_capturedElemChanged); | ||||
|  | ||||
| export function setCapture(target) { | ||||
|     if (target.setCapture) { | ||||
|  | ||||
|         target.setCapture(); | ||||
|         document.captureElement = target; | ||||
|     } else { | ||||
|         // Release any existing capture in case this method is | ||||
|         // called multiple times without coordination | ||||
|         releaseCapture(); | ||||
|  | ||||
|         let proxyElem = document.getElementById("noVNC_mouse_capture_elem"); | ||||
|  | ||||
|         if (proxyElem === null) { | ||||
|             proxyElem = document.createElement("div"); | ||||
|             proxyElem.id = "noVNC_mouse_capture_elem"; | ||||
|             proxyElem.style.position = "fixed"; | ||||
|             proxyElem.style.top = "0px"; | ||||
|             proxyElem.style.left = "0px"; | ||||
|             proxyElem.style.width = "100%"; | ||||
|             proxyElem.style.height = "100%"; | ||||
|             proxyElem.style.zIndex = 10000; | ||||
|             proxyElem.style.display = "none"; | ||||
|             document.body.appendChild(proxyElem); | ||||
|  | ||||
|             // This is to make sure callers don't get confused by having | ||||
|             // our blocking element as the target | ||||
|             proxyElem.addEventListener('contextmenu', _captureProxy); | ||||
|  | ||||
|             proxyElem.addEventListener('mousemove', _captureProxy); | ||||
|             proxyElem.addEventListener('mouseup', _captureProxy); | ||||
|         } | ||||
|  | ||||
|         document.captureElement = target; | ||||
|  | ||||
|         // Track cursor and get initial cursor | ||||
|         _captureObserver.observe(target, {attributes: true}); | ||||
|         _capturedElemChanged(); | ||||
|  | ||||
|         proxyElem.style.display = ""; | ||||
|  | ||||
|         // We listen to events on window in order to keep tracking if it | ||||
|         // happens to leave the viewport | ||||
|         window.addEventListener('mousemove', _captureProxy); | ||||
|         window.addEventListener('mouseup', _captureProxy); | ||||
|     } | ||||
| } | ||||
|  | ||||
| export function releaseCapture() { | ||||
|     if (document.releaseCapture) { | ||||
|  | ||||
|         document.releaseCapture(); | ||||
|         document.captureElement = null; | ||||
|  | ||||
|     } else { | ||||
|         if (!document.captureElement) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // There might be events already queued. The event proxy needs | ||||
|         // access to the captured element for these queued events. | ||||
|         // E.g. contextmenu (right-click) in Microsoft Edge | ||||
|         // | ||||
|         // Before removing the capturedElem pointer we save it to a | ||||
|         // temporary variable that the unflushed events can use. | ||||
|         _elementForUnflushedEvents = document.captureElement; | ||||
|         document.captureElement = null; | ||||
|  | ||||
|         _captureObserver.disconnect(); | ||||
|  | ||||
|         const proxyElem = document.getElementById("noVNC_mouse_capture_elem"); | ||||
|         proxyElem.style.display = "none"; | ||||
|  | ||||
|         window.removeEventListener('mousemove', _captureProxy); | ||||
|         window.removeEventListener('mouseup', _captureProxy); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										35
									
								
								public/novnc/core/util/eventtarget.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,35 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| export default class EventTargetMixin { | ||||
|     constructor() { | ||||
|         this._listeners = new Map(); | ||||
|     } | ||||
|  | ||||
|     addEventListener(type, callback) { | ||||
|         if (!this._listeners.has(type)) { | ||||
|             this._listeners.set(type, new Set()); | ||||
|         } | ||||
|         this._listeners.get(type).add(callback); | ||||
|     } | ||||
|  | ||||
|     removeEventListener(type, callback) { | ||||
|         if (this._listeners.has(type)) { | ||||
|             this._listeners.get(type).delete(callback); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     dispatchEvent(event) { | ||||
|         if (!this._listeners.has(event.type)) { | ||||
|             return true; | ||||
|         } | ||||
|         this._listeners.get(event.type) | ||||
|             .forEach(callback => callback.call(this, event)); | ||||
|         return !event.defaultPrevented; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										15
									
								
								public/novnc/core/util/int.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,15 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2020 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| export function toUnsigned32bit(toConvert) { | ||||
|     return toConvert >>> 0; | ||||
| } | ||||
|  | ||||
| export function toSigned32bit(toConvert) { | ||||
|     return toConvert | 0; | ||||
| } | ||||
							
								
								
									
										56
									
								
								public/novnc/core/util/logging.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,56 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Logging/debug routines | ||||
|  */ | ||||
|  | ||||
| let _logLevel = 'warn'; | ||||
|  | ||||
| let Debug = () => {}; | ||||
| let Info = () => {}; | ||||
| let Warn = () => {}; | ||||
| let Error = () => {}; | ||||
|  | ||||
| export function initLogging(level) { | ||||
|     if (typeof level === 'undefined') { | ||||
|         level = _logLevel; | ||||
|     } else { | ||||
|         _logLevel = level; | ||||
|     } | ||||
|  | ||||
|     Debug = Info = Warn = Error = () => {}; | ||||
|  | ||||
|     if (typeof window.console !== "undefined") { | ||||
|         /* eslint-disable no-console, no-fallthrough */ | ||||
|         switch (level) { | ||||
|             case 'debug': | ||||
|                 Debug = console.debug.bind(window.console); | ||||
|             case 'info': | ||||
|                 Info  = console.info.bind(window.console); | ||||
|             case 'warn': | ||||
|                 Warn  = console.warn.bind(window.console); | ||||
|             case 'error': | ||||
|                 Error = console.error.bind(window.console); | ||||
|             case 'none': | ||||
|                 break; | ||||
|             default: | ||||
|                 throw new window.Error("invalid logging type '" + level + "'"); | ||||
|         } | ||||
|         /* eslint-enable no-console, no-fallthrough */ | ||||
|     } | ||||
| } | ||||
|  | ||||
| export function getLogging() { | ||||
|     return _logLevel; | ||||
| } | ||||
|  | ||||
| export { Debug, Info, Warn, Error }; | ||||
|  | ||||
| // Initialize logging level | ||||
| initLogging(); | ||||
							
								
								
									
										28
									
								
								public/novnc/core/util/strings.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,28 @@ | ||||
| /* | ||||
|  * noVNC: HTML5 VNC client | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * See README.md for usage and integration instructions. | ||||
|  */ | ||||
|  | ||||
| // Decode from UTF-8 | ||||
| export function decodeUTF8(utf8string, allowLatin1=false) { | ||||
|     try { | ||||
|         return decodeURIComponent(escape(utf8string)); | ||||
|     } catch (e) { | ||||
|         if (e instanceof URIError) { | ||||
|             if (allowLatin1) { | ||||
|                 // If we allow Latin1 we can ignore any decoding fails | ||||
|                 // and in these cases return the original string | ||||
|                 return utf8string; | ||||
|             } | ||||
|         } | ||||
|         throw e; | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Encode to UTF-8 | ||||
| export function encodeUTF8(DOMString) { | ||||
|     return unescape(encodeURIComponent(DOMString)); | ||||
| } | ||||
							
								
								
									
										353
									
								
								public/novnc/core/websock.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,353 @@ | ||||
| /* | ||||
|  * Websock: high-performance buffering wrapper | ||||
|  * Copyright (C) 2019 The noVNC Authors | ||||
|  * Licensed under MPL 2.0 (see LICENSE.txt) | ||||
|  * | ||||
|  * Websock is similar to the standard WebSocket / RTCDataChannel 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 | ||||
|  * there is new data available. Several rQ* methods are available to | ||||
|  * read binary data off of the receive queue. | ||||
|  */ | ||||
|  | ||||
| import * as Log from './util/logging.js'; | ||||
|  | ||||
| // 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. | ||||
| const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024;  // 40 MiB | ||||
|  | ||||
| // Constants pulled from RTCDataChannelState enum | ||||
| // https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/readyState#RTCDataChannelState_enum | ||||
| const DataChannel = { | ||||
|     CONNECTING: "connecting", | ||||
|     OPEN: "open", | ||||
|     CLOSING: "closing", | ||||
|     CLOSED: "closed" | ||||
| }; | ||||
|  | ||||
| const ReadyStates = { | ||||
|     CONNECTING: [WebSocket.CONNECTING, DataChannel.CONNECTING], | ||||
|     OPEN: [WebSocket.OPEN, DataChannel.OPEN], | ||||
|     CLOSING: [WebSocket.CLOSING, DataChannel.CLOSING], | ||||
|     CLOSED: [WebSocket.CLOSED, DataChannel.CLOSED], | ||||
| }; | ||||
|  | ||||
| // Properties a raw channel must have, WebSocket and RTCDataChannel are two examples | ||||
| const rawChannelProps = [ | ||||
|     "send", | ||||
|     "close", | ||||
|     "binaryType", | ||||
|     "onerror", | ||||
|     "onmessage", | ||||
|     "onopen", | ||||
|     "protocol", | ||||
|     "readyState", | ||||
| ]; | ||||
|  | ||||
| export default class Websock { | ||||
|     constructor() { | ||||
|         this._websocket = null;  // WebSocket or RTCDataChannel object | ||||
|  | ||||
|         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) | ||||
|         // 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: () => {}, | ||||
|             open: () => {}, | ||||
|             close: () => {}, | ||||
|             error: () => {} | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     // Getters and Setters | ||||
|  | ||||
|     get readyState() { | ||||
|         let subState; | ||||
|  | ||||
|         if (this._websocket === null) { | ||||
|             return "unused"; | ||||
|         } | ||||
|  | ||||
|         subState = this._websocket.readyState; | ||||
|  | ||||
|         if (ReadyStates.CONNECTING.includes(subState)) { | ||||
|             return "connecting"; | ||||
|         } else if (ReadyStates.OPEN.includes(subState)) { | ||||
|             return "open"; | ||||
|         } else if (ReadyStates.CLOSING.includes(subState)) { | ||||
|             return "closing"; | ||||
|         } else if (ReadyStates.CLOSED.includes(subState)) { | ||||
|             return "closed"; | ||||
|         } | ||||
|  | ||||
|         return "unknown"; | ||||
|     } | ||||
|  | ||||
|     get sQ() { | ||||
|         return this._sQ; | ||||
|     } | ||||
|  | ||||
|     get rQ() { | ||||
|         return this._rQ; | ||||
|     } | ||||
|  | ||||
|     get rQi() { | ||||
|         return this._rQi; | ||||
|     } | ||||
|  | ||||
|     set rQi(val) { | ||||
|         this._rQi = val; | ||||
|     } | ||||
|  | ||||
|     // Receive Queue | ||||
|     get rQlen() { | ||||
|         return this._rQlen - this._rQi; | ||||
|     } | ||||
|  | ||||
|     rQpeek8() { | ||||
|         return this._rQ[this._rQi]; | ||||
|     } | ||||
|  | ||||
|     rQskipBytes(bytes) { | ||||
|         this._rQi += bytes; | ||||
|     } | ||||
|  | ||||
|     rQshift8() { | ||||
|         return this._rQshift(1); | ||||
|     } | ||||
|  | ||||
|     rQshift16() { | ||||
|         return this._rQshift(2); | ||||
|     } | ||||
|  | ||||
|     rQshift32() { | ||||
|         return this._rQshift(4); | ||||
|     } | ||||
|  | ||||
|     // TODO(directxman12): test performance with these vs a DataView | ||||
|     _rQshift(bytes) { | ||||
|         let res = 0; | ||||
|         for (let byte = bytes - 1; byte >= 0; byte--) { | ||||
|             res += this._rQ[this._rQi++] << (byte * 8); | ||||
|         } | ||||
|         return res; | ||||
|     } | ||||
|  | ||||
|     rQshiftStr(len) { | ||||
|         if (typeof(len) === 'undefined') { len = this.rQlen; } | ||||
|         let str = ""; | ||||
|         // Handle large arrays in steps to avoid long strings on the stack | ||||
|         for (let i = 0; i < len; i += 4096) { | ||||
|             let part = this.rQshiftBytes(Math.min(4096, len - i)); | ||||
|             str += String.fromCharCode.apply(null, part); | ||||
|         } | ||||
|         return str; | ||||
|     } | ||||
|  | ||||
|     rQshiftBytes(len) { | ||||
|         if (typeof(len) === 'undefined') { len = this.rQlen; } | ||||
|         this._rQi += len; | ||||
|         return new Uint8Array(this._rQ.buffer, this._rQi - len, len); | ||||
|     } | ||||
|  | ||||
|     rQshiftTo(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; | ||||
|     } | ||||
|  | ||||
|     rQslice(start, end = this.rQlen) { | ||||
|         return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start); | ||||
|     } | ||||
|  | ||||
|     // Check to see if we must wait for 'num' bytes (default to FBU.bytes) | ||||
|     // to be available in the receive queue. Return true if we need to | ||||
|     // wait (and possibly print a debug message), otherwise false. | ||||
|     rQwait(msg, num, goback) { | ||||
|         if (this.rQlen < num) { | ||||
|             if (goback) { | ||||
|                 if (this._rQi < goback) { | ||||
|                     throw new Error("rQwait cannot backup " + goback + " bytes"); | ||||
|                 } | ||||
|                 this._rQi -= goback; | ||||
|             } | ||||
|             return true; // true means need more data | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     // Send Queue | ||||
|  | ||||
|     flush() { | ||||
|         if (this._sQlen > 0 && this.readyState === 'open') { | ||||
|             this._websocket.send(this._encodeMessage()); | ||||
|             this._sQlen = 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     send(arr) { | ||||
|         this._sQ.set(arr, this._sQlen); | ||||
|         this._sQlen += arr.length; | ||||
|         this.flush(); | ||||
|     } | ||||
|  | ||||
|     sendString(str) { | ||||
|         this.send(str.split('').map(chr => chr.charCodeAt(0))); | ||||
|     } | ||||
|  | ||||
|     // Event Handlers | ||||
|     off(evt) { | ||||
|         this._eventHandlers[evt] = () => {}; | ||||
|     } | ||||
|  | ||||
|     on(evt, handler) { | ||||
|         this._eventHandlers[evt] = handler; | ||||
|     } | ||||
|  | ||||
|     _allocateBuffers() { | ||||
|         this._rQ = new Uint8Array(this._rQbufferSize); | ||||
|         this._sQ = new Uint8Array(this._sQbufferSize); | ||||
|     } | ||||
|  | ||||
|     init() { | ||||
|         this._allocateBuffers(); | ||||
|         this._rQi = 0; | ||||
|         this._websocket = null; | ||||
|     } | ||||
|  | ||||
|     open(uri, protocols) { | ||||
|         this.attach(new WebSocket(uri, protocols)); | ||||
|     } | ||||
|  | ||||
|     attach(rawChannel) { | ||||
|         this.init(); | ||||
|  | ||||
|         // Must get object and class methods to be compatible with the tests. | ||||
|         const channelProps = [...Object.keys(rawChannel), ...Object.getOwnPropertyNames(Object.getPrototypeOf(rawChannel))]; | ||||
|         for (let i = 0; i < rawChannelProps.length; i++) { | ||||
|             const prop = rawChannelProps[i]; | ||||
|             if (channelProps.indexOf(prop) < 0) { | ||||
|                 throw new Error('Raw channel missing property: ' + prop); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this._websocket = rawChannel; | ||||
|         this._websocket.binaryType = "arraybuffer"; | ||||
|         this._websocket.onmessage = this._recvMessage.bind(this); | ||||
|  | ||||
|         this._websocket.onopen = () => { | ||||
|             Log.Debug('>> WebSock.onopen'); | ||||
|             if (this._websocket.protocol) { | ||||
|                 Log.Info("Server choose sub-protocol: " + this._websocket.protocol); | ||||
|             } | ||||
|  | ||||
|             this._eventHandlers.open(); | ||||
|             Log.Debug("<< WebSock.onopen"); | ||||
|         }; | ||||
|  | ||||
|         this._websocket.onclose = (e) => { | ||||
|             Log.Debug(">> WebSock.onclose"); | ||||
|             this._eventHandlers.close(e); | ||||
|             Log.Debug("<< WebSock.onclose"); | ||||
|         }; | ||||
|  | ||||
|         this._websocket.onerror = (e) => { | ||||
|             Log.Debug(">> WebSock.onerror: " + e); | ||||
|             this._eventHandlers.error(e); | ||||
|             Log.Debug("<< WebSock.onerror: " + e); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     close() { | ||||
|         if (this._websocket) { | ||||
|             if (this.readyState === 'connecting' || | ||||
|                 this.readyState === 'open') { | ||||
|                 Log.Info("Closing WebSocket connection"); | ||||
|                 this._websocket.close(); | ||||
|             } | ||||
|  | ||||
|             this._websocket.onmessage = () => {}; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // private methods | ||||
|     _encodeMessage() { | ||||
|         // 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); | ||||
|     } | ||||
|  | ||||
|     // We want to move all the unread data to the start of the queue, | ||||
|     // e.g. compacting. | ||||
|     // The function also expands the receive que if needed, and for | ||||
|     // performance reasons we combine these two actions to avoid | ||||
|     // unneccessary copying. | ||||
|     _expandCompactRQ(minFit) { | ||||
|         // if we're using less than 1/8th of the buffer even with the incoming bytes, compact in place | ||||
|         // instead of resizing | ||||
|         const requiredBufferSize =  (this._rQlen - this._rQi + minFit) * 8; | ||||
|         const resizeNeeded = this._rQbufferSize < requiredBufferSize; | ||||
|  | ||||
|         if (resizeNeeded) { | ||||
|             // Make sure we always *at least* double the buffer size, and have at least space for 8x | ||||
|             // the current amount of data | ||||
|             this._rQbufferSize = Math.max(this._rQbufferSize * 2, requiredBufferSize); | ||||
|         } | ||||
|  | ||||
|         // 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 < minFit) { | ||||
|                 throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (resizeNeeded) { | ||||
|             const oldRQbuffer = this._rQ.buffer; | ||||
|             this._rQ = new Uint8Array(this._rQbufferSize); | ||||
|             this._rQ.set(new Uint8Array(oldRQbuffer, this._rQi, this._rQlen - this._rQi)); | ||||
|         } else { | ||||
|             this._rQ.copyWithin(0, this._rQi, this._rQlen); | ||||
|         } | ||||
|  | ||||
|         this._rQlen = this._rQlen - this._rQi; | ||||
|         this._rQi = 0; | ||||
|     } | ||||
|  | ||||
|     // push arraybuffer values onto the end of the receive que | ||||
|     _DecodeMessage(data) { | ||||
|         const u8 = new Uint8Array(data); | ||||
|         if (u8.length > this._rQbufferSize - this._rQlen) { | ||||
|             this._expandCompactRQ(u8.length); | ||||
|         } | ||||
|         this._rQ.set(u8, this._rQlen); | ||||
|         this._rQlen += u8.length; | ||||
|     } | ||||
|  | ||||
|     _recvMessage(e) { | ||||
|         this._DecodeMessage(e.data); | ||||
|         if (this.rQlen > 0) { | ||||
|             this._eventHandlers.message(); | ||||
|             if (this._rQlen == this._rQi) { | ||||
|                 // All data has now been processed, this means we | ||||
|                 // can reset the receive queue. | ||||
|                 this._rQlen = 0; | ||||
|                 this._rQi = 0; | ||||
|             } | ||||
|         } else { | ||||
|             Log.Debug("Ignoring empty message"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,167 +1,71 @@ | ||||
| // Karma configuration | ||||
|  | ||||
| module.exports = function(config) { | ||||
|   /*var customLaunchers = { | ||||
|     sl_chrome_win7: { | ||||
|       base: 'SauceLabs', | ||||
|       browserName: 'chrome', | ||||
|       platform: 'Windows 7' | ||||
|     }, | ||||
| // The Safari launcher is broken, so construct our own | ||||
| function SafariBrowser(id, baseBrowserDecorator, args) { | ||||
|   baseBrowserDecorator(this); | ||||
|  | ||||
|     sl_firefox30_linux: { | ||||
|       base: 'SauceLabs', | ||||
|       browserName: 'firefox', | ||||
|       version: '30', | ||||
|       platform: 'Linux' | ||||
|     }, | ||||
|  | ||||
|     sl_firefox26_linux: { | ||||
|       base: 'SauceLabs', | ||||
|       browserName: 'firefox', | ||||
|       version: 26, | ||||
|       platform: 'Linux' | ||||
|     }, | ||||
|  | ||||
|     sl_windows7_ie10: { | ||||
|       base: 'SauceLabs', | ||||
|       browserName: 'internet explorer', | ||||
|       platform: 'Windows 7', | ||||
|       version: '10' | ||||
|     }, | ||||
|  | ||||
|     sl_windows81_ie11: { | ||||
|       base: 'SauceLabs', | ||||
|       browserName: 'internet explorer', | ||||
|       platform: 'Windows 8.1', | ||||
|       version: '11' | ||||
|     }, | ||||
|  | ||||
|     sl_osxmavericks_safari7: { | ||||
|       base: 'SauceLabs', | ||||
|       browserName: 'safari', | ||||
|       platform: 'OS X 10.9', | ||||
|       version: '7' | ||||
|     }, | ||||
|  | ||||
|     sl_osxmtnlion_safari6: { | ||||
|       base: 'SauceLabs', | ||||
|       browserName: 'safari', | ||||
|       platform: 'OS X 10.8', | ||||
|       version: '6' | ||||
|   this._start = function(url) { | ||||
|     this._execCommand('/usr/bin/open', ['-W', '-n', '-a', 'Safari', url]); | ||||
|   } | ||||
|   };*/ | ||||
| } | ||||
|  | ||||
|   var customLaunchers = {}; | ||||
|   var browsers = []; | ||||
|   var useSauce = false; | ||||
| SafariBrowser.prototype = { | ||||
|   name: 'Safari' | ||||
| } | ||||
|  | ||||
|   if (process.env.SAUCE_USERNAME && process.env.SAUCE_ACCESS_KEY) { | ||||
|     useSauce = true; | ||||
| module.exports = (config) => { | ||||
|   let browsers = []; | ||||
|  | ||||
|   if (process.env.TEST_BROWSER_NAME) { | ||||
|     browsers = process.env.TEST_BROWSER_NAME.split(','); | ||||
|   } | ||||
|  | ||||
|   if (useSauce && process.env.TEST_BROWSER_NAME && process.env.TEST_BROWSER_NAME != 'PhantomJS') { | ||||
|     var names = process.env.TEST_BROWSER_NAME.split(','); | ||||
|     var platforms = process.env.TEST_BROWSER_OS.split(','); | ||||
|     var versions = []; | ||||
|     if (process.env.TEST_BROWSER_VERSION) { | ||||
|       versions = process.env.TEST_BROWSER_VERSION.split(','); | ||||
|     } else { | ||||
|       versions = [null]; | ||||
|     } | ||||
|  | ||||
|     for (var i = 0; i < names.length; i++) { | ||||
|       for (var j = 0; j < platforms.length; j++) { | ||||
|         for (var k = 0; k < versions.length; k++) { | ||||
|           var launcher_name = 'sl_' + platforms[j].replace(/[^a-zA-Z0-9]/g, '') + '_' + names[i]; | ||||
|           if (versions[k]) { | ||||
|             launcher_name += '_' + versions[k]; | ||||
|           } | ||||
|  | ||||
|           customLaunchers[launcher_name] = { | ||||
|             base: 'SauceLabs', | ||||
|             browserName: names[i], | ||||
|             platform: platforms[j], | ||||
|           }; | ||||
|  | ||||
|           if (versions[i]) { | ||||
|             customLaunchers[launcher_name].version = versions[k]; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     browsers = Object.keys(customLaunchers); | ||||
|   } else { | ||||
|     useSauce = false; | ||||
|     browsers = ['PhantomJS']; | ||||
|   } | ||||
|  | ||||
|   var my_conf = { | ||||
|   const my_conf = { | ||||
|  | ||||
|     // base path that will be used to resolve all patterns (eg. files, exclude) | ||||
|     basePath: '', | ||||
|  | ||||
|     // frameworks to use | ||||
|     // available frameworks: https://npmjs.org/browse/keyword/karma-adapter | ||||
|     frameworks: ['mocha', 'sinon', 'chai', 'sinon-chai'], | ||||
|  | ||||
|     frameworks: ['mocha', 'sinon-chai'], | ||||
|  | ||||
|     // list of files / patterns to load in the browser (loaded in order) | ||||
|     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/des.js', | ||||
|       'include/display.js', | ||||
|       'include/inflator.js', | ||||
|       'tests/test.*.js' | ||||
|       { pattern: 'app/localization.js', included: false, type: 'module' }, | ||||
|       { pattern: 'app/webutil.js', included: false, type: 'module' }, | ||||
|       { pattern: 'core/**/*.js', included: false, type: 'module' }, | ||||
|       { pattern: 'vendor/pako/**/*.js', included: false, type: 'module' }, | ||||
|       { pattern: 'tests/test.*.js', type: 'module' }, | ||||
|       { pattern: 'tests/fake.*.js', included: false, type: 'module' }, | ||||
|       { pattern: 'tests/assertions.js', type: 'module' }, | ||||
|     ], | ||||
|  | ||||
|     client: { | ||||
|       mocha: { | ||||
|         // replace Karma debug page with mocha display | ||||
|         'reporter': 'html', | ||||
|         'ui': 'bdd' | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     // list of files to exclude | ||||
|     exclude: [ | ||||
|       '../include/playback.js', | ||||
|       '../include/ui.js' | ||||
|     ], | ||||
|  | ||||
|     customLaunchers: customLaunchers, | ||||
|     plugins: [ | ||||
|       'karma-*', | ||||
|       '@chiragrupani/karma-chromium-edge-launcher', | ||||
|       { 'launcher:Safari': [ 'type', SafariBrowser ] }, | ||||
|     ], | ||||
|  | ||||
|     // start these browsers | ||||
|     // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher | ||||
|     browsers: browsers, | ||||
|  | ||||
|     // preprocess matching files before serving them to the browser | ||||
|     // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor | ||||
|     preprocessors: { | ||||
|  | ||||
|     }, | ||||
|  | ||||
|  | ||||
|     // test results reporter to use | ||||
|     // possible values: 'dots', 'progress' | ||||
|     // available reporters: https://npmjs.org/browse/keyword/karma-reporter | ||||
|     reporters: ['mocha', 'saucelabs'], | ||||
|  | ||||
|  | ||||
|     // web server port | ||||
|     port: 9876, | ||||
|  | ||||
|  | ||||
|     // enable / disable colors in the output (reporters and logs) | ||||
|     colors: true, | ||||
|     reporters: ['mocha'], | ||||
|  | ||||
|  | ||||
|     // level of logging | ||||
| @@ -175,23 +79,7 @@ module.exports = function(config) { | ||||
|     // Continuous Integration mode | ||||
|     // if true, Karma captures browsers, runs the tests and exits | ||||
|     singleRun: true, | ||||
|  | ||||
|     // Increase timeout in case connection is slow/we run more browsers than possible | ||||
|     // (we currently get 3 for free, and we try to run 7, so it can take a while) | ||||
|     captureTimeout: 240000, | ||||
|  | ||||
|     // similarly to above | ||||
|     browserNoActivityTimeout: 100000, | ||||
|   }; | ||||
|  | ||||
|   if (useSauce) { | ||||
|     my_conf.captureTimeout = 0; // use SL timeout | ||||
|     my_conf.sauceLabs = { | ||||
|       testName: 'noVNC Tests (all)', | ||||
|       startConnect: false, | ||||
|       tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   config.set(my_conf); | ||||
| }; | ||||
|   | ||||
| @@ -1,50 +1,82 @@ | ||||
| { | ||||
|   "name": "noVNC", | ||||
|   "version": "0.6.2", | ||||
|   "name": "@novnc/novnc", | ||||
|   "version": "1.3.0", | ||||
|   "description": "An HTML5 VNC client", | ||||
|   "main": "karma.conf.js", | ||||
|   "browser": "lib/rfb", | ||||
|   "directories": { | ||||
|     "lib": "lib", | ||||
|     "doc": "docs", | ||||
|     "test": "tests" | ||||
|   }, | ||||
|   "files": [ | ||||
|     "lib", | ||||
|     "AUTHORS", | ||||
|     "VERSION", | ||||
|     "docs/API.md", | ||||
|     "docs/LIBRARY.md", | ||||
|     "docs/LICENSE*", | ||||
|     "core", | ||||
|     "vendor/pako" | ||||
|   ], | ||||
|   "scripts": { | ||||
|     "test": "PATH=$PATH:node_modules/karma/bin karma start karma.conf.js" | ||||
|     "lint": "eslint app core po/po2js po/xgettext-html tests utils", | ||||
|     "test": "karma start karma.conf.js", | ||||
|     "prepublish": "node ./utils/use_require.js --clean" | ||||
|   }, | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "https://github.com/kanaka/noVNC.git" | ||||
|     "url": "git+https://github.com/novnc/noVNC.git" | ||||
|   }, | ||||
|   "author": "Joel Martin <github@martintribe.org> (https://github.com/kanaka)", | ||||
|   "contributors": [ | ||||
|     "Solly Ross <sross@redhat.com> (https://github.com/directxman12)", | ||||
|     "Peter Åstrand <astrand@cendio.se> (https://github.com/astrand)", | ||||
|     "Samuel Mannehed <samuel@cendio.se> (https://github.com/samhed)" | ||||
|     "Samuel Mannehed <samuel@cendio.se> (https://github.com/samhed)", | ||||
|     "Pierre Ossman <ossman@cendio.se> (https://github.com/CendioOssman)" | ||||
|   ], | ||||
|   "license": "MPL 2.0", | ||||
|   "license": "MPL-2.0", | ||||
|   "bugs": { | ||||
|     "url": "https://github.com/kanaka/noVNC/issues" | ||||
|     "url": "https://github.com/novnc/noVNC/issues" | ||||
|   }, | ||||
|   "homepage": "https://github.com/kanaka/noVNC", | ||||
|   "homepage": "https://github.com/novnc/noVNC", | ||||
|   "devDependencies": { | ||||
|     "ansi": "^0.3.0", | ||||
|     "casperjs": "^1.1.0-beta3", | ||||
|     "chai": "^2.1.0", | ||||
|     "commander": "^2.6.0", | ||||
|     "karma": "^0.12.31", | ||||
|     "karma-chai": "^0.1.0", | ||||
|     "karma-mocha": "^0.1.10", | ||||
|     "karma-mocha-reporter": "^1.0.0", | ||||
|     "karma-phantomjs-launcher": "^0.1.4", | ||||
|     "karma-sauce-launcher": "^0.2.10", | ||||
|     "karma-sinon": "^1.0.4", | ||||
|     "karma-sinon-chai-latest": "^0.1.0", | ||||
|     "mocha": "^2.1.0", | ||||
|     "open": "^0.0.5", | ||||
|     "phantom": "^0.7.2", | ||||
|     "phantomjs": "^1.9.15", | ||||
|     "sinon": "^1.12.2", | ||||
|     "sinon-chai": "^2.7.0", | ||||
|     "spooky": "^0.2.5", | ||||
|     "temp": "^0.8.1" | ||||
|   } | ||||
|     "@babel/core": "*", | ||||
|     "@babel/plugin-syntax-dynamic-import": "*", | ||||
|     "@babel/plugin-transform-modules-commonjs": "*", | ||||
|     "@babel/preset-env": "*", | ||||
|     "@babel/cli": "*", | ||||
|     "babel-plugin-import-redirect": "*", | ||||
|     "browserify": "*", | ||||
|     "babelify": "*", | ||||
|     "core-js": "*", | ||||
|     "chai": "*", | ||||
|     "commander": "*", | ||||
|     "es-module-loader": "*", | ||||
|     "eslint": "*", | ||||
|     "fs-extra": "*", | ||||
|     "jsdom": "*", | ||||
|     "karma": "*", | ||||
|     "karma-mocha": "*", | ||||
|     "karma-chrome-launcher": "*", | ||||
|     "@chiragrupani/karma-chromium-edge-launcher": "*", | ||||
|     "karma-firefox-launcher": "*", | ||||
|     "karma-ie-launcher": "*", | ||||
|     "karma-mocha-reporter": "*", | ||||
|     "karma-safari-launcher": "*", | ||||
|     "karma-script-launcher": "*", | ||||
|     "karma-sinon-chai": "*", | ||||
|     "mocha": "*", | ||||
|     "node-getopt": "*", | ||||
|     "po2json": "*", | ||||
|     "requirejs": "*", | ||||
|     "rollup": "*", | ||||
|     "rollup-plugin-node-resolve": "*", | ||||
|     "sinon": "*", | ||||
|     "sinon-chai": "*" | ||||
|   }, | ||||
|   "dependencies": {}, | ||||
|   "keywords": [ | ||||
|     "vnc", | ||||
|     "rfb", | ||||
|     "novnc", | ||||
|     "websockify" | ||||
|   ] | ||||
| } | ||||
|   | ||||
 Charlie Root
					Charlie Root