update novnc (#16)
* Use theme-color to color address bar in browsers This makes the address bar on mobile browsers match the background. Note that it requires a valid certificate and a non-dark mode set on the device. Not supported on desktop browsers. * Interrupt AltGr sequence detection on focus lost, fixes #1880 * Stop creating sinon sandbox early sinon might not be loaded at this point, which can cause tests to fail. We could create the sandbox in one of the hooks instead, but let's remove the sandbox completely to stay consistent with our other tests. * Manually load sinon and chai karma-sinon-chai is not compatible with Chai 5+, and Karma is no longer being updated. Load sinon and chai manually instead, until we can have a long term plan in place. * Add test for AltGr abort on blur * Let browser construct URL string for us Likely a lot safer for corner cases than us trying to figure this out ourselves. * Allow relative WebSocket URLs This can be very useful if you have multiple instances of noVNC, and you want to redirect them to different VNC servers. The new default settings will have the same behaviour as before for systems where noVNC is deployed in the root web folder. * Handle all settings via UI.getSetting() Makes sure everything behaves the same way, even if there is no visible UI for a settings. * Merge UI startup in to a single routine Makes it easier to see how things are connected. * Handle disabling settings without label * Add Zlib encoding * Add H.264 decoder This adds an H.264 decoder based on WebCodecs. * Fix host and port via query string We need to call initSetting() even if we don't have any interesting default to set, as that is what checks if values have been provided as a query string. Fixes96c76f7. * Add unit tests for H.264 decoder * Fix sQpushBytes sending the beginning of the array multiple times * Let fake WebSocket handle large sends Dynamically grow the recorded send buffer if the test needs to send a lot of data. * Fix tests for large WebSocket sends These failed to test that the data was correctly split as they only checked the first chunk transmitted. Use random values to avoid the risk of aligning our test data with the split boundaries and hence allowing false positives. * Make it easier for downstream to modify settings Expose a simple and stable API to override default settings, and force settings that users shouldn't be able to change. * Load settings from web server Make it even easier to customize things by loading the settings from separate configuration files. * Fix typos in Russian translation * Fix handling of VideoDecoder.isConfigSupported() It returns an object with details, not just a simple boolean. * Use common H.264 check in tests Avoid duplicating this logic in multiple places. * Raise JavaScript version requirement So that we can use await at module top level. * Do a real H.264 test decode to determine support Firefox is buggy and reports support for H.264 but then throws errors once we actually try to decode things. Detect this early by doing a quick test decode of a single frame. * Handle exceptions from VideoDecoder.flush() These are not supposed to happen according to the specification, but Firefox has some bug and throws them anyway. * Detect broken Firefox H.264 decoder The Firefox H.264 decoder on Windows might simply just refuse to deliver any finished frames. It also doesn't deliver any errors. Detect this early by expecting a frame after flush() has completed. * Update zh_CN.po * Consistently use "sentence case" style Try to be more consistent in how we capitalize things. Both the "Title Case" and "Sentence case" styles are popular, so either would work. Google and Mozilla both prefer "Sentence case", so let's follow them. * Also adjust to "sentence case" in translations This would have resolved itself automatically on the next translation update, but this commit will reduce unnecessary noise in that change. * Update Japanese translation * Replace node-getopt with commander for args node-getopt isn't maintained and nodejs has started complaining about deprecated features in it. * Replace po2json with pofile The former doesn't seem to be properly maintained and nodejs gives deprecation warnings. * Fix resizes back to initial remote session size Since the expected client size wasn't updated when the browser window resized, noVNC didn't resize the canvas properly when going back to the exact same dimensions. Fixes issue #1903 * Comment different resize functions in rfb.js * Standardize on 4 space-indentation in CSS files This is what we use in every other file in noVNC. It also much more common for a CSS file in general. By standardizing on 4 spaces we can avoid indentation mistakes. * Increase padding of buttons and inputs Gives them a more modern and spacious look. * Add margin between label and input in noVNC_panel To make stuff feel less cramped, lets add some margin here. As of comitting this, it only affects the logging-level select dropdown in the settings, but this is a general rule of thumb. It doesn't apply to checkboxes or radios since they have a margin by default, and their label to the left. * Create CSS variables for common noVNC-colors * Move mouse event help functions to broader scope These functions can be used elsewhere in the tests. We want to use these in the dragging tests in the future instead of directly calling private methods. * Add unit test for wheel + buttons pressed * Split button click with dragging test * Move mouse move flushing to separate function * Dispatch mouse events in dragging unit tests This makes our tests reflect the real world better, as we now send real mouse events instead of calling private methods directly. * Check for correct button events in dragging tests Previously, these unit tests did not check which events were sent to the server, only how many events were sent. This commit adds checks to see that the expected button events are sent. * Move gesture event help functions to broader scope This is needed if we want to test gestures with dragging. * Add tests for dragging with gestures There were no test for viewport dragging using gesture previously, so let's add some. Note that there currently are some viewport dragging behaviours that we don't want to have, so some tests have commented out what our desired behaviour should be. * Use MouseEvent.buttons for button state tracking Instead of keeping track of button states ourselves by looking at MouseEvent.button, we can use the MouseEvent.buttons which already contains the state of all buttons. * Don't send mouse events when dragging viewport We don't want to send any mouse events to the server when dragging the viewport. Instead, we treat them as a client-only operation. * Flush mouseMove when initiating viewport dragging We want to flush pending mouse moves before we initiate viewport dragging. Before this commit, there were scenarios where the _mouseButtonMask would track a released button as being down. * Move sendFbuMsg() to broader scope This is needed if we want to use this function elsewhere in our tests. * Add support for forward and back mouse buttons This commit implements the extendedMouseButtons pseudo-encoding, which makes it possible to use the forward and back mouse buttons. * Also test Ctrl+AltGr, as that is what browsers use Modern browsers now send the odd sequence of Ctrl+AltGr, rather than the raw Ctrl+Alt, or the fully adjusted just AltGr. Make sure we have a test for this scenario and don't break it. * Remove bold styling tags in vnc.html We aren't emphasizing important information with bold tags anywhere else, so we shouldn't do it here either. * Standardize on 6px or 12px border-radius This results in a few things becoming slighly more rounded, for example the controlbar, the settings panel and buttons/inputs. Increased rounding gives a more friendly feel. * Get rid of gradients on buttons and inputs Lets make things more flat and modern. * Differentiate buttons from text inputs By making buttons grey with bold text, they are easy to distinguish from text inputs. * Redesign select dropdown arrow Makes it more of a "V"-shape rather than a triangle, suits better in the new spacier select-buttons. * Redesign checkboxes and radiobuttons Makes them bigger and gets rid of their borders. The change also allowed for some shared styling between them. * Add indeterminate styling to checkboxes and radios This is used when the control is neither checked or unchecked. * Rework how buttons react to :hover and :active Instead of having two different types of effects (hover had a different color, and active had a 3d-effect simulating a pressed button), we now have an increasing activation-level. That means the button goes a bit dark for hover, and then even darker when pressed. There is also a variant that goes lighter for each activation level, that can be used when the initial color is dark. With this change, we can get rid of special :hover and :active styling for the connect button and the control bar buttons. We can use the same activation level principle for all buttons. * Make buttons flat by removing borders Gives a more clean look that fits well with the new checkboxes and radios. The old border was mostly used to contribute to a 3d-effect, that was used for :active. That :active-styling has been replaced by activation levels. * Fix :disabled styling of file-selector-button By applying the rule to the button within the input, we effectively applied the opacity twice - making the button almost disappear. Applying the opacity to the input element is enough. * Put specific :disabled rules with its element It makes more sense to group rules per element type. * Move general :disabled rules to common top section Start with general stuff, followed by specific things. * Support 'disabled' attribute on labels Note that the :disabled selector only works on inputs, buttons and the like. The current method of applying .noVNC_disabled to the settings labels is still used. This support is added mostly for completeness. Note that when a label wraps an input, only the label should have the disabled attribute. Otherwise the effect applies twice to the input. * Capitalize CSS section headings Makes them easier to distinguish from regular comments. * Keep CSS for different input elements together By moving the CSS for select buttons to the bottom, we keep a more logical ordering of the elements. * Avoid 2 borders when focus-visible on text inputs By having the focus-visible outline overlapping the regular border things look a bit more sane on text input elements. * Add some sane default CSS for textareas * Remove number picker's increase/decrease buttons We can't style them, and they don't fit the noVNC CSS style - we are better off without them. * Standardize on ellipsis-type text-overflow * Add minimum width to buttons This ensures they aren't too small, even if the text label is short. * Pointer cursor on buttons & grab on sliders This makes buttons and slider stand out more. * Add styling for color pickers Note that no color picker elements are currently in use, this is for completeness. * Make interface airier by increasing line-height Modern interfaces are less cramped, this makes noVNC feel more up to date. Note that this required some adjustments on noVNC_headings and noVNC_connect_button since the text now takes up more height than the images. * Add styling for toggle switches These are a type of checkbox that is suitable for ON/OFF-type switches. * Utilize toggle switch in settings These settings are well suited to use toggle switches. This makes these settings more approachable and user-friendly. * Add styling for checked options in select boxes * Add styling for multi-select lists This is a type of select box that doesn't appear like a button, but more like a textarea that lists options. It is not currently used, but added for completeness. * Make range slider thumbs circular Fits better with the new slightly rounded and spacious style. The track was made slightly thicker to ensure proper centering of the new thumb. * Only color the left part of the range track Makes it easier to envision the value is selected. * Make text in panel headings bold Makes the heading pop a bit more in the new airier layout. * Fix spacing between elements in dialogs Dialogs have had text inputs and buttons cramped together without space between, this fixes that. * Tweak design of noVNC connect button Make the color contrast with the background and the button more rounded. The goal is to make the button stand out. * Fix settings panel layout on small screens Both labels and inputs protruded outside the panel on for example a phone in portrait mode. This commit fixes that by allowing wrapping and setting a max-width. Since the --input-xpadding variable is now used in two different CSS files, it was moved to constants.css. * Add exceptions for CSS validator false positives Some new CSS incorrectly give errors from validator.w3.org. Issues were opened in that repo, so hopefully we can remove these exceptions soon. I searched for alternative validators, but couldn't find a different one that had a simple API like this one. In order to reliably detect & handle these exceptions we unfortunately need to make the validator output parsing quite a bit more complicated. * Make the background of expanded settings lighter A very slight change to the background color, to make the contrast better with the light-grey input elements. * Update README.md with ExtendedMouseButtons feature * Use less technical phrasing in README * Add helper for ExtendedDesktopSize in tests * Make resizeSession setting test more realistic We shouldn't expect a resize request to be sent if the container didn't change size first. * Include SetDesktopSize responses in tests There might be subtle changes in behaviour, so we should mimic what a real server does. * Better resize rate limiting Be more aggressive with resizing, limiting it to once ever 100 ms instead of after a 500 ms idle period. This gives a more responsive user experience. * chore: fix some typos Signed-off-by: tianzedavid <cuitianze@aliyun.com> * Update translation template file * Update Swedish translations * Update README.md with H.264 encoding support * noVNC 1.6.0 beta * Upgrade to websockify 0.13.0 in snap package * Let browser handle parsing of URLs before relaying We don't want to assign a path directly to url.pathname that contains a search query, since this causes '?' at the beginning of the query to be URL-encoded to '%3F'. Instead use URL() to parse the path for us. * Update French translation * Update Dutch translation * Update generated json files for new translations * noVNC 1.6.0 * Fix appearance of extra key buttons Since the extra keys panel is quite narrow in width, a max-width style resulted in the buttons almost disappearing. That rule was only intended for elements inside the settings panel. Broken by commit14f9ea5880. Another minor error that is also fixed by this commit is that the clipboard textarea no longer incorrectly gets a left margin of 6px. Fixes #1946. * Update comment reference missed in previous commit Should have been part off0a39cd357* Only include valid translations in .json files Fuzzy translations might be incorrect, and obsolete translations aren't used anywhere. * Close VideoFrame after H.264 detection Otherwise browser will complain when it is garbage collected. * Fix typo in error-handler.js * Fix typo in Portuguese translation for "Show extra keys" * Document new behaviour of host/port/encrypt/path This changed in96c76f7, but we forgot to adjust the documentation for the parameters. * Document new JSON settings files This mechanism was added in438e5b3, but we forgot to document it. * Disable setting showDotCursor in RFB constructor This has been deprecated for around six years now. Let's remove the deprecation warning and disable setting showDotCursor via the options parameter. * initial * fixed js imports * fixed html import paths * override defaults and add host and port * fixed locales path * link fixes * replace config paths with cdn --------- Signed-off-by: tianzedavid <cuitianze@aliyun.com> Co-authored-by: Samuel Mannehed <samuel@cendio.se> Co-authored-by: leedagee <61650578+leedagee@users.noreply.github.com> Co-authored-by: Pierre Ossman <ossman@cendio.se> Co-authored-by: Mark Peek <mark@peek.org> Co-authored-by: Andri Yngvason <andri@yngvason.is> Co-authored-by: Tomasz Kalisiak <tomasz.kalisiak3@gmail.com> Co-authored-by: dim5x <dim5x@yahoo.com> Co-authored-by: wxtewx <181315147@qq.com> Co-authored-by: NNN1590 <nnn1590@nnn1590.org> Co-authored-by: Adam Halim <adaha@cendio.se> Co-authored-by: Alexander Zeijlon <aleze@cendio.se> Co-authored-by: tianzedavid <cuitianze@aliyun.com> Co-authored-by: Zeijlon (ThinLinc Team) <122010116+ThinLinc-Zeijlon@users.noreply.github.com> Co-authored-by: Martine & Philippe <martineke.breizh@gmail.com> Co-authored-by: Harold Horsman <haroldhorsman@gmail.com> Co-authored-by: Liao Peiyuan <peiyuan@generalagents.com> Co-authored-by: leandro ostruka <leandro.sakae@hotmail.com>
This commit is contained in:
parent
f0d4315338
commit
719e1df166
|
|
@ -7,7 +7,7 @@ about: Create a report to help us improve
|
|||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
**To reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
noVNC is Copyright (C) 2022 The noVNC Authors
|
||||
noVNC is Copyright (C) 2022 The noVNC authors
|
||||
(./AUTHORS)
|
||||
|
||||
The noVNC core library files are licensed under the MPL 2.0 (Mozilla
|
||||
|
|
|
|||
51
README.md
51
README.md
|
|
@ -1,4 +1,4 @@
|
|||
## noVNC: HTML VNC Client Library and Application
|
||||
## noVNC: HTML VNC client library and application
|
||||
|
||||
[](https://github.com/novnc/noVNC/actions?query=workflow%3ATest)
|
||||
[](https://github.com/novnc/noVNC/actions?query=workflow%3ALint)
|
||||
|
|
@ -14,19 +14,19 @@ Many companies, projects and products have integrated noVNC including
|
|||
[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)
|
||||
[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
|
||||
### 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)
|
||||
- [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
|
||||
|
|
@ -66,8 +66,9 @@ profits such as:
|
|||
RSA-AES, Tight, VeNCrypt Plain, XVP, Apple's Diffie-Hellman,
|
||||
UltraVNC's MSLogonII
|
||||
* Supported VNC encodings: raw, copyrect, rre, hextile, tight, tightPNG,
|
||||
ZRLE, JPEG
|
||||
ZRLE, JPEG, Zlib, H.264
|
||||
* Supports scaling, clipping and resizing the desktop
|
||||
* Supports back & forward mouse buttons
|
||||
* Local cursor rendering
|
||||
* Clipboard copy/paste with full Unicode support
|
||||
* Translations
|
||||
|
|
@ -86,16 +87,16 @@ See more screenshots
|
|||
[here](http://novnc.com/screenshots.html).
|
||||
|
||||
|
||||
### Browser Requirements
|
||||
### Browser requirements
|
||||
|
||||
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:
|
||||
|
||||
* Chrome 64, Firefox 79, Safari 13.4, Opera 51, Edge 79
|
||||
* Chrome 89, Firefox 89, Safari 15, Opera 75, Edge 89
|
||||
|
||||
|
||||
### Server Requirements
|
||||
### Server requirements
|
||||
|
||||
noVNC follows the standard VNC protocol, but unlike other VNC clients it does
|
||||
require WebSockets support. Many servers include support (e.g.
|
||||
|
|
@ -107,7 +108,7 @@ use a WebSockets to TCP socket proxy. noVNC has a sister project
|
|||
proxy.
|
||||
|
||||
|
||||
### Quick Start
|
||||
### Quick start
|
||||
|
||||
* Use the `novnc_proxy` script to automatically download and start websockify, which
|
||||
includes a mini-webserver and the WebSockets proxy. The `--vnc` option is
|
||||
|
|
@ -124,25 +125,25 @@ proxy.
|
|||
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:
|
||||
### Installation from snap package
|
||||
Running the command below will install the latest release of noVNC from snap:
|
||||
|
||||
`sudo snap install novnc`
|
||||
|
||||
#### Running noVNC from Snap Directly
|
||||
#### Running noVNC from snap directly
|
||||
|
||||
You can run the Snap-package installed novnc directly with, for example:
|
||||
You can run the snap package installed novnc directly with, for example:
|
||||
|
||||
`novnc --listen 6081 --vnc localhost:5901 # /snap/bin/novnc if /snap/bin is not in your PATH`
|
||||
|
||||
If you want to use certificate files, due to standard Snap confinement restrictions you need to have them in the /home/\<user\>/snap/novnc/current/ directory. If your username is jsmith an example command would be:
|
||||
If you want to use certificate files, due to standard snap confinement restrictions you need to have them in the /home/\<user\>/snap/novnc/current/ directory. If your username is jsmith an example command would be:
|
||||
|
||||
`novnc --listen 8443 --cert ~jsmith/snap/novnc/current/self.crt --key ~jsmith/snap/novnc/current/self.key --vnc ubuntu.example.com:5901`
|
||||
|
||||
#### Running noVNC from Snap as a Service (Daemon)
|
||||
The Snap package also has the capability to run a 'novnc' service which can be
|
||||
#### Running noVNC from snap 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).
|
||||
(effectively a service running multiple instances of novnc).
|
||||
Instructions (with example values):
|
||||
|
||||
List current services (out-of-box this will be blank):
|
||||
|
|
@ -172,7 +173,7 @@ services.n6082.listen 6082
|
|||
services.n6082.vnc localhost:5902
|
||||
```
|
||||
|
||||
Disable a service (note that because of a limitation in Snap it's currently not
|
||||
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):
|
||||
|
||||
|
|
@ -189,7 +190,7 @@ services.n6082.listen
|
|||
services.n6082.vnc
|
||||
```
|
||||
|
||||
### Integration and Deployment
|
||||
### 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:
|
||||
|
|
@ -212,8 +213,8 @@ that list and you think you should be, feel free to send a PR to fix that.
|
|||
* [Solly Ross](https://github.com/DirectXMan12) (Red Hat / OpenStack)
|
||||
|
||||
* Notable contributions:
|
||||
* UI and Icons : Pierre Ossman, Chris Gordon
|
||||
* Original Logo : Michael Sersen
|
||||
* UI and icons : Pierre Ossman, Chris Gordon
|
||||
* Original logo : Michael Sersen
|
||||
* tight encoding : Michael Tinglof (Mercuri.ca)
|
||||
* RealVNC RSA AES authentication : USTC Vlab Team
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
export const overrideDefaults = (defaults) => {
|
||||
if (!defaults['host']) {
|
||||
defaults['host'] = window.location.hostname;
|
||||
}
|
||||
if (!defaults['port']) {
|
||||
let port = window.location.port;
|
||||
if (!port) {
|
||||
if (window.location.protocol.substring(0, 5) == 'https') {
|
||||
port = 443;
|
||||
} else if (window.location.protocol.substring(0, 4) == 'http') {
|
||||
port = 80;
|
||||
}
|
||||
}
|
||||
defaults['port'] = port;
|
||||
}
|
||||
};
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
// Fallback for all uncought errors
|
||||
// Fallback for all uncaught errors
|
||||
function handleError(event, err) {
|
||||
try {
|
||||
const msg = document.getElementById('noVNC_fallback_errormsg');
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
"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",
|
||||
"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é",
|
||||
|
|
@ -22,9 +22,9 @@
|
|||
"Middle mousebutton": "Prostřední tlačítko myši",
|
||||
"Right mousebutton": "Pravé tlačítko myši",
|
||||
"Keyboard": "Klávesnice",
|
||||
"Show Keyboard": "Zobrazit klávesnici",
|
||||
"Show keyboard": "Zobrazit klávesnici",
|
||||
"Extra keys": "Extra klávesy",
|
||||
"Show Extra Keys": "Zobrazit extra klávesy",
|
||||
"Show extra keys": "Zobrazit extra klávesy",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Přepnout Ctrl",
|
||||
"Alt": "Alt",
|
||||
|
|
@ -45,13 +45,13 @@
|
|||
"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",
|
||||
"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é",
|
||||
"Local scaling": "Místní",
|
||||
"Remote resizing": "Vzdálené",
|
||||
"Advanced": "Pokročilé",
|
||||
"Repeater ID:": "ID opakovače",
|
||||
"WebSocket": "WebSocket",
|
||||
|
|
@ -59,9 +59,9 @@
|
|||
"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",
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
"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",
|
||||
"Move/Drag viewport": "Ansichtsfenster verschieben/ziehen",
|
||||
"viewport drag": "Ansichtsfenster ziehen",
|
||||
"Active Mouse Button": "Aktive Maustaste",
|
||||
"No mousebutton": "Keine Maustaste",
|
||||
|
|
@ -21,9 +21,9 @@
|
|||
"Middle mousebutton": "Mittlere Maustaste",
|
||||
"Right mousebutton": "Rechte Maustaste",
|
||||
"Keyboard": "Tastatur",
|
||||
"Show Keyboard": "Tastatur anzeigen",
|
||||
"Show keyboard": "Tastatur anzeigen",
|
||||
"Extra keys": "Zusatztasten",
|
||||
"Show Extra Keys": "Zusatztasten anzeigen",
|
||||
"Show extra keys": "Zusatztasten anzeigen",
|
||||
"Ctrl": "Strg",
|
||||
"Toggle Ctrl": "Strg umschalten",
|
||||
"Alt": "Alt",
|
||||
|
|
@ -44,13 +44,13 @@
|
|||
"Clear": "Löschen",
|
||||
"Fullscreen": "Vollbild",
|
||||
"Settings": "Einstellungen",
|
||||
"Shared Mode": "Geteilter Modus",
|
||||
"View Only": "Nur betrachten",
|
||||
"Clip to Window": "Auf Fenster begrenzen",
|
||||
"Scaling Mode:": "Skalierungsmodus:",
|
||||
"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",
|
||||
"Local scaling": "Lokales skalieren",
|
||||
"Remote resizing": "Serverseitiges skalieren",
|
||||
"Advanced": "Erweitert",
|
||||
"Repeater ID:": "Repeater ID:",
|
||||
"WebSocket": "WebSocket",
|
||||
|
|
@ -58,12 +58,17 @@
|
|||
"Host:": "Server:",
|
||||
"Port:": "Port:",
|
||||
"Path:": "Pfad:",
|
||||
"Automatic Reconnect": "Automatisch wiederverbinden",
|
||||
"Reconnect Delay (ms):": "Wiederverbindungsverzögerung (ms):",
|
||||
"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."
|
||||
"Canvas not supported.": "Canvas nicht unterstützt.",
|
||||
"Disconnect timeout": "Zeitüberschreitung beim Trennen",
|
||||
"Local Downscaling": "Lokales herunterskalieren",
|
||||
"Local Cursor": "Lokaler Mauszeiger",
|
||||
"Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "'Clipping-Modus' aktiviert, Scrollbalken in 'IE-Vollbildmodus' werden nicht unterstützt",
|
||||
"True Color": "True Color"
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
"Reset": "Επαναφορά",
|
||||
"Clipboard": "Πρόχειρο",
|
||||
"Edit clipboard content in the textarea below.": "Επεξεργαστείτε το περιεχόμενο του πρόχειρου στην περιοχή κειμένου παρακάτω.",
|
||||
"Full Screen": "Πλήρης Οθόνη",
|
||||
"Settings": "Ρυθμίσεις",
|
||||
"Shared Mode": "Κοινόχρηστη Λειτουργία",
|
||||
"View Only": "Μόνο Θέαση",
|
||||
|
|
@ -75,5 +76,25 @@
|
|||
"Username:": "Κωδικός Χρήστη:",
|
||||
"Password:": "Κωδικός Πρόσβασης:",
|
||||
"Send Credentials": "Αποστολή Διαπιστευτηρίων",
|
||||
"Cancel": "Ακύρωση"
|
||||
"Cancel": "Ακύρωση",
|
||||
"Password is required": "Απαιτείται ο κωδικός πρόσβασης",
|
||||
"viewport drag": "σύρσιμο θεατού πεδίου",
|
||||
"Active Mouse Button": "Ενεργό Πλήκτρο Ποντικιού",
|
||||
"No mousebutton": "Χωρίς Πλήκτρο Ποντικιού",
|
||||
"Left mousebutton": "Αριστερό Πλήκτρο Ποντικιού",
|
||||
"Middle mousebutton": "Μεσαίο Πλήκτρο Ποντικιού",
|
||||
"Right mousebutton": "Δεξί Πλήκτρο Ποντικιού",
|
||||
"Clear": "Καθάρισμα",
|
||||
"Canvas not supported.": "Δεν υποστηρίζεται το στοιχείο Canvas",
|
||||
"Disconnect timeout": "Παρέλευση χρονικού ορίου αποσύνδεσης",
|
||||
"Local Downscaling": "Τοπική Συρρίκνωση",
|
||||
"Local Cursor": "Τοπικός Δρομέας",
|
||||
"Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "Εφαρμογή λειτουργίας αποκοπής αφού δεν υποστηρίζονται οι λωρίδες κύλισης σε πλήρη οθόνη στον IE",
|
||||
"True Color": "Πραγματικά Χρώματα",
|
||||
"Style:": "Στυλ:",
|
||||
"default": "προεπιλεγμένο",
|
||||
"Apply": "Εφαρμογή",
|
||||
"Connection": "Σύνδεση",
|
||||
"Token:": "Διακριτικό:",
|
||||
"Send Password": "Αποστολή Κωδικού Πρόσβασης"
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
"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",
|
||||
"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",
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
"Middle mousebutton": "Botón central del ratón",
|
||||
"Right mousebutton": "Botón derecho del ratón",
|
||||
"Keyboard": "Teclado",
|
||||
"Show Keyboard": "Mostrar teclado",
|
||||
"Show keyboard": "Mostrar teclado",
|
||||
"Extra keys": "Teclas adicionales",
|
||||
"Show Extra Keys": "Mostrar Teclas Adicionales",
|
||||
"Ctrl": "Ctrl",
|
||||
|
|
@ -43,13 +43,13 @@
|
|||
"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:",
|
||||
"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",
|
||||
"Remote resizing": "Cambio de tamaño remoto",
|
||||
"Advanced": "Avanzado",
|
||||
"Local Cursor": "Cursor Local",
|
||||
"Repeater ID:": "ID del Repetidor:",
|
||||
|
|
@ -57,8 +57,8 @@
|
|||
"Host:": "Host:",
|
||||
"Port:": "Puerto:",
|
||||
"Path:": "Ruta:",
|
||||
"Automatic Reconnect": "Reconexión automática",
|
||||
"Reconnect Delay (ms):": "Retraso en la reconexión (ms):",
|
||||
"Automatic reconnect": "Reconexión automática",
|
||||
"Reconnect delay (ms):": "Retraso en la reconexión (ms):",
|
||||
"Logging:": "Registrando:",
|
||||
"Disconnect": "Desconectar",
|
||||
"Connect": "Conectar",
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
"Running without HTTPS is not recommended, crashes or other issues are likely.": "Lancer sans HTTPS n'est pas recommandé, crashs ou autres problèmes en vue.",
|
||||
"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",
|
||||
"Failed to connect to server: ": "Échec de connexion au serveur ",
|
||||
"Connected (encrypted) to ": "Connecté (chiffré) à ",
|
||||
"Connected (unencrypted) to ": "Connecté (non chiffré) à ",
|
||||
"Something went wrong, connection is closed": "Quelque chose s'est mal passé, la connexion a été fermée",
|
||||
|
|
@ -15,19 +16,19 @@
|
|||
"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 le Viewport",
|
||||
"Move/Drag viewport": "Déplacer la fenêtre de visualisation",
|
||||
"Keyboard": "Clavier",
|
||||
"Show Keyboard": "Afficher le clavier",
|
||||
"Show keyboard": "Afficher le clavier",
|
||||
"Extra keys": "Touches supplémentaires",
|
||||
"Show Extra Keys": "Afficher les 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",
|
||||
"Windows": "Fenêtre",
|
||||
"Send Tab": "Envoyer Tab",
|
||||
"Tab": "Tabulation",
|
||||
"Esc": "Esc",
|
||||
"Send Escape": "Envoyer Escape",
|
||||
"Ctrl+Alt+Del": "Ctrl+Alt+Del",
|
||||
|
|
@ -39,16 +40,16 @@
|
|||
"Reboot": "Redémarrer",
|
||||
"Reset": "Réinitialiser",
|
||||
"Clipboard": "Presse-papiers",
|
||||
"Clear": "Effacer",
|
||||
"Fullscreen": "Plein écran",
|
||||
"Edit clipboard content in the textarea below.": "Editer le contenu du presse-papier dans la zone ci-dessous.",
|
||||
"Full screen": "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 :",
|
||||
"Shared mode": "Mode partagé",
|
||||
"View only": "Afficher uniquement",
|
||||
"Clip to window": "Ajuster à la fenêtre",
|
||||
"Scaling mode:": "Mode mise à l'échelle :",
|
||||
"None": "Aucun",
|
||||
"Local Scaling": "Mise à l'échelle locale",
|
||||
"Remote Resizing": "Redimensionnement à distance",
|
||||
"Local scaling": "Mise à l'échelle locale",
|
||||
"Remote resizing": "Redimensionnement à distance",
|
||||
"Advanced": "Avancé",
|
||||
"Quality:": "Qualité :",
|
||||
"Compression level:": "Niveau de compression :",
|
||||
|
|
@ -58,15 +59,24 @@
|
|||
"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",
|
||||
"Automatic reconnect": "Reconnecter automatiquement",
|
||||
"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",
|
||||
"Server identity": "Identité du serveur",
|
||||
"The server has provided the following identifying information:": "Le serveur a fourni l'identification suivante :",
|
||||
"Fingerprint:": "Empreinte digitale :",
|
||||
"Please verify that the information is correct and press \"Approve\". Otherwise press \"Reject\".": "SVP, verifiez que l'information est correcte et pressez \"Accepter\". Sinon pressez \"Refuser\".",
|
||||
"Approve": "Accepter",
|
||||
"Reject": "Refuser",
|
||||
"Credentials": "Envoyer les identifiants",
|
||||
"Username:": "Nom d'utilisateur :",
|
||||
"Password:": "Mot de passe :",
|
||||
"Send Credentials": "Envoyer les identifiants",
|
||||
"Cancel": "Annuler"
|
||||
"Send credentials": "Envoyer les identifiants",
|
||||
"Cancel": "Annuler",
|
||||
"Must set host": "Doit définir l'hôte",
|
||||
"Clear": "Effacer"
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
"noVNC encountered an error:": "noVNC ha riscontrato un errore:",
|
||||
"Hide/Show the control bar": "Nascondi/Mostra la barra di controllo",
|
||||
"Keyboard": "Tastiera",
|
||||
"Show Keyboard": "Mostra tastiera",
|
||||
"Show keyboard": "Mostra tastiera",
|
||||
"Extra keys": "Tasti Aggiuntivi",
|
||||
"Show Extra Keys": "Mostra Tasti Aggiuntivi",
|
||||
"Ctrl": "Ctrl",
|
||||
|
|
@ -40,9 +40,9 @@
|
|||
"Clear": "Pulisci",
|
||||
"Fullscreen": "Schermo intero",
|
||||
"Settings": "Impostazioni",
|
||||
"Shared Mode": "Modalità condivisa",
|
||||
"Shared mode": "Modalità condivisa",
|
||||
"View Only": "Sola Visualizzazione",
|
||||
"Scaling Mode:": "Modalità di ridimensionamento:",
|
||||
"Scaling mode:": "Modalità di ridimensionamento:",
|
||||
"None": "Nessuna",
|
||||
"Local Scaling": "Ridimensionamento Locale",
|
||||
"Remote Resizing": "Ridimensionamento Remoto",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
{
|
||||
"HTTPS is required for full functionality": "すべての機能を使用するにはHTTPS接続が必要です",
|
||||
"Running without HTTPS is not recommended, crashes or other issues are likely.": "HTTPS接続なしで実行することは推奨されません。クラッシュしたりその他の問題が発生したりする可能性があります。",
|
||||
"Connecting...": "接続しています...",
|
||||
"Disconnecting...": "切断しています...",
|
||||
"Reconnecting...": "再接続しています...",
|
||||
"Internal error": "内部エラー",
|
||||
"Must set host": "ホストを設定する必要があります",
|
||||
"Failed to connect to server: ": "サーバーへの接続に失敗しました: ",
|
||||
"Connected (encrypted) to ": "接続しました (暗号化済み): ",
|
||||
"Connected (unencrypted) to ": "接続しました (暗号化されていません): ",
|
||||
"Something went wrong, connection is closed": "何らかの問題で、接続が閉じられました",
|
||||
"Something went wrong, connection is closed": "問題が発生したため、接続が閉じられました",
|
||||
"Failed to connect to server": "サーバーへの接続に失敗しました",
|
||||
"Disconnected": "切断しました",
|
||||
"New connection has been rejected with reason: ": "新規接続は次の理由で拒否されました: ",
|
||||
|
|
@ -16,11 +17,11 @@
|
|||
"noVNC encountered an error:": "noVNC でエラーが発生しました:",
|
||||
"Hide/Show the control bar": "コントロールバーを隠す/表示する",
|
||||
"Drag": "ドラッグ",
|
||||
"Move/Drag Viewport": "ビューポートを移動/ドラッグ",
|
||||
"Move/Drag viewport": "ビューポートを移動/ドラッグ",
|
||||
"Keyboard": "キーボード",
|
||||
"Show Keyboard": "キーボードを表示",
|
||||
"Show keyboard": "キーボードを表示",
|
||||
"Extra keys": "追加キー",
|
||||
"Show Extra Keys": "追加キーを表示",
|
||||
"Show extra keys": "追加キーを表示",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Ctrl キーをトグル",
|
||||
"Alt": "Alt",
|
||||
|
|
@ -41,15 +42,15 @@
|
|||
"Reset": "リセット",
|
||||
"Clipboard": "クリップボード",
|
||||
"Edit clipboard content in the textarea below.": "以下の入力欄からクリップボードの内容を編集できます。",
|
||||
"Full Screen": "全画面表示",
|
||||
"Full screen": "全画面表示",
|
||||
"Settings": "設定",
|
||||
"Shared Mode": "共有モード",
|
||||
"View Only": "表示専用",
|
||||
"Clip to Window": "ウィンドウにクリップ",
|
||||
"Scaling Mode:": "スケーリングモード:",
|
||||
"Shared mode": "共有モード",
|
||||
"View only": "表示専用",
|
||||
"Clip to window": "ウィンドウにクリップ",
|
||||
"Scaling mode:": "スケーリングモード:",
|
||||
"None": "なし",
|
||||
"Local Scaling": "ローカルスケーリング",
|
||||
"Remote Resizing": "リモートでリサイズ",
|
||||
"Local scaling": "ローカルでスケーリング",
|
||||
"Remote resizing": "リモートでリサイズ",
|
||||
"Advanced": "高度",
|
||||
"Quality:": "品質:",
|
||||
"Compression level:": "圧縮レベル:",
|
||||
|
|
@ -59,9 +60,9 @@
|
|||
"Host:": "ホスト:",
|
||||
"Port:": "ポート:",
|
||||
"Path:": "パス:",
|
||||
"Automatic Reconnect": "自動再接続",
|
||||
"Reconnect Delay (ms):": "再接続する遅延 (ミリ秒):",
|
||||
"Show Dot when No Cursor": "カーソルがないときにドットを表示する",
|
||||
"Automatic reconnect": "自動再接続",
|
||||
"Reconnect delay (ms):": "再接続する遅延 (ミリ秒):",
|
||||
"Show dot when no cursor": "カーソルがないときにドットを表示する",
|
||||
"Logging:": "ロギング:",
|
||||
"Version:": "バージョン:",
|
||||
"Disconnect": "切断",
|
||||
|
|
@ -75,6 +76,6 @@
|
|||
"Credentials": "資格情報",
|
||||
"Username:": "ユーザー名:",
|
||||
"Password:": "パスワード:",
|
||||
"Send Credentials": "資格情報を送信",
|
||||
"Send credentials": "資格情報を送信",
|
||||
"Cancel": "キャンセル"
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
"Password is required": "비밀번호가 필요합니다.",
|
||||
"noVNC encountered an error:": "noVNC에 오류가 발생했습니다:",
|
||||
"Hide/Show the control bar": "컨트롤 바 숨기기/보이기",
|
||||
"Move/Drag Viewport": "움직이기/드래그 뷰포트",
|
||||
"Move/Drag viewport": "움직이기/드래그 뷰포트",
|
||||
"viewport drag": "뷰포트 드래그",
|
||||
"Active Mouse Button": "마우스 버튼 활성화",
|
||||
"No mousebutton": "마우스 버튼 없음",
|
||||
|
|
@ -22,9 +22,9 @@
|
|||
"Middle mousebutton": "중간 마우스 버튼",
|
||||
"Right mousebutton": "오른쪽 마우스 버튼",
|
||||
"Keyboard": "키보드",
|
||||
"Show Keyboard": "키보드 보이기",
|
||||
"Show keyboard": "키보드 보이기",
|
||||
"Extra keys": "기타 키들",
|
||||
"Show Extra Keys": "기타 키들 보이기",
|
||||
"Show extra keys": "기타 키들 보이기",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Ctrl 켜기/끄기",
|
||||
"Alt": "Alt",
|
||||
|
|
@ -45,13 +45,13 @@
|
|||
"Clear": "지우기",
|
||||
"Fullscreen": "전체화면",
|
||||
"Settings": "설정",
|
||||
"Shared Mode": "공유 모드",
|
||||
"View Only": "보기 전용",
|
||||
"Clip to Window": "창에 클립",
|
||||
"Scaling Mode:": "스케일링 모드:",
|
||||
"Shared mode": "공유 모드",
|
||||
"View only": "보기 전용",
|
||||
"Clip to window": "창에 클립",
|
||||
"Scaling mode:": "스케일링 모드:",
|
||||
"None": "없음",
|
||||
"Local Scaling": "로컬 스케일링",
|
||||
"Remote Resizing": "원격 크기 조절",
|
||||
"Local scaling": "로컬 스케일링",
|
||||
"Remote resizing": "원격 크기 조절",
|
||||
"Advanced": "고급",
|
||||
"Repeater ID:": "중계 ID",
|
||||
"WebSocket": "웹소켓",
|
||||
|
|
@ -59,8 +59,8 @@
|
|||
"Host:": "호스트:",
|
||||
"Port:": "포트:",
|
||||
"Path:": "위치:",
|
||||
"Automatic Reconnect": "자동 재연결",
|
||||
"Reconnect Delay (ms):": "재연결 지연 시간 (ms)",
|
||||
"Automatic reconnect": "자동 재연결",
|
||||
"Reconnect delay (ms):": "재연결 지연 시간 (ms)",
|
||||
"Logging:": "로깅",
|
||||
"Disconnect": "연결 해제",
|
||||
"Connect": "연결",
|
||||
|
|
|
|||
|
|
@ -1,36 +1,32 @@
|
|||
{
|
||||
"Connecting...": "Verbinden...",
|
||||
"Disconnecting...": "Verbinding verbreken...",
|
||||
"Running without HTTPS is not recommended, crashes or other issues are likely.": "Het is niet aan te raden om zonder HTTPS te werken, crashes of andere problemen zijn dan waarschijnlijk.",
|
||||
"Connecting...": "Aan het verbinden…",
|
||||
"Disconnecting...": "Bezig om verbinding te verbreken...",
|
||||
"Reconnecting...": "Opnieuw verbinding maken...",
|
||||
"Internal error": "Interne fout",
|
||||
"Must set host": "Host moeten worden ingesteld",
|
||||
"Failed to connect to server: ": "Verbinding maken met server is mislukt",
|
||||
"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 with reason: ": "Nieuwe verbinding is geweigerd met de volgende reden: ",
|
||||
"New connection has been rejected": "Nieuwe verbinding is geweigerd",
|
||||
"Password is required": "Wachtwoord is vereist",
|
||||
"Credentials are required": "Inloggegevens zijn nodig",
|
||||
"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",
|
||||
"Drag": "Sleep",
|
||||
"Move/Drag viewport": "Verplaats/Versleep Kijkvenster",
|
||||
"Keyboard": "Toetsenbord",
|
||||
"Show Keyboard": "Toon Toetsenbord",
|
||||
"Show keyboard": "Toon Toetsenbord",
|
||||
"Extra keys": "Extra toetsen",
|
||||
"Show Extra Keys": "Toon 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",
|
||||
"Toggle Windows": "Vensters omschakelen",
|
||||
"Windows": "Vensters",
|
||||
"Send Tab": "Tab Sturen",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
|
|
@ -44,30 +40,56 @@
|
|||
"Reboot": "Herstarten",
|
||||
"Reset": "Resetten",
|
||||
"Clipboard": "Klembord",
|
||||
"Clear": "Wissen",
|
||||
"Fullscreen": "Volledig Scherm",
|
||||
"Edit clipboard content in the textarea below.": "Edit de inhoud van het klembord in het tekstveld hieronder",
|
||||
"Full screen": "Volledig Scherm",
|
||||
"Settings": "Instellingen",
|
||||
"Shared Mode": "Gedeelde Modus",
|
||||
"View Only": "Alleen Kijken",
|
||||
"Clip to Window": "Randen buiten venster afsnijden",
|
||||
"Scaling Mode:": "Schaalmodus:",
|
||||
"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",
|
||||
"Local scaling": "Lokaal Schalen",
|
||||
"Remote resizing": "Op Afstand Formaat Wijzigen",
|
||||
"Advanced": "Geavanceerd",
|
||||
"Quality:": "Kwaliteit:",
|
||||
"Compression level:": "Compressieniveau:",
|
||||
"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",
|
||||
"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:",
|
||||
"Version:": "Versie:",
|
||||
"Disconnect": "Verbinding verbreken",
|
||||
"Connect": "Verbinden",
|
||||
"Server identity": "Serveridentiteit",
|
||||
"The server has provided the following identifying information:": "De server geeft de volgende identificerende informatie:",
|
||||
"Fingerprint:": "Vingerafdruk:",
|
||||
"Please verify that the information is correct and press \"Approve\". Otherwise press \"Reject\".": "Verifieer dat de informatie is correct en druk “OK”. Druk anders op “Afwijzen”.",
|
||||
"Approve": "OK",
|
||||
"Reject": "Afwijzen",
|
||||
"Credentials": "Inloggegevens",
|
||||
"Username:": "Gebruikersnaam:",
|
||||
"Password:": "Wachtwoord:",
|
||||
"Send credentials": "Stuur inloggegevens",
|
||||
"Cancel": "Annuleren",
|
||||
"Must set host": "Host moeten worden ingesteld",
|
||||
"Password is required": "Wachtwoord is vereist",
|
||||
"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",
|
||||
"Clear": "Wissen",
|
||||
"Send Password": "Verzend Wachtwoord:",
|
||||
"Cancel": "Annuleren"
|
||||
"Disconnect timeout": "Timeout tijdens verbreken van verbinding",
|
||||
"Local Downscaling": "Lokaal Neerschalen",
|
||||
"Local Cursor": "Lokale Cursor",
|
||||
"Canvas not supported.": "Canvas wordt niet ondersteund.",
|
||||
"Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "''Clipping mode' ingeschakeld, omdat schuifbalken in volledige-scherm-modus in IE niet worden ondersteund"
|
||||
}
|
||||
|
|
@ -21,9 +21,9 @@
|
|||
"Middle mousebutton": "Środkowy przycisk myszy",
|
||||
"Right mousebutton": "Prawy przycisk myszy",
|
||||
"Keyboard": "Klawiatura",
|
||||
"Show Keyboard": "Pokaż klawiaturę",
|
||||
"Show keyboard": "Pokaż klawiaturę",
|
||||
"Extra keys": "Przyciski dodatkowe",
|
||||
"Show Extra Keys": "Pokaż przyciski dodatkowe",
|
||||
"Show extra keys": "Pokaż przyciski dodatkowe",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Przełącz Ctrl",
|
||||
"Alt": "Alt",
|
||||
|
|
@ -49,8 +49,8 @@
|
|||
"Clip to Window": "Przytnij do Okna",
|
||||
"Scaling Mode:": "Tryb Skalowania:",
|
||||
"None": "Brak",
|
||||
"Local Scaling": "Skalowanie lokalne",
|
||||
"Remote Resizing": "Skalowanie zdalne",
|
||||
"Local scaling": "Skalowanie lokalne",
|
||||
"Remote resizing": "Skalowanie zdalne",
|
||||
"Advanced": "Zaawansowane",
|
||||
"Repeater ID:": "ID Repeatera:",
|
||||
"WebSocket": "WebSocket",
|
||||
|
|
@ -58,12 +58,23 @@
|
|||
"Host:": "Host:",
|
||||
"Port:": "Port:",
|
||||
"Path:": "Ścieżka:",
|
||||
"Automatic Reconnect": "Automatycznie wznawiaj połączenie",
|
||||
"Reconnect Delay (ms):": "Opóźnienie wznawiania (ms):",
|
||||
"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."
|
||||
"Canvas not supported.": "Element Canvas nie jest wspierany.",
|
||||
"Disconnect timeout": "Timeout rozłączenia",
|
||||
"Local Downscaling": "Downscaling lokalny",
|
||||
"Local Cursor": "Lokalny kursor",
|
||||
"Forcing clipping mode since scrollbars aren't supported by IE in fullscreen": "Wymuszam clipping mode ponieważ paski przewijania nie są wspierane przez IE w trybie pełnoekranowym",
|
||||
"True Color": "True Color",
|
||||
"Style:": "Styl:",
|
||||
"default": "domyślny",
|
||||
"Apply": "Zapisz",
|
||||
"Connection": "Połączenie",
|
||||
"Token:": "Token:",
|
||||
"Send Password": "Wyślij Hasło"
|
||||
}
|
||||
|
|
@ -15,11 +15,11 @@
|
|||
"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",
|
||||
"Move/Drag viewport": "Mover/arrastar a janela",
|
||||
"Keyboard": "Teclado",
|
||||
"Show Keyboard": "Mostrar teclado",
|
||||
"Show keyboard": "Mostrar teclado",
|
||||
"Extra keys": "Teclas adicionais",
|
||||
"Show Extra Keys": "Mostar teclas adicionais",
|
||||
"Show extra keys": "Mostrar teclas adicionais",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Pressionar/soltar Ctrl",
|
||||
"Alt": "Alt",
|
||||
|
|
@ -42,13 +42,13 @@
|
|||
"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:",
|
||||
"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",
|
||||
"Local scaling": "Local",
|
||||
"Remote resizing": "Remoto",
|
||||
"Advanced": "Avançado",
|
||||
"Quality:": "Qualidade:",
|
||||
"Compression level:": "Nível de compressão:",
|
||||
|
|
@ -58,15 +58,15 @@
|
|||
"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",
|
||||
"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",
|
||||
"Send credentials": "Enviar credenciais",
|
||||
"Cancel": "Cancelar"
|
||||
}
|
||||
|
|
@ -15,16 +15,16 @@
|
|||
"noVNC encountered an error:": "Ошибка noVNC: ",
|
||||
"Hide/Show the control bar": "Скрыть/Показать контрольную панель",
|
||||
"Drag": "Переместить",
|
||||
"Move/Drag Viewport": "Переместить окно",
|
||||
"Move/Drag viewport": "Переместить окно",
|
||||
"Keyboard": "Клавиатура",
|
||||
"Show Keyboard": "Показать клавиатуру",
|
||||
"Show keyboard": "Показать клавиатуру",
|
||||
"Extra keys": "Дополнительные Кнопки",
|
||||
"Show Extra Keys": "Показать Дополнительные Кнопки",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Переключение нажатия Ctrl",
|
||||
"Toggle Ctrl": "Зажать Ctrl",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "Переключение нажатия Alt",
|
||||
"Toggle Windows": "Переключение вкладок",
|
||||
"Toggle Alt": "Зажать Alt",
|
||||
"Toggle Windows": "Зажать Windows",
|
||||
"Windows": "Вкладка",
|
||||
"Send Tab": "Передать нажатие Tab",
|
||||
"Tab": "Tab",
|
||||
|
|
@ -42,13 +42,13 @@
|
|||
"Clear": "Очистить",
|
||||
"Fullscreen": "Во весь экран",
|
||||
"Settings": "Настройки",
|
||||
"Shared Mode": "Общий режим",
|
||||
"Shared mode": "Общий режим",
|
||||
"View Only": "Только Просмотр",
|
||||
"Clip to Window": "В окно",
|
||||
"Scaling Mode:": "Масштаб:",
|
||||
"Clip to window": "В окно",
|
||||
"Scaling mode:": "Масштаб:",
|
||||
"None": "Нет",
|
||||
"Local Scaling": "Локльный масштаб",
|
||||
"Remote Resizing": "Удаленная перенастройка размера",
|
||||
"Local scaling": "Локальный масштаб",
|
||||
"Remote resizing": "Удаленная перенастройка размера",
|
||||
"Advanced": "Дополнительно",
|
||||
"Quality:": "Качество",
|
||||
"Compression level:": "Уровень Сжатия",
|
||||
|
|
@ -58,9 +58,9 @@
|
|||
"Host:": "Сервер:",
|
||||
"Port:": "Порт:",
|
||||
"Path:": "Путь:",
|
||||
"Automatic Reconnect": "Автоматическое переподключение",
|
||||
"Reconnect Delay (ms):": "Задержка переподключения (мс):",
|
||||
"Show Dot when No Cursor": "Показать точку вместо курсора",
|
||||
"Automatic reconnect": "Автоматическое переподключение",
|
||||
"Reconnect delay (ms):": "Задержка переподключения (мс):",
|
||||
"Show dot when no cursor": "Показать точку вместо курсора",
|
||||
"Logging:": "Лог:",
|
||||
"Version:": "Версия",
|
||||
"Disconnect": "Отключение",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
"Disconnecting...": "Kopplar ner...",
|
||||
"Reconnecting...": "Återansluter...",
|
||||
"Internal error": "Internt fel",
|
||||
"Must set host": "Du måste specifiera en värd",
|
||||
"Failed to connect to server: ": "Misslyckades att ansluta till servern: ",
|
||||
"Connected (encrypted) to ": "Ansluten (krypterat) till ",
|
||||
"Connected (unencrypted) to ": "Ansluten (okrypterat) till ",
|
||||
|
|
@ -17,11 +16,11 @@
|
|||
"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",
|
||||
"Move/Drag viewport": "Flytta/Dra vyn",
|
||||
"Keyboard": "Tangentbord",
|
||||
"Show Keyboard": "Visa Tangentbord",
|
||||
"Show keyboard": "Visa tangentbord",
|
||||
"Extra keys": "Extraknappar",
|
||||
"Show Extra Keys": "Visa Extraknappar",
|
||||
"Show extra keys": "Visa extraknappar",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Växla Ctrl",
|
||||
"Alt": "Alt",
|
||||
|
|
@ -42,15 +41,15 @@
|
|||
"Reset": "Återställ",
|
||||
"Clipboard": "Urklipp",
|
||||
"Edit clipboard content in the textarea below.": "Redigera urklippets innehåll i fältet nedan.",
|
||||
"Full Screen": "Fullskärm",
|
||||
"Full screen": "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:",
|
||||
"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",
|
||||
"Local scaling": "Lokal skalning",
|
||||
"Remote resizing": "Ändra storlek",
|
||||
"Advanced": "Avancerat",
|
||||
"Quality:": "Kvalitet:",
|
||||
"Compression level:": "Kompressionsnivå:",
|
||||
|
|
@ -60,9 +59,9 @@
|
|||
"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",
|
||||
"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",
|
||||
|
|
@ -76,6 +75,9 @@
|
|||
"Credentials": "Användaruppgifter",
|
||||
"Username:": "Användarnamn:",
|
||||
"Password:": "Lösenord:",
|
||||
"Send Credentials": "Skicka Användaruppgifter",
|
||||
"Cancel": "Avbryt"
|
||||
"Send credentials": "Skicka användaruppgifter",
|
||||
"Cancel": "Avbryt",
|
||||
"Must set host": "Du måste specifiera en värd",
|
||||
"HTTPS is required for full functionality": "HTTPS krävs för full funktionalitet",
|
||||
"Clear": "Rensa"
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
"Keyboard": "Klavye",
|
||||
"Show Keyboard": "Klavye Düzenini Göster",
|
||||
"Extra keys": "Ekstra tuşlar",
|
||||
"Show Extra Keys": "Ekstra tuşları göster",
|
||||
"Show extra keys": "Ekstra tuşları göster",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "Ctrl Değiştir ",
|
||||
"Alt": "Alt",
|
||||
|
|
|
|||
|
|
@ -1,31 +1,33 @@
|
|||
{
|
||||
"Running without HTTPS is not recommended, crashes or other issues are likely.": "不建议在没有 HTTPS 的情况下运行,可能会出现崩溃或出现其他问题。",
|
||||
"Connecting...": "连接中...",
|
||||
"Disconnecting...": "正在断开连接...",
|
||||
"Reconnecting...": "重新连接中...",
|
||||
"Internal error": "内部错误",
|
||||
"Must set host": "必须设置主机",
|
||||
"Failed to connect to server: ": "无法连接到服务器:",
|
||||
"Connected (encrypted) to ": "已连接(已加密)到",
|
||||
"Connected (unencrypted) to ": "已连接(未加密)到",
|
||||
"Disconnecting...": "正在断开连接...",
|
||||
"Something went wrong, connection is closed": "出了点问题,连接已关闭",
|
||||
"Failed to connect to server": "无法连接到服务器",
|
||||
"Disconnected": "已断开连接",
|
||||
"Must set host": "必须设置主机",
|
||||
"Reconnecting...": "重新连接中...",
|
||||
"Password is required": "请提供密码",
|
||||
"Disconnect timeout": "超时断开",
|
||||
"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": "显示/隐藏控制栏",
|
||||
"Move/Drag Viewport": "移动/拖动窗口",
|
||||
"viewport drag": "窗口拖动",
|
||||
"Active Mouse Button": "启动鼠标按键",
|
||||
"No mousebutton": "禁用鼠标按键",
|
||||
"Left mousebutton": "鼠标左键",
|
||||
"Middle mousebutton": "鼠标中键",
|
||||
"Right mousebutton": "鼠标右键",
|
||||
"Drag": "拖动",
|
||||
"Move/Drag viewport": "移动/拖动窗口",
|
||||
"Keyboard": "键盘",
|
||||
"Show Keyboard": "显示键盘",
|
||||
"Show keyboard": "显示键盘",
|
||||
"Extra keys": "额外按键",
|
||||
"Show Extra Keys": "显示额外按键",
|
||||
"Show extra keys": "显示额外按键",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "切换 Ctrl",
|
||||
"Edit clipboard content in the textarea below.": "在下面的文本区域中编辑剪贴板内容。",
|
||||
"Alt": "Alt",
|
||||
"Toggle Alt": "切换 Alt",
|
||||
"Toggle Windows": "切换窗口",
|
||||
"Windows": "窗口",
|
||||
"Send Tab": "发送 Tab 键",
|
||||
"Tab": "Tab",
|
||||
"Esc": "Esc",
|
||||
|
|
@ -39,31 +41,53 @@
|
|||
"Reboot": "重启",
|
||||
"Reset": "重置",
|
||||
"Clipboard": "剪贴板",
|
||||
"Clear": "清除",
|
||||
"Fullscreen": "全屏",
|
||||
"Edit clipboard content in the textarea below.": "在下面的文本区域中编辑剪贴板内容。",
|
||||
"Full screen": "全屏",
|
||||
"Settings": "设置",
|
||||
"Encrypt": "加密",
|
||||
"Shared Mode": "分享模式",
|
||||
"View Only": "仅查看",
|
||||
"Clip to Window": "限制/裁切窗口大小",
|
||||
"Scaling Mode:": "缩放模式:",
|
||||
"Shared mode": "分享模式",
|
||||
"View only": "仅查看",
|
||||
"Clip to window": "限制/裁切窗口大小",
|
||||
"Scaling mode:": "缩放模式:",
|
||||
"None": "无",
|
||||
"Local Scaling": "本地缩放",
|
||||
"Local Downscaling": "降低本地尺寸",
|
||||
"Remote Resizing": "远程调整大小",
|
||||
"Local scaling": "本地缩放",
|
||||
"Remote resizing": "远程调整大小",
|
||||
"Advanced": "高级",
|
||||
"Local Cursor": "本地光标",
|
||||
"Quality:": "品质:",
|
||||
"Compression level:": "压缩级别:",
|
||||
"Repeater ID:": "中继站 ID",
|
||||
"WebSocket": "WebSocket",
|
||||
"Encrypt": "加密",
|
||||
"Host:": "主机:",
|
||||
"Port:": "端口:",
|
||||
"Path:": "路径:",
|
||||
"Automatic Reconnect": "自动重新连接",
|
||||
"Reconnect Delay (ms):": "重新连接间隔 (ms):",
|
||||
"Automatic reconnect": "自动重新连接",
|
||||
"Reconnect delay (ms):": "重新连接间隔 (ms):",
|
||||
"Show dot when no cursor": "无光标时显示点",
|
||||
"Logging:": "日志级别:",
|
||||
"Version:": "版本:",
|
||||
"Disconnect": "断开连接",
|
||||
"Connect": "连接",
|
||||
"Server identity": "服务器身份",
|
||||
"The server has provided the following identifying information:": "服务器提供了以下识别信息:",
|
||||
"Fingerprint:": "指纹:",
|
||||
"Please verify that the information is correct and press \"Approve\". Otherwise press \"Reject\".": "请核实信息是否正确,并按 “同意”,否则按 “拒绝”。",
|
||||
"Approve": "同意",
|
||||
"Reject": "拒绝",
|
||||
"Credentials": "凭证",
|
||||
"Username:": "用户名:",
|
||||
"Password:": "密码:",
|
||||
"Send credentials": "发送凭证",
|
||||
"Cancel": "取消",
|
||||
"Password is required": "请提供密码",
|
||||
"Disconnect timeout": "超时断开",
|
||||
"viewport drag": "窗口拖动",
|
||||
"Active Mouse Button": "启动鼠标按键",
|
||||
"No mousebutton": "禁用鼠标按键",
|
||||
"Left mousebutton": "鼠标左键",
|
||||
"Middle mousebutton": "鼠标中键",
|
||||
"Right mousebutton": "鼠标右键",
|
||||
"Clear": "清除",
|
||||
"Local Downscaling": "降低本地尺寸",
|
||||
"Local Cursor": "本地光标",
|
||||
"Canvas not supported.": "不支持 Canvas。"
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
"Password is required": "請提供密碼",
|
||||
"noVNC encountered an error:": "noVNC 遇到一個錯誤:",
|
||||
"Hide/Show the control bar": "顯示/隱藏控制列",
|
||||
"Move/Drag Viewport": "拖放顯示範圍",
|
||||
"Move/Drag viewport": "拖放顯示範圍",
|
||||
"viewport drag": "顯示範圍拖放",
|
||||
"Active Mouse Button": "啟用滑鼠按鍵",
|
||||
"No mousebutton": "無滑鼠按鍵",
|
||||
|
|
@ -22,9 +22,9 @@
|
|||
"Middle mousebutton": "滑鼠中鍵",
|
||||
"Right mousebutton": "滑鼠右鍵",
|
||||
"Keyboard": "鍵盤",
|
||||
"Show Keyboard": "顯示鍵盤",
|
||||
"Show keyboard": "顯示鍵盤",
|
||||
"Extra keys": "額外按鍵",
|
||||
"Show Extra Keys": "顯示額外按鍵",
|
||||
"Show extra keys": "顯示額外按鍵",
|
||||
"Ctrl": "Ctrl",
|
||||
"Toggle Ctrl": "切換 Ctrl",
|
||||
"Alt": "Alt",
|
||||
|
|
@ -45,13 +45,13 @@
|
|||
"Clear": "清除",
|
||||
"Fullscreen": "全螢幕",
|
||||
"Settings": "設定",
|
||||
"Shared Mode": "分享模式",
|
||||
"View Only": "僅檢視",
|
||||
"Clip to Window": "限制/裁切視窗大小",
|
||||
"Scaling Mode:": "縮放模式:",
|
||||
"Shared mode": "分享模式",
|
||||
"View only": "僅檢視",
|
||||
"Clip to window": "限制/裁切視窗大小",
|
||||
"Scaling mode:": "縮放模式:",
|
||||
"None": "無",
|
||||
"Local Scaling": "本機縮放",
|
||||
"Remote Resizing": "遠端調整大小",
|
||||
"Local scaling": "本機縮放",
|
||||
"Remote resizing": "遠端調整大小",
|
||||
"Advanced": "進階",
|
||||
"Repeater ID:": "中繼站 ID",
|
||||
"WebSocket": "WebSocket",
|
||||
|
|
@ -59,8 +59,8 @@
|
|||
"Host:": "主機:",
|
||||
"Port:": "連接埠:",
|
||||
"Path:": "路徑:",
|
||||
"Automatic Reconnect": "自動重新連線",
|
||||
"Reconnect Delay (ms):": "重新連線間隔 (ms):",
|
||||
"Automatic reconnect": "自動重新連線",
|
||||
"Reconnect delay (ms):": "重新連線間隔 (ms):",
|
||||
"Logging:": "日誌級別:",
|
||||
"Disconnect": "中斷連線",
|
||||
"Connect": "連線",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Copyright (C) 2018 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Localization Utilities
|
||||
* Localization utilities
|
||||
*/
|
||||
|
||||
export class Localizer {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* noVNC general CSS constant variables
|
||||
* Copyright (C) 2025 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).
|
||||
*/
|
||||
|
||||
/* ---------- COLORS ----------- */
|
||||
|
||||
:root {
|
||||
--novnc-grey: rgb(128, 128, 128);
|
||||
--novnc-lightgrey: rgb(192, 192, 192);
|
||||
--novnc-darkgrey: rgb(92, 92, 92);
|
||||
|
||||
/* Transparent to make button colors adapt to the background */
|
||||
--novnc-buttongrey: rgba(192, 192, 192, 0.5);
|
||||
|
||||
--novnc-blue: rgb(110, 132, 163);
|
||||
--novnc-lightblue: rgb(74, 144, 217);
|
||||
--novnc-darkblue: rgb(83, 99, 122);
|
||||
|
||||
--novnc-green: rgb(0, 128, 0);
|
||||
--novnc-yellow: rgb(255, 255, 0);
|
||||
}
|
||||
|
||||
/* ------ MISC PROPERTIES ------ */
|
||||
|
||||
:root {
|
||||
--input-xpadding: 1em;
|
||||
}
|
||||
|
|
@ -1,32 +1,170 @@
|
|||
/*
|
||||
* noVNC general input element CSS
|
||||
* Copyright (C) 2022 The noVNC Authors
|
||||
* Copyright (C) 2025 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).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Common for all inputs
|
||||
*/
|
||||
input, input::file-selector-button, button, select, textarea {
|
||||
/* Respect standard font settings */
|
||||
font: inherit;
|
||||
/* ------- SHARED BETWEEN INPUT ELEMENTS -------- */
|
||||
|
||||
/* Disable default rendering */
|
||||
appearance: none;
|
||||
background: none;
|
||||
input,
|
||||
textarea,
|
||||
button,
|
||||
select,
|
||||
input::file-selector-button {
|
||||
padding: 0.5em var(--input-xpadding);
|
||||
border-radius: 6px;
|
||||
appearance: none;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
padding: 5px;
|
||||
border: 1px solid rgb(192, 192, 192);
|
||||
border-radius: 5px;
|
||||
color: black;
|
||||
--bg-gradient: linear-gradient(to top, rgb(255, 255, 255) 80%, rgb(240, 240, 240));
|
||||
background-image: var(--bg-gradient);
|
||||
/* Respect standard font settings */
|
||||
font: inherit;
|
||||
line-height: 1.6;
|
||||
}
|
||||
input:disabled,
|
||||
textarea:disabled,
|
||||
button:disabled,
|
||||
select:disabled,
|
||||
label[disabled] {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Buttons
|
||||
*/
|
||||
input:focus-visible,
|
||||
textarea:focus-visible,
|
||||
button:focus-visible,
|
||||
select:focus-visible,
|
||||
input:focus-visible::file-selector-button {
|
||||
outline: 2px solid var(--novnc-lightblue);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
/* ------- TEXT INPUT -------- */
|
||||
|
||||
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 {
|
||||
border: 1px solid var(--novnc-lightgrey);
|
||||
/* Account for borders on text inputs, buttons dont have borders */
|
||||
padding: calc(0.5em - 1px) var(--input-xpadding);
|
||||
}
|
||||
input:not([type]):focus-visible,
|
||||
input[type=date]:focus-visible,
|
||||
input[type=datetime-local]:focus-visible,
|
||||
input[type=email]:focus-visible,
|
||||
input[type=month]:focus-visible,
|
||||
input[type=number]:focus-visible,
|
||||
input[type=password]:focus-visible,
|
||||
input[type=search]:focus-visible,
|
||||
input[type=tel]:focus-visible,
|
||||
input[type=text]:focus-visible,
|
||||
input[type=time]:focus-visible,
|
||||
input[type=url]:focus-visible,
|
||||
input[type=week]:focus-visible,
|
||||
textarea:focus-visible {
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
margin: unset; /* Remove Firefox's built in margin */
|
||||
/* Prevent layout from shifting when scrollbars show */
|
||||
scrollbar-gutter: stable;
|
||||
/* Make textareas show at minimum one line. This does not work when
|
||||
using box-sizing border-box, in which case, vertical padding and
|
||||
border width needs to be taken into account. */
|
||||
min-height: 1lh;
|
||||
vertical-align: baseline; /* Firefox gives "text-bottom" by default */
|
||||
}
|
||||
|
||||
/* ------- NUMBER PICKERS ------- */
|
||||
|
||||
/* We can't style the number spinner buttons:
|
||||
https://github.com/w3c/csswg-drafts/issues/8777 */
|
||||
input[type=number]::-webkit-inner-spin-button,
|
||||
input[type=number]::-webkit-outer-spin-button {
|
||||
/* Get rid of increase/decrease buttons in WebKit */
|
||||
appearance: none;
|
||||
}
|
||||
input[type=number] {
|
||||
/* Get rid of increase/decrease buttons in Firefox */
|
||||
appearance: textfield;
|
||||
}
|
||||
|
||||
/* ------- BUTTON ACTIVATIONS -------- */
|
||||
|
||||
/* A color overlay that depends on the activation level. The level can then be
|
||||
set for different states on an element, for example hover and click on a
|
||||
<button>. */
|
||||
input, button, select, option,
|
||||
input::file-selector-button,
|
||||
.button-activations {
|
||||
--button-activation-level: 0;
|
||||
/* Note that CSS variables aren't functions, beware when inheriting */
|
||||
--button-activation-alpha: calc(0.08 * var(--button-activation-level));
|
||||
/* FIXME: We want the image() function instead of the linear-gradient()
|
||||
function below. But it's not supported in the browsers yet. */
|
||||
--button-activation-overlay:
|
||||
linear-gradient(rgba(0, 0, 0, var(--button-activation-alpha))
|
||||
100%, transparent);
|
||||
--button-activation-overlay-light:
|
||||
linear-gradient(rgba(255, 255, 255, calc(0.23 * var(--button-activation-level)))
|
||||
100%, transparent);
|
||||
}
|
||||
.button-activations {
|
||||
background-image: var(--button-activation-overlay);
|
||||
|
||||
/* Disable Chrome's touch tap highlight to avoid conflicts with overlay */
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
/* When we want the light overlay on activations instead.
|
||||
This is best used on elements with darker backgrounds. */
|
||||
.button-activations.light-overlay {
|
||||
background-image: var(--button-activation-overlay-light);
|
||||
/* Can't use the normal blend mode since that gives washed out colors. */
|
||||
/* FIXME: For elements with these activation overlays we'd like only
|
||||
the luminosity to change. The proprty "background-blend-mode" set
|
||||
to "luminosity" sounds good, but it doesn't work as intended,
|
||||
see: https://bugzilla.mozilla.org/show_bug.cgi?id=1806417 */
|
||||
background-blend-mode: overlay;
|
||||
}
|
||||
|
||||
input:hover, button:hover, select:hover, option:hover,
|
||||
input::file-selector-button:hover,
|
||||
.button-activations:hover {
|
||||
--button-activation-level: 1;
|
||||
}
|
||||
/* Unfortunately we have to disable the :hover effect on touch devices,
|
||||
otherwise the style lingers after tapping the button. */
|
||||
@media (any-pointer: coarse) {
|
||||
input:hover, button:hover, select:hover, option:hover,
|
||||
input::file-selector-button:hover,
|
||||
.button-activations:hover {
|
||||
--button-activation-level: 0;
|
||||
}
|
||||
}
|
||||
input:active, button:active, select:active, option:active,
|
||||
input::file-selector-button:active,
|
||||
.button-activations:active {
|
||||
--button-activation-level: 2;
|
||||
}
|
||||
input:disabled, button:disabled, select:disabled, select:disabled option,
|
||||
input:disabled::file-selector-button,
|
||||
.button-activations:disabled {
|
||||
--button-activation-level: 0;
|
||||
}
|
||||
|
||||
/* ------- BUTTONS -------- */
|
||||
|
||||
input[type=button],
|
||||
input[type=color],
|
||||
input[type=image],
|
||||
|
|
@ -35,226 +173,15 @@ input[type=submit],
|
|||
input::file-selector-button,
|
||||
button,
|
||||
select {
|
||||
border-bottom-width: 2px;
|
||||
|
||||
/* This avoids it jumping around when :active */
|
||||
vertical-align: middle;
|
||||
margin-top: 0;
|
||||
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
|
||||
/* Disable Chrome's touch tap highlight */
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select dropdowns
|
||||
*/
|
||||
select {
|
||||
--select-arrow: url('data:image/svg+xml;utf8, \
|
||||
<svg width="8" height="6" version="1.1" viewBox="0 0 8 6" \
|
||||
xmlns="http://www.w3.org/2000/svg"> \
|
||||
<path d="m6.5 1.5 -2.5 3 -2.5 -3 5 0" stroke-width="3" \
|
||||
stroke="rgb(31,31,31)" fill="none" \
|
||||
stroke-linecap="round" stroke-linejoin="round" /> \
|
||||
</svg>');
|
||||
background-image: var(--select-arrow), var(--bg-gradient);
|
||||
background-position: calc(100% - 7px), left top;
|
||||
background-repeat: no-repeat;
|
||||
padding-right: calc(2*7px + 8px);
|
||||
padding-left: 7px;
|
||||
}
|
||||
/* FIXME: :active isn't set when the <select> is opened in Firefox:
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1805406 */
|
||||
select:active {
|
||||
/* Rotated arrow */
|
||||
background-image: url('data:image/svg+xml;utf8, \
|
||||
<svg width="8" height="6" version="1.1" viewBox="0 0 8 6" \
|
||||
xmlns="http://www.w3.org/2000/svg" transform="rotate(180)" > \
|
||||
<path d="m6.5 1.5 -2.5 3 -2.5 -3 5 0" stroke-width="3" \
|
||||
stroke="rgb(31,31,31)" fill="none" \
|
||||
stroke-linecap="round" stroke-linejoin="round" /> \
|
||||
</svg>'), var(--bg-gradient);
|
||||
}
|
||||
option {
|
||||
color: black;
|
||||
background: white;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checkboxes
|
||||
*/
|
||||
input[type=checkbox] {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: white;
|
||||
background-image: unset;
|
||||
border: 1px solid dimgrey;
|
||||
border-radius: 3px;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
padding: 0;
|
||||
margin-right: 6px;
|
||||
vertical-align: bottom;
|
||||
transition: 0.2s background-color linear;
|
||||
}
|
||||
input[type=checkbox]:checked {
|
||||
background-color: rgb(110, 132, 163);
|
||||
border-color: rgb(110, 132, 163);
|
||||
}
|
||||
input[type=checkbox]:checked::after {
|
||||
content: "";
|
||||
display: block; /* width & height doesn't work on inline elements */
|
||||
width: 3px;
|
||||
height: 7px;
|
||||
border: 1px solid white;
|
||||
border-width: 0 2px 2px 0;
|
||||
transform: rotate(40deg) translateY(-1px);
|
||||
}
|
||||
|
||||
/*
|
||||
* Radiobuttons
|
||||
*/
|
||||
input[type=radio] {
|
||||
border-radius: 50%;
|
||||
border: 1px solid dimgrey;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
padding: 0;
|
||||
margin-right: 6px;
|
||||
transition: 0.2s border linear;
|
||||
}
|
||||
input[type=radio]:checked {
|
||||
border: 6px solid rgb(110, 132, 163);
|
||||
}
|
||||
|
||||
/*
|
||||
* Range sliders
|
||||
*/
|
||||
input[type=range] {
|
||||
border: unset;
|
||||
border-radius: 3px;
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
}
|
||||
/* -webkit-slider.. & -moz-range.. cant be in selector lists:
|
||||
https://bugs.chromium.org/p/chromium/issues/detail?id=1154623 */
|
||||
input[type=range]::-webkit-slider-runnable-track {
|
||||
background-color: rgb(110, 132, 163);
|
||||
height: 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
input[type=range]::-moz-range-track {
|
||||
background-color: rgb(110, 132, 163);
|
||||
height: 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
input[type=range]::-webkit-slider-thumb {
|
||||
appearance: none;
|
||||
width: 18px;
|
||||
height: 20px;
|
||||
border-radius: 5px;
|
||||
background-color: white;
|
||||
border: 1px solid dimgray;
|
||||
margin-top: -7px;
|
||||
}
|
||||
input[type=range]::-moz-range-thumb {
|
||||
appearance: none;
|
||||
width: 18px;
|
||||
height: 20px;
|
||||
border-radius: 5px;
|
||||
background-color: white;
|
||||
border: 1px solid dimgray;
|
||||
margin-top: -7px;
|
||||
}
|
||||
|
||||
/*
|
||||
* File choosers
|
||||
*/
|
||||
input[type=file] {
|
||||
background-image: none;
|
||||
border: none;
|
||||
}
|
||||
input::file-selector-button {
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hover
|
||||
*/
|
||||
input[type=button]:hover,
|
||||
input[type=color]:hover,
|
||||
input[type=image]:hover,
|
||||
input[type=reset]:hover,
|
||||
input[type=submit]:hover,
|
||||
input::file-selector-button:hover,
|
||||
button:hover {
|
||||
background-image: linear-gradient(to top, rgb(255, 255, 255), rgb(250, 250, 250));
|
||||
}
|
||||
select:hover {
|
||||
background-image: var(--select-arrow),
|
||||
linear-gradient(to top, rgb(255, 255, 255), rgb(250, 250, 250));
|
||||
background-position: calc(100% - 7px), left top;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
@media (any-pointer: coarse) {
|
||||
/* We don't want a hover style after touch input */
|
||||
input[type=button]:hover,
|
||||
input[type=color]:hover,
|
||||
input[type=image]:hover,
|
||||
input[type=reset]:hover,
|
||||
input[type=submit]:hover,
|
||||
input::file-selector-button:hover,
|
||||
button:hover {
|
||||
background-image: var(--bg-gradient);
|
||||
}
|
||||
select:hover {
|
||||
background-image: var(--select-arrow), var(--bg-gradient);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Active (clicked)
|
||||
*/
|
||||
input[type=button]:active,
|
||||
input[type=color]:active,
|
||||
input[type=image]:active,
|
||||
input[type=reset]:active,
|
||||
input[type=submit]:active,
|
||||
input::file-selector-button:active,
|
||||
button:active,
|
||||
select:active {
|
||||
border-bottom-width: 1px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Focus (tab)
|
||||
*/
|
||||
input:focus-visible,
|
||||
input:focus-visible::file-selector-button,
|
||||
button:focus-visible,
|
||||
select:focus-visible,
|
||||
textarea:focus-visible {
|
||||
outline: 2px solid rgb(74, 144, 217);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
input[type=file]:focus-visible {
|
||||
outline: none; /* We outline the button instead of the entire element */
|
||||
}
|
||||
|
||||
/*
|
||||
* Disabled
|
||||
*/
|
||||
input:disabled,
|
||||
input:disabled::file-selector-button,
|
||||
button:disabled,
|
||||
select:disabled,
|
||||
textarea:disabled {
|
||||
opacity: 0.4;
|
||||
min-width: 8em;
|
||||
border: none;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
background-color: var(--novnc-buttongrey);
|
||||
background-image: var(--button-activation-overlay);
|
||||
cursor: pointer;
|
||||
/* Disable Chrome's touch tap highlight */
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
input[type=button]:disabled,
|
||||
input[type=color]:disabled,
|
||||
|
|
@ -264,18 +191,438 @@ input[type=submit]:disabled,
|
|||
input:disabled::file-selector-button,
|
||||
button:disabled,
|
||||
select:disabled {
|
||||
background-image: var(--bg-gradient);
|
||||
border-bottom-width: 2px;
|
||||
margin-top: 0;
|
||||
/* See Firefox bug:
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1798304 */
|
||||
cursor: default;
|
||||
}
|
||||
input[type=file]:disabled {
|
||||
background-image: none;
|
||||
|
||||
input[type=button],
|
||||
input[type=color],
|
||||
input[type=reset],
|
||||
input[type=submit] {
|
||||
/* Workaround for text-overflow bugs in Firefox and Chromium:
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1800077
|
||||
https://bugs.chromium.org/p/chromium/issues/detail?id=1383144 */
|
||||
overflow: clip;
|
||||
}
|
||||
|
||||
/* ------- COLOR PICKERS ------- */
|
||||
|
||||
input[type=color] {
|
||||
min-width: unset;
|
||||
box-sizing: content-box;
|
||||
width: 1.4em;
|
||||
height: 1.4em;
|
||||
}
|
||||
input[type=color]::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
/* -webkit-color-swatch & -moz-color-swatch cant be in a selector list:
|
||||
https://bugs.chromium.org/p/chromium/issues/detail?id=1154623 */
|
||||
input[type=color]::-webkit-color-swatch {
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
}
|
||||
input[type=color]::-moz-color-swatch {
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
/* -- SHARED BETWEEN CHECKBOXES, RADIOBUTTONS AND THE TOGGLE CLASS -- */
|
||||
|
||||
input[type=radio],
|
||||
input[type=checkbox] {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--novnc-buttongrey);
|
||||
background-image: var(--button-activation-overlay);
|
||||
/* Disable Chrome's touch tap highlight to avoid conflicts with overlay */
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
width: 16px;
|
||||
--checkradio-height: 16px;
|
||||
height: var(--checkradio-height);
|
||||
padding: 0;
|
||||
margin: 0 6px 0 0;
|
||||
/* Don't have transitions for outline in order to be consistent
|
||||
with other elements */
|
||||
transition: all 0.2s, outline-color 0s, outline-offset 0s;
|
||||
|
||||
/* A transparent outline in order to work around a graphical clipping issue
|
||||
in WebKit. See bug: https://bugs.webkit.org/show_bug.cgi?id=256003 */
|
||||
outline: 1px solid transparent;
|
||||
position: relative; /* Since ::before & ::after are absolute positioned */
|
||||
|
||||
/* We want to align with the middle of capital letters, this requires
|
||||
a workaround. The default behavior is to align the bottom of the element
|
||||
on top of the text baseline, this is too far up.
|
||||
We want to push the element down half the difference in height between
|
||||
it and a capital X. In our font, the height of a capital "X" is 0.698em.
|
||||
*/
|
||||
vertical-align: calc(0px - (var(--checkradio-height) - 0.698em) / 2);
|
||||
/* FIXME: Could write 1cap instead of 0.698em, but it's only supported in
|
||||
Firefox as of 2023 */
|
||||
/* FIXME: We probably want to use round() here, see bug 8148 */
|
||||
}
|
||||
input[type=radio]:focus-visible,
|
||||
input[type=checkbox]:focus-visible {
|
||||
outline-color: var(--novnc-lightblue);
|
||||
}
|
||||
input[type=checkbox]::before,
|
||||
input[type=checkbox]:not(.toggle)::after,
|
||||
input[type=radio]::before,
|
||||
input[type=radio]::after {
|
||||
content: "";
|
||||
display: block; /* width & height doesn't work on inline elements */
|
||||
transition: inherit;
|
||||
/* Let's prevent the pseudo-elements from taking up layout space so that
|
||||
the ::before and ::after pseudo-elements can be in the same place. This
|
||||
is also required for vertical-align: baseline to work like we want it to
|
||||
on radio/checkboxes. If the pseudo-elements take up layout space, the
|
||||
baseline of text inside them will be used instead. */
|
||||
position: absolute;
|
||||
}
|
||||
input[type=checkbox]:not(.toggle)::after,
|
||||
input[type=radio]::after {
|
||||
width: 10px;
|
||||
height: 2px;
|
||||
background-color: transparent;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* ------- CHECKBOXES ------- */
|
||||
|
||||
input[type=checkbox]:not(.toggle) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
input[type=checkbox]:not(.toggle):checked,
|
||||
input[type=checkbox]:not(.toggle):indeterminate {
|
||||
background-color: var(--novnc-blue);
|
||||
background-image: var(--button-activation-overlay-light);
|
||||
background-blend-mode: overlay;
|
||||
}
|
||||
input[type=checkbox]:not(.toggle)::before {
|
||||
width: 25%;
|
||||
height: 55%;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border-width: 0 2px 2px 0;
|
||||
border-radius: 1px;
|
||||
transform: translateY(-1px) rotate(35deg);
|
||||
}
|
||||
input[type=checkbox]:not(.toggle):checked::before {
|
||||
border-color: white;
|
||||
}
|
||||
input[type=checkbox]:not(.toggle):indeterminate::after {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
/* ------- RADIO BUTTONS ------- */
|
||||
|
||||
input[type=radio] {
|
||||
border-radius: 50%;
|
||||
border: 1px solid transparent; /* To ensure a smooth transition */
|
||||
}
|
||||
input[type=radio]:checked {
|
||||
border: 4px solid var(--novnc-blue);
|
||||
background-color: white;
|
||||
/* button-activation-overlay should be removed from the radio
|
||||
element to not interfere with button-activation-overlay-light
|
||||
that is set on the ::before element. */
|
||||
background-image: none;
|
||||
}
|
||||
input[type=radio]::before {
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
border-radius: inherit;
|
||||
/* We can achieve the highlight overlay effect on border colors by
|
||||
setting button-activation-overlay-light on an element that stays
|
||||
on top (z-axis) of the element with a border. */
|
||||
background-image: var(--button-activation-overlay-light);
|
||||
mix-blend-mode: overlay;
|
||||
opacity: 0;
|
||||
}
|
||||
input[type=radio]:checked::before {
|
||||
opacity: 1;
|
||||
}
|
||||
input[type=radio]:indeterminate::after {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
/* ------- TOGGLE SWITCHES ------- */
|
||||
|
||||
/* These are meant to be used instead of checkboxes in some cases. If all of
|
||||
the following critera are true you should use a toggle switch:
|
||||
|
||||
* The choice is a simple ON/OFF or ENABLE/DISABLE
|
||||
* The choice doesn't give the feeling of "I agree" or "I confirm"
|
||||
* There are not multiple related & grouped options
|
||||
*/
|
||||
|
||||
input[type=checkbox].toggle {
|
||||
display: inline-block;
|
||||
--checkradio-height: 18px; /* Height value used in calc, see above */
|
||||
width: 31px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
border-radius: 9px;
|
||||
}
|
||||
input[type=checkbox].toggle:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
input[type=checkbox].toggle:indeterminate {
|
||||
background-color: var(--novnc-buttongrey);
|
||||
background-image: var(--button-activation-overlay);
|
||||
}
|
||||
input[type=checkbox].toggle:checked {
|
||||
background-color: var(--novnc-blue);
|
||||
background-image: var(--button-activation-overlay-light);
|
||||
background-blend-mode: overlay;
|
||||
}
|
||||
input[type=checkbox].toggle::before {
|
||||
--circle-diameter: 10px;
|
||||
--circle-offset: 4px;
|
||||
width: var(--circle-diameter);
|
||||
height: var(--circle-diameter);
|
||||
top: var(--circle-offset);
|
||||
left: var(--circle-offset);
|
||||
background: white;
|
||||
border-radius: 6px;
|
||||
}
|
||||
input[type=checkbox].toggle:checked::before {
|
||||
left: calc(100% - var(--circle-offset) - var(--circle-diameter));
|
||||
}
|
||||
input[type=checkbox].toggle:indeterminate::before {
|
||||
left: calc(50% - var(--circle-diameter) / 2);
|
||||
}
|
||||
|
||||
/* ------- RANGE SLIDERS ------- */
|
||||
|
||||
input[type=range] {
|
||||
border: unset;
|
||||
border-radius: 8px;
|
||||
height: 15px;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
/* Needed to get properly rounded corners on -moz-range-progress
|
||||
when the thumb is all the way to the right. Without overflow
|
||||
hidden, the pointy edges of the progress track shows to the
|
||||
right of the thumb. */
|
||||
overflow: hidden;
|
||||
}
|
||||
@supports selector(::-webkit-slider-thumb) {
|
||||
input[type=range] {
|
||||
/* Needs a fixed width to match clip-path */
|
||||
width: 125px;
|
||||
/* overflow: hidden is not ideal for hiding the left part of the box
|
||||
shadow of -webkit-slider-thumb since it doesn't match the smaller
|
||||
border-radius of the progress track. The below clip-path has two
|
||||
circular sides to make the ends of the track have correctly rounded
|
||||
corners. The clip path shape looks something like this:
|
||||
|
||||
+-------------------------------+
|
||||
/---| |---\
|
||||
| |
|
||||
\---| |---/
|
||||
+-------------------------------+
|
||||
|
||||
The larger middle part of the clip path is made to have room for the
|
||||
thumb. By using margins on the track, we prevent the thumb from
|
||||
touching the ends of the track.
|
||||
*/
|
||||
clip-path: path(' \
|
||||
M 4.5 3 \
|
||||
L 4.5 0 \
|
||||
L 120.5 0 \
|
||||
L 120.5 3 \
|
||||
A 1 1 0 0 1 120.5 12 \
|
||||
L 120.5 15 \
|
||||
L 4.5 15 \
|
||||
L 4.5 12 \
|
||||
A 1 1 0 0 1 4.5 3 \
|
||||
');
|
||||
}
|
||||
}
|
||||
input[type=range]:hover {
|
||||
cursor: grab;
|
||||
}
|
||||
input[type=range]:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
input[type=range]:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
input[type=range]:focus-visible {
|
||||
clip-path: none; /* Otherwise it hides the outline */
|
||||
}
|
||||
/* -webkit-slider.. & -moz-range.. cant be in selector lists:
|
||||
https://bugs.chromium.org/p/chromium/issues/detail?id=1154623 */
|
||||
input[type=range]::-webkit-slider-runnable-track {
|
||||
background-color: var(--novnc-buttongrey);
|
||||
height: 7px;
|
||||
border-radius: 4px;
|
||||
margin: 0 3px;
|
||||
}
|
||||
input[type=range]::-moz-range-track {
|
||||
background-color: var(--novnc-buttongrey);
|
||||
height: 7px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
input[type=range]::-moz-range-progress {
|
||||
background-color: var(--novnc-blue);
|
||||
height: 9px;
|
||||
/* Needs rounded corners only on the left side. Otherwise the rounding of
|
||||
the progress track starts before the thumb, when the thumb is close to
|
||||
the left edge. */
|
||||
border-radius: 5px 0 0 5px;
|
||||
}
|
||||
input[type=range]::-webkit-slider-thumb {
|
||||
appearance: none;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: 50%;
|
||||
background-color: white;
|
||||
background-image: var(--button-activation-overlay);
|
||||
/* Disable Chrome's touch tap highlight to avoid conflicts with overlay */
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
border: 3px solid var(--novnc-blue);
|
||||
margin-top: -4px; /* (track height / 2) - (thumb height /2) */
|
||||
|
||||
/* Since there is no way to style the left part of the range track in
|
||||
webkit, we add a large shadow (1000px wide) to the left of the thumb and
|
||||
then crop it with a clip-path shaped like this:
|
||||
___
|
||||
+-------------------/ \
|
||||
| progress |Thumb|
|
||||
+-------------------\ ___ /
|
||||
|
||||
The large left part of the shadow is clipped by another clip-path on on
|
||||
the main range input element. */
|
||||
/* FIXME: We can remove the box shadow workaround when this is standardized:
|
||||
https://github.com/w3c/csswg-drafts/issues/4410 */
|
||||
|
||||
box-shadow: calc(-100vw - 8px) 0 0 100vw var(--novnc-blue);
|
||||
clip-path: path(' \
|
||||
M -1000 3 \
|
||||
L 3 3 \
|
||||
L 15 7.5 \
|
||||
A 1 1 0 0 1 0 7.5 \
|
||||
A 1 1 0 0 1 15 7.5 \
|
||||
L 3 12 \
|
||||
L -1000 12 Z \
|
||||
');
|
||||
}
|
||||
input[type=range]::-moz-range-thumb {
|
||||
appearance: none;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
background-color: white;
|
||||
background-image: var(--button-activation-overlay);
|
||||
border: 3px solid var(--novnc-blue);
|
||||
margin-top: -7px;
|
||||
}
|
||||
|
||||
/* ------- FILE CHOOSERS ------- */
|
||||
|
||||
input[type=file] {
|
||||
background-image: none;
|
||||
border: none;
|
||||
}
|
||||
input::file-selector-button {
|
||||
margin-right: 6px;
|
||||
}
|
||||
input[type=file]:focus-visible {
|
||||
outline: none; /* We outline the button instead of the entire element */
|
||||
}
|
||||
|
||||
/* ------- SELECT BUTTONS ------- */
|
||||
|
||||
select {
|
||||
--select-arrow: url('data:image/svg+xml;utf8, \
|
||||
<svg width="11" height="6" version="1.1" viewBox="0 0 11 6" \
|
||||
xmlns="http://www.w3.org/2000/svg"> \
|
||||
<path d="m10.5.5-5 5-5-5" fill="none" \
|
||||
stroke="black" stroke-width="1.5" \
|
||||
stroke-linecap="round" stroke-linejoin="round"/> \
|
||||
</svg>');
|
||||
|
||||
/* FIXME: A bug in Firefox, requires a workaround for the background:
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1810958 */
|
||||
/* The dropdown list will show the select element's background above and
|
||||
below the options in Firefox. We want the entire dropdown to be white. */
|
||||
background-color: white;
|
||||
/* However, we don't want the select element to actually show a white
|
||||
background, so let's place a gradient above it with the color we want. */
|
||||
--grey-background: linear-gradient(var(--novnc-buttongrey) 100%,
|
||||
transparent);
|
||||
background-image:
|
||||
var(--select-arrow),
|
||||
var(--button-activation-overlay),
|
||||
var(--grey-background);
|
||||
background-position: calc(100% - var(--input-xpadding)), left top, left top;
|
||||
background-repeat: no-repeat;
|
||||
padding-right: calc(2*var(--input-xpadding) + 11px);
|
||||
overflow: auto;
|
||||
}
|
||||
/* FIXME: :active isn't set when the <select> is opened in Firefox:
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1805406 */
|
||||
select:active {
|
||||
/* Rotated arrow */
|
||||
background-image: url('data:image/svg+xml;utf8, \
|
||||
<svg width="11" height="6" version="1.1" viewBox="0 0 11 6" \
|
||||
xmlns="http://www.w3.org/2000/svg" transform="rotate(180)"> \
|
||||
<path d="m10.5.5-5 5-5-5" fill="none" \
|
||||
stroke="black" stroke-width="1.5" \
|
||||
stroke-linecap="round" stroke-linejoin="round"/> \
|
||||
</svg>'),
|
||||
var(--button-activation-overlay),
|
||||
var(--grey-background);
|
||||
}
|
||||
select:disabled {
|
||||
background-image: var(--select-arrow), var(--bg-gradient);
|
||||
background-image:
|
||||
var(--select-arrow),
|
||||
var(--grey-background);
|
||||
}
|
||||
input[type=image]:disabled {
|
||||
/* See Firefox bug:
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1798304 */
|
||||
cursor: default;
|
||||
/* Note that styling for <option> doesn't work in all browsers
|
||||
since its often drawn directly by the OS. We are generally very
|
||||
limited in what we can change here. */
|
||||
option {
|
||||
/* Prevent Chrome from inheriting background-color from the <select> */
|
||||
background-color: white;
|
||||
color: black;
|
||||
font-weight: normal;
|
||||
background-image: var(--button-activation-overlay);
|
||||
}
|
||||
option:checked {
|
||||
background-color: var(--novnc-lightgrey);
|
||||
}
|
||||
/* Change the look when the <select> isn't used as a dropdown. When "size"
|
||||
or "multiple" are set, these elements behaves more like lists. */
|
||||
select[size]:not([size="1"]), select[multiple] {
|
||||
background-color: white;
|
||||
background-image: unset; /* Don't show the arrow and other gradients */
|
||||
border: 1px solid var(--novnc-lightgrey);
|
||||
padding: 0;
|
||||
font-weight: normal; /* Without this, options get bold font in WebKit. */
|
||||
|
||||
/* As an exception to the "list"-look, multi-selects in Chrome on Android,
|
||||
and Safari on iOS, are unfortunately designed to be shown as a single
|
||||
line. We can mitigate this inconsistency by at least fixing the height
|
||||
here. By setting a min-height that matches other input elements, it
|
||||
doesn't look too much out of place:
|
||||
(1px border * 2) + (6.5px padding * 2) + 24px line-height = 39px */
|
||||
min-height: 39px;
|
||||
}
|
||||
select[size]:not([size="1"]):focus-visible,
|
||||
select[multiple]:focus-visible {
|
||||
/* Text input style focus-visible highlight */
|
||||
outline-offset: -1px;
|
||||
}
|
||||
select[size]:not([size="1"]) option, select[multiple] option {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding: 4px var(--input-xpadding);
|
||||
}
|
||||
|
|
|
|||
170
app/ui.js
170
app/ui.js
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
@ -20,8 +20,12 @@ import * as WebUtil from "./webutil.js";
|
|||
|
||||
const PAGE_TITLE = "noVNC";
|
||||
|
||||
const LINGUAS = ["cs", "de", "el", "es", "fr", "it", "ja", "ko", "nl", "pl", "pt_BR", "ru", "sv", "tr", "zh_CN", "zh_TW"];
|
||||
|
||||
const UI = {
|
||||
|
||||
customSettings: {},
|
||||
|
||||
connected: false,
|
||||
desktopName: "",
|
||||
|
||||
|
|
@ -43,20 +47,31 @@ const UI = {
|
|||
reconnectPassword: null,
|
||||
disconnectStatusTimeout: null,
|
||||
|
||||
prime() {
|
||||
return WebUtil.initSettings().then(() => {
|
||||
if (document.readyState === "interactive" || document.readyState === "complete") {
|
||||
return UI.start();
|
||||
}
|
||||
async start(options={}) {
|
||||
UI.customSettings = options.settings || {};
|
||||
if (UI.customSettings.defaults === undefined) {
|
||||
UI.customSettings.defaults = {};
|
||||
}
|
||||
if (UI.customSettings.mandatory === undefined) {
|
||||
UI.customSettings.mandatory = {};
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
document.addEventListener('DOMContentLoaded', () => UI.start().then(resolve).catch(reject));
|
||||
// Set up translations
|
||||
try {
|
||||
await l10n.setup(LINGUAS, "app/locale/");
|
||||
} catch (err) {
|
||||
Log.Error("Failed to load translations: " + err);
|
||||
}
|
||||
|
||||
// Initialize setting storage
|
||||
await WebUtil.initSettings();
|
||||
|
||||
// Wait for the page to load
|
||||
if (document.readyState !== "interactive" && document.readyState !== "complete") {
|
||||
await new Promise((resolve, reject) => {
|
||||
document.addEventListener('DOMContentLoaded', resolve);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Render default UI and initialize settings menu
|
||||
start() {
|
||||
}
|
||||
|
||||
UI.initSettings();
|
||||
|
||||
|
|
@ -71,22 +86,20 @@ const UI = {
|
|||
}
|
||||
|
||||
// Try to fetch version number
|
||||
fetch('./package.json')
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw Error("" + response.status + " " + response.statusText);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((packageInfo) => {
|
||||
Array.from(document.getElementsByClassName('noVNC_version')).forEach(el => el.innerText = packageInfo.version);
|
||||
})
|
||||
.catch((err) => {
|
||||
Log.Error("Couldn't fetch package.json: " + err);
|
||||
Array.from(document.getElementsByClassName('noVNC_version_wrapper'))
|
||||
.concat(Array.from(document.getElementsByClassName('noVNC_version_separator')))
|
||||
.forEach(el => el.style.display = 'none');
|
||||
});
|
||||
try {
|
||||
let response = await fetch('./package.json');
|
||||
if (!response.ok) {
|
||||
throw Error("" + response.status + " " + response.statusText);
|
||||
}
|
||||
|
||||
let packageInfo = await response.json();
|
||||
Array.from(document.getElementsByClassName('noVNC_version')).forEach(el => el.innerText = packageInfo.version);
|
||||
} catch (err) {
|
||||
Log.Error("Couldn't fetch package.json: " + err);
|
||||
Array.from(document.getElementsByClassName('noVNC_version_wrapper'))
|
||||
.concat(Array.from(document.getElementsByClassName('noVNC_version_separator')))
|
||||
.forEach(el => el.style.display = 'none');
|
||||
}
|
||||
|
||||
// Adapt the interface for touch screen devices
|
||||
if (isTouchDevice) {
|
||||
|
|
@ -121,7 +134,7 @@ const UI = {
|
|||
|
||||
document.documentElement.classList.remove("noVNC_loading");
|
||||
|
||||
let autoconnect = WebUtil.getConfigVar('autoconnect', true);
|
||||
let autoconnect = UI.getSetting('autoconnect', true);
|
||||
if (autoconnect === 'true' || autoconnect == '1') {
|
||||
autoconnect = true;
|
||||
UI.inhibitReconnect = false;
|
||||
|
|
@ -131,8 +144,6 @@ const UI = {
|
|||
// Show the connect panel on first load unless autoconnecting
|
||||
UI.openConnectPanel();
|
||||
}
|
||||
|
||||
return Promise.resolve(UI.rfb);
|
||||
},
|
||||
|
||||
initFullscreen() {
|
||||
|
|
@ -160,34 +171,26 @@ const UI = {
|
|||
UI.initSetting('logging', 'warn');
|
||||
UI.updateLogging();
|
||||
|
||||
// if port == 80 (or 443) then it won't be present and should be
|
||||
// set manually
|
||||
let port = window.location.port;
|
||||
if (!port) {
|
||||
if (window.location.protocol.substring(0, 5) == 'https') {
|
||||
port = 443;
|
||||
} else if (window.location.protocol.substring(0, 4) == 'http') {
|
||||
port = 80;
|
||||
}
|
||||
}
|
||||
UI.setupSettingLabels();
|
||||
|
||||
/* Populate the controls if defaults are provided in the URL */
|
||||
UI.initSetting('host', window.location.hostname);
|
||||
UI.initSetting('port', port);
|
||||
UI.initSetting('host', '');
|
||||
UI.initSetting('port', 0);
|
||||
UI.initSetting('encrypt', (window.location.protocol === "https:"));
|
||||
UI.initSetting('password');
|
||||
UI.initSetting('autoconnect', false);
|
||||
UI.initSetting('view_clip', false);
|
||||
UI.initSetting('resize', 'remote');
|
||||
UI.initSetting('quality', 6);
|
||||
UI.initSetting('compression', 2);
|
||||
UI.initSetting('shared', true);
|
||||
UI.initSetting('bell', 'on');
|
||||
UI.initSetting('view_only', false);
|
||||
UI.initSetting('show_dot', false);
|
||||
UI.initSetting('path', 'websockify');
|
||||
UI.initSetting('repeaterID', '');
|
||||
UI.initSetting('reconnect', true);
|
||||
UI.initSetting('reconnect_delay', 2000);
|
||||
|
||||
UI.setupSettingLabels();
|
||||
},
|
||||
// Adds a link to the label elements on the corresponding input elements
|
||||
setupSettingLabels() {
|
||||
|
|
@ -751,6 +754,10 @@ const UI = {
|
|||
|
||||
// Initial page load read/initialization of settings
|
||||
initSetting(name, defVal) {
|
||||
// Has the user overridden the default value?
|
||||
if (name in UI.customSettings.defaults) {
|
||||
defVal = UI.customSettings.defaults[name];
|
||||
}
|
||||
// Check Query string followed by cookie
|
||||
let val = WebUtil.getConfigVar(name);
|
||||
if (val === null) {
|
||||
|
|
@ -758,6 +765,11 @@ const UI = {
|
|||
}
|
||||
WebUtil.setSetting(name, val);
|
||||
UI.updateSetting(name);
|
||||
// Has the user forced a value?
|
||||
if (name in UI.customSettings.mandatory) {
|
||||
val = UI.customSettings.mandatory[name];
|
||||
UI.forceSetting(name, val);
|
||||
}
|
||||
return val;
|
||||
},
|
||||
|
||||
|
|
@ -776,9 +788,12 @@ const UI = {
|
|||
let value = UI.getSetting(name);
|
||||
|
||||
const ctrl = document.getElementById('noVNC_setting_' + name);
|
||||
if (ctrl === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctrl.type === 'checkbox') {
|
||||
ctrl.checked = value;
|
||||
|
||||
} else if (typeof ctrl.options !== 'undefined') {
|
||||
for (let i = 0; i < ctrl.options.length; i += 1) {
|
||||
if (ctrl.options[i].value === value) {
|
||||
|
|
@ -811,7 +826,8 @@ const UI = {
|
|||
getSetting(name) {
|
||||
const ctrl = document.getElementById('noVNC_setting_' + name);
|
||||
let val = WebUtil.readSetting(name);
|
||||
if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') {
|
||||
if (typeof val !== 'undefined' && val !== null &&
|
||||
ctrl !== null && ctrl.type === 'checkbox') {
|
||||
if (val.toString().toLowerCase() in {'0': 1, 'no': 1, 'false': 1}) {
|
||||
val = false;
|
||||
} else {
|
||||
|
|
@ -826,14 +842,22 @@ const UI = {
|
|||
// disable the labels that belong to disabled input elements.
|
||||
disableSetting(name) {
|
||||
const ctrl = document.getElementById('noVNC_setting_' + name);
|
||||
ctrl.disabled = true;
|
||||
ctrl.label.classList.add('noVNC_disabled');
|
||||
if (ctrl !== null) {
|
||||
ctrl.disabled = true;
|
||||
if (ctrl.label !== undefined) {
|
||||
ctrl.label.classList.add('noVNC_disabled');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
enableSetting(name) {
|
||||
const ctrl = document.getElementById('noVNC_setting_' + name);
|
||||
ctrl.disabled = false;
|
||||
ctrl.label.classList.remove('noVNC_disabled');
|
||||
if (ctrl !== null) {
|
||||
ctrl.disabled = false;
|
||||
if (ctrl.label !== undefined) {
|
||||
ctrl.label.classList.remove('noVNC_disabled');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/* ------^-------
|
||||
|
|
@ -1067,7 +1091,7 @@ const UI = {
|
|||
const path = UI.getSetting('path');
|
||||
|
||||
if (typeof password === 'undefined') {
|
||||
password = WebUtil.getConfigVar('password');
|
||||
password = UI.getSetting('password');
|
||||
UI.reconnectPassword = password;
|
||||
}
|
||||
|
||||
|
|
@ -1077,28 +1101,36 @@ const UI = {
|
|||
|
||||
UI.hideStatus();
|
||||
|
||||
if (!host) {
|
||||
Log.Error("Can't connect when host is: " + host);
|
||||
UI.showStatus(_("Must set host"), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
UI.closeConnectPanel();
|
||||
|
||||
UI.updateVisualState('connecting');
|
||||
|
||||
let url;
|
||||
|
||||
url = UI.getSetting('encrypt') ? 'wss' : 'ws';
|
||||
if (host) {
|
||||
url = new URL("https://" + host);
|
||||
|
||||
url += '://' + host;
|
||||
if (port) {
|
||||
url += ':' + port;
|
||||
url.protocol = UI.getSetting('encrypt') ? 'wss:' : 'ws:';
|
||||
if (port) {
|
||||
url.port = port;
|
||||
}
|
||||
|
||||
// "./" is needed to force URL() to interpret the path-variable as
|
||||
// a path and not as an URL. This is relevant if for example path
|
||||
// starts with more than one "/", in which case it would be
|
||||
// interpreted as a host name instead.
|
||||
url = new URL("./" + path, url);
|
||||
} else {
|
||||
// Current (May 2024) browsers support relative WebSocket
|
||||
// URLs natively, but we need to support older browsers for
|
||||
// some time.
|
||||
url = new URL(path, location.href);
|
||||
url.protocol = (window.location.protocol === "https:") ? 'wss:' : 'ws:';
|
||||
}
|
||||
url += '/' + path;
|
||||
|
||||
try {
|
||||
UI.rfb = new RFB(document.getElementById('noVNC_container'), url,
|
||||
UI.rfb = new RFB(document.getElementById('noVNC_container'),
|
||||
url.href,
|
||||
{ shared: UI.getSetting('shared'),
|
||||
repeaterID: UI.getSetting('repeaterID'),
|
||||
credentials: { password: password } });
|
||||
|
|
@ -1801,7 +1833,7 @@ const UI = {
|
|||
},
|
||||
|
||||
bell(e) {
|
||||
if (WebUtil.getConfigVar('bell', 'on') === 'on') {
|
||||
if (UI.getSetting('bell') === 'on') {
|
||||
const promise = document.getElementById('noVNC_bell').play();
|
||||
// The standards disagree on the return value here
|
||||
if (promise) {
|
||||
|
|
@ -1832,10 +1864,4 @@ const UI = {
|
|||
*/
|
||||
};
|
||||
|
||||
// Set up translations
|
||||
const LINGUAS = ["cs", "de", "el", "es", "fr", "it", "ja", "ko", "nl", "pl", "pt_BR", "ru", "sv", "tr", "zh_CN", "zh_TW"];
|
||||
l10n.setup(LINGUAS, "app/locale/")
|
||||
.catch(err => Log.Error("Failed to load translations: " + err))
|
||||
.then(UI.prime);
|
||||
|
||||
export default UI;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
@ -27,7 +27,7 @@ export function initLogging(level) {
|
|||
// the url can be requested in the following way:
|
||||
// https://www.example.com#myqueryparam=myvalue&password=secretvalue
|
||||
//
|
||||
// Even Mixing public and non public parameters will work:
|
||||
// Even mixing public and non public parameters will work:
|
||||
// https://www.example.com?nonsecretparam=example.com#password=secretvalue
|
||||
export function getQueryVar(name, defVal) {
|
||||
"use strict";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2021 The noVNC Authors
|
||||
* Copyright (C) 2021 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2024 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 class H264Parser {
|
||||
constructor(data) {
|
||||
this._data = data;
|
||||
this._index = 0;
|
||||
this.profileIdc = null;
|
||||
this.constraintSet = null;
|
||||
this.levelIdc = null;
|
||||
}
|
||||
|
||||
_getStartSequenceLen(index) {
|
||||
let data = this._data;
|
||||
if (data[index + 0] == 0 && data[index + 1] == 0 && data[index + 2] == 0 && data[index + 3] == 1) {
|
||||
return 4;
|
||||
}
|
||||
if (data[index + 0] == 0 && data[index + 1] == 0 && data[index + 2] == 1) {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
_indexOfNextNalUnit(index) {
|
||||
let data = this._data;
|
||||
for (let i = index; i < data.length; ++i) {
|
||||
if (this._getStartSequenceLen(i) != 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
_parseSps(index) {
|
||||
this.profileIdc = this._data[index];
|
||||
this.constraintSet = this._data[index + 1];
|
||||
this.levelIdc = this._data[index + 2];
|
||||
}
|
||||
|
||||
_parseNalUnit(index) {
|
||||
const firstByte = this._data[index];
|
||||
if (firstByte & 0x80) {
|
||||
throw new Error('H264 parsing sanity check failed, forbidden zero bit is set');
|
||||
}
|
||||
const unitType = firstByte & 0x1f;
|
||||
|
||||
switch (unitType) {
|
||||
case 1: // coded slice, non-idr
|
||||
return { slice: true };
|
||||
case 5: // coded slice, idr
|
||||
return { slice: true, key: true };
|
||||
case 6: // sei
|
||||
return {};
|
||||
case 7: // sps
|
||||
this._parseSps(index + 1);
|
||||
return {};
|
||||
case 8: // pps
|
||||
return {};
|
||||
default:
|
||||
Log.Warn("Unhandled unit type: ", unitType);
|
||||
break;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
parse() {
|
||||
const startIndex = this._index;
|
||||
let isKey = false;
|
||||
|
||||
while (this._index < this._data.length) {
|
||||
const startSequenceLen = this._getStartSequenceLen(this._index);
|
||||
if (startSequenceLen == 0) {
|
||||
throw new Error('Invalid start sequence in bit stream');
|
||||
}
|
||||
|
||||
const { slice, key } = this._parseNalUnit(this._index + startSequenceLen);
|
||||
|
||||
let nextIndex = this._indexOfNextNalUnit(this._index + startSequenceLen);
|
||||
if (nextIndex == -1) {
|
||||
this._index = this._data.length;
|
||||
} else {
|
||||
this._index = nextIndex;
|
||||
}
|
||||
|
||||
if (key) {
|
||||
isKey = true;
|
||||
}
|
||||
if (slice) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (startIndex === this._index) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
frame: this._data.subarray(startIndex, this._index),
|
||||
key: isKey,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class H264Context {
|
||||
constructor(width, height) {
|
||||
this.lastUsed = 0;
|
||||
this._width = width;
|
||||
this._height = height;
|
||||
this._profileIdc = null;
|
||||
this._constraintSet = null;
|
||||
this._levelIdc = null;
|
||||
this._decoder = null;
|
||||
this._pendingFrames = [];
|
||||
}
|
||||
|
||||
_handleFrame(frame) {
|
||||
let pending = this._pendingFrames.shift();
|
||||
if (pending === undefined) {
|
||||
throw new Error("Pending frame queue empty when receiving frame from decoder");
|
||||
}
|
||||
|
||||
if (pending.timestamp != frame.timestamp) {
|
||||
throw new Error("Video frame timestamp mismatch. Expected " +
|
||||
frame.timestamp + " but but got " + pending.timestamp);
|
||||
}
|
||||
|
||||
pending.frame = frame;
|
||||
pending.ready = true;
|
||||
pending.resolve();
|
||||
|
||||
if (!pending.keep) {
|
||||
frame.close();
|
||||
}
|
||||
}
|
||||
|
||||
_handleError(e) {
|
||||
throw new Error("Failed to decode frame: " + e.message);
|
||||
}
|
||||
|
||||
_configureDecoder(profileIdc, constraintSet, levelIdc) {
|
||||
if (this._decoder === null || this._decoder.state === 'closed') {
|
||||
this._decoder = new VideoDecoder({
|
||||
output: frame => this._handleFrame(frame),
|
||||
error: e => this._handleError(e),
|
||||
});
|
||||
}
|
||||
const codec = 'avc1.' +
|
||||
profileIdc.toString(16).padStart(2, '0') +
|
||||
constraintSet.toString(16).padStart(2, '0') +
|
||||
levelIdc.toString(16).padStart(2, '0');
|
||||
this._decoder.configure({
|
||||
codec: codec,
|
||||
codedWidth: this._width,
|
||||
codedHeight: this._height,
|
||||
optimizeForLatency: true,
|
||||
});
|
||||
}
|
||||
|
||||
_preparePendingFrame(timestamp) {
|
||||
let pending = {
|
||||
timestamp: timestamp,
|
||||
promise: null,
|
||||
resolve: null,
|
||||
frame: null,
|
||||
ready: false,
|
||||
keep: false,
|
||||
};
|
||||
pending.promise = new Promise((resolve) => {
|
||||
pending.resolve = resolve;
|
||||
});
|
||||
this._pendingFrames.push(pending);
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
||||
decode(payload) {
|
||||
let parser = new H264Parser(payload);
|
||||
let result = null;
|
||||
|
||||
// Ideally, this timestamp should come from the server, but we'll just
|
||||
// approximate it instead.
|
||||
let timestamp = Math.round(window.performance.now() * 1e3);
|
||||
|
||||
while (true) {
|
||||
let encodedFrame = parser.parse();
|
||||
if (encodedFrame === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (parser.profileIdc !== null) {
|
||||
self._profileIdc = parser.profileIdc;
|
||||
self._constraintSet = parser.constraintSet;
|
||||
self._levelIdc = parser.levelIdc;
|
||||
}
|
||||
|
||||
if (this._decoder === null || this._decoder.state !== 'configured') {
|
||||
if (!encodedFrame.key) {
|
||||
Log.Warn("Missing key frame. Can't decode until one arrives");
|
||||
continue;
|
||||
}
|
||||
if (self._profileIdc === null) {
|
||||
Log.Warn('Cannot config decoder. Have not received SPS and PPS yet.');
|
||||
continue;
|
||||
}
|
||||
this._configureDecoder(self._profileIdc, self._constraintSet,
|
||||
self._levelIdc);
|
||||
}
|
||||
|
||||
result = this._preparePendingFrame(timestamp);
|
||||
|
||||
const chunk = new EncodedVideoChunk({
|
||||
timestamp: timestamp,
|
||||
type: encodedFrame.key ? 'key' : 'delta',
|
||||
data: encodedFrame.frame,
|
||||
});
|
||||
|
||||
try {
|
||||
this._decoder.decode(chunk);
|
||||
} catch (e) {
|
||||
Log.Warn("Failed to decode:", e);
|
||||
}
|
||||
}
|
||||
|
||||
// We only keep last frame of each payload
|
||||
if (result !== null) {
|
||||
result.keep = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export default class H264Decoder {
|
||||
constructor() {
|
||||
this._tick = 0;
|
||||
this._contexts = {};
|
||||
}
|
||||
|
||||
_contextId(x, y, width, height) {
|
||||
return [x, y, width, height].join(',');
|
||||
}
|
||||
|
||||
_findOldestContextId() {
|
||||
let oldestTick = Number.MAX_VALUE;
|
||||
let oldestKey = undefined;
|
||||
for (const [key, value] of Object.entries(this._contexts)) {
|
||||
if (value.lastUsed < oldestTick) {
|
||||
oldestTick = value.lastUsed;
|
||||
oldestKey = key;
|
||||
}
|
||||
}
|
||||
return oldestKey;
|
||||
}
|
||||
|
||||
_createContext(x, y, width, height) {
|
||||
const maxContexts = 64;
|
||||
if (Object.keys(this._contexts).length >= maxContexts) {
|
||||
let oldestContextId = this._findOldestContextId();
|
||||
delete this._contexts[oldestContextId];
|
||||
}
|
||||
let context = new H264Context(width, height);
|
||||
this._contexts[this._contextId(x, y, width, height)] = context;
|
||||
return context;
|
||||
}
|
||||
|
||||
_getContext(x, y, width, height) {
|
||||
let context = this._contexts[this._contextId(x, y, width, height)];
|
||||
return context !== undefined ? context : this._createContext(x, y, width, height);
|
||||
}
|
||||
|
||||
_resetContext(x, y, width, height) {
|
||||
delete this._contexts[this._contextId(x, y, width, height)];
|
||||
}
|
||||
|
||||
_resetAllContexts() {
|
||||
this._contexts = {};
|
||||
}
|
||||
|
||||
decodeRect(x, y, width, height, sock, display, depth) {
|
||||
const resetContextFlag = 1;
|
||||
const resetAllContextsFlag = 2;
|
||||
|
||||
if (sock.rQwait("h264 header", 8)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const length = sock.rQshift32();
|
||||
const flags = sock.rQshift32();
|
||||
|
||||
if (sock.rQwait("h264 payload", length, 8)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flags & resetAllContextsFlag) {
|
||||
this._resetAllContexts();
|
||||
} else if (flags & resetContextFlag) {
|
||||
this._resetContext(x, y, width, height);
|
||||
}
|
||||
|
||||
let context = this._getContext(x, y, width, height);
|
||||
context.lastUsed = this._tick++;
|
||||
|
||||
if (length !== 0) {
|
||||
let payload = sock.rQshiftBytes(length, false);
|
||||
let frame = context.decode(payload);
|
||||
if (frame !== null) {
|
||||
display.videoFrame(x, y, width, height, frame);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca)
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2024 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
import Inflator from "../inflator.js";
|
||||
|
||||
export default class ZlibDecoder {
|
||||
constructor() {
|
||||
this._zlib = new Inflator();
|
||||
this._length = 0;
|
||||
}
|
||||
|
||||
decodeRect(x, y, width, height, sock, display, depth) {
|
||||
if ((width === 0) || (height === 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this._length === 0) {
|
||||
if (sock.rQwait("ZLIB", 4)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._length = sock.rQshift32();
|
||||
}
|
||||
|
||||
if (sock.rQwait("ZLIB", this._length)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let data = new Uint8Array(sock.rQshiftBytes(this._length, false));
|
||||
this._length = 0;
|
||||
|
||||
this._zlib.setInput(data);
|
||||
data = this._zlib.inflate(width * height * 4);
|
||||
this._zlib.setInput(null);
|
||||
|
||||
// Max sure the image is fully opaque
|
||||
for (let i = 0; i < width * height; i++) {
|
||||
data[i * 4 + 3] = 255;
|
||||
}
|
||||
|
||||
display.blitImage(x, y, width, height, data, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2021 The noVNC Authors
|
||||
* Copyright (C) 2021 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2020 The noVNC Authors
|
||||
* Copyright (C) 2020 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
@ -380,6 +380,17 @@ export default class Display {
|
|||
});
|
||||
}
|
||||
|
||||
videoFrame(x, y, width, height, frame) {
|
||||
this._renderQPush({
|
||||
'type': 'frame',
|
||||
'frame': frame,
|
||||
'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,
|
||||
|
|
@ -406,9 +417,16 @@ export default class Display {
|
|||
}
|
||||
}
|
||||
|
||||
drawImage(img, x, y) {
|
||||
this._drawCtx.drawImage(img, x, y);
|
||||
this._damage(x, y, img.width, img.height);
|
||||
drawImage(img, ...args) {
|
||||
this._drawCtx.drawImage(img, ...args);
|
||||
|
||||
if (args.length <= 4) {
|
||||
const [x, y] = args;
|
||||
this._damage(x, y, img.width, img.height);
|
||||
} else {
|
||||
const [,, sw, sh, dx, dy] = args;
|
||||
this._damage(dx, dy, sw, sh);
|
||||
}
|
||||
}
|
||||
|
||||
autoscale(containerWidth, containerHeight) {
|
||||
|
|
@ -511,6 +529,35 @@ export default class Display {
|
|||
ready = false;
|
||||
}
|
||||
break;
|
||||
case 'frame':
|
||||
if (a.frame.ready) {
|
||||
// The encoded frame may be larger than the rect due to
|
||||
// limitations of the encoder, so we need to crop the
|
||||
// frame.
|
||||
let frame = a.frame.frame;
|
||||
if (frame.codedWidth < a.width || frame.codedHeight < a.height) {
|
||||
Log.Warn("Decoded video frame does not cover its full rectangle area. Expecting at least " +
|
||||
a.width + "x" + a.height + " but got " +
|
||||
frame.codedWidth + "x" + frame.codedHeight);
|
||||
}
|
||||
const sx = 0;
|
||||
const sy = 0;
|
||||
const sw = a.width;
|
||||
const sh = a.height;
|
||||
const dx = a.x;
|
||||
const dy = a.y;
|
||||
const dw = sw;
|
||||
const dh = sh;
|
||||
this.drawImage(frame, sx, sy, sw, sh, dx, dy, dw, dh);
|
||||
frame.close();
|
||||
} else {
|
||||
let display = this;
|
||||
a.frame.promise.then(() => {
|
||||
display._scanRenderQ();
|
||||
});
|
||||
ready = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
@ -11,10 +11,12 @@ export const encodings = {
|
|||
encodingCopyRect: 1,
|
||||
encodingRRE: 2,
|
||||
encodingHextile: 5,
|
||||
encodingZlib: 6,
|
||||
encodingTight: 7,
|
||||
encodingZRLE: 16,
|
||||
encodingTightPNG: -260,
|
||||
encodingJPEG: 21,
|
||||
encodingH264: 50,
|
||||
|
||||
pseudoEncodingQualityLevel9: -23,
|
||||
pseudoEncodingQualityLevel0: -32,
|
||||
|
|
@ -28,6 +30,7 @@ export const encodings = {
|
|||
pseudoEncodingXvp: -309,
|
||||
pseudoEncodingFence: -312,
|
||||
pseudoEncodingContinuousUpdates: -313,
|
||||
pseudoEncodingExtendedMouseButtons: -316,
|
||||
pseudoEncodingCompressLevel9: -247,
|
||||
pseudoEncodingCompressLevel0: -256,
|
||||
pseudoEncodingVMwareCursor: 0x574d5664,
|
||||
|
|
@ -40,10 +43,12 @@ export function encodingName(num) {
|
|||
case encodings.encodingCopyRect: return "CopyRect";
|
||||
case encodings.encodingRRE: return "RRE";
|
||||
case encodings.encodingHextile: return "Hextile";
|
||||
case encodings.encodingZlib: return "Zlib";
|
||||
case encodings.encodingTight: return "Tight";
|
||||
case encodings.encodingZRLE: return "ZRLE";
|
||||
case encodings.encodingTightPNG: return "TightPNG";
|
||||
case encodings.encodingJPEG: return "JPEG";
|
||||
case encodings.encodingH264: return "H.264";
|
||||
default: return "[unknown encoding " + num + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2020 The noVNC Authors
|
||||
* Copyright (C) 2020 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Copyright (C) 2018 The noVNC authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Copyright (C) 2018 The noVNC authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2020 The noVNC Authors
|
||||
* Copyright (C) 2020 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ export default class Keyboard {
|
|||
if ((code === "ControlLeft") && browser.isWindows() &&
|
||||
!("ControlLeft" in this._keyDownList)) {
|
||||
this._altGrArmed = true;
|
||||
this._altGrTimeout = setTimeout(this._handleAltGrTimeout.bind(this), 100);
|
||||
this._altGrTimeout = setTimeout(this._interruptAltGrSequence.bind(this), 100);
|
||||
this._altGrCtrlTime = e.timeStamp;
|
||||
return;
|
||||
}
|
||||
|
|
@ -218,11 +218,7 @@ export default class Keyboard {
|
|||
|
||||
// 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);
|
||||
}
|
||||
this._interruptAltGrSequence();
|
||||
|
||||
// See comment in _handleKeyDown()
|
||||
if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) {
|
||||
|
|
@ -249,14 +245,20 @@ export default class Keyboard {
|
|||
}
|
||||
}
|
||||
|
||||
_handleAltGrTimeout() {
|
||||
this._altGrArmed = false;
|
||||
clearTimeout(this._altGrTimeout);
|
||||
this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true);
|
||||
_interruptAltGrSequence() {
|
||||
if (this._altGrArmed) {
|
||||
this._altGrArmed = false;
|
||||
clearTimeout(this._altGrTimeout);
|
||||
this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true);
|
||||
}
|
||||
}
|
||||
|
||||
_allKeysUp() {
|
||||
Log.Debug(">> Keyboard.allKeysUp");
|
||||
|
||||
// Prevent control key being processed after losing focus.
|
||||
this._interruptAltGrSequence();
|
||||
|
||||
for (let code in this._keyDownList) {
|
||||
this._sendKeyEvent(this._keyDownList[code], code, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Copyright (C) 2018 The noVNC authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
|
|
|
|||
392
core/rfb.js
392
core/rfb.js
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2020 The noVNC Authors
|
||||
* Copyright (C) 2020 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
import { toUnsigned32bit, toSigned32bit } from './util/int.js';
|
||||
import * as Log from './util/logging.js';
|
||||
import { encodeUTF8, decodeUTF8 } from './util/strings.js';
|
||||
import { dragThreshold } from './util/browser.js';
|
||||
import { dragThreshold, supportsWebCodecsH264Decode } from './util/browser.js';
|
||||
import { clientToElement } from './util/element.js';
|
||||
import { setCapture } from './util/events.js';
|
||||
import EventTargetMixin from './util/eventtarget.js';
|
||||
|
|
@ -31,10 +31,12 @@ import RawDecoder from "./decoders/raw.js";
|
|||
import CopyRectDecoder from "./decoders/copyrect.js";
|
||||
import RREDecoder from "./decoders/rre.js";
|
||||
import HextileDecoder from "./decoders/hextile.js";
|
||||
import ZlibDecoder from './decoders/zlib.js';
|
||||
import TightDecoder from "./decoders/tight.js";
|
||||
import TightPNGDecoder from "./decoders/tightpng.js";
|
||||
import ZRLEDecoder from "./decoders/zrle.js";
|
||||
import JPEGDecoder from "./decoders/jpeg.js";
|
||||
import H264Decoder from "./decoders/h264.js";
|
||||
|
||||
// How many seconds to wait for a disconnect to finish
|
||||
const DISCONNECT_TIMEOUT = 3;
|
||||
|
|
@ -147,9 +149,13 @@ export default class RFB extends EventTargetMixin {
|
|||
this._supportsSetDesktopSize = false;
|
||||
this._screenID = 0;
|
||||
this._screenFlags = 0;
|
||||
this._pendingRemoteResize = false;
|
||||
this._lastResize = 0;
|
||||
|
||||
this._qemuExtKeyEventSupported = false;
|
||||
|
||||
this._extendedPointerEventSupported = false;
|
||||
|
||||
this._clipboardText = null;
|
||||
this._clipboardServerCapabilitiesActions = {};
|
||||
this._clipboardServerCapabilitiesFormats = {};
|
||||
|
|
@ -244,10 +250,12 @@ export default class RFB extends EventTargetMixin {
|
|||
this._decoders[encodings.encodingCopyRect] = new CopyRectDecoder();
|
||||
this._decoders[encodings.encodingRRE] = new RREDecoder();
|
||||
this._decoders[encodings.encodingHextile] = new HextileDecoder();
|
||||
this._decoders[encodings.encodingZlib] = new ZlibDecoder();
|
||||
this._decoders[encodings.encodingTight] = new TightDecoder();
|
||||
this._decoders[encodings.encodingTightPNG] = new TightPNGDecoder();
|
||||
this._decoders[encodings.encodingZRLE] = new ZRLEDecoder();
|
||||
this._decoders[encodings.encodingJPEG] = new JPEGDecoder();
|
||||
this._decoders[encodings.encodingH264] = new H264Decoder();
|
||||
|
||||
// NB: nothing that needs explicit teardown should be done
|
||||
// before this point, since this can throw an exception
|
||||
|
|
@ -294,10 +302,6 @@ export default class RFB extends EventTargetMixin {
|
|||
this._resizeSession = false;
|
||||
|
||||
this._showDotCursor = false;
|
||||
if (options.showDotCursor !== undefined) {
|
||||
Log.Warn("Specifying showDotCursor as a RFB constructor argument is deprecated");
|
||||
this._showDotCursor = options.showDotCursor;
|
||||
}
|
||||
|
||||
this._qualityLevel = 6;
|
||||
this._compressionLevel = 2;
|
||||
|
|
@ -719,6 +723,7 @@ export default class RFB extends EventTargetMixin {
|
|||
currentHeight == this._expectedClientHeight;
|
||||
}
|
||||
|
||||
// Handle browser window resizes
|
||||
_handleResize() {
|
||||
// Don't change anything if the client size is already as expected
|
||||
if (this._clientHasExpectedSize()) {
|
||||
|
|
@ -729,17 +734,12 @@ export default class RFB extends EventTargetMixin {
|
|||
window.requestAnimationFrame(() => {
|
||||
this._updateClip();
|
||||
this._updateScale();
|
||||
this._saveExpectedClientSize();
|
||||
});
|
||||
|
||||
if (this._resizeSession) {
|
||||
// Request changing the resolution of the remote display to
|
||||
// the size of the local browser viewport.
|
||||
|
||||
// In order to not send multiple requests before the browser-resize
|
||||
// is finished we wait 0.5 seconds before sending the request.
|
||||
clearTimeout(this._resizeTimeout);
|
||||
this._resizeTimeout = setTimeout(this._requestRemoteResize.bind(this), 500);
|
||||
}
|
||||
// Request changing the resolution of the remote display to
|
||||
// the size of the local browser viewport.
|
||||
this._requestRemoteResize();
|
||||
}
|
||||
|
||||
// Update state of clipping in Display object, and make sure the
|
||||
|
|
@ -789,16 +789,39 @@ export default class RFB extends EventTargetMixin {
|
|||
// Requests a change of remote desktop size. This message is an extension
|
||||
// and may only be sent if we have received an ExtendedDesktopSize message
|
||||
_requestRemoteResize() {
|
||||
clearTimeout(this._resizeTimeout);
|
||||
this._resizeTimeout = null;
|
||||
|
||||
if (!this._resizeSession || this._viewOnly ||
|
||||
!this._supportsSetDesktopSize) {
|
||||
if (!this._resizeSession) {
|
||||
return;
|
||||
}
|
||||
if (this._viewOnly) {
|
||||
return;
|
||||
}
|
||||
if (!this._supportsSetDesktopSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Rate limit to one pending resize at a time
|
||||
if (this._pendingRemoteResize) {
|
||||
return;
|
||||
}
|
||||
|
||||
// And no more than once every 100ms
|
||||
if ((Date.now() - this._lastResize) < 100) {
|
||||
clearTimeout(this._resizeTimeout);
|
||||
this._resizeTimeout = setTimeout(this._requestRemoteResize.bind(this),
|
||||
100 - (Date.now() - this._lastResize));
|
||||
return;
|
||||
}
|
||||
this._resizeTimeout = null;
|
||||
|
||||
const size = this._screenSize();
|
||||
|
||||
// Do we actually change anything?
|
||||
if (size.w === this._fbWidth && size.h === this._fbHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._pendingRemoteResize = true;
|
||||
this._lastResize = Date.now();
|
||||
RFB.messages.setDesktopSize(this._sock,
|
||||
Math.floor(size.w), Math.floor(size.h),
|
||||
this._screenID, this._screenFlags);
|
||||
|
|
@ -1035,6 +1058,36 @@ export default class RFB extends EventTargetMixin {
|
|||
this.sendKey(keysym, code, down);
|
||||
}
|
||||
|
||||
static _convertButtonMask(buttons) {
|
||||
/* The bits in MouseEvent.buttons property correspond
|
||||
* to the following mouse buttons:
|
||||
* 0: Left
|
||||
* 1: Right
|
||||
* 2: Middle
|
||||
* 3: Back
|
||||
* 4: Forward
|
||||
*
|
||||
* These bits needs to be converted to what they are defined as
|
||||
* in the RFB protocol.
|
||||
*/
|
||||
|
||||
const buttonMaskMap = {
|
||||
0: 1 << 0, // Left
|
||||
1: 1 << 2, // Right
|
||||
2: 1 << 1, // Middle
|
||||
3: 1 << 7, // Back
|
||||
4: 1 << 8, // Forward
|
||||
};
|
||||
|
||||
let bmask = 0;
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (buttons & (1 << i)) {
|
||||
bmask |= buttonMaskMap[i];
|
||||
}
|
||||
}
|
||||
return bmask;
|
||||
}
|
||||
|
||||
_handleMouse(ev) {
|
||||
this._sendPingMessage();
|
||||
/*
|
||||
|
|
@ -1065,80 +1118,75 @@ export default class RFB extends EventTargetMixin {
|
|||
let pos = clientToElement(ev.clientX, ev.clientY,
|
||||
this._canvas);
|
||||
|
||||
let bmask = RFB._convertButtonMask(ev.buttons);
|
||||
|
||||
let down = ev.type == 'mousedown';
|
||||
switch (ev.type) {
|
||||
case 'mousedown':
|
||||
setCapture(this._canvas);
|
||||
this._handleMouseButton(pos.x, pos.y,
|
||||
true, 1 << ev.button);
|
||||
break;
|
||||
case 'mouseup':
|
||||
this._handleMouseButton(pos.x, pos.y,
|
||||
false, 1 << ev.button);
|
||||
if (this.dragViewport) {
|
||||
if (down && !this._viewportDragging) {
|
||||
this._viewportDragging = true;
|
||||
this._viewportDragPos = {'x': pos.x, 'y': pos.y};
|
||||
this._viewportHasMoved = false;
|
||||
|
||||
this._flushMouseMoveTimer(pos.x, pos.y);
|
||||
|
||||
// Skip sending mouse events, instead save the current
|
||||
// mouse mask so we can send it later.
|
||||
this._mouseButtonMask = bmask;
|
||||
break;
|
||||
} else {
|
||||
this._viewportDragging = false;
|
||||
|
||||
// If we actually performed a drag then we are done
|
||||
// here and should not send any mouse events
|
||||
if (this._viewportHasMoved) {
|
||||
this._mouseButtonMask = bmask;
|
||||
break;
|
||||
}
|
||||
// Otherwise we treat this as a mouse click event.
|
||||
// Send the previously saved button mask, followed
|
||||
// by the current button mask at the end of this
|
||||
// function.
|
||||
this._sendMouse(pos.x, pos.y, this._mouseButtonMask);
|
||||
}
|
||||
}
|
||||
if (down) {
|
||||
setCapture(this._canvas);
|
||||
}
|
||||
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||
break;
|
||||
case 'mousemove':
|
||||
if (this._viewportDragging) {
|
||||
const deltaX = this._viewportDragPos.x - pos.x;
|
||||
const deltaY = this._viewportDragPos.y - pos.y;
|
||||
|
||||
if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold ||
|
||||
Math.abs(deltaY) > dragThreshold)) {
|
||||
this._viewportHasMoved = true;
|
||||
|
||||
this._viewportDragPos = {'x': pos.x, 'y': pos.y};
|
||||
this._display.viewportChangePos(deltaX, deltaY);
|
||||
}
|
||||
|
||||
// Skip sending mouse events
|
||||
break;
|
||||
}
|
||||
this._handleMouseMove(pos.x, pos.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_handleMouseButton(x, y, down, bmask) {
|
||||
if (this.dragViewport) {
|
||||
if (down && !this._viewportDragging) {
|
||||
this._viewportDragging = true;
|
||||
this._viewportDragPos = {'x': x, 'y': y};
|
||||
this._viewportHasMoved = false;
|
||||
|
||||
// Skip sending mouse events
|
||||
return;
|
||||
} else {
|
||||
this._viewportDragging = false;
|
||||
|
||||
// If we actually performed a drag then we are done
|
||||
// here and should not send any mouse events
|
||||
if (this._viewportHasMoved) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise we treat this as a mouse click event.
|
||||
// Send the button down event here, as the button up
|
||||
// event is sent at the end of this function.
|
||||
this._sendMouse(x, y, bmask);
|
||||
}
|
||||
}
|
||||
|
||||
_handleMouseButton(x, y, bmask) {
|
||||
// Flush waiting move event first
|
||||
if (this._mouseMoveTimer !== null) {
|
||||
clearTimeout(this._mouseMoveTimer);
|
||||
this._mouseMoveTimer = null;
|
||||
this._sendMouse(x, y, this._mouseButtonMask);
|
||||
}
|
||||
|
||||
if (down) {
|
||||
this._mouseButtonMask |= bmask;
|
||||
} else {
|
||||
this._mouseButtonMask &= ~bmask;
|
||||
}
|
||||
this._flushMouseMoveTimer(x, y);
|
||||
|
||||
this._mouseButtonMask = bmask;
|
||||
this._sendMouse(x, y, this._mouseButtonMask);
|
||||
}
|
||||
|
||||
_handleMouseMove(x, y) {
|
||||
if (this._viewportDragging) {
|
||||
const deltaX = this._viewportDragPos.x - x;
|
||||
const deltaY = this._viewportDragPos.y - y;
|
||||
|
||||
if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold ||
|
||||
Math.abs(deltaY) > dragThreshold)) {
|
||||
this._viewportHasMoved = true;
|
||||
|
||||
this._viewportDragPos = {'x': x, 'y': y};
|
||||
this._display.viewportChangePos(deltaX, deltaY);
|
||||
}
|
||||
|
||||
// Skip sending mouse events
|
||||
return;
|
||||
}
|
||||
|
||||
this._mousePos = { 'x': x, 'y': y };
|
||||
|
||||
// Limit many mouse move events to one every MOUSE_MOVE_DELAY ms
|
||||
|
|
@ -1168,8 +1216,20 @@ export default class RFB extends EventTargetMixin {
|
|||
if (this._rfbConnectionState !== 'connected') { return; }
|
||||
if (this._viewOnly) { return; } // View only, skip mouse events
|
||||
|
||||
RFB.messages.pointerEvent(this._sock, this._display.absX(x),
|
||||
this._display.absY(y), mask);
|
||||
// Highest bit in mask is never sent to the server
|
||||
if (mask & 0x8000) {
|
||||
throw new Error("Illegal mouse button mask (mask: " + mask + ")");
|
||||
}
|
||||
|
||||
let extendedMouseButtons = mask & 0x7f80;
|
||||
|
||||
if (this._extendedPointerEventSupported && extendedMouseButtons) {
|
||||
RFB.messages.extendedPointerEvent(this._sock, this._display.absX(x),
|
||||
this._display.absY(y), mask);
|
||||
} else {
|
||||
RFB.messages.pointerEvent(this._sock, this._display.absX(x),
|
||||
this._display.absY(y), mask);
|
||||
}
|
||||
}
|
||||
|
||||
_handleWheel(ev) {
|
||||
|
|
@ -1184,6 +1244,7 @@ export default class RFB extends EventTargetMixin {
|
|||
let pos = clientToElement(ev.clientX, ev.clientY,
|
||||
this._canvas);
|
||||
|
||||
let bmask = RFB._convertButtonMask(ev.buttons);
|
||||
let dX = ev.deltaX;
|
||||
let dY = ev.deltaY;
|
||||
|
||||
|
|
@ -1203,26 +1264,27 @@ export default class RFB extends EventTargetMixin {
|
|||
this._accumulatedWheelDeltaX += dX;
|
||||
this._accumulatedWheelDeltaY += dY;
|
||||
|
||||
|
||||
// Generate a mouse wheel step event when the accumulated delta
|
||||
// for one of the axes is large enough.
|
||||
if (Math.abs(this._accumulatedWheelDeltaX) >= WHEEL_STEP) {
|
||||
if (this._accumulatedWheelDeltaX < 0) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 1 << 5);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 1 << 5);
|
||||
this._handleMouseButton(pos.x, pos.y, bmask | 1 << 5);
|
||||
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||
} else if (this._accumulatedWheelDeltaX > 0) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 1 << 6);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 1 << 6);
|
||||
this._handleMouseButton(pos.x, pos.y, bmask | 1 << 6);
|
||||
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||
}
|
||||
|
||||
this._accumulatedWheelDeltaX = 0;
|
||||
}
|
||||
if (Math.abs(this._accumulatedWheelDeltaY) >= WHEEL_STEP) {
|
||||
if (this._accumulatedWheelDeltaY < 0) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 1 << 3);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 1 << 3);
|
||||
this._handleMouseButton(pos.x, pos.y, bmask | 1 << 3);
|
||||
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||
} else if (this._accumulatedWheelDeltaY > 0) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 1 << 4);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 1 << 4);
|
||||
this._handleMouseButton(pos.x, pos.y, bmask | 1 << 4);
|
||||
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||
}
|
||||
|
||||
this._accumulatedWheelDeltaY = 0;
|
||||
|
|
@ -1261,8 +1323,8 @@ export default class RFB extends EventTargetMixin {
|
|||
this._gestureLastTapTime = Date.now();
|
||||
|
||||
this._fakeMouseMove(this._gestureFirstDoubleTapEv, pos.x, pos.y);
|
||||
this._handleMouseButton(pos.x, pos.y, true, bmask);
|
||||
this._handleMouseButton(pos.x, pos.y, false, bmask);
|
||||
this._handleMouseButton(pos.x, pos.y, bmask);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||
}
|
||||
|
||||
_handleGesture(ev) {
|
||||
|
|
@ -1285,14 +1347,27 @@ export default class RFB extends EventTargetMixin {
|
|||
this._handleTapEvent(ev, 0x2);
|
||||
break;
|
||||
case 'drag':
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
this._handleMouseButton(pos.x, pos.y, true, 0x1);
|
||||
if (this.dragViewport) {
|
||||
this._viewportHasMoved = false;
|
||||
this._viewportDragging = true;
|
||||
this._viewportDragPos = {'x': pos.x, 'y': pos.y};
|
||||
} else {
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x1);
|
||||
}
|
||||
break;
|
||||
case 'longpress':
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
this._handleMouseButton(pos.x, pos.y, true, 0x4);
|
||||
if (this.dragViewport) {
|
||||
// If dragViewport is true, we need to wait to see
|
||||
// if we have dragged outside the threshold before
|
||||
// sending any events to the server.
|
||||
this._viewportHasMoved = false;
|
||||
this._viewportDragPos = {'x': pos.x, 'y': pos.y};
|
||||
} else {
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x4);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'twodrag':
|
||||
this._gestureLastMagnitudeX = ev.detail.magnitudeX;
|
||||
this._gestureLastMagnitudeY = ev.detail.magnitudeY;
|
||||
|
|
@ -1314,7 +1389,21 @@ export default class RFB extends EventTargetMixin {
|
|||
break;
|
||||
case 'drag':
|
||||
case 'longpress':
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
if (this.dragViewport) {
|
||||
this._viewportDragging = true;
|
||||
const deltaX = this._viewportDragPos.x - pos.x;
|
||||
const deltaY = this._viewportDragPos.y - pos.y;
|
||||
|
||||
if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold ||
|
||||
Math.abs(deltaY) > dragThreshold)) {
|
||||
this._viewportHasMoved = true;
|
||||
|
||||
this._viewportDragPos = {'x': pos.x, 'y': pos.y};
|
||||
this._display.viewportChangePos(deltaX, deltaY);
|
||||
}
|
||||
} else {
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
}
|
||||
break;
|
||||
case 'twodrag':
|
||||
// Always scroll in the same position.
|
||||
|
|
@ -1322,23 +1411,23 @@ export default class RFB extends EventTargetMixin {
|
|||
// every update.
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
while ((ev.detail.magnitudeY - this._gestureLastMagnitudeY) > GESTURE_SCRLSENS) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 0x8);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 0x8);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x8);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||
this._gestureLastMagnitudeY += GESTURE_SCRLSENS;
|
||||
}
|
||||
while ((ev.detail.magnitudeY - this._gestureLastMagnitudeY) < -GESTURE_SCRLSENS) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 0x10);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 0x10);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x10);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||
this._gestureLastMagnitudeY -= GESTURE_SCRLSENS;
|
||||
}
|
||||
while ((ev.detail.magnitudeX - this._gestureLastMagnitudeX) > GESTURE_SCRLSENS) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 0x20);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 0x20);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x20);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||
this._gestureLastMagnitudeX += GESTURE_SCRLSENS;
|
||||
}
|
||||
while ((ev.detail.magnitudeX - this._gestureLastMagnitudeX) < -GESTURE_SCRLSENS) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 0x40);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 0x40);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x40);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||
this._gestureLastMagnitudeX -= GESTURE_SCRLSENS;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1351,13 +1440,13 @@ export default class RFB extends EventTargetMixin {
|
|||
if (Math.abs(magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) {
|
||||
this._handleKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true);
|
||||
while ((magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 0x8);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 0x8);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x8);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||
this._gestureLastMagnitudeX += GESTURE_ZOOMSENS;
|
||||
}
|
||||
while ((magnitude - this._gestureLastMagnitudeX) < -GESTURE_ZOOMSENS) {
|
||||
this._handleMouseButton(pos.x, pos.y, true, 0x10);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 0x10);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x10);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||
this._gestureLastMagnitudeX -= GESTURE_ZOOMSENS;
|
||||
}
|
||||
}
|
||||
|
|
@ -1375,19 +1464,47 @@ export default class RFB extends EventTargetMixin {
|
|||
case 'twodrag':
|
||||
break;
|
||||
case 'drag':
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 0x1);
|
||||
if (this.dragViewport) {
|
||||
this._viewportDragging = false;
|
||||
} else {
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||
}
|
||||
break;
|
||||
case 'longpress':
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
this._handleMouseButton(pos.x, pos.y, false, 0x4);
|
||||
if (this._viewportHasMoved) {
|
||||
// We don't want to send any events if we have moved
|
||||
// our viewport
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.dragViewport && !this._viewportHasMoved) {
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
// If dragViewport is true, we need to wait to see
|
||||
// if we have dragged outside the threshold before
|
||||
// sending any events to the server.
|
||||
this._handleMouseButton(pos.x, pos.y, 0x4);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||
this._viewportDragging = false;
|
||||
} else {
|
||||
this._fakeMouseMove(ev, pos.x, pos.y);
|
||||
this._handleMouseButton(pos.x, pos.y, 0x0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Message Handlers
|
||||
_flushMouseMoveTimer(x, y) {
|
||||
if (this._mouseMoveTimer !== null) {
|
||||
clearTimeout(this._mouseMoveTimer);
|
||||
this._mouseMoveTimer = null;
|
||||
this._sendMouse(x, y, this._mouseButtonMask);
|
||||
}
|
||||
}
|
||||
|
||||
// Message handlers
|
||||
|
||||
_negotiateProtocolVersion() {
|
||||
if (this._sock.rQwait("version", 12)) {
|
||||
|
|
@ -2128,12 +2245,16 @@ export default class RFB extends EventTargetMixin {
|
|||
encs.push(encodings.encodingCopyRect);
|
||||
// Only supported with full depth support
|
||||
if (this._fbDepth == 24) {
|
||||
if (supportsWebCodecsH264Decode) {
|
||||
encs.push(encodings.encodingH264);
|
||||
}
|
||||
encs.push(encodings.encodingTight);
|
||||
encs.push(encodings.encodingTightPNG);
|
||||
encs.push(encodings.encodingZRLE);
|
||||
encs.push(encodings.encodingJPEG);
|
||||
encs.push(encodings.encodingHextile);
|
||||
encs.push(encodings.encodingRRE);
|
||||
encs.push(encodings.encodingZlib);
|
||||
}
|
||||
encs.push(encodings.encodingRaw);
|
||||
|
||||
|
|
@ -2151,6 +2272,7 @@ export default class RFB extends EventTargetMixin {
|
|||
encs.push(encodings.pseudoEncodingContinuousUpdates);
|
||||
encs.push(encodings.pseudoEncodingDesktopName);
|
||||
encs.push(encodings.pseudoEncodingExtendedClipboard);
|
||||
encs.push(encodings.pseudoEncodingExtendedMouseButtons);
|
||||
|
||||
if (this._fbDepth == 24) {
|
||||
encs.push(encodings.pseudoEncodingVMwareCursor);
|
||||
|
|
@ -2432,7 +2554,7 @@ export default class RFB extends EventTargetMixin {
|
|||
|
||||
switch (xvpMsg) {
|
||||
case 0: // XVP_FAIL
|
||||
Log.Error("XVP Operation Failed");
|
||||
Log.Error("XVP operation failed");
|
||||
break;
|
||||
case 1: // XVP_INIT
|
||||
this._rfbXvpVer = xvpVer;
|
||||
|
|
@ -2580,6 +2702,10 @@ export default class RFB extends EventTargetMixin {
|
|||
case encodings.pseudoEncodingExtendedDesktopSize:
|
||||
return this._handleExtendedDesktopSize();
|
||||
|
||||
case encodings.pseudoEncodingExtendedMouseButtons:
|
||||
this._extendedPointerEventSupported = true;
|
||||
return true;
|
||||
|
||||
case encodings.pseudoEncodingQEMULedEvent:
|
||||
return this._handleLedEvent();
|
||||
|
||||
|
|
@ -2761,7 +2887,7 @@ export default class RFB extends EventTargetMixin {
|
|||
}
|
||||
|
||||
_handleLedEvent() {
|
||||
if (this._sock.rQwait("LED Status", 1)) {
|
||||
if (this._sock.rQwait("LED status", 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2815,6 +2941,10 @@ export default class RFB extends EventTargetMixin {
|
|||
* 2 - another client requested the resize
|
||||
*/
|
||||
|
||||
if (this._FBU.x === 1) {
|
||||
this._pendingRemoteResize = false;
|
||||
}
|
||||
|
||||
// We need to handle errors when we requested the resize.
|
||||
if (this._FBU.x === 1 && this._FBU.y !== 0) {
|
||||
let msg = "";
|
||||
|
|
@ -2847,6 +2977,12 @@ export default class RFB extends EventTargetMixin {
|
|||
this._requestRemoteResize();
|
||||
}
|
||||
|
||||
if (this._FBU.x === 1 && this._FBU.y === 0) {
|
||||
// We might have resized again whilst waiting for the
|
||||
// previous request, so check if we are in sync
|
||||
this._requestRemoteResize();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2876,6 +3012,7 @@ export default class RFB extends EventTargetMixin {
|
|||
this._fbWidth, this._fbHeight);
|
||||
}
|
||||
|
||||
// Handle resize-messages from the server
|
||||
_resize(width, height) {
|
||||
this._fbWidth = width;
|
||||
this._fbHeight = height;
|
||||
|
|
@ -2988,6 +3125,10 @@ RFB.messages = {
|
|||
pointerEvent(sock, x, y, mask) {
|
||||
sock.sQpush8(5); // msg-type
|
||||
|
||||
// Marker bit must be set to 0, otherwise the server might
|
||||
// confuse the marker bit with the highest bit in a normal
|
||||
// PointerEvent message.
|
||||
mask = mask & 0x7f;
|
||||
sock.sQpush8(mask);
|
||||
|
||||
sock.sQpush16(x);
|
||||
|
|
@ -2996,6 +3137,27 @@ RFB.messages = {
|
|||
sock.flush();
|
||||
},
|
||||
|
||||
extendedPointerEvent(sock, x, y, mask) {
|
||||
sock.sQpush8(5); // msg-type
|
||||
|
||||
let higherBits = (mask >> 7) & 0xff;
|
||||
|
||||
// Bits 2-7 are reserved
|
||||
if (higherBits & 0xfc) {
|
||||
throw new Error("Invalid mouse button mask: " + mask);
|
||||
}
|
||||
|
||||
let lowerBits = mask & 0x7f;
|
||||
lowerBits |= 0x80; // Set marker bit to 1
|
||||
|
||||
sock.sQpush8(lowerBits);
|
||||
sock.sQpush16(x);
|
||||
sock.sQpush16(y);
|
||||
sock.sQpush8(higherBits);
|
||||
|
||||
sock.flush();
|
||||
},
|
||||
|
||||
// Used to build Notify and Request data.
|
||||
_buildExtendedClipboardFlags(actions, formats) {
|
||||
let data = new Uint8Array(4);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
@ -9,10 +9,11 @@
|
|||
*/
|
||||
|
||||
import * as Log from './logging.js';
|
||||
import Base64 from '../base64.js';
|
||||
|
||||
// Touch detection
|
||||
export let isTouchDevice = ('ontouchstart' in document.documentElement) ||
|
||||
// requried for Chrome debugger
|
||||
// required for Chrome debugger
|
||||
(document.ontouchstart !== undefined) ||
|
||||
// required for MS Surface
|
||||
(navigator.maxTouchPoints > 0) ||
|
||||
|
|
@ -70,6 +71,86 @@ try {
|
|||
}
|
||||
export const hasScrollbarGutter = _hasScrollbarGutter;
|
||||
|
||||
export let supportsWebCodecsH264Decode = false;
|
||||
|
||||
async function _checkWebCodecsH264DecodeSupport() {
|
||||
if (!('VideoDecoder' in window)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We'll need to make do with some placeholders here
|
||||
const config = {
|
||||
codec: 'avc1.42401f',
|
||||
codedWidth: 1920,
|
||||
codedHeight: 1080,
|
||||
optimizeForLatency: true,
|
||||
};
|
||||
|
||||
let support = await VideoDecoder.isConfigSupported(config);
|
||||
if (!support.supported) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Firefox incorrectly reports supports for H.264 under some
|
||||
// circumstances, so we need to actually test a real frame
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1932392
|
||||
|
||||
const data = new Uint8Array(Base64.decode(
|
||||
'AAAAAWdCwBTZnpuAgICgAAADACAAAAZB4oVNAAAAAWjJYyyAAAABBgX//4Hc' +
|
||||
'Rem95tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTY0IHIzMTA4IDMxZTE5Zjkg' +
|
||||
'LSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDIz' +
|
||||
'IC0gaHR0cDovL3d3dy52aWRlb2xhbi5vcmcveDI2NC5odG1sIC0gb3B0aW9u' +
|
||||
'czogY2FiYWM9MCByZWY9NSBkZWJsb2NrPTE6MDowIGFuYWx5c2U9MHgxOjB4' +
|
||||
'MTExIG1lPWhleCBzdWJtZT04IHBzeT0xIHBzeV9yZD0xLjAwOjAuMDAgbWl4' +
|
||||
'ZWRfcmVmPTEgbWVfcmFuZ2U9MTYgY2hyb21hX21lPTEgdHJlbGxpcz0yIDh4' +
|
||||
'OGRjdD0wIGNxbT0wIGRlYWR6b25lPTIxLDExIGZhc3RfcHNraXA9MSBjaHJv' +
|
||||
'bWFfcXBfb2Zmc2V0PS0yIHRocmVhZHM9MSBsb29rYWhlYWRfdGhyZWFkcz0x' +
|
||||
'IHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9' +
|
||||
'MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVz' +
|
||||
'PTAgd2VpZ2h0cD0wIGtleWludD1pbmZpbml0ZSBrZXlpbnRfbWluPTI1IHNj' +
|
||||
'ZW5lY3V0PTQwIGludHJhX3JlZnJlc2g9MCByY19sb29rYWhlYWQ9NTAgcmM9' +
|
||||
'YWJyIG1idHJlZT0xIGJpdHJhdGU9NDAwIHJhdGV0b2w9MS4wIHFjb21wPTAu' +
|
||||
'NjAgcXBtaW49MCBxcG1heD02OSBxcHN0ZXA9NCBpcF9yYXRpbz0xLjQwIGFx' +
|
||||
'PTE6MS4wMACAAAABZYiEBrxmKAAPVccAAS044AA5DRJMnkycJk4TPw=='));
|
||||
|
||||
let gotframe = false;
|
||||
let error = null;
|
||||
|
||||
let decoder = new VideoDecoder({
|
||||
output: (frame) => { gotframe = true; frame.close(); },
|
||||
error: (e) => { error = e; },
|
||||
});
|
||||
let chunk = new EncodedVideoChunk({
|
||||
timestamp: 0,
|
||||
type: 'key',
|
||||
data: data,
|
||||
});
|
||||
|
||||
decoder.configure(config);
|
||||
decoder.decode(chunk);
|
||||
try {
|
||||
await decoder.flush();
|
||||
} catch (e) {
|
||||
// Firefox incorrectly throws an exception here
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1932566
|
||||
error = e;
|
||||
}
|
||||
|
||||
// Firefox fails to deliver the error on Windows, so we need to
|
||||
// check if we got a frame instead
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1932579
|
||||
if (!gotframe) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (error !== null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
supportsWebCodecsH264Decode = await _checkWebCodecsH264DecodeSupport();
|
||||
|
||||
/*
|
||||
* The functions for detection of platforms and browsers below are exported
|
||||
* but the use of these should be minimized as much as possible.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2020 The noVNC Authors
|
||||
* Copyright (C) 2020 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Copyright (C) 2018 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2020 The noVNC Authors
|
||||
* Copyright (C) 2020 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* See README.md for usage and integration instructions.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Websock: high-performance buffering wrapper
|
||||
* Copyright (C) 2019 The noVNC Authors
|
||||
* Copyright (C) 2019 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*
|
||||
* Websock is similar to the standard WebSocket / RTCDataChannel object
|
||||
|
|
@ -70,7 +70,7 @@ export default class Websock {
|
|||
};
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
// Getters and setters
|
||||
|
||||
get readyState() {
|
||||
let subState;
|
||||
|
|
@ -94,7 +94,7 @@ export default class Websock {
|
|||
return "unknown";
|
||||
}
|
||||
|
||||
// Receive Queue
|
||||
// Receive queue
|
||||
rQpeek8() {
|
||||
return this._rQ[this._rQi];
|
||||
}
|
||||
|
|
@ -173,7 +173,7 @@ export default class Websock {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Send Queue
|
||||
// Send queue
|
||||
|
||||
sQpush8(num) {
|
||||
this._sQensureSpace(1);
|
||||
|
|
@ -208,7 +208,7 @@ export default class Websock {
|
|||
chunkSize = bytes.length - offset;
|
||||
}
|
||||
|
||||
this._sQ.set(bytes.subarray(offset, chunkSize), this._sQlen);
|
||||
this._sQ.set(bytes.subarray(offset, offset + chunkSize), this._sQlen);
|
||||
this._sQlen += chunkSize;
|
||||
offset += chunkSize;
|
||||
}
|
||||
|
|
@ -227,7 +227,7 @@ export default class Websock {
|
|||
}
|
||||
}
|
||||
|
||||
// Event Handlers
|
||||
// Event handlers
|
||||
off(evt) {
|
||||
this._eventHandlers[evt] = () => {};
|
||||
}
|
||||
|
|
@ -325,7 +325,7 @@ export default class Websock {
|
|||
if (this._rQbufferSize > MAX_RQ_GROW_SIZE) {
|
||||
this._rQbufferSize = MAX_RQ_GROW_SIZE;
|
||||
if (this._rQbufferSize - (this._rQlen - this._rQi) < minFit) {
|
||||
throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
|
||||
throw new Error("Receive queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# 1. Internal Modules
|
||||
# 1. Internal modules
|
||||
|
||||
The noVNC client is composed of several internal modules that handle
|
||||
rendering, input, networking, etc. Each of the modules is designed to
|
||||
|
|
@ -9,7 +9,7 @@ stable, and this documentation is not maintained as well as the
|
|||
official external API.
|
||||
|
||||
|
||||
## 1.1 Module List
|
||||
## 1.1 Module list
|
||||
|
||||
* __Keyboard__ (core/input/keyboard.js): Keyboard input event handler with
|
||||
non-US keyboard support. Translates keyDown and keyUp events to X11
|
||||
|
|
@ -32,9 +32,9 @@ callback event name, and the callback function.
|
|||
|
||||
## 2. Modules
|
||||
|
||||
## 2.1 Keyboard Module
|
||||
## 2.1 Keyboard module
|
||||
|
||||
### 2.1.1 Configuration Attributes
|
||||
### 2.1.1 Configuration attributes
|
||||
|
||||
None
|
||||
|
||||
|
|
@ -52,9 +52,9 @@ None
|
|||
| onkeypress | (keysym, code, down) | Handler for key press/release
|
||||
|
||||
|
||||
## 2.2 Display Module
|
||||
## 2.2 Display module
|
||||
|
||||
### 2.2.1 Configuration Attributes
|
||||
### 2.2.1 Configuration attributes
|
||||
|
||||
| name | type | mode | default | description
|
||||
| ------------ | ----- | ---- | ------- | ------------
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Embedding and Deploying noVNC Application
|
||||
# Embedding and deploying noVNC application
|
||||
|
||||
This document describes how to embed and deploy the noVNC application, which
|
||||
includes settings and a full user interface. If you are looking for
|
||||
|
|
@ -25,8 +25,27 @@ server and setting up a WebSocket proxy to the VNC server.
|
|||
|
||||
## Parameters
|
||||
|
||||
The noVNC application can be controlled by including certain settings in the
|
||||
query string. Currently the following options are available:
|
||||
The noVNC application can be controlled via a number of settings. All of
|
||||
them are available in the UI for the user to change, but they can also
|
||||
be set via other means:
|
||||
|
||||
* Via the URL, either as a query parameter:
|
||||
|
||||
```
|
||||
https://www.example.com/vnc.html?reconnect=0&shared=1
|
||||
```
|
||||
|
||||
or as a fragment:
|
||||
|
||||
```
|
||||
https://www.example.com/vnc.html#reconnect=0&shared=1
|
||||
```
|
||||
|
||||
The latter might be preferred as it is not sent to the server.
|
||||
|
||||
* Via the files `defaults.json` and `mandatory.json`
|
||||
|
||||
Currently, the following options are available:
|
||||
|
||||
* `autoconnect` - Automatically connect as soon as the page has finished
|
||||
loading.
|
||||
|
|
@ -37,13 +56,18 @@ query string. Currently the following options are available:
|
|||
* `reconnect_delay` - How long to wait in milliseconds before attempting to
|
||||
reconnect.
|
||||
|
||||
* `host` - The WebSocket host to connect to.
|
||||
* `host` - The WebSocket host to connect to. This setting is deprecated
|
||||
in favor of specifying a URL in `path`.
|
||||
|
||||
* `port` - The WebSocket port to connect to.
|
||||
* `port` - The WebSocket port to connect to. This setting is deprecated
|
||||
in favor of specifying a URL in `path`.
|
||||
|
||||
* `encrypt` - If TLS should be used for the WebSocket connection.
|
||||
* `encrypt` - If TLS should be used for the WebSocket connection. This
|
||||
setting is deprecated in favor of specifying a URL in `path`.
|
||||
|
||||
* `path` - The WebSocket path to use.
|
||||
* `path` - The WebSocket URL to use. It can be either an absolute URL,
|
||||
or a URL relative vnc.html. If `host` is specified, then `path` will
|
||||
be interpreted as the path component in the URL instead.
|
||||
|
||||
* `password` - The password sent to the server, if required.
|
||||
|
||||
|
|
@ -71,8 +95,8 @@ query string. Currently the following options are available:
|
|||
* `logging` - The console log level. Can be one of `error`, `warn`, `info` or
|
||||
`debug`.
|
||||
|
||||
## HTTP Serving Considerations
|
||||
### Browser Cache Issue
|
||||
## HTTP serving considerations
|
||||
### Browser cache issue
|
||||
|
||||
If you serve noVNC files using a web server that provides an ETag header, and
|
||||
include any options in the query string, a nasty browser cache issue can bite
|
||||
|
|
@ -84,7 +108,7 @@ to always revalidate cached files using conditional requests. The correct
|
|||
semantics are achieved via the (confusingly named) `Cache-Control: no-cache`
|
||||
header that needs to be provided in the web server responses.
|
||||
|
||||
### Example Server Configurations
|
||||
### Example server configurations
|
||||
|
||||
Apache:
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ noVNC includes a small example application called `vnc_lite.html`. This does
|
|||
not make use of all the features of noVNC, but is a good start to see how to
|
||||
do things.
|
||||
|
||||
## Conversion of Modules
|
||||
## Conversion of modules
|
||||
|
||||
noVNC is written using ECMAScript 6 modules. This is not supported by older
|
||||
versions of Node.js. To use noVNC with those older versions of Node.js the
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ provides a cut-and-paste URL to go to.
|
|||
active connections
|
||||
|
||||
.SH AUTHOR
|
||||
The noVNC Authors
|
||||
The noVNC authors
|
||||
https://github.com/novnc/noVNC
|
||||
|
||||
.SH SEE ALSO
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ export default [
|
|||
js.configs.recommended,
|
||||
{
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
ecmaVersion: 2022,
|
||||
sourceType: "module",
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.es2020,
|
||||
...globals.es2022,
|
||||
}
|
||||
},
|
||||
ignores: ["**/xtscancodes.js"],
|
||||
|
|
@ -79,7 +79,7 @@ export default [
|
|||
...globals.node,
|
||||
...globals.mocha,
|
||||
sinon: false,
|
||||
chai: false,
|
||||
expect: false,
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
|
|
|
|||
|
|
@ -27,15 +27,22 @@ module.exports = (config) => {
|
|||
|
||||
// frameworks to use
|
||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
||||
frameworks: ['mocha', 'sinon-chai'],
|
||||
frameworks: ['mocha'],
|
||||
|
||||
// list of files / patterns to load in the browser (loaded in order)
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
// node modules
|
||||
{ pattern: 'node_modules/chai/**', included: false },
|
||||
{ pattern: 'node_modules/sinon/**', included: false },
|
||||
{ pattern: 'node_modules/sinon-chai/**', included: false },
|
||||
// modules to test
|
||||
{ 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' },
|
||||
// tests
|
||||
{ pattern: 'tests/test.*.js', type: 'module' },
|
||||
// test support files
|
||||
{ pattern: 'tests/fake.*.js', included: false, type: 'module' },
|
||||
{ pattern: 'tests/assertions.js', type: 'module' },
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@novnc/novnc",
|
||||
"version": "1.5.0",
|
||||
"version": "1.6.0",
|
||||
"description": "An HTML5 VNC client",
|
||||
"browser": "lib/rfb",
|
||||
"directories": {
|
||||
|
|
@ -55,10 +55,8 @@
|
|||
"karma-mocha-reporter": "latest",
|
||||
"karma-safari-launcher": "latest",
|
||||
"karma-script-launcher": "latest",
|
||||
"karma-sinon-chai": "latest",
|
||||
"mocha": "latest",
|
||||
"node-getopt": "latest",
|
||||
"po2json": "latest",
|
||||
"pofile": "latest",
|
||||
"sinon": "latest",
|
||||
"sinon-chai": "latest"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ update-js: $(JSONFILES)
|
|||
|
||||
update-pot:
|
||||
xgettext --output=noVNC.js.pot \
|
||||
--copyright-holder="The noVNC Authors" \
|
||||
--copyright-holder="The noVNC authors" \
|
||||
--package-name="noVNC" \
|
||||
--package-version="$(VERSION)" \
|
||||
--msgid-bugs-address="novnc@googlegroups.com" \
|
||||
|
|
|
|||
26
po/cs.po
26
po/cs.po
|
|
@ -1,5 +1,5 @@
|
|||
# Czech translations for noVNC package.
|
||||
# Copyright (C) 2018 The noVNC Authors
|
||||
# Copyright (C) 2018 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Petr <petr@kle.cz>, 2018.
|
||||
#
|
||||
|
|
@ -78,7 +78,7 @@ msgid "Hide/Show the control bar"
|
|||
msgstr "Skrýt/zobrazit ovládací panel"
|
||||
|
||||
#: ../vnc.html:101
|
||||
msgid "Move/Drag Viewport"
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "Přesunout/přetáhnout výřez"
|
||||
|
||||
#: ../vnc.html:101
|
||||
|
|
@ -110,7 +110,7 @@ msgid "Keyboard"
|
|||
msgstr "Klávesnice"
|
||||
|
||||
#: ../vnc.html:119
|
||||
msgid "Show Keyboard"
|
||||
msgid "Show keyboard"
|
||||
msgstr "Zobrazit klávesnici"
|
||||
|
||||
#: ../vnc.html:126
|
||||
|
|
@ -118,7 +118,7 @@ msgid "Extra keys"
|
|||
msgstr "Extra klávesy"
|
||||
|
||||
#: ../vnc.html:126
|
||||
msgid "Show Extra Keys"
|
||||
msgid "Show extra keys"
|
||||
msgstr "Zobrazit extra klávesy"
|
||||
|
||||
#: ../vnc.html:131
|
||||
|
|
@ -202,19 +202,19 @@ msgid "Settings"
|
|||
msgstr "Nastavení"
|
||||
|
||||
#: ../vnc.html:197
|
||||
msgid "Shared Mode"
|
||||
msgid "Shared mode"
|
||||
msgstr "Sdílený režim"
|
||||
|
||||
#: ../vnc.html:200
|
||||
msgid "View Only"
|
||||
msgid "View only"
|
||||
msgstr "Pouze prohlížení"
|
||||
|
||||
#: ../vnc.html:204
|
||||
msgid "Clip to Window"
|
||||
msgid "Clip to window"
|
||||
msgstr "Přizpůsobit oknu"
|
||||
|
||||
#: ../vnc.html:207
|
||||
msgid "Scaling Mode:"
|
||||
msgid "Scaling mode:"
|
||||
msgstr "Přizpůsobení velikosti"
|
||||
|
||||
#: ../vnc.html:209
|
||||
|
|
@ -222,11 +222,11 @@ msgid "None"
|
|||
msgstr "Žádné"
|
||||
|
||||
#: ../vnc.html:210
|
||||
msgid "Local Scaling"
|
||||
msgid "Local scaling"
|
||||
msgstr "Místní"
|
||||
|
||||
#: ../vnc.html:211
|
||||
msgid "Remote Resizing"
|
||||
msgid "Remote resizing"
|
||||
msgstr "Vzdálené"
|
||||
|
||||
#: ../vnc.html:216
|
||||
|
|
@ -258,15 +258,15 @@ msgid "Path:"
|
|||
msgstr "Cesta"
|
||||
|
||||
#: ../vnc.html:244
|
||||
msgid "Automatic Reconnect"
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "Automatická obnova připojení"
|
||||
|
||||
#: ../vnc.html:247
|
||||
msgid "Reconnect Delay (ms):"
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "Zpoždění připojení (ms)"
|
||||
|
||||
#: ../vnc.html:252
|
||||
msgid "Show Dot when No Cursor"
|
||||
msgid "Show dot when no cursor"
|
||||
msgstr "Tečka místo chybějícího kurzoru myši"
|
||||
|
||||
#: ../vnc.html:257
|
||||
|
|
|
|||
24
po/de.po
24
po/de.po
|
|
@ -1,6 +1,6 @@
|
|||
# German translations for noVNC package
|
||||
# German translation for noVNC.
|
||||
# Copyright (C) 2018 The noVNC Authors
|
||||
# Copyright (C) 2018 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Loek Janssen <loekjanssen@gmail.com>, 2016.
|
||||
#
|
||||
|
|
@ -76,7 +76,7 @@ msgid "Hide/Show the control bar"
|
|||
msgstr "Kontrollleiste verstecken/anzeigen"
|
||||
|
||||
#: ../vnc.html:106
|
||||
msgid "Move/Drag Viewport"
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "Ansichtsfenster verschieben/ziehen"
|
||||
|
||||
#: ../vnc.html:106
|
||||
|
|
@ -108,7 +108,7 @@ msgid "Keyboard"
|
|||
msgstr "Tastatur"
|
||||
|
||||
#: ../vnc.html:124
|
||||
msgid "Show Keyboard"
|
||||
msgid "Show keyboard"
|
||||
msgstr "Tastatur anzeigen"
|
||||
|
||||
#: ../vnc.html:131
|
||||
|
|
@ -116,7 +116,7 @@ msgid "Extra keys"
|
|||
msgstr "Zusatztasten"
|
||||
|
||||
#: ../vnc.html:131
|
||||
msgid "Show Extra Keys"
|
||||
msgid "Show extra keys"
|
||||
msgstr "Zusatztasten anzeigen"
|
||||
|
||||
#: ../vnc.html:136
|
||||
|
|
@ -200,19 +200,19 @@ msgid "Settings"
|
|||
msgstr "Einstellungen"
|
||||
|
||||
#: ../vnc.html:202
|
||||
msgid "Shared Mode"
|
||||
msgid "Shared mode"
|
||||
msgstr "Geteilter Modus"
|
||||
|
||||
#: ../vnc.html:205
|
||||
msgid "View Only"
|
||||
msgid "View only"
|
||||
msgstr "Nur betrachten"
|
||||
|
||||
#: ../vnc.html:209
|
||||
msgid "Clip to Window"
|
||||
msgid "Clip to window"
|
||||
msgstr "Auf Fenster begrenzen"
|
||||
|
||||
#: ../vnc.html:212
|
||||
msgid "Scaling Mode:"
|
||||
msgid "Scaling mode:"
|
||||
msgstr "Skalierungsmodus:"
|
||||
|
||||
#: ../vnc.html:214
|
||||
|
|
@ -220,11 +220,11 @@ msgid "None"
|
|||
msgstr "Keiner"
|
||||
|
||||
#: ../vnc.html:215
|
||||
msgid "Local Scaling"
|
||||
msgid "Local scaling"
|
||||
msgstr "Lokales skalieren"
|
||||
|
||||
#: ../vnc.html:216
|
||||
msgid "Remote Resizing"
|
||||
msgid "Remote resizing"
|
||||
msgstr "Serverseitiges skalieren"
|
||||
|
||||
#: ../vnc.html:221
|
||||
|
|
@ -256,11 +256,11 @@ msgid "Path:"
|
|||
msgstr "Pfad:"
|
||||
|
||||
#: ../vnc.html:249
|
||||
msgid "Automatic Reconnect"
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "Automatisch wiederverbinden"
|
||||
|
||||
#: ../vnc.html:252
|
||||
msgid "Reconnect Delay (ms):"
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "Wiederverbindungsverzögerung (ms):"
|
||||
|
||||
#: ../vnc.html:258
|
||||
|
|
|
|||
2
po/el.po
2
po/el.po
|
|
@ -1,5 +1,5 @@
|
|||
# Greek translations for noVNC package.
|
||||
# Copyright (C) 2018 The noVNC Authors
|
||||
# Copyright (C) 2018 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Giannis Kosmas <kosmasgiannis@gmail.com>, 2016.
|
||||
#
|
||||
|
|
|
|||
18
po/es.po
18
po/es.po
|
|
@ -1,6 +1,6 @@
|
|||
# Spanish translations for noVNC package
|
||||
# Traducciones al español para el paquete noVNC.
|
||||
# Copyright (C) 2018 The noVNC Authors
|
||||
# Copyright (C) 2018 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Juanjo Diaz <juanjo.diazmo@gmail.com>, 2018.
|
||||
# Adrian Scillato <ascillato@gmail.com>, 2021.
|
||||
|
|
@ -64,7 +64,7 @@ msgid "Hide/Show the control bar"
|
|||
msgstr "Ocultar/Mostrar la barra de control"
|
||||
|
||||
#: ../vnc.html:106
|
||||
msgid "Move/Drag Viewport"
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "Mover/Arrastrar la ventana"
|
||||
|
||||
#: ../vnc.html:106
|
||||
|
|
@ -96,7 +96,7 @@ msgid "Keyboard"
|
|||
msgstr "Teclado"
|
||||
|
||||
#: ../vnc.html:124
|
||||
msgid "Show Keyboard"
|
||||
msgid "Show keyboard"
|
||||
msgstr "Mostrar teclado"
|
||||
|
||||
#: ../vnc.html:131
|
||||
|
|
@ -196,15 +196,15 @@ msgid "Shared Mode"
|
|||
msgstr "Modo Compartido"
|
||||
|
||||
#: ../vnc.html:205
|
||||
msgid "View Only"
|
||||
msgid "View only"
|
||||
msgstr "Solo visualización"
|
||||
|
||||
#: ../vnc.html:209
|
||||
msgid "Clip to Window"
|
||||
msgid "Clip to window"
|
||||
msgstr "Recortar al tamaño de la ventana"
|
||||
|
||||
#: ../vnc.html:212
|
||||
msgid "Scaling Mode:"
|
||||
msgid "Scaling mode:"
|
||||
msgstr "Modo de escalado:"
|
||||
|
||||
#: ../vnc.html:214
|
||||
|
|
@ -220,7 +220,7 @@ msgid "Local Downscaling"
|
|||
msgstr "Reducción de escala local"
|
||||
|
||||
#: ../vnc.html:217
|
||||
msgid "Remote Resizing"
|
||||
msgid "Remote resizing"
|
||||
msgstr "Cambio de tamaño remoto"
|
||||
|
||||
#: ../vnc.html:222
|
||||
|
|
@ -252,11 +252,11 @@ msgid "Path:"
|
|||
msgstr "Ruta:"
|
||||
|
||||
#: ../vnc.html:254
|
||||
msgid "Automatic Reconnect"
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "Reconexión automática"
|
||||
|
||||
#: ../vnc.html:257
|
||||
msgid "Reconnect Delay (ms):"
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "Retraso en la reconexión (ms):"
|
||||
|
||||
#: ../vnc.html:263
|
||||
|
|
|
|||
243
po/fr.po
243
po/fr.po
|
|
@ -1,300 +1,345 @@
|
|||
# French translations for noVNC package
|
||||
# Traductions françaises du paquet noVNC.
|
||||
# Copyright (C) 2021 The noVNC Authors
|
||||
# Copyright (C) 2021 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Jose <jose.matsuda@canada.ca>, 2021.
|
||||
# Lowxorx <lowxorx@lahan.fr>, 2022.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: noVNC 1.2.0\n"
|
||||
"Project-Id-Version: noVNC 1.6.0\n"
|
||||
"Report-Msgid-Bugs-To: novnc@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2020-07-03 16:11+0200\n"
|
||||
"PO-Revision-Date: 2022-04-25 23:40+0200\n"
|
||||
"Last-Translator: Lowxorx <lowxorx@lahan.fr>\n"
|
||||
"POT-Creation-Date: 2025-02-14 10:14+0100\n"
|
||||
"PO-Revision-Date: 2025-02-17 10:04+0100\n"
|
||||
"Last-Translator: Martine & Philippe <martineke.breizh@gmail.com>\n"
|
||||
"Language-Team: French\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Poedit 3.5\n"
|
||||
|
||||
#: ../app/ui.js:394
|
||||
#: ../app/ui.js:84
|
||||
msgid ""
|
||||
"Running without HTTPS is not recommended, crashes or other issues are likely."
|
||||
msgstr ""
|
||||
"Lancer sans HTTPS n'est pas recommandé, crashs ou autres problèmes en vue."
|
||||
|
||||
#: ../app/ui.js:413
|
||||
msgid "Connecting..."
|
||||
msgstr "En cours de connexion..."
|
||||
|
||||
#: ../app/ui.js:401
|
||||
#: ../app/ui.js:420
|
||||
msgid "Disconnecting..."
|
||||
msgstr "Déconnexion en cours..."
|
||||
|
||||
#: ../app/ui.js:407
|
||||
#: ../app/ui.js:426
|
||||
msgid "Reconnecting..."
|
||||
msgstr "Reconnexion en cours..."
|
||||
|
||||
#: ../app/ui.js:412
|
||||
#: ../app/ui.js:431
|
||||
msgid "Internal error"
|
||||
msgstr "Erreur interne"
|
||||
|
||||
#: ../app/ui.js:1008
|
||||
msgid "Must set host"
|
||||
msgstr "Doit définir l'hôte"
|
||||
#: ../app/ui.js:1079
|
||||
msgid "Failed to connect to server: "
|
||||
msgstr "Échec de connexion au serveur "
|
||||
|
||||
#: ../app/ui.js:1090
|
||||
#: ../app/ui.js:1145
|
||||
msgid "Connected (encrypted) to "
|
||||
msgstr "Connecté (chiffré) à "
|
||||
|
||||
#: ../app/ui.js:1092
|
||||
#: ../app/ui.js:1147
|
||||
msgid "Connected (unencrypted) to "
|
||||
msgstr "Connecté (non chiffré) à "
|
||||
|
||||
#: ../app/ui.js:1115
|
||||
#: ../app/ui.js:1170
|
||||
msgid "Something went wrong, connection is closed"
|
||||
msgstr "Quelque chose s'est mal passé, la connexion a été fermée"
|
||||
|
||||
#: ../app/ui.js:1118
|
||||
#: ../app/ui.js:1173
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "Échec de connexion au serveur"
|
||||
|
||||
#: ../app/ui.js:1128
|
||||
#: ../app/ui.js:1185
|
||||
msgid "Disconnected"
|
||||
msgstr "Déconnecté"
|
||||
|
||||
#: ../app/ui.js:1143
|
||||
#: ../app/ui.js:1200
|
||||
msgid "New connection has been rejected with reason: "
|
||||
msgstr "Une nouvelle connexion a été rejetée avec motif : "
|
||||
|
||||
#: ../app/ui.js:1146
|
||||
#: ../app/ui.js:1203
|
||||
msgid "New connection has been rejected"
|
||||
msgstr "Une nouvelle connexion a été rejetée"
|
||||
|
||||
#: ../app/ui.js:1181
|
||||
#: ../app/ui.js:1269
|
||||
msgid "Credentials are required"
|
||||
msgstr "Les identifiants sont requis"
|
||||
|
||||
#: ../vnc.html:74
|
||||
#: ../vnc.html:106
|
||||
msgid "noVNC encountered an error:"
|
||||
msgstr "noVNC a rencontré une erreur :"
|
||||
|
||||
#: ../vnc.html:84
|
||||
#: ../vnc.html:116
|
||||
msgid "Hide/Show the control bar"
|
||||
msgstr "Masquer/Afficher la barre de contrôle"
|
||||
|
||||
#: ../vnc.html:91
|
||||
#: ../vnc.html:125
|
||||
msgid "Drag"
|
||||
msgstr "Faire glisser"
|
||||
|
||||
#: ../vnc.html:91
|
||||
msgid "Move/Drag Viewport"
|
||||
msgstr "Déplacer/faire glisser le Viewport"
|
||||
#: ../vnc.html:125
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "Déplacer la fenêtre de visualisation"
|
||||
|
||||
#: ../vnc.html:97
|
||||
#: ../vnc.html:131
|
||||
msgid "Keyboard"
|
||||
msgstr "Clavier"
|
||||
|
||||
#: ../vnc.html:97
|
||||
msgid "Show Keyboard"
|
||||
#: ../vnc.html:131
|
||||
msgid "Show keyboard"
|
||||
msgstr "Afficher le clavier"
|
||||
|
||||
#: ../vnc.html:102
|
||||
#: ../vnc.html:136
|
||||
msgid "Extra keys"
|
||||
msgstr "Touches supplémentaires"
|
||||
|
||||
#: ../vnc.html:102
|
||||
msgid "Show Extra Keys"
|
||||
#: ../vnc.html:136
|
||||
msgid "Show extra keys"
|
||||
msgstr "Afficher les touches supplémentaires"
|
||||
|
||||
#: ../vnc.html:107
|
||||
#: ../vnc.html:141
|
||||
msgid "Ctrl"
|
||||
msgstr "Ctrl"
|
||||
|
||||
#: ../vnc.html:107
|
||||
#: ../vnc.html:141
|
||||
msgid "Toggle Ctrl"
|
||||
msgstr "Basculer Ctrl"
|
||||
|
||||
#: ../vnc.html:110
|
||||
#: ../vnc.html:144
|
||||
msgid "Alt"
|
||||
msgstr "Alt"
|
||||
|
||||
#: ../vnc.html:110
|
||||
#: ../vnc.html:144
|
||||
msgid "Toggle Alt"
|
||||
msgstr "Basculer Alt"
|
||||
|
||||
#: ../vnc.html:113
|
||||
#: ../vnc.html:147
|
||||
msgid "Toggle Windows"
|
||||
msgstr "Basculer Windows"
|
||||
|
||||
#: ../vnc.html:113
|
||||
#: ../vnc.html:147
|
||||
msgid "Windows"
|
||||
msgstr "Windows"
|
||||
msgstr "Fenêtre"
|
||||
|
||||
#: ../vnc.html:116
|
||||
#: ../vnc.html:150
|
||||
msgid "Send Tab"
|
||||
msgstr "Envoyer l'onglet"
|
||||
msgstr "Envoyer Tab"
|
||||
|
||||
#: ../vnc.html:116
|
||||
#: ../vnc.html:150
|
||||
msgid "Tab"
|
||||
msgstr "l'onglet"
|
||||
msgstr "Tabulation"
|
||||
|
||||
#: ../vnc.html:119
|
||||
#: ../vnc.html:153
|
||||
msgid "Esc"
|
||||
msgstr "Esc"
|
||||
|
||||
#: ../vnc.html:119
|
||||
#: ../vnc.html:153
|
||||
msgid "Send Escape"
|
||||
msgstr "Envoyer Escape"
|
||||
|
||||
#: ../vnc.html:122
|
||||
#: ../vnc.html:156
|
||||
msgid "Ctrl+Alt+Del"
|
||||
msgstr "Ctrl+Alt+Del"
|
||||
|
||||
#: ../vnc.html:122
|
||||
#: ../vnc.html:156
|
||||
msgid "Send Ctrl-Alt-Del"
|
||||
msgstr "Envoyer Ctrl-Alt-Del"
|
||||
|
||||
#: ../vnc.html:129
|
||||
#: ../vnc.html:163
|
||||
msgid "Shutdown/Reboot"
|
||||
msgstr "Arrêter/Redémarrer"
|
||||
|
||||
#: ../vnc.html:129
|
||||
#: ../vnc.html:163
|
||||
msgid "Shutdown/Reboot..."
|
||||
msgstr "Arrêter/Redémarrer..."
|
||||
|
||||
#: ../vnc.html:135
|
||||
#: ../vnc.html:169
|
||||
msgid "Power"
|
||||
msgstr "Alimentation"
|
||||
|
||||
#: ../vnc.html:137
|
||||
#: ../vnc.html:171
|
||||
msgid "Shutdown"
|
||||
msgstr "Arrêter"
|
||||
|
||||
#: ../vnc.html:138
|
||||
#: ../vnc.html:172
|
||||
msgid "Reboot"
|
||||
msgstr "Redémarrer"
|
||||
|
||||
#: ../vnc.html:139
|
||||
#: ../vnc.html:173
|
||||
msgid "Reset"
|
||||
msgstr "Réinitialiser"
|
||||
|
||||
#: ../vnc.html:144 ../vnc.html:150
|
||||
#: ../vnc.html:178 ../vnc.html:184
|
||||
msgid "Clipboard"
|
||||
msgstr "Presse-papiers"
|
||||
|
||||
#: ../vnc.html:154
|
||||
msgid "Clear"
|
||||
msgstr "Effacer"
|
||||
#: ../vnc.html:186
|
||||
msgid "Edit clipboard content in the textarea below."
|
||||
msgstr "Editer le contenu du presse-papier dans la zone ci-dessous."
|
||||
|
||||
#: ../vnc.html:160
|
||||
msgid "Fullscreen"
|
||||
#: ../vnc.html:194
|
||||
msgid "Full screen"
|
||||
msgstr "Plein écran"
|
||||
|
||||
#: ../vnc.html:165 ../vnc.html:172
|
||||
#: ../vnc.html:199 ../vnc.html:205
|
||||
msgid "Settings"
|
||||
msgstr "Paramètres"
|
||||
|
||||
#: ../vnc.html:175
|
||||
msgid "Shared Mode"
|
||||
#: ../vnc.html:211
|
||||
msgid "Shared mode"
|
||||
msgstr "Mode partagé"
|
||||
|
||||
#: ../vnc.html:178
|
||||
msgid "View Only"
|
||||
#: ../vnc.html:218
|
||||
msgid "View only"
|
||||
msgstr "Afficher uniquement"
|
||||
|
||||
#: ../vnc.html:182
|
||||
msgid "Clip to Window"
|
||||
msgstr "Clip à fenêtre"
|
||||
#: ../vnc.html:226
|
||||
msgid "Clip to window"
|
||||
msgstr "Ajuster à la fenêtre"
|
||||
|
||||
#: ../vnc.html:185
|
||||
msgid "Scaling Mode:"
|
||||
#: ../vnc.html:231
|
||||
msgid "Scaling mode:"
|
||||
msgstr "Mode mise à l'échelle :"
|
||||
|
||||
#: ../vnc.html:187
|
||||
#: ../vnc.html:233
|
||||
msgid "None"
|
||||
msgstr "Aucun"
|
||||
|
||||
#: ../vnc.html:188
|
||||
msgid "Local Scaling"
|
||||
#: ../vnc.html:234
|
||||
msgid "Local scaling"
|
||||
msgstr "Mise à l'échelle locale"
|
||||
|
||||
#: ../vnc.html:189
|
||||
msgid "Remote Resizing"
|
||||
#: ../vnc.html:235
|
||||
msgid "Remote resizing"
|
||||
msgstr "Redimensionnement à distance"
|
||||
|
||||
#: ../vnc.html:194
|
||||
#: ../vnc.html:240
|
||||
msgid "Advanced"
|
||||
msgstr "Avancé"
|
||||
|
||||
#: ../vnc.html:197
|
||||
#: ../vnc.html:243
|
||||
msgid "Quality:"
|
||||
msgstr "Qualité :"
|
||||
|
||||
#: ../vnc.html:201
|
||||
#: ../vnc.html:247
|
||||
msgid "Compression level:"
|
||||
msgstr "Niveau de compression :"
|
||||
|
||||
#: ../vnc.html:206
|
||||
#: ../vnc.html:252
|
||||
msgid "Repeater ID:"
|
||||
msgstr "ID Répéteur :"
|
||||
|
||||
#: ../vnc.html:210
|
||||
#: ../vnc.html:256
|
||||
msgid "WebSocket"
|
||||
msgstr "WebSocket"
|
||||
|
||||
#: ../vnc.html:213
|
||||
#: ../vnc.html:261
|
||||
msgid "Encrypt"
|
||||
msgstr "Chiffrer"
|
||||
|
||||
#: ../vnc.html:216
|
||||
#: ../vnc.html:266
|
||||
msgid "Host:"
|
||||
msgstr "Hôte :"
|
||||
|
||||
#: ../vnc.html:220
|
||||
#: ../vnc.html:270
|
||||
msgid "Port:"
|
||||
msgstr "Port :"
|
||||
|
||||
#: ../vnc.html:224
|
||||
#: ../vnc.html:274
|
||||
msgid "Path:"
|
||||
msgstr "Chemin :"
|
||||
|
||||
#: ../vnc.html:231
|
||||
msgid "Automatic Reconnect"
|
||||
msgstr "Reconnecter automatiquemen"
|
||||
#: ../vnc.html:283
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "Reconnecter automatiquement"
|
||||
|
||||
#: ../vnc.html:234
|
||||
msgid "Reconnect Delay (ms):"
|
||||
#: ../vnc.html:288
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "Délai de reconnexion (ms) :"
|
||||
|
||||
#: ../vnc.html:239
|
||||
msgid "Show Dot when No Cursor"
|
||||
#: ../vnc.html:295
|
||||
msgid "Show dot when no cursor"
|
||||
msgstr "Afficher le point lorsqu'il n'y a pas de curseur"
|
||||
|
||||
#: ../vnc.html:244
|
||||
#: ../vnc.html:302
|
||||
msgid "Logging:"
|
||||
msgstr "Se connecter :"
|
||||
|
||||
#: ../vnc.html:253
|
||||
#: ../vnc.html:311
|
||||
msgid "Version:"
|
||||
msgstr "Version :"
|
||||
|
||||
#: ../vnc.html:261
|
||||
#: ../vnc.html:319
|
||||
msgid "Disconnect"
|
||||
msgstr "Déconnecter"
|
||||
|
||||
#: ../vnc.html:280
|
||||
#: ../vnc.html:342
|
||||
msgid "Connect"
|
||||
msgstr "Connecter"
|
||||
|
||||
#: ../vnc.html:290
|
||||
#: ../vnc.html:351
|
||||
msgid "Server identity"
|
||||
msgstr "Identité du serveur"
|
||||
|
||||
#: ../vnc.html:354
|
||||
msgid "The server has provided the following identifying information:"
|
||||
msgstr "Le serveur a fourni l'identification suivante :"
|
||||
|
||||
#: ../vnc.html:357
|
||||
msgid "Fingerprint:"
|
||||
msgstr "Empreinte digitale :"
|
||||
|
||||
#: ../vnc.html:361
|
||||
msgid ""
|
||||
"Please verify that the information is correct and press \"Approve\". "
|
||||
"Otherwise press \"Reject\"."
|
||||
msgstr ""
|
||||
"SVP, verifiez que l'information est correcte et pressez \"Accepter\". Sinon "
|
||||
"pressez \"Refuser\"."
|
||||
|
||||
#: ../vnc.html:366
|
||||
msgid "Approve"
|
||||
msgstr "Accepter"
|
||||
|
||||
#: ../vnc.html:367
|
||||
msgid "Reject"
|
||||
msgstr "Refuser"
|
||||
|
||||
#: ../vnc.html:375
|
||||
msgid "Credentials"
|
||||
msgstr "Envoyer les identifiants"
|
||||
|
||||
#: ../vnc.html:379
|
||||
msgid "Username:"
|
||||
msgstr "Nom d'utilisateur :"
|
||||
|
||||
#: ../vnc.html:294
|
||||
#: ../vnc.html:383
|
||||
msgid "Password:"
|
||||
msgstr "Mot de passe :"
|
||||
|
||||
#: ../vnc.html:298
|
||||
msgid "Send Credentials"
|
||||
#: ../vnc.html:387
|
||||
msgid "Send credentials"
|
||||
msgstr "Envoyer les identifiants"
|
||||
|
||||
#: ../vnc.html:308
|
||||
#: ../vnc.html:396
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
#~ msgid "Must set host"
|
||||
#~ msgstr "Doit définir l'hôte"
|
||||
|
||||
#~ msgid "Clear"
|
||||
#~ msgstr "Effacer"
|
||||
|
|
|
|||
12
po/it.po
12
po/it.po
|
|
@ -1,6 +1,6 @@
|
|||
# Italian translations for noVNC
|
||||
# Traduzione italiana di noVNC
|
||||
# Copyright (C) 2022 The noVNC Authors
|
||||
# Copyright (C) 2022 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Fabio Fantoni <fabio.fantoni@m2r.biz>, 2022.
|
||||
#
|
||||
|
|
@ -84,7 +84,7 @@ msgid "Drag"
|
|||
msgstr ""
|
||||
|
||||
#: ../vnc.html:78
|
||||
msgid "Move/Drag Viewport"
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:84
|
||||
|
|
@ -92,7 +92,7 @@ msgid "Keyboard"
|
|||
msgstr "Tastiera"
|
||||
|
||||
#: ../vnc.html:84
|
||||
msgid "Show Keyboard"
|
||||
msgid "Show keyboard"
|
||||
msgstr "Mostra tastiera"
|
||||
|
||||
#: ../vnc.html:89
|
||||
|
|
@ -192,7 +192,7 @@ msgid "Settings"
|
|||
msgstr "Impostazioni"
|
||||
|
||||
#: ../vnc.html:162
|
||||
msgid "Shared Mode"
|
||||
msgid "Shared mode"
|
||||
msgstr "Modalità condivisa"
|
||||
|
||||
#: ../vnc.html:165
|
||||
|
|
@ -200,11 +200,11 @@ msgid "View Only"
|
|||
msgstr "Sola Visualizzazione"
|
||||
|
||||
#: ../vnc.html:169
|
||||
msgid "Clip to Window"
|
||||
msgid "Clip to window"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:172
|
||||
msgid "Scaling Mode:"
|
||||
msgid "Scaling mode:"
|
||||
msgstr "Modalità di ridimensionamento:"
|
||||
|
||||
#: ../vnc.html:174
|
||||
|
|
|
|||
227
po/ja.po
227
po/ja.po
|
|
@ -1,15 +1,15 @@
|
|||
# Japanese translations for noVNC package
|
||||
# noVNC パッケージに対する日訳
|
||||
# Copyright (C) 2019 The noVNC Authors
|
||||
# Copyright (C) 2019-2024 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# nnn1590 <nnn1590@nnn1590.org>, 2019-2020.
|
||||
# nnn1590 <nnn1590@nnn1590.org>, 2019-2024.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: noVNC 1.1.0\n"
|
||||
"Project-Id-Version: noVNC 1.5.0\n"
|
||||
"Report-Msgid-Bugs-To: novnc@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2022-12-27 15:24+0100\n"
|
||||
"PO-Revision-Date: 2023-03-21 12:42+0900\n"
|
||||
"POT-Creation-Date: 2024-06-03 14:10+0200\n"
|
||||
"PO-Revision-Date: 2024-12-14 15:22+0900\n"
|
||||
"Last-Translator: nnn1590 <nnn1590@nnn1590.org>\n"
|
||||
"Language-Team: Japanese\n"
|
||||
"Language: ja\n"
|
||||
|
|
@ -20,8 +20,11 @@ msgstr ""
|
|||
"X-Generator: Poedit 2.3\n"
|
||||
|
||||
#: ../app/ui.js:69
|
||||
msgid "HTTPS is required for full functionality"
|
||||
msgstr "すべての機能を使用するにはHTTPS接続が必要です"
|
||||
msgid ""
|
||||
"Running without HTTPS is not recommended, crashes or other issues are likely."
|
||||
msgstr ""
|
||||
"HTTPS接続なしで実行することは推奨されません。クラッシュしたりその他の問題が発"
|
||||
"生したりする可能性があります。"
|
||||
|
||||
#: ../app/ui.js:410
|
||||
msgid "Connecting..."
|
||||
|
|
@ -43,321 +46,297 @@ msgstr "内部エラー"
|
|||
msgid "Must set host"
|
||||
msgstr "ホストを設定する必要があります"
|
||||
|
||||
#: ../app/ui.js:1110
|
||||
#: ../app/ui.js:1052
|
||||
msgid "Failed to connect to server: "
|
||||
msgstr "サーバーへの接続に失敗しました: "
|
||||
|
||||
#: ../app/ui.js:1118
|
||||
msgid "Connected (encrypted) to "
|
||||
msgstr "接続しました (暗号化済み): "
|
||||
|
||||
#: ../app/ui.js:1112
|
||||
#: ../app/ui.js:1120
|
||||
msgid "Connected (unencrypted) to "
|
||||
msgstr "接続しました (暗号化されていません): "
|
||||
|
||||
#: ../app/ui.js:1135
|
||||
#: ../app/ui.js:1143
|
||||
msgid "Something went wrong, connection is closed"
|
||||
msgstr "何らかの問題で、接続が閉じられました"
|
||||
msgstr "問題が発生したため、接続が閉じられました"
|
||||
|
||||
#: ../app/ui.js:1138
|
||||
#: ../app/ui.js:1146
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "サーバーへの接続に失敗しました"
|
||||
|
||||
#: ../app/ui.js:1150
|
||||
#: ../app/ui.js:1158
|
||||
msgid "Disconnected"
|
||||
msgstr "切断しました"
|
||||
|
||||
#: ../app/ui.js:1165
|
||||
#: ../app/ui.js:1173
|
||||
msgid "New connection has been rejected with reason: "
|
||||
msgstr "新規接続は次の理由で拒否されました: "
|
||||
|
||||
#: ../app/ui.js:1168
|
||||
#: ../app/ui.js:1176
|
||||
msgid "New connection has been rejected"
|
||||
msgstr "新規接続は拒否されました"
|
||||
|
||||
#: ../app/ui.js:1234
|
||||
#: ../app/ui.js:1242
|
||||
msgid "Credentials are required"
|
||||
msgstr "資格情報が必要です"
|
||||
|
||||
#: ../vnc.html:57
|
||||
#: ../vnc.html:55
|
||||
msgid "noVNC encountered an error:"
|
||||
msgstr "noVNC でエラーが発生しました:"
|
||||
|
||||
#: ../vnc.html:67
|
||||
#: ../vnc.html:65
|
||||
msgid "Hide/Show the control bar"
|
||||
msgstr "コントロールバーを隠す/表示する"
|
||||
|
||||
#: ../vnc.html:76
|
||||
#: ../vnc.html:74
|
||||
msgid "Drag"
|
||||
msgstr "ドラッグ"
|
||||
|
||||
#: ../vnc.html:76
|
||||
msgid "Move/Drag Viewport"
|
||||
#: ../vnc.html:74
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "ビューポートを移動/ドラッグ"
|
||||
|
||||
#: ../vnc.html:82
|
||||
#: ../vnc.html:80
|
||||
msgid "Keyboard"
|
||||
msgstr "キーボード"
|
||||
|
||||
#: ../vnc.html:82
|
||||
msgid "Show Keyboard"
|
||||
#: ../vnc.html:80
|
||||
msgid "Show keyboard"
|
||||
msgstr "キーボードを表示"
|
||||
|
||||
#: ../vnc.html:87
|
||||
#: ../vnc.html:85
|
||||
msgid "Extra keys"
|
||||
msgstr "追加キー"
|
||||
|
||||
#: ../vnc.html:87
|
||||
msgid "Show Extra Keys"
|
||||
#: ../vnc.html:85
|
||||
msgid "Show extra keys"
|
||||
msgstr "追加キーを表示"
|
||||
|
||||
#: ../vnc.html:92
|
||||
#: ../vnc.html:90
|
||||
msgid "Ctrl"
|
||||
msgstr "Ctrl"
|
||||
|
||||
#: ../vnc.html:92
|
||||
#: ../vnc.html:90
|
||||
msgid "Toggle Ctrl"
|
||||
msgstr "Ctrl キーをトグル"
|
||||
|
||||
#: ../vnc.html:95
|
||||
#: ../vnc.html:93
|
||||
msgid "Alt"
|
||||
msgstr "Alt"
|
||||
|
||||
#: ../vnc.html:95
|
||||
#: ../vnc.html:93
|
||||
msgid "Toggle Alt"
|
||||
msgstr "Alt キーをトグル"
|
||||
|
||||
#: ../vnc.html:98
|
||||
#: ../vnc.html:96
|
||||
msgid "Toggle Windows"
|
||||
msgstr "Windows キーをトグル"
|
||||
|
||||
#: ../vnc.html:98
|
||||
#: ../vnc.html:96
|
||||
msgid "Windows"
|
||||
msgstr "Windows"
|
||||
|
||||
#: ../vnc.html:101
|
||||
#: ../vnc.html:99
|
||||
msgid "Send Tab"
|
||||
msgstr "Tab キーを送信"
|
||||
|
||||
#: ../vnc.html:101
|
||||
#: ../vnc.html:99
|
||||
msgid "Tab"
|
||||
msgstr "Tab"
|
||||
|
||||
#: ../vnc.html:104
|
||||
#: ../vnc.html:102
|
||||
msgid "Esc"
|
||||
msgstr "Esc"
|
||||
|
||||
#: ../vnc.html:104
|
||||
#: ../vnc.html:102
|
||||
msgid "Send Escape"
|
||||
msgstr "Escape キーを送信"
|
||||
|
||||
#: ../vnc.html:107
|
||||
#: ../vnc.html:105
|
||||
msgid "Ctrl+Alt+Del"
|
||||
msgstr "Ctrl+Alt+Del"
|
||||
|
||||
#: ../vnc.html:107
|
||||
#: ../vnc.html:105
|
||||
msgid "Send Ctrl-Alt-Del"
|
||||
msgstr "Ctrl-Alt-Del を送信"
|
||||
|
||||
#: ../vnc.html:114
|
||||
#: ../vnc.html:112
|
||||
msgid "Shutdown/Reboot"
|
||||
msgstr "シャットダウン/再起動"
|
||||
|
||||
#: ../vnc.html:114
|
||||
#: ../vnc.html:112
|
||||
msgid "Shutdown/Reboot..."
|
||||
msgstr "シャットダウン/再起動..."
|
||||
|
||||
#: ../vnc.html:120
|
||||
#: ../vnc.html:118
|
||||
msgid "Power"
|
||||
msgstr "電源"
|
||||
|
||||
#: ../vnc.html:122
|
||||
#: ../vnc.html:120
|
||||
msgid "Shutdown"
|
||||
msgstr "シャットダウン"
|
||||
|
||||
#: ../vnc.html:123
|
||||
#: ../vnc.html:121
|
||||
msgid "Reboot"
|
||||
msgstr "再起動"
|
||||
|
||||
#: ../vnc.html:124
|
||||
#: ../vnc.html:122
|
||||
msgid "Reset"
|
||||
msgstr "リセット"
|
||||
|
||||
#: ../vnc.html:129 ../vnc.html:135
|
||||
#: ../vnc.html:127 ../vnc.html:133
|
||||
msgid "Clipboard"
|
||||
msgstr "クリップボード"
|
||||
|
||||
#: ../vnc.html:137
|
||||
#: ../vnc.html:135
|
||||
msgid "Edit clipboard content in the textarea below."
|
||||
msgstr "以下の入力欄からクリップボードの内容を編集できます。"
|
||||
|
||||
#: ../vnc.html:145
|
||||
msgid "Full Screen"
|
||||
#: ../vnc.html:143
|
||||
msgid "Full screen"
|
||||
msgstr "全画面表示"
|
||||
|
||||
#: ../vnc.html:150 ../vnc.html:156
|
||||
#: ../vnc.html:148 ../vnc.html:154
|
||||
msgid "Settings"
|
||||
msgstr "設定"
|
||||
|
||||
#: ../vnc.html:160
|
||||
msgid "Shared Mode"
|
||||
#: ../vnc.html:158
|
||||
msgid "Shared mode"
|
||||
msgstr "共有モード"
|
||||
|
||||
#: ../vnc.html:163
|
||||
msgid "View Only"
|
||||
#: ../vnc.html:161
|
||||
msgid "View only"
|
||||
msgstr "表示専用"
|
||||
|
||||
#: ../vnc.html:167
|
||||
msgid "Clip to Window"
|
||||
#: ../vnc.html:165
|
||||
msgid "Clip to window"
|
||||
msgstr "ウィンドウにクリップ"
|
||||
|
||||
#: ../vnc.html:170
|
||||
msgid "Scaling Mode:"
|
||||
#: ../vnc.html:168
|
||||
msgid "Scaling mode:"
|
||||
msgstr "スケーリングモード:"
|
||||
|
||||
#: ../vnc.html:172
|
||||
#: ../vnc.html:170
|
||||
msgid "None"
|
||||
msgstr "なし"
|
||||
|
||||
#: ../vnc.html:173
|
||||
msgid "Local Scaling"
|
||||
msgstr "ローカルスケーリング"
|
||||
#: ../vnc.html:171
|
||||
msgid "Local scaling"
|
||||
msgstr "ローカルでスケーリング"
|
||||
|
||||
#: ../vnc.html:174
|
||||
msgid "Remote Resizing"
|
||||
#: ../vnc.html:172
|
||||
msgid "Remote resizing"
|
||||
msgstr "リモートでリサイズ"
|
||||
|
||||
#: ../vnc.html:179
|
||||
#: ../vnc.html:177
|
||||
msgid "Advanced"
|
||||
msgstr "高度"
|
||||
|
||||
#: ../vnc.html:182
|
||||
#: ../vnc.html:180
|
||||
msgid "Quality:"
|
||||
msgstr "品質:"
|
||||
|
||||
#: ../vnc.html:186
|
||||
#: ../vnc.html:184
|
||||
msgid "Compression level:"
|
||||
msgstr "圧縮レベル:"
|
||||
|
||||
#: ../vnc.html:191
|
||||
#: ../vnc.html:189
|
||||
msgid "Repeater ID:"
|
||||
msgstr "リピーター ID:"
|
||||
|
||||
#: ../vnc.html:195
|
||||
#: ../vnc.html:193
|
||||
msgid "WebSocket"
|
||||
msgstr "WebSocket"
|
||||
|
||||
#: ../vnc.html:198
|
||||
#: ../vnc.html:196
|
||||
msgid "Encrypt"
|
||||
msgstr "暗号化"
|
||||
|
||||
#: ../vnc.html:201
|
||||
#: ../vnc.html:199
|
||||
msgid "Host:"
|
||||
msgstr "ホスト:"
|
||||
|
||||
#: ../vnc.html:205
|
||||
#: ../vnc.html:203
|
||||
msgid "Port:"
|
||||
msgstr "ポート:"
|
||||
|
||||
#: ../vnc.html:209
|
||||
#: ../vnc.html:207
|
||||
msgid "Path:"
|
||||
msgstr "パス:"
|
||||
|
||||
#: ../vnc.html:216
|
||||
msgid "Automatic Reconnect"
|
||||
#: ../vnc.html:214
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "自動再接続"
|
||||
|
||||
#: ../vnc.html:219
|
||||
msgid "Reconnect Delay (ms):"
|
||||
#: ../vnc.html:217
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "再接続する遅延 (ミリ秒):"
|
||||
|
||||
#: ../vnc.html:224
|
||||
msgid "Show Dot when No Cursor"
|
||||
#: ../vnc.html:222
|
||||
msgid "Show dot when no cursor"
|
||||
msgstr "カーソルがないときにドットを表示する"
|
||||
|
||||
#: ../vnc.html:229
|
||||
#: ../vnc.html:227
|
||||
msgid "Logging:"
|
||||
msgstr "ロギング:"
|
||||
|
||||
#: ../vnc.html:238
|
||||
#: ../vnc.html:236
|
||||
msgid "Version:"
|
||||
msgstr "バージョン:"
|
||||
|
||||
#: ../vnc.html:246
|
||||
#: ../vnc.html:244
|
||||
msgid "Disconnect"
|
||||
msgstr "切断"
|
||||
|
||||
#: ../vnc.html:269
|
||||
#: ../vnc.html:267
|
||||
msgid "Connect"
|
||||
msgstr "接続"
|
||||
|
||||
#: ../vnc.html:278
|
||||
#: ../vnc.html:276
|
||||
msgid "Server identity"
|
||||
msgstr "サーバーの識別情報"
|
||||
|
||||
#: ../vnc.html:281
|
||||
#: ../vnc.html:279
|
||||
msgid "The server has provided the following identifying information:"
|
||||
msgstr "サーバーは以下の識別情報を提供しています:"
|
||||
|
||||
#: ../vnc.html:285
|
||||
#: ../vnc.html:283
|
||||
msgid "Fingerprint:"
|
||||
msgstr "フィンガープリント:"
|
||||
|
||||
#: ../vnc.html:288
|
||||
#: ../vnc.html:286
|
||||
msgid ""
|
||||
"Please verify that the information is correct and press \"Approve\". "
|
||||
"Otherwise press \"Reject\"."
|
||||
msgstr ""
|
||||
"この情報が正しい場合は「承認」を、そうでない場合は「拒否」を押してく"
|
||||
"ださい。"
|
||||
"この情報が正しい場合は「承認」を、そうでない場合は「拒否」を押してください。"
|
||||
|
||||
#: ../vnc.html:293
|
||||
#: ../vnc.html:291
|
||||
msgid "Approve"
|
||||
msgstr "承認"
|
||||
|
||||
#: ../vnc.html:294
|
||||
#: ../vnc.html:292
|
||||
msgid "Reject"
|
||||
msgstr "拒否"
|
||||
|
||||
#: ../vnc.html:302
|
||||
#: ../vnc.html:300
|
||||
msgid "Credentials"
|
||||
msgstr "資格情報"
|
||||
|
||||
#: ../vnc.html:306
|
||||
#: ../vnc.html:304
|
||||
msgid "Username:"
|
||||
msgstr "ユーザー名:"
|
||||
|
||||
#: ../vnc.html:310
|
||||
#: ../vnc.html:308
|
||||
msgid "Password:"
|
||||
msgstr "パスワード:"
|
||||
|
||||
#: ../vnc.html:314
|
||||
msgid "Send Credentials"
|
||||
#: ../vnc.html:312
|
||||
msgid "Send credentials"
|
||||
msgstr "資格情報を送信"
|
||||
|
||||
#: ../vnc.html:323
|
||||
#: ../vnc.html:321
|
||||
msgid "Cancel"
|
||||
msgstr "キャンセル"
|
||||
|
||||
#~ msgid "Clear"
|
||||
#~ msgstr "クリア"
|
||||
|
||||
#~ msgid "Password is required"
|
||||
#~ msgstr "パスワードが必要です"
|
||||
|
||||
#~ msgid "viewport drag"
|
||||
#~ msgstr "ビューポートをドラッグ"
|
||||
|
||||
#~ msgid "Active Mouse Button"
|
||||
#~ msgstr "アクティブなマウスボタン"
|
||||
|
||||
#~ msgid "No mousebutton"
|
||||
#~ msgstr "マウスボタンなし"
|
||||
|
||||
#~ msgid "Left mousebutton"
|
||||
#~ msgstr "左マウスボタン"
|
||||
|
||||
#~ msgid "Middle mousebutton"
|
||||
#~ msgstr "中マウスボタン"
|
||||
|
||||
#~ msgid "Right mousebutton"
|
||||
#~ msgstr "右マウスボタン"
|
||||
|
||||
#~ msgid "Send Password"
|
||||
#~ msgstr "パスワードを送信"
|
||||
|
|
|
|||
24
po/ko.po
24
po/ko.po
|
|
@ -1,5 +1,5 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) 2018 The noVNC Authors
|
||||
# Copyright (C) 2018 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Baw Appie <pp121324@gmail.com>, 2018.
|
||||
#
|
||||
|
|
@ -78,7 +78,7 @@ msgid "Hide/Show the control bar"
|
|||
msgstr "컨트롤 바 숨기기/보이기"
|
||||
|
||||
#: ../vnc.html:108
|
||||
msgid "Move/Drag Viewport"
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "움직이기/드래그 뷰포트"
|
||||
|
||||
#: ../vnc.html:108
|
||||
|
|
@ -110,7 +110,7 @@ msgid "Keyboard"
|
|||
msgstr "키보드"
|
||||
|
||||
#: ../vnc.html:126
|
||||
msgid "Show Keyboard"
|
||||
msgid "Show keyboard"
|
||||
msgstr "키보드 보이기"
|
||||
|
||||
#: ../vnc.html:133
|
||||
|
|
@ -118,7 +118,7 @@ msgid "Extra keys"
|
|||
msgstr "기타 키들"
|
||||
|
||||
#: ../vnc.html:133
|
||||
msgid "Show Extra Keys"
|
||||
msgid "Show extra keys"
|
||||
msgstr "기타 키들 보이기"
|
||||
|
||||
#: ../vnc.html:138
|
||||
|
|
@ -202,19 +202,19 @@ msgid "Settings"
|
|||
msgstr "설정"
|
||||
|
||||
#: ../vnc.html:204
|
||||
msgid "Shared Mode"
|
||||
msgid "Shared mode"
|
||||
msgstr "공유 모드"
|
||||
|
||||
#: ../vnc.html:207
|
||||
msgid "View Only"
|
||||
msgid "View only"
|
||||
msgstr "보기 전용"
|
||||
|
||||
#: ../vnc.html:211
|
||||
msgid "Clip to Window"
|
||||
msgid "Clip to window"
|
||||
msgstr "창에 클립"
|
||||
|
||||
#: ../vnc.html:214
|
||||
msgid "Scaling Mode:"
|
||||
msgid "Scaling mode:"
|
||||
msgstr "스케일링 모드:"
|
||||
|
||||
#: ../vnc.html:216
|
||||
|
|
@ -222,11 +222,11 @@ msgid "None"
|
|||
msgstr "없음"
|
||||
|
||||
#: ../vnc.html:217
|
||||
msgid "Local Scaling"
|
||||
msgid "Local scaling"
|
||||
msgstr "로컬 스케일링"
|
||||
|
||||
#: ../vnc.html:218
|
||||
msgid "Remote Resizing"
|
||||
msgid "Remote resizing"
|
||||
msgstr "원격 크기 조절"
|
||||
|
||||
#: ../vnc.html:223
|
||||
|
|
@ -258,11 +258,11 @@ msgid "Path:"
|
|||
msgstr "위치:"
|
||||
|
||||
#: ../vnc.html:251
|
||||
msgid "Automatic Reconnect"
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "자동 재연결"
|
||||
|
||||
#: ../vnc.html:254
|
||||
msgid "Reconnect Delay (ms):"
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "재연결 지연 시간 (ms)"
|
||||
|
||||
#: ../vnc.html:260
|
||||
|
|
|
|||
318
po/nl.po
318
po/nl.po
|
|
@ -1,307 +1,385 @@
|
|||
# Dutch translations for noVNC package
|
||||
# Nederlandse vertalingen voor het pakket noVNC.
|
||||
# Copyright (C) 2018 The noVNC Authors
|
||||
# Copyright (C) 2018 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Loek Janssen <loekjanssen@gmail.com>, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: noVNC 1.1.0\n"
|
||||
"Project-Id-Version: noVNC 1.6.0\n"
|
||||
"Report-Msgid-Bugs-To: novnc@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2019-04-09 11:06+0100\n"
|
||||
"PO-Revision-Date: 2019-04-09 17:17+0100\n"
|
||||
"Last-Translator: Arend Lapere <arend.lapere@gmail.com>\n"
|
||||
"POT-Creation-Date: 2025-02-14 10:14+0100\n"
|
||||
"PO-Revision-Date: 2025-03-03 18:20+0100\n"
|
||||
"Last-Translator: Harold Horsman <haroldhorsman@gmail.com>\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: nl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.5\n"
|
||||
|
||||
#: ../app/ui.js:383
|
||||
#: ../app/ui.js:84
|
||||
msgid ""
|
||||
"Running without HTTPS is not recommended, crashes or other issues are likely."
|
||||
msgstr ""
|
||||
"Het is niet aan te raden om zonder HTTPS te werken, crashes of andere "
|
||||
"problemen zijn dan waarschijnlijk."
|
||||
|
||||
#: ../app/ui.js:413
|
||||
msgid "Connecting..."
|
||||
msgstr "Verbinden..."
|
||||
msgstr "Aan het verbinden…"
|
||||
|
||||
#: ../app/ui.js:390
|
||||
#: ../app/ui.js:420
|
||||
msgid "Disconnecting..."
|
||||
msgstr "Verbinding verbreken..."
|
||||
msgstr "Bezig om verbinding te verbreken..."
|
||||
|
||||
#: ../app/ui.js:396
|
||||
#: ../app/ui.js:426
|
||||
msgid "Reconnecting..."
|
||||
msgstr "Opnieuw verbinding maken..."
|
||||
|
||||
#: ../app/ui.js:401
|
||||
#: ../app/ui.js:431
|
||||
msgid "Internal error"
|
||||
msgstr "Interne fout"
|
||||
|
||||
#: ../app/ui.js:991
|
||||
msgid "Must set host"
|
||||
msgstr "Host moeten worden ingesteld"
|
||||
#: ../app/ui.js:1079
|
||||
#, fuzzy
|
||||
msgid "Failed to connect to server: "
|
||||
msgstr "Verbinding maken met server is mislukt"
|
||||
|
||||
#: ../app/ui.js:1073
|
||||
#: ../app/ui.js:1145
|
||||
msgid "Connected (encrypted) to "
|
||||
msgstr "Verbonden (versleuteld) met "
|
||||
|
||||
#: ../app/ui.js:1075
|
||||
#: ../app/ui.js:1147
|
||||
msgid "Connected (unencrypted) to "
|
||||
msgstr "Verbonden (onversleuteld) met "
|
||||
|
||||
#: ../app/ui.js:1098
|
||||
#: ../app/ui.js:1170
|
||||
msgid "Something went wrong, connection is closed"
|
||||
msgstr "Er iets fout gelopen, verbinding werd verbroken"
|
||||
|
||||
#: ../app/ui.js:1101
|
||||
#: ../app/ui.js:1173
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "Verbinding maken met server is mislukt"
|
||||
|
||||
#: ../app/ui.js:1111
|
||||
#: ../app/ui.js:1185
|
||||
msgid "Disconnected"
|
||||
msgstr "Verbinding verbroken"
|
||||
|
||||
#: ../app/ui.js:1124
|
||||
#: ../app/ui.js:1200
|
||||
msgid "New connection has been rejected with reason: "
|
||||
msgstr "Nieuwe verbinding is geweigerd omwille van de volgende reden: "
|
||||
msgstr "Nieuwe verbinding is geweigerd met de volgende reden: "
|
||||
|
||||
#: ../app/ui.js:1127
|
||||
#: ../app/ui.js:1203
|
||||
msgid "New connection has been rejected"
|
||||
msgstr "Nieuwe verbinding is geweigerd"
|
||||
|
||||
#: ../app/ui.js:1147
|
||||
msgid "Password is required"
|
||||
msgstr "Wachtwoord is vereist"
|
||||
#: ../app/ui.js:1269
|
||||
msgid "Credentials are required"
|
||||
msgstr "Inloggegevens zijn nodig"
|
||||
|
||||
#: ../vnc.html:80
|
||||
#: ../vnc.html:106
|
||||
msgid "noVNC encountered an error:"
|
||||
msgstr "noVNC heeft een fout bemerkt:"
|
||||
|
||||
#: ../vnc.html:90
|
||||
#: ../vnc.html:116
|
||||
msgid "Hide/Show the control bar"
|
||||
msgstr "Verberg/Toon de bedieningsbalk"
|
||||
|
||||
#: ../vnc.html:97
|
||||
msgid "Move/Drag Viewport"
|
||||
#: ../vnc.html:125
|
||||
msgid "Drag"
|
||||
msgstr "Sleep"
|
||||
|
||||
#: ../vnc.html:125
|
||||
#, fuzzy
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "Verplaats/Versleep Kijkvenster"
|
||||
|
||||
#: ../vnc.html:97
|
||||
msgid "viewport drag"
|
||||
msgstr "kijkvenster slepen"
|
||||
|
||||
#: ../vnc.html:103 ../vnc.html:106 ../vnc.html:109 ../vnc.html:112
|
||||
msgid "Active Mouse Button"
|
||||
msgstr "Actieve Muisknop"
|
||||
|
||||
#: ../vnc.html:103
|
||||
msgid "No mousebutton"
|
||||
msgstr "Geen muisknop"
|
||||
|
||||
#: ../vnc.html:106
|
||||
msgid "Left mousebutton"
|
||||
msgstr "Linker muisknop"
|
||||
|
||||
#: ../vnc.html:109
|
||||
msgid "Middle mousebutton"
|
||||
msgstr "Middelste muisknop"
|
||||
|
||||
#: ../vnc.html:112
|
||||
msgid "Right mousebutton"
|
||||
msgstr "Rechter muisknop"
|
||||
|
||||
#: ../vnc.html:115
|
||||
#: ../vnc.html:131
|
||||
msgid "Keyboard"
|
||||
msgstr "Toetsenbord"
|
||||
|
||||
#: ../vnc.html:115
|
||||
msgid "Show Keyboard"
|
||||
#: ../vnc.html:131
|
||||
#, fuzzy
|
||||
msgid "Show keyboard"
|
||||
msgstr "Toon Toetsenbord"
|
||||
|
||||
#: ../vnc.html:121
|
||||
#: ../vnc.html:136
|
||||
msgid "Extra keys"
|
||||
msgstr "Extra toetsen"
|
||||
|
||||
#: ../vnc.html:121
|
||||
msgid "Show Extra Keys"
|
||||
#: ../vnc.html:136
|
||||
#, fuzzy
|
||||
msgid "Show extra keys"
|
||||
msgstr "Toon Extra Toetsen"
|
||||
|
||||
#: ../vnc.html:126
|
||||
#: ../vnc.html:141
|
||||
msgid "Ctrl"
|
||||
msgstr "Ctrl"
|
||||
|
||||
#: ../vnc.html:126
|
||||
#: ../vnc.html:141
|
||||
msgid "Toggle Ctrl"
|
||||
msgstr "Ctrl omschakelen"
|
||||
|
||||
#: ../vnc.html:129
|
||||
#: ../vnc.html:144
|
||||
msgid "Alt"
|
||||
msgstr "Alt"
|
||||
|
||||
#: ../vnc.html:129
|
||||
#: ../vnc.html:144
|
||||
msgid "Toggle Alt"
|
||||
msgstr "Alt omschakelen"
|
||||
|
||||
#: ../vnc.html:132
|
||||
#: ../vnc.html:147
|
||||
msgid "Toggle Windows"
|
||||
msgstr "Windows omschakelen"
|
||||
msgstr "Vensters omschakelen"
|
||||
|
||||
#: ../vnc.html:132
|
||||
#: ../vnc.html:147
|
||||
msgid "Windows"
|
||||
msgstr "Windows"
|
||||
msgstr "Vensters"
|
||||
|
||||
#: ../vnc.html:135
|
||||
#: ../vnc.html:150
|
||||
msgid "Send Tab"
|
||||
msgstr "Tab Sturen"
|
||||
|
||||
#: ../vnc.html:135
|
||||
#: ../vnc.html:150
|
||||
msgid "Tab"
|
||||
msgstr "Tab"
|
||||
|
||||
#: ../vnc.html:138
|
||||
#: ../vnc.html:153
|
||||
msgid "Esc"
|
||||
msgstr "Esc"
|
||||
|
||||
#: ../vnc.html:138
|
||||
#: ../vnc.html:153
|
||||
msgid "Send Escape"
|
||||
msgstr "Escape Sturen"
|
||||
|
||||
#: ../vnc.html:141
|
||||
#: ../vnc.html:156
|
||||
msgid "Ctrl+Alt+Del"
|
||||
msgstr "Ctrl-Alt-Del"
|
||||
|
||||
#: ../vnc.html:141
|
||||
#: ../vnc.html:156
|
||||
msgid "Send Ctrl-Alt-Del"
|
||||
msgstr "Ctrl-Alt-Del Sturen"
|
||||
|
||||
#: ../vnc.html:149
|
||||
#: ../vnc.html:163
|
||||
msgid "Shutdown/Reboot"
|
||||
msgstr "Uitschakelen/Herstarten"
|
||||
|
||||
#: ../vnc.html:149
|
||||
#: ../vnc.html:163
|
||||
msgid "Shutdown/Reboot..."
|
||||
msgstr "Uitschakelen/Herstarten..."
|
||||
|
||||
#: ../vnc.html:155
|
||||
#: ../vnc.html:169
|
||||
msgid "Power"
|
||||
msgstr "Systeem"
|
||||
|
||||
#: ../vnc.html:157
|
||||
#: ../vnc.html:171
|
||||
msgid "Shutdown"
|
||||
msgstr "Uitschakelen"
|
||||
|
||||
#: ../vnc.html:158
|
||||
#: ../vnc.html:172
|
||||
msgid "Reboot"
|
||||
msgstr "Herstarten"
|
||||
|
||||
#: ../vnc.html:159
|
||||
#: ../vnc.html:173
|
||||
msgid "Reset"
|
||||
msgstr "Resetten"
|
||||
|
||||
#: ../vnc.html:164 ../vnc.html:170
|
||||
#: ../vnc.html:178 ../vnc.html:184
|
||||
msgid "Clipboard"
|
||||
msgstr "Klembord"
|
||||
|
||||
#: ../vnc.html:174
|
||||
msgid "Clear"
|
||||
msgstr "Wissen"
|
||||
#: ../vnc.html:186
|
||||
msgid "Edit clipboard content in the textarea below."
|
||||
msgstr "Edit de inhoud van het klembord in het tekstveld hieronder"
|
||||
|
||||
#: ../vnc.html:180
|
||||
msgid "Fullscreen"
|
||||
#: ../vnc.html:194
|
||||
#, fuzzy
|
||||
msgid "Full screen"
|
||||
msgstr "Volledig Scherm"
|
||||
|
||||
#: ../vnc.html:185 ../vnc.html:192
|
||||
#: ../vnc.html:199 ../vnc.html:205
|
||||
msgid "Settings"
|
||||
msgstr "Instellingen"
|
||||
|
||||
#: ../vnc.html:195
|
||||
msgid "Shared Mode"
|
||||
#: ../vnc.html:211
|
||||
#, fuzzy
|
||||
msgid "Shared mode"
|
||||
msgstr "Gedeelde Modus"
|
||||
|
||||
#: ../vnc.html:198
|
||||
msgid "View Only"
|
||||
#: ../vnc.html:218
|
||||
#, fuzzy
|
||||
msgid "View only"
|
||||
msgstr "Alleen Kijken"
|
||||
|
||||
#: ../vnc.html:202
|
||||
msgid "Clip to Window"
|
||||
#: ../vnc.html:226
|
||||
msgid "Clip to window"
|
||||
msgstr "Randen buiten venster afsnijden"
|
||||
|
||||
#: ../vnc.html:205
|
||||
msgid "Scaling Mode:"
|
||||
#: ../vnc.html:231
|
||||
msgid "Scaling mode:"
|
||||
msgstr "Schaalmodus:"
|
||||
|
||||
#: ../vnc.html:207
|
||||
#: ../vnc.html:233
|
||||
msgid "None"
|
||||
msgstr "Geen"
|
||||
|
||||
#: ../vnc.html:208
|
||||
msgid "Local Scaling"
|
||||
#: ../vnc.html:234
|
||||
#, fuzzy
|
||||
msgid "Local scaling"
|
||||
msgstr "Lokaal Schalen"
|
||||
|
||||
#: ../vnc.html:209
|
||||
msgid "Remote Resizing"
|
||||
#: ../vnc.html:235
|
||||
#, fuzzy
|
||||
msgid "Remote resizing"
|
||||
msgstr "Op Afstand Formaat Wijzigen"
|
||||
|
||||
#: ../vnc.html:214
|
||||
#: ../vnc.html:240
|
||||
msgid "Advanced"
|
||||
msgstr "Geavanceerd"
|
||||
|
||||
#: ../vnc.html:217
|
||||
#: ../vnc.html:243
|
||||
msgid "Quality:"
|
||||
msgstr "Kwaliteit:"
|
||||
|
||||
#: ../vnc.html:247
|
||||
msgid "Compression level:"
|
||||
msgstr "Compressieniveau:"
|
||||
|
||||
#: ../vnc.html:252
|
||||
msgid "Repeater ID:"
|
||||
msgstr "Repeater ID:"
|
||||
|
||||
#: ../vnc.html:221
|
||||
#: ../vnc.html:256
|
||||
msgid "WebSocket"
|
||||
msgstr "WebSocket"
|
||||
|
||||
#: ../vnc.html:224
|
||||
#: ../vnc.html:261
|
||||
msgid "Encrypt"
|
||||
msgstr "Versleutelen"
|
||||
|
||||
#: ../vnc.html:227
|
||||
#: ../vnc.html:266
|
||||
msgid "Host:"
|
||||
msgstr "Host:"
|
||||
|
||||
#: ../vnc.html:231
|
||||
#: ../vnc.html:270
|
||||
msgid "Port:"
|
||||
msgstr "Poort:"
|
||||
|
||||
#: ../vnc.html:235
|
||||
#: ../vnc.html:274
|
||||
msgid "Path:"
|
||||
msgstr "Pad:"
|
||||
|
||||
#: ../vnc.html:242
|
||||
msgid "Automatic Reconnect"
|
||||
#: ../vnc.html:283
|
||||
#, fuzzy
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "Automatisch Opnieuw Verbinden"
|
||||
|
||||
#: ../vnc.html:245
|
||||
msgid "Reconnect Delay (ms):"
|
||||
#: ../vnc.html:288
|
||||
#, fuzzy
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "Vertraging voor Opnieuw Verbinden (ms):"
|
||||
|
||||
#: ../vnc.html:250
|
||||
msgid "Show Dot when No Cursor"
|
||||
#: ../vnc.html:295
|
||||
msgid "Show dot when no cursor"
|
||||
msgstr "Geef stip weer indien geen cursor"
|
||||
|
||||
#: ../vnc.html:255
|
||||
#: ../vnc.html:302
|
||||
msgid "Logging:"
|
||||
msgstr "Logmeldingen:"
|
||||
|
||||
#: ../vnc.html:267
|
||||
#: ../vnc.html:311
|
||||
msgid "Version:"
|
||||
msgstr "Versie:"
|
||||
|
||||
#: ../vnc.html:319
|
||||
msgid "Disconnect"
|
||||
msgstr "Verbinding verbreken"
|
||||
|
||||
#: ../vnc.html:286
|
||||
#: ../vnc.html:342
|
||||
msgid "Connect"
|
||||
msgstr "Verbinden"
|
||||
|
||||
#: ../vnc.html:296
|
||||
#: ../vnc.html:351
|
||||
msgid "Server identity"
|
||||
msgstr "Serveridentiteit"
|
||||
|
||||
#: ../vnc.html:354
|
||||
msgid "The server has provided the following identifying information:"
|
||||
msgstr "De server geeft de volgende identificerende informatie:"
|
||||
|
||||
#: ../vnc.html:357
|
||||
msgid "Fingerprint:"
|
||||
msgstr "Vingerafdruk:"
|
||||
|
||||
#: ../vnc.html:361
|
||||
msgid ""
|
||||
"Please verify that the information is correct and press \"Approve\". "
|
||||
"Otherwise press \"Reject\"."
|
||||
msgstr ""
|
||||
"Verifieer dat de informatie is correct en druk “OK”. Druk anders op "
|
||||
"“Afwijzen”."
|
||||
|
||||
#: ../vnc.html:366
|
||||
msgid "Approve"
|
||||
msgstr "OK"
|
||||
|
||||
#: ../vnc.html:367
|
||||
msgid "Reject"
|
||||
msgstr "Afwijzen"
|
||||
|
||||
#: ../vnc.html:375
|
||||
msgid "Credentials"
|
||||
msgstr "Inloggegevens"
|
||||
|
||||
#: ../vnc.html:379
|
||||
msgid "Username:"
|
||||
msgstr "Gebruikersnaam:"
|
||||
|
||||
#: ../vnc.html:383
|
||||
msgid "Password:"
|
||||
msgstr "Wachtwoord:"
|
||||
|
||||
#: ../vnc.html:300
|
||||
msgid "Send Password"
|
||||
msgstr "Verzend Wachtwoord:"
|
||||
# Translated by Harold Horsman
|
||||
#: ../vnc.html:387
|
||||
msgid "Send credentials"
|
||||
msgstr "Stuur inloggegevens"
|
||||
|
||||
#: ../vnc.html:310
|
||||
#: ../vnc.html:396
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleren"
|
||||
|
||||
#~ msgid "Must set host"
|
||||
#~ msgstr "Host moeten worden ingesteld"
|
||||
|
||||
#~ msgid "Password is required"
|
||||
#~ msgstr "Wachtwoord is vereist"
|
||||
|
||||
#~ msgid "viewport drag"
|
||||
#~ msgstr "kijkvenster slepen"
|
||||
|
||||
#~ msgid "Active Mouse Button"
|
||||
#~ msgstr "Actieve Muisknop"
|
||||
|
||||
#~ msgid "No mousebutton"
|
||||
#~ msgstr "Geen muisknop"
|
||||
|
||||
#~ msgid "Left mousebutton"
|
||||
#~ msgstr "Linker muisknop"
|
||||
|
||||
#~ msgid "Middle mousebutton"
|
||||
#~ msgstr "Middelste muisknop"
|
||||
|
||||
#~ msgid "Right mousebutton"
|
||||
#~ msgstr "Rechter muisknop"
|
||||
|
||||
#~ msgid "Clear"
|
||||
#~ msgstr "Wissen"
|
||||
|
||||
#~ msgid "Send Password"
|
||||
#~ msgstr "Verzend Wachtwoord:"
|
||||
|
||||
#~ msgid "Disconnect timeout"
|
||||
#~ msgstr "Timeout tijdens verbreken van verbinding"
|
||||
|
||||
|
|
|
|||
194
po/noVNC.pot
194
po/noVNC.pot
|
|
@ -1,14 +1,14 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR The noVNC Authors
|
||||
# Copyright (C) YEAR The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: noVNC 1.5.0\n"
|
||||
"Project-Id-Version: noVNC 1.6.0\n"
|
||||
"Report-Msgid-Bugs-To: novnc@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2024-06-03 14:10+0200\n"
|
||||
"POT-Creation-Date: 2025-02-14 10:14+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
@ -17,321 +17,317 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: ../app/ui.js:69
|
||||
#: ../app/ui.js:84
|
||||
msgid ""
|
||||
"Running without HTTPS is not recommended, crashes or other issues are likely."
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:410
|
||||
#: ../app/ui.js:413
|
||||
msgid "Connecting..."
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:417
|
||||
#: ../app/ui.js:420
|
||||
msgid "Disconnecting..."
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:423
|
||||
#: ../app/ui.js:426
|
||||
msgid "Reconnecting..."
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:428
|
||||
#: ../app/ui.js:431
|
||||
msgid "Internal error"
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:1026
|
||||
msgid "Must set host"
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:1052
|
||||
#: ../app/ui.js:1079
|
||||
msgid "Failed to connect to server: "
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:1118
|
||||
#: ../app/ui.js:1145
|
||||
msgid "Connected (encrypted) to "
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:1120
|
||||
#: ../app/ui.js:1147
|
||||
msgid "Connected (unencrypted) to "
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:1143
|
||||
#: ../app/ui.js:1170
|
||||
msgid "Something went wrong, connection is closed"
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:1146
|
||||
#: ../app/ui.js:1173
|
||||
msgid "Failed to connect to server"
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:1158
|
||||
#: ../app/ui.js:1185
|
||||
msgid "Disconnected"
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:1173
|
||||
#: ../app/ui.js:1200
|
||||
msgid "New connection has been rejected with reason: "
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:1176
|
||||
#: ../app/ui.js:1203
|
||||
msgid "New connection has been rejected"
|
||||
msgstr ""
|
||||
|
||||
#: ../app/ui.js:1242
|
||||
#: ../app/ui.js:1269
|
||||
msgid "Credentials are required"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:55
|
||||
#: ../vnc.html:106
|
||||
msgid "noVNC encountered an error:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:65
|
||||
#: ../vnc.html:116
|
||||
msgid "Hide/Show the control bar"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:74
|
||||
#: ../vnc.html:125
|
||||
msgid "Drag"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:74
|
||||
msgid "Move/Drag Viewport"
|
||||
#: ../vnc.html:125
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:80
|
||||
#: ../vnc.html:131
|
||||
msgid "Keyboard"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:80
|
||||
msgid "Show Keyboard"
|
||||
#: ../vnc.html:131
|
||||
msgid "Show keyboard"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:85
|
||||
#: ../vnc.html:136
|
||||
msgid "Extra keys"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:85
|
||||
msgid "Show Extra Keys"
|
||||
#: ../vnc.html:136
|
||||
msgid "Show extra keys"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:90
|
||||
#: ../vnc.html:141
|
||||
msgid "Ctrl"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:90
|
||||
#: ../vnc.html:141
|
||||
msgid "Toggle Ctrl"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:93
|
||||
#: ../vnc.html:144
|
||||
msgid "Alt"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:93
|
||||
#: ../vnc.html:144
|
||||
msgid "Toggle Alt"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:96
|
||||
#: ../vnc.html:147
|
||||
msgid "Toggle Windows"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:96
|
||||
#: ../vnc.html:147
|
||||
msgid "Windows"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:99
|
||||
#: ../vnc.html:150
|
||||
msgid "Send Tab"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:99
|
||||
#: ../vnc.html:150
|
||||
msgid "Tab"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:102
|
||||
#: ../vnc.html:153
|
||||
msgid "Esc"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:102
|
||||
#: ../vnc.html:153
|
||||
msgid "Send Escape"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:105
|
||||
#: ../vnc.html:156
|
||||
msgid "Ctrl+Alt+Del"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:105
|
||||
#: ../vnc.html:156
|
||||
msgid "Send Ctrl-Alt-Del"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:112
|
||||
#: ../vnc.html:163
|
||||
msgid "Shutdown/Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:112
|
||||
#: ../vnc.html:163
|
||||
msgid "Shutdown/Reboot..."
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:118
|
||||
#: ../vnc.html:169
|
||||
msgid "Power"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:120
|
||||
#: ../vnc.html:171
|
||||
msgid "Shutdown"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:121
|
||||
#: ../vnc.html:172
|
||||
msgid "Reboot"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:122
|
||||
#: ../vnc.html:173
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:127 ../vnc.html:133
|
||||
#: ../vnc.html:178 ../vnc.html:184
|
||||
msgid "Clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:135
|
||||
#: ../vnc.html:186
|
||||
msgid "Edit clipboard content in the textarea below."
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:143
|
||||
msgid "Full Screen"
|
||||
#: ../vnc.html:194
|
||||
msgid "Full screen"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:148 ../vnc.html:154
|
||||
#: ../vnc.html:199 ../vnc.html:205
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:158
|
||||
msgid "Shared Mode"
|
||||
#: ../vnc.html:211
|
||||
msgid "Shared mode"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:161
|
||||
msgid "View Only"
|
||||
#: ../vnc.html:218
|
||||
msgid "View only"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:165
|
||||
msgid "Clip to Window"
|
||||
#: ../vnc.html:226
|
||||
msgid "Clip to window"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:168
|
||||
msgid "Scaling Mode:"
|
||||
#: ../vnc.html:231
|
||||
msgid "Scaling mode:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:170
|
||||
#: ../vnc.html:233
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:171
|
||||
msgid "Local Scaling"
|
||||
#: ../vnc.html:234
|
||||
msgid "Local scaling"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:172
|
||||
msgid "Remote Resizing"
|
||||
#: ../vnc.html:235
|
||||
msgid "Remote resizing"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:177
|
||||
#: ../vnc.html:240
|
||||
msgid "Advanced"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:180
|
||||
#: ../vnc.html:243
|
||||
msgid "Quality:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:184
|
||||
#: ../vnc.html:247
|
||||
msgid "Compression level:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:189
|
||||
#: ../vnc.html:252
|
||||
msgid "Repeater ID:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:193
|
||||
#: ../vnc.html:256
|
||||
msgid "WebSocket"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:196
|
||||
#: ../vnc.html:261
|
||||
msgid "Encrypt"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:199
|
||||
#: ../vnc.html:266
|
||||
msgid "Host:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:203
|
||||
#: ../vnc.html:270
|
||||
msgid "Port:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:207
|
||||
#: ../vnc.html:274
|
||||
msgid "Path:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:214
|
||||
msgid "Automatic Reconnect"
|
||||
#: ../vnc.html:283
|
||||
msgid "Automatic reconnect"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:217
|
||||
msgid "Reconnect Delay (ms):"
|
||||
#: ../vnc.html:288
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:222
|
||||
msgid "Show Dot when No Cursor"
|
||||
#: ../vnc.html:295
|
||||
msgid "Show dot when no cursor"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:227
|
||||
#: ../vnc.html:302
|
||||
msgid "Logging:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:236
|
||||
#: ../vnc.html:311
|
||||
msgid "Version:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:244
|
||||
#: ../vnc.html:319
|
||||
msgid "Disconnect"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:267
|
||||
#: ../vnc.html:342
|
||||
msgid "Connect"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:276
|
||||
#: ../vnc.html:351
|
||||
msgid "Server identity"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:279
|
||||
#: ../vnc.html:354
|
||||
msgid "The server has provided the following identifying information:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:283
|
||||
#: ../vnc.html:357
|
||||
msgid "Fingerprint:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:286
|
||||
#: ../vnc.html:361
|
||||
msgid ""
|
||||
"Please verify that the information is correct and press \"Approve\". "
|
||||
"Otherwise press \"Reject\"."
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:291
|
||||
#: ../vnc.html:366
|
||||
msgid "Approve"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:292
|
||||
#: ../vnc.html:367
|
||||
msgid "Reject"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:300
|
||||
#: ../vnc.html:375
|
||||
msgid "Credentials"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:304
|
||||
#: ../vnc.html:379
|
||||
msgid "Username:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:308
|
||||
#: ../vnc.html:383
|
||||
msgid "Password:"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:312
|
||||
msgid "Send Credentials"
|
||||
#: ../vnc.html:387
|
||||
msgid "Send credentials"
|
||||
msgstr ""
|
||||
|
||||
#: ../vnc.html:321
|
||||
#: ../vnc.html:396
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
|
|
|||
14
po/pl.po
14
po/pl.po
|
|
@ -1,5 +1,5 @@
|
|||
# Polish translations for noVNC package.
|
||||
# Copyright (C) 2018 The noVNC Authors
|
||||
# Copyright (C) 2018 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Mariusz Jamro <mariusz.jamro@gmail.com>, 2017.
|
||||
#
|
||||
|
|
@ -108,7 +108,7 @@ msgid "Keyboard"
|
|||
msgstr "Klawiatura"
|
||||
|
||||
#: ../vnc.html:124
|
||||
msgid "Show Keyboard"
|
||||
msgid "Show keyboard"
|
||||
msgstr "Pokaż klawiaturę"
|
||||
|
||||
#: ../vnc.html:131
|
||||
|
|
@ -116,7 +116,7 @@ msgid "Extra keys"
|
|||
msgstr "Przyciski dodatkowe"
|
||||
|
||||
#: ../vnc.html:131
|
||||
msgid "Show Extra Keys"
|
||||
msgid "Show extra keys"
|
||||
msgstr "Pokaż przyciski dodatkowe"
|
||||
|
||||
#: ../vnc.html:136
|
||||
|
|
@ -220,11 +220,11 @@ msgid "None"
|
|||
msgstr "Brak"
|
||||
|
||||
#: ../vnc.html:215
|
||||
msgid "Local Scaling"
|
||||
msgid "Local scaling"
|
||||
msgstr "Skalowanie lokalne"
|
||||
|
||||
#: ../vnc.html:216
|
||||
msgid "Remote Resizing"
|
||||
msgid "Remote resizing"
|
||||
msgstr "Skalowanie zdalne"
|
||||
|
||||
#: ../vnc.html:221
|
||||
|
|
@ -256,11 +256,11 @@ msgid "Path:"
|
|||
msgstr "Ścieżka:"
|
||||
|
||||
#: ../vnc.html:249
|
||||
msgid "Automatic Reconnect"
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "Automatycznie wznawiaj połączenie"
|
||||
|
||||
#: ../vnc.html:252
|
||||
msgid "Reconnect Delay (ms):"
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "Opóźnienie wznawiania (ms):"
|
||||
|
||||
#: ../vnc.html:258
|
||||
|
|
|
|||
37
po/po2js
37
po/po2js
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env node
|
||||
/*
|
||||
* ps2js: gettext .po to noVNC .js converter
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Copyright (C) 2018 The noVNC authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -17,29 +17,26 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const getopt = require('node-getopt');
|
||||
const { program } = require('commander');
|
||||
const fs = require('fs');
|
||||
const po2json = require("po2json");
|
||||
const pofile = require("pofile");
|
||||
|
||||
const opt = getopt.create([
|
||||
['h', 'help', 'display this help'],
|
||||
]).bindHelp().parseSystem();
|
||||
program
|
||||
.argument('<input>')
|
||||
.argument('<output>')
|
||||
.parse(process.argv);
|
||||
|
||||
if (opt.argv.length != 2) {
|
||||
console.error("Incorrect number of arguments given");
|
||||
process.exit(1);
|
||||
}
|
||||
let data = fs.readFileSync(program.args[0], "utf8");
|
||||
let po = pofile.parse(data);
|
||||
|
||||
const data = po2json.parseFileSync(opt.argv[0]);
|
||||
|
||||
const bodyPart = Object.keys(data)
|
||||
.filter(msgid => msgid !== "")
|
||||
.filter(msgid => data[msgid][1] !== "")
|
||||
.map((msgid) => {
|
||||
const msgstr = data[msgid][1];
|
||||
return " " + JSON.stringify(msgid) + ": " + JSON.stringify(msgstr);
|
||||
}).join(",\n");
|
||||
const bodyPart = po.items
|
||||
.filter(item => item.msgid !== "")
|
||||
.filter(item => item.msgstr[0] !== "")
|
||||
.filter(item => !item.flags.fuzzy)
|
||||
.filter(item => !item.obsolete)
|
||||
.map(item => " " + JSON.stringify(item.msgid) + ": " + JSON.stringify(item.msgstr[0]))
|
||||
.join(",\n");
|
||||
|
||||
const output = "{\n" + bodyPart + "\n}";
|
||||
|
||||
fs.writeFileSync(opt.argv[1], output);
|
||||
fs.writeFileSync(program.args[1], output);
|
||||
|
|
|
|||
30
po/pt_BR.po
30
po/pt_BR.po
|
|
@ -1,5 +1,5 @@
|
|||
# Portuguese translations for noVNC package.
|
||||
# Copyright (C) 2021 The noVNC Authors
|
||||
# Copyright (C) 2021 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# <liddack@outlook.com>, 2021.
|
||||
#
|
||||
|
|
@ -83,7 +83,7 @@ msgid "Drag"
|
|||
msgstr "Arrastar"
|
||||
|
||||
#: ../vnc.html:78
|
||||
msgid "Move/Drag Viewport"
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "Mover/arrastar a janela"
|
||||
|
||||
#: ../vnc.html:84
|
||||
|
|
@ -91,7 +91,7 @@ msgid "Keyboard"
|
|||
msgstr "Teclado"
|
||||
|
||||
#: ../vnc.html:84
|
||||
msgid "Show Keyboard"
|
||||
msgid "Show keyboard"
|
||||
msgstr "Mostrar teclado"
|
||||
|
||||
#: ../vnc.html:89
|
||||
|
|
@ -99,8 +99,8 @@ msgid "Extra keys"
|
|||
msgstr "Teclas adicionais"
|
||||
|
||||
#: ../vnc.html:89
|
||||
msgid "Show Extra Keys"
|
||||
msgstr "Mostar teclas adicionais"
|
||||
msgid "Show extra keys"
|
||||
msgstr "Mostrar teclas adicionais"
|
||||
|
||||
#: ../vnc.html:94
|
||||
msgid "Ctrl"
|
||||
|
|
@ -191,19 +191,19 @@ msgid "Settings"
|
|||
msgstr "Configurações"
|
||||
|
||||
#: ../vnc.html:162
|
||||
msgid "Shared Mode"
|
||||
msgid "Shared mode"
|
||||
msgstr "Modo compartilhado"
|
||||
|
||||
#: ../vnc.html:165
|
||||
msgid "View Only"
|
||||
msgid "View only"
|
||||
msgstr "Apenas visualizar"
|
||||
|
||||
#: ../vnc.html:169
|
||||
msgid "Clip to Window"
|
||||
msgid "Clip to window"
|
||||
msgstr "Recortar à janela"
|
||||
|
||||
#: ../vnc.html:172
|
||||
msgid "Scaling Mode:"
|
||||
msgid "Scaling mode:"
|
||||
msgstr "Modo de dimensionamento:"
|
||||
|
||||
#: ../vnc.html:174
|
||||
|
|
@ -211,11 +211,11 @@ msgid "None"
|
|||
msgstr "Nenhum"
|
||||
|
||||
#: ../vnc.html:175
|
||||
msgid "Local Scaling"
|
||||
msgid "Local scaling"
|
||||
msgstr "Local"
|
||||
|
||||
#: ../vnc.html:176
|
||||
msgid "Remote Resizing"
|
||||
msgid "Remote resizing"
|
||||
msgstr "Remoto"
|
||||
|
||||
#: ../vnc.html:181
|
||||
|
|
@ -255,15 +255,15 @@ msgid "Path:"
|
|||
msgstr "Caminho:"
|
||||
|
||||
#: ../vnc.html:218
|
||||
msgid "Automatic Reconnect"
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "Reconexão automática"
|
||||
|
||||
#: ../vnc.html:221
|
||||
msgid "Reconnect Delay (ms):"
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "Atraso da reconexão (ms)"
|
||||
|
||||
#: ../vnc.html:226
|
||||
msgid "Show Dot when No Cursor"
|
||||
msgid "Show dot when no cursor"
|
||||
msgstr "Mostrar ponto quando não há cursor"
|
||||
|
||||
#: ../vnc.html:231
|
||||
|
|
@ -291,7 +291,7 @@ msgid "Password:"
|
|||
msgstr "Senha:"
|
||||
|
||||
#: ../vnc.html:285
|
||||
msgid "Send Credentials"
|
||||
msgid "Send credentials"
|
||||
msgstr "Enviar credenciais"
|
||||
|
||||
#: ../vnc.html:295
|
||||
|
|
|
|||
34
po/ru.po
34
po/ru.po
|
|
@ -6,11 +6,11 @@
|
|||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: noVNC 1.3.0\n"
|
||||
"Project-Id-Version: noVNC 1.5.0\n"
|
||||
"Report-Msgid-Bugs-To: novnc@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2021-08-27 16:03+0200\n"
|
||||
"PO-Revision-Date: 2021-09-09 10:29+0400\n"
|
||||
"Last-Translator: Nia Remez <nia.remez@cendio.com>\n"
|
||||
"PO-Revision-Date: 2024-02-11 03:58+0300\n"
|
||||
"Last-Translator: Dim5x <dim5x@yahoo.com>\n"
|
||||
"Language-Team: Russian\n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -86,7 +86,7 @@ msgid "Drag"
|
|||
msgstr "Переместить"
|
||||
|
||||
#: ../vnc.html:78
|
||||
msgid "Move/Drag Viewport"
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "Переместить окно"
|
||||
|
||||
#: ../vnc.html:84
|
||||
|
|
@ -94,7 +94,7 @@ msgid "Keyboard"
|
|||
msgstr "Клавиатура"
|
||||
|
||||
#: ../vnc.html:84
|
||||
msgid "Show Keyboard"
|
||||
msgid "Show keyboard"
|
||||
msgstr "Показать клавиатуру"
|
||||
|
||||
#: ../vnc.html:89
|
||||
|
|
@ -111,7 +111,7 @@ msgstr "Ctrl"
|
|||
|
||||
#: ../vnc.html:94
|
||||
msgid "Toggle Ctrl"
|
||||
msgstr "Переключение нажатия Ctrl"
|
||||
msgstr "Зажать Ctrl"
|
||||
|
||||
#: ../vnc.html:97
|
||||
msgid "Alt"
|
||||
|
|
@ -119,11 +119,11 @@ msgstr "Alt"
|
|||
|
||||
#: ../vnc.html:97
|
||||
msgid "Toggle Alt"
|
||||
msgstr "Переключение нажатия Alt"
|
||||
msgstr "Зажать Alt"
|
||||
|
||||
#: ../vnc.html:100
|
||||
msgid "Toggle Windows"
|
||||
msgstr "Переключение вкладок"
|
||||
msgstr "Зажать Windows"
|
||||
|
||||
#: ../vnc.html:100
|
||||
msgid "Windows"
|
||||
|
|
@ -194,7 +194,7 @@ msgid "Settings"
|
|||
msgstr "Настройки"
|
||||
|
||||
#: ../vnc.html:162
|
||||
msgid "Shared Mode"
|
||||
msgid "Shared mode"
|
||||
msgstr "Общий режим"
|
||||
|
||||
#: ../vnc.html:165
|
||||
|
|
@ -202,11 +202,11 @@ msgid "View Only"
|
|||
msgstr "Только Просмотр"
|
||||
|
||||
#: ../vnc.html:169
|
||||
msgid "Clip to Window"
|
||||
msgid "Clip to window"
|
||||
msgstr "В окно"
|
||||
|
||||
#: ../vnc.html:172
|
||||
msgid "Scaling Mode:"
|
||||
msgid "Scaling mode:"
|
||||
msgstr "Масштаб:"
|
||||
|
||||
#: ../vnc.html:174
|
||||
|
|
@ -214,11 +214,11 @@ msgid "None"
|
|||
msgstr "Нет"
|
||||
|
||||
#: ../vnc.html:175
|
||||
msgid "Local Scaling"
|
||||
msgstr "Локльный масштаб"
|
||||
msgid "Local scaling"
|
||||
msgstr "Локальный масштаб"
|
||||
|
||||
#: ../vnc.html:176
|
||||
msgid "Remote Resizing"
|
||||
msgid "Remote resizing"
|
||||
msgstr "Удаленная перенастройка размера"
|
||||
|
||||
#: ../vnc.html:181
|
||||
|
|
@ -258,15 +258,15 @@ msgid "Path:"
|
|||
msgstr "Путь:"
|
||||
|
||||
#: ../vnc.html:218
|
||||
msgid "Automatic Reconnect"
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "Автоматическое переподключение"
|
||||
|
||||
#: ../vnc.html:221
|
||||
msgid "Reconnect Delay (ms):"
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "Задержка переподключения (мс):"
|
||||
|
||||
#: ../vnc.html:226
|
||||
msgid "Show Dot when No Cursor"
|
||||
msgid "Show dot when no cursor"
|
||||
msgstr "Показать точку вместо курсора"
|
||||
|
||||
#: ../vnc.html:231
|
||||
|
|
|
|||
223
po/sv.po
223
po/sv.po
|
|
@ -1,312 +1,308 @@
|
|||
# Swedish translations for noVNC package
|
||||
# Svenska översättningar för paketet noVNC.
|
||||
# Copyright (C) 2020 The noVNC Authors
|
||||
# Copyright (C) 2025 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Samuel Mannehed <samuel@cendio.se>, 2020.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: noVNC 1.3.0\n"
|
||||
"Project-Id-Version: noVNC 1.6.0\n"
|
||||
"Report-Msgid-Bugs-To: novnc@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2024-06-03 14:10+0200\n"
|
||||
"PO-Revision-Date: 2024-06-18 13:52+0200\n"
|
||||
"Last-Translator: Pierre Ossman <ossman@cendio.se>\n"
|
||||
"POT-Creation-Date: 2025-02-14 10:14+0100\n"
|
||||
"PO-Revision-Date: 2025-02-14 10:29+0100\n"
|
||||
"Last-Translator: Alexander Zeijlon <aleze@cendio.com>\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: sv\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.4.4\n"
|
||||
"X-Generator: Poedit 3.5\n"
|
||||
|
||||
#: ../app/ui.js:69
|
||||
#: ../app/ui.js:84
|
||||
msgid ""
|
||||
"Running without HTTPS is not recommended, crashes or other issues are likely."
|
||||
msgstr ""
|
||||
"Det är ej rekommenderat att köra utan HTTPS, krascher och andra problem är "
|
||||
"troliga."
|
||||
|
||||
#: ../app/ui.js:410
|
||||
#: ../app/ui.js:413
|
||||
msgid "Connecting..."
|
||||
msgstr "Ansluter..."
|
||||
|
||||
#: ../app/ui.js:417
|
||||
#: ../app/ui.js:420
|
||||
msgid "Disconnecting..."
|
||||
msgstr "Kopplar ner..."
|
||||
|
||||
#: ../app/ui.js:423
|
||||
#: ../app/ui.js:426
|
||||
msgid "Reconnecting..."
|
||||
msgstr "Återansluter..."
|
||||
|
||||
#: ../app/ui.js:428
|
||||
#: ../app/ui.js:431
|
||||
msgid "Internal error"
|
||||
msgstr "Internt fel"
|
||||
|
||||
#: ../app/ui.js:1026
|
||||
msgid "Must set host"
|
||||
msgstr "Du måste specifiera en värd"
|
||||
|
||||
#: ../app/ui.js:1052
|
||||
#: ../app/ui.js:1079
|
||||
msgid "Failed to connect to server: "
|
||||
msgstr "Misslyckades att ansluta till servern: "
|
||||
|
||||
#: ../app/ui.js:1118
|
||||
#: ../app/ui.js:1145
|
||||
msgid "Connected (encrypted) to "
|
||||
msgstr "Ansluten (krypterat) till "
|
||||
|
||||
#: ../app/ui.js:1120
|
||||
#: ../app/ui.js:1147
|
||||
msgid "Connected (unencrypted) to "
|
||||
msgstr "Ansluten (okrypterat) till "
|
||||
|
||||
#: ../app/ui.js:1143
|
||||
#: ../app/ui.js:1170
|
||||
msgid "Something went wrong, connection is closed"
|
||||
msgstr "Något gick fel, anslutningen avslutades"
|
||||
|
||||
#: ../app/ui.js:1146
|
||||
#: ../app/ui.js:1173
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "Misslyckades att ansluta till servern"
|
||||
|
||||
#: ../app/ui.js:1158
|
||||
#: ../app/ui.js:1185
|
||||
msgid "Disconnected"
|
||||
msgstr "Frånkopplad"
|
||||
|
||||
#: ../app/ui.js:1173
|
||||
#: ../app/ui.js:1200
|
||||
msgid "New connection has been rejected with reason: "
|
||||
msgstr "Ny anslutning har blivit nekad med följande skäl: "
|
||||
|
||||
#: ../app/ui.js:1176
|
||||
#: ../app/ui.js:1203
|
||||
msgid "New connection has been rejected"
|
||||
msgstr "Ny anslutning har blivit nekad"
|
||||
|
||||
#: ../app/ui.js:1242
|
||||
#: ../app/ui.js:1269
|
||||
msgid "Credentials are required"
|
||||
msgstr "Användaruppgifter krävs"
|
||||
|
||||
#: ../vnc.html:55
|
||||
#: ../vnc.html:106
|
||||
msgid "noVNC encountered an error:"
|
||||
msgstr "noVNC stötte på ett problem:"
|
||||
|
||||
#: ../vnc.html:65
|
||||
#: ../vnc.html:116
|
||||
msgid "Hide/Show the control bar"
|
||||
msgstr "Göm/Visa kontrollbaren"
|
||||
|
||||
#: ../vnc.html:74
|
||||
#: ../vnc.html:125
|
||||
msgid "Drag"
|
||||
msgstr "Dra"
|
||||
|
||||
#: ../vnc.html:74
|
||||
msgid "Move/Drag Viewport"
|
||||
msgstr "Flytta/Dra Vyn"
|
||||
#: ../vnc.html:125
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "Flytta/Dra vyn"
|
||||
|
||||
#: ../vnc.html:80
|
||||
#: ../vnc.html:131
|
||||
msgid "Keyboard"
|
||||
msgstr "Tangentbord"
|
||||
|
||||
#: ../vnc.html:80
|
||||
msgid "Show Keyboard"
|
||||
msgstr "Visa Tangentbord"
|
||||
#: ../vnc.html:131
|
||||
msgid "Show keyboard"
|
||||
msgstr "Visa tangentbord"
|
||||
|
||||
#: ../vnc.html:85
|
||||
#: ../vnc.html:136
|
||||
msgid "Extra keys"
|
||||
msgstr "Extraknappar"
|
||||
|
||||
#: ../vnc.html:85
|
||||
msgid "Show Extra Keys"
|
||||
msgstr "Visa Extraknappar"
|
||||
#: ../vnc.html:136
|
||||
msgid "Show extra keys"
|
||||
msgstr "Visa extraknappar"
|
||||
|
||||
#: ../vnc.html:90
|
||||
#: ../vnc.html:141
|
||||
msgid "Ctrl"
|
||||
msgstr "Ctrl"
|
||||
|
||||
#: ../vnc.html:90
|
||||
#: ../vnc.html:141
|
||||
msgid "Toggle Ctrl"
|
||||
msgstr "Växla Ctrl"
|
||||
|
||||
#: ../vnc.html:93
|
||||
#: ../vnc.html:144
|
||||
msgid "Alt"
|
||||
msgstr "Alt"
|
||||
|
||||
#: ../vnc.html:93
|
||||
#: ../vnc.html:144
|
||||
msgid "Toggle Alt"
|
||||
msgstr "Växla Alt"
|
||||
|
||||
#: ../vnc.html:96
|
||||
#: ../vnc.html:147
|
||||
msgid "Toggle Windows"
|
||||
msgstr "Växla Windows"
|
||||
|
||||
#: ../vnc.html:96
|
||||
#: ../vnc.html:147
|
||||
msgid "Windows"
|
||||
msgstr "Windows"
|
||||
|
||||
#: ../vnc.html:99
|
||||
#: ../vnc.html:150
|
||||
msgid "Send Tab"
|
||||
msgstr "Skicka Tab"
|
||||
|
||||
#: ../vnc.html:99
|
||||
#: ../vnc.html:150
|
||||
msgid "Tab"
|
||||
msgstr "Tab"
|
||||
|
||||
#: ../vnc.html:102
|
||||
#: ../vnc.html:153
|
||||
msgid "Esc"
|
||||
msgstr "Esc"
|
||||
|
||||
#: ../vnc.html:102
|
||||
#: ../vnc.html:153
|
||||
msgid "Send Escape"
|
||||
msgstr "Skicka Escape"
|
||||
|
||||
#: ../vnc.html:105
|
||||
#: ../vnc.html:156
|
||||
msgid "Ctrl+Alt+Del"
|
||||
msgstr "Ctrl+Alt+Del"
|
||||
|
||||
#: ../vnc.html:105
|
||||
#: ../vnc.html:156
|
||||
msgid "Send Ctrl-Alt-Del"
|
||||
msgstr "Skicka Ctrl-Alt-Del"
|
||||
|
||||
#: ../vnc.html:112
|
||||
#: ../vnc.html:163
|
||||
msgid "Shutdown/Reboot"
|
||||
msgstr "Stäng av/Boota om"
|
||||
|
||||
#: ../vnc.html:112
|
||||
#: ../vnc.html:163
|
||||
msgid "Shutdown/Reboot..."
|
||||
msgstr "Stäng av/Boota om..."
|
||||
|
||||
#: ../vnc.html:118
|
||||
#: ../vnc.html:169
|
||||
msgid "Power"
|
||||
msgstr "Ström"
|
||||
|
||||
#: ../vnc.html:120
|
||||
#: ../vnc.html:171
|
||||
msgid "Shutdown"
|
||||
msgstr "Stäng av"
|
||||
|
||||
#: ../vnc.html:121
|
||||
#: ../vnc.html:172
|
||||
msgid "Reboot"
|
||||
msgstr "Boota om"
|
||||
|
||||
#: ../vnc.html:122
|
||||
#: ../vnc.html:173
|
||||
msgid "Reset"
|
||||
msgstr "Återställ"
|
||||
|
||||
#: ../vnc.html:127 ../vnc.html:133
|
||||
#: ../vnc.html:178 ../vnc.html:184
|
||||
msgid "Clipboard"
|
||||
msgstr "Urklipp"
|
||||
|
||||
#: ../vnc.html:135
|
||||
#: ../vnc.html:186
|
||||
msgid "Edit clipboard content in the textarea below."
|
||||
msgstr "Redigera urklippets innehåll i fältet nedan."
|
||||
|
||||
#: ../vnc.html:143
|
||||
msgid "Full Screen"
|
||||
#: ../vnc.html:194
|
||||
msgid "Full screen"
|
||||
msgstr "Fullskärm"
|
||||
|
||||
#: ../vnc.html:148 ../vnc.html:154
|
||||
#: ../vnc.html:199 ../vnc.html:205
|
||||
msgid "Settings"
|
||||
msgstr "Inställningar"
|
||||
|
||||
#: ../vnc.html:158
|
||||
msgid "Shared Mode"
|
||||
msgstr "Delat Läge"
|
||||
#: ../vnc.html:211
|
||||
msgid "Shared mode"
|
||||
msgstr "Delat läge"
|
||||
|
||||
#: ../vnc.html:161
|
||||
msgid "View Only"
|
||||
msgstr "Endast Visning"
|
||||
#: ../vnc.html:218
|
||||
msgid "View only"
|
||||
msgstr "Endast visning"
|
||||
|
||||
#: ../vnc.html:165
|
||||
msgid "Clip to Window"
|
||||
msgstr "Begränsa till Fönster"
|
||||
#: ../vnc.html:226
|
||||
msgid "Clip to window"
|
||||
msgstr "Begränsa till fönster"
|
||||
|
||||
#: ../vnc.html:168
|
||||
msgid "Scaling Mode:"
|
||||
#: ../vnc.html:231
|
||||
msgid "Scaling mode:"
|
||||
msgstr "Skalningsläge:"
|
||||
|
||||
#: ../vnc.html:170
|
||||
#: ../vnc.html:233
|
||||
msgid "None"
|
||||
msgstr "Ingen"
|
||||
|
||||
#: ../vnc.html:171
|
||||
msgid "Local Scaling"
|
||||
msgstr "Lokal Skalning"
|
||||
#: ../vnc.html:234
|
||||
msgid "Local scaling"
|
||||
msgstr "Lokal skalning"
|
||||
|
||||
#: ../vnc.html:172
|
||||
msgid "Remote Resizing"
|
||||
msgstr "Ändra Storlek"
|
||||
#: ../vnc.html:235
|
||||
msgid "Remote resizing"
|
||||
msgstr "Ändra storlek"
|
||||
|
||||
#: ../vnc.html:177
|
||||
#: ../vnc.html:240
|
||||
msgid "Advanced"
|
||||
msgstr "Avancerat"
|
||||
|
||||
#: ../vnc.html:180
|
||||
#: ../vnc.html:243
|
||||
msgid "Quality:"
|
||||
msgstr "Kvalitet:"
|
||||
|
||||
#: ../vnc.html:184
|
||||
#: ../vnc.html:247
|
||||
msgid "Compression level:"
|
||||
msgstr "Kompressionsnivå:"
|
||||
|
||||
#: ../vnc.html:189
|
||||
#: ../vnc.html:252
|
||||
msgid "Repeater ID:"
|
||||
msgstr "Repeater-ID:"
|
||||
|
||||
#: ../vnc.html:193
|
||||
#: ../vnc.html:256
|
||||
msgid "WebSocket"
|
||||
msgstr "WebSocket"
|
||||
|
||||
#: ../vnc.html:196
|
||||
#: ../vnc.html:261
|
||||
msgid "Encrypt"
|
||||
msgstr "Kryptera"
|
||||
|
||||
#: ../vnc.html:199
|
||||
#: ../vnc.html:266
|
||||
msgid "Host:"
|
||||
msgstr "Värd:"
|
||||
|
||||
#: ../vnc.html:203
|
||||
#: ../vnc.html:270
|
||||
msgid "Port:"
|
||||
msgstr "Port:"
|
||||
|
||||
#: ../vnc.html:207
|
||||
#: ../vnc.html:274
|
||||
msgid "Path:"
|
||||
msgstr "Sökväg:"
|
||||
|
||||
#: ../vnc.html:214
|
||||
msgid "Automatic Reconnect"
|
||||
msgstr "Automatisk Återanslutning"
|
||||
#: ../vnc.html:283
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "Automatisk återanslutning"
|
||||
|
||||
#: ../vnc.html:217
|
||||
msgid "Reconnect Delay (ms):"
|
||||
#: ../vnc.html:288
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "Fördröjning (ms):"
|
||||
|
||||
#: ../vnc.html:222
|
||||
msgid "Show Dot when No Cursor"
|
||||
#: ../vnc.html:295
|
||||
msgid "Show dot when no cursor"
|
||||
msgstr "Visa prick när ingen muspekare finns"
|
||||
|
||||
#: ../vnc.html:227
|
||||
#: ../vnc.html:302
|
||||
msgid "Logging:"
|
||||
msgstr "Loggning:"
|
||||
|
||||
#: ../vnc.html:236
|
||||
#: ../vnc.html:311
|
||||
msgid "Version:"
|
||||
msgstr "Version:"
|
||||
|
||||
#: ../vnc.html:244
|
||||
#: ../vnc.html:319
|
||||
msgid "Disconnect"
|
||||
msgstr "Koppla från"
|
||||
|
||||
#: ../vnc.html:267
|
||||
#: ../vnc.html:342
|
||||
msgid "Connect"
|
||||
msgstr "Anslut"
|
||||
|
||||
#: ../vnc.html:276
|
||||
#: ../vnc.html:351
|
||||
msgid "Server identity"
|
||||
msgstr "Server-identitet"
|
||||
|
||||
#: ../vnc.html:279
|
||||
#: ../vnc.html:354
|
||||
msgid "The server has provided the following identifying information:"
|
||||
msgstr "Servern har gett följande identifierande information:"
|
||||
|
||||
#: ../vnc.html:283
|
||||
#: ../vnc.html:357
|
||||
msgid "Fingerprint:"
|
||||
msgstr "Fingeravtryck:"
|
||||
|
||||
#: ../vnc.html:286
|
||||
#: ../vnc.html:361
|
||||
msgid ""
|
||||
"Please verify that the information is correct and press \"Approve\". "
|
||||
"Otherwise press \"Reject\"."
|
||||
|
|
@ -314,34 +310,37 @@ msgstr ""
|
|||
"Kontrollera att informationen är korrekt och tryck sedan \"Godkänn\". Tryck "
|
||||
"annars \"Neka\"."
|
||||
|
||||
#: ../vnc.html:291
|
||||
#: ../vnc.html:366
|
||||
msgid "Approve"
|
||||
msgstr "Godkänn"
|
||||
|
||||
#: ../vnc.html:292
|
||||
#: ../vnc.html:367
|
||||
msgid "Reject"
|
||||
msgstr "Neka"
|
||||
|
||||
#: ../vnc.html:300
|
||||
#: ../vnc.html:375
|
||||
msgid "Credentials"
|
||||
msgstr "Användaruppgifter"
|
||||
|
||||
#: ../vnc.html:304
|
||||
#: ../vnc.html:379
|
||||
msgid "Username:"
|
||||
msgstr "Användarnamn:"
|
||||
|
||||
#: ../vnc.html:308
|
||||
#: ../vnc.html:383
|
||||
msgid "Password:"
|
||||
msgstr "Lösenord:"
|
||||
|
||||
#: ../vnc.html:312
|
||||
msgid "Send Credentials"
|
||||
msgstr "Skicka Användaruppgifter"
|
||||
#: ../vnc.html:387
|
||||
msgid "Send credentials"
|
||||
msgstr "Skicka användaruppgifter"
|
||||
|
||||
#: ../vnc.html:321
|
||||
#: ../vnc.html:396
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
#~ msgid "Must set host"
|
||||
#~ msgstr "Du måste specifiera en värd"
|
||||
|
||||
#~ msgid "HTTPS is required for full functionality"
|
||||
#~ msgstr "HTTPS krävs för full funktionalitet"
|
||||
|
||||
|
|
|
|||
4
po/tr.po
4
po/tr.po
|
|
@ -1,6 +1,6 @@
|
|||
# Turkish translations for noVNC package
|
||||
# Turkish translation for noVNC.
|
||||
# Copyright (C) 2018 The noVNC Authors
|
||||
# Copyright (C) 2018 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Ömer ÇAKMAK <farukomercakmak@gmail.com>, 2018.
|
||||
#
|
||||
|
|
@ -116,7 +116,7 @@ msgid "Extra keys"
|
|||
msgstr "Ekstra tuşlar"
|
||||
|
||||
#: ../vnc.html:131
|
||||
msgid "Show Extra Keys"
|
||||
msgid "Show extra keys"
|
||||
msgstr "Ekstra tuşları göster"
|
||||
|
||||
#: ../vnc.html:136
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
#!/usr/bin/env node
|
||||
/*
|
||||
* xgettext-html: HTML gettext parser
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Copyright (C) 2018 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
const getopt = require('node-getopt');
|
||||
const { program } = require('commander');
|
||||
const jsdom = require("jsdom");
|
||||
const fs = require("fs");
|
||||
|
||||
const opt = getopt.create([
|
||||
['o', 'output=FILE', 'write output to specified file'],
|
||||
['h', 'help', 'display this help'],
|
||||
]).bindHelp().parseSystem();
|
||||
program
|
||||
.argument('<INPUT...>')
|
||||
.requiredOption('-o, --output <FILE>', 'write output to specified file')
|
||||
.parse(process.argv);
|
||||
|
||||
const strings = {};
|
||||
|
||||
|
|
@ -87,8 +87,8 @@ function process(elem, locator, enabled) {
|
|||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < opt.argv.length; i++) {
|
||||
const fn = opt.argv[i];
|
||||
for (let i = 0; i < program.args.length; i++) {
|
||||
const fn = program.args[i];
|
||||
const file = fs.readFileSync(fn, "utf8");
|
||||
const dom = new jsdom.JSDOM(file, { includeNodeLocations: true });
|
||||
const body = dom.window.document.body;
|
||||
|
|
@ -116,4 +116,4 @@ for (let str in strings) {
|
|||
output += "\n";
|
||||
}
|
||||
|
||||
fs.writeFileSync(opt.options.output, output);
|
||||
fs.writeFileSync(program.opts().output, output);
|
||||
|
|
|
|||
351
po/zh_CN.po
351
po/zh_CN.po
|
|
@ -1,5 +1,5 @@
|
|||
# Simplified Chinese translations for noVNC package.
|
||||
# Copyright (C) 2020 The noVNC Authors
|
||||
# Copyright (C) 2020 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Peter Dave Hello <hsu@peterdavehello.org>, 2018.
|
||||
#
|
||||
|
|
@ -7,278 +7,367 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: noVNC 1.1.0\n"
|
||||
"Report-Msgid-Bugs-To: novnc@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2018-01-10 00:53+0800\n"
|
||||
"PO-Revision-Date: 2020-01-02 13:19+0800\n"
|
||||
"Last-Translator: CUI Wei <ghostplant@qq.com>\n"
|
||||
"POT-Creation-Date: 2024-06-03 14:10+0200\n"
|
||||
"PO-Revision-Date: 2024-11-23 15:29+0800\n"
|
||||
"Last-Translator: wxtewx <wxtewx@qq.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: zh_CN\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 3.5\n"
|
||||
|
||||
#: ../app/ui.js:430
|
||||
#: ../app/ui.js:69
|
||||
msgid ""
|
||||
"Running without HTTPS is not recommended, crashes or other issues are likely."
|
||||
msgstr "不建议在没有 HTTPS 的情况下运行,可能会出现崩溃或出现其他问题。"
|
||||
|
||||
#: ../app/ui.js:410
|
||||
msgid "Connecting..."
|
||||
msgstr "连接中..."
|
||||
|
||||
#: ../app/ui.js:438
|
||||
msgid "Connected (encrypted) to "
|
||||
msgstr "已连接(已加密)到"
|
||||
|
||||
#: ../app/ui.js:440
|
||||
msgid "Connected (unencrypted) to "
|
||||
msgstr "已连接(未加密)到"
|
||||
|
||||
#: ../app/ui.js:446
|
||||
#: ../app/ui.js:417
|
||||
msgid "Disconnecting..."
|
||||
msgstr "正在断开连接..."
|
||||
|
||||
#: ../app/ui.js:450
|
||||
msgid "Disconnected"
|
||||
msgstr "已断开连接"
|
||||
|
||||
#: ../app/ui.js:1052 ../core/rfb.js:248
|
||||
msgid "Must set host"
|
||||
msgstr "必须设置主机"
|
||||
|
||||
#: ../app/ui.js:1101
|
||||
#: ../app/ui.js:423
|
||||
msgid "Reconnecting..."
|
||||
msgstr "重新连接中..."
|
||||
|
||||
#: ../app/ui.js:1140
|
||||
msgid "Password is required"
|
||||
msgstr "请提供密码"
|
||||
#: ../app/ui.js:428
|
||||
msgid "Internal error"
|
||||
msgstr "内部错误"
|
||||
|
||||
#: ../core/rfb.js:548
|
||||
msgid "Disconnect timeout"
|
||||
msgstr "超时断开"
|
||||
#: ../app/ui.js:1026
|
||||
msgid "Must set host"
|
||||
msgstr "必须设置主机"
|
||||
|
||||
#: ../vnc.html:89
|
||||
#: ../app/ui.js:1052
|
||||
msgid "Failed to connect to server: "
|
||||
msgstr "无法连接到服务器:"
|
||||
|
||||
#: ../app/ui.js:1118
|
||||
msgid "Connected (encrypted) to "
|
||||
msgstr "已连接(已加密)到"
|
||||
|
||||
#: ../app/ui.js:1120
|
||||
msgid "Connected (unencrypted) to "
|
||||
msgstr "已连接(未加密)到"
|
||||
|
||||
#: ../app/ui.js:1143
|
||||
msgid "Something went wrong, connection is closed"
|
||||
msgstr "出了点问题,连接已关闭"
|
||||
|
||||
#: ../app/ui.js:1146
|
||||
msgid "Failed to connect to server"
|
||||
msgstr "无法连接到服务器"
|
||||
|
||||
#: ../app/ui.js:1158
|
||||
msgid "Disconnected"
|
||||
msgstr "已断开连接"
|
||||
|
||||
#: ../app/ui.js:1173
|
||||
msgid "New connection has been rejected with reason: "
|
||||
msgstr "新连接被拒绝,原因如下:"
|
||||
|
||||
#: ../app/ui.js:1176
|
||||
msgid "New connection has been rejected"
|
||||
msgstr "新连接已被拒绝"
|
||||
|
||||
#: ../app/ui.js:1242
|
||||
msgid "Credentials are required"
|
||||
msgstr "需要凭证"
|
||||
|
||||
#: ../vnc.html:55
|
||||
msgid "noVNC encountered an error:"
|
||||
msgstr "noVNC 遇到一个错误:"
|
||||
|
||||
#: ../vnc.html:99
|
||||
#: ../vnc.html:65
|
||||
msgid "Hide/Show the control bar"
|
||||
msgstr "显示/隐藏控制栏"
|
||||
|
||||
#: ../vnc.html:106
|
||||
msgid "Move/Drag Viewport"
|
||||
#: ../vnc.html:74
|
||||
msgid "Drag"
|
||||
msgstr "拖动"
|
||||
|
||||
#: ../vnc.html:74
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "移动/拖动窗口"
|
||||
|
||||
#: ../vnc.html:106
|
||||
msgid "viewport drag"
|
||||
msgstr "窗口拖动"
|
||||
|
||||
#: ../vnc.html:112 ../vnc.html:115 ../vnc.html:118 ../vnc.html:121
|
||||
msgid "Active Mouse Button"
|
||||
msgstr "启动鼠标按键"
|
||||
|
||||
#: ../vnc.html:112
|
||||
msgid "No mousebutton"
|
||||
msgstr "禁用鼠标按键"
|
||||
|
||||
#: ../vnc.html:115
|
||||
msgid "Left mousebutton"
|
||||
msgstr "鼠标左键"
|
||||
|
||||
#: ../vnc.html:118
|
||||
msgid "Middle mousebutton"
|
||||
msgstr "鼠标中键"
|
||||
|
||||
#: ../vnc.html:121
|
||||
msgid "Right mousebutton"
|
||||
msgstr "鼠标右键"
|
||||
|
||||
#: ../vnc.html:124
|
||||
#: ../vnc.html:80
|
||||
msgid "Keyboard"
|
||||
msgstr "键盘"
|
||||
|
||||
#: ../vnc.html:124
|
||||
msgid "Show Keyboard"
|
||||
#: ../vnc.html:80
|
||||
msgid "Show keyboard"
|
||||
msgstr "显示键盘"
|
||||
|
||||
#: ../vnc.html:131
|
||||
#: ../vnc.html:85
|
||||
msgid "Extra keys"
|
||||
msgstr "额外按键"
|
||||
|
||||
#: ../vnc.html:131
|
||||
msgid "Show Extra Keys"
|
||||
#: ../vnc.html:85
|
||||
msgid "Show extra keys"
|
||||
msgstr "显示额外按键"
|
||||
|
||||
#: ../vnc.html:136
|
||||
#: ../vnc.html:90
|
||||
msgid "Ctrl"
|
||||
msgstr "Ctrl"
|
||||
|
||||
#: ../vnc.html:136
|
||||
#: ../vnc.html:90
|
||||
msgid "Toggle Ctrl"
|
||||
msgstr "切换 Ctrl"
|
||||
|
||||
#: ../vnc.html:136
|
||||
msgid "Edit clipboard content in the textarea below."
|
||||
msgstr "在下面的文本区域中编辑剪贴板内容。"
|
||||
|
||||
#: ../vnc.html:139
|
||||
#: ../vnc.html:93
|
||||
msgid "Alt"
|
||||
msgstr "Alt"
|
||||
|
||||
#: ../vnc.html:139
|
||||
#: ../vnc.html:93
|
||||
msgid "Toggle Alt"
|
||||
msgstr "切换 Alt"
|
||||
|
||||
#: ../vnc.html:142
|
||||
#: ../vnc.html:96
|
||||
msgid "Toggle Windows"
|
||||
msgstr "切换窗口"
|
||||
|
||||
#: ../vnc.html:96
|
||||
msgid "Windows"
|
||||
msgstr "窗口"
|
||||
|
||||
#: ../vnc.html:99
|
||||
msgid "Send Tab"
|
||||
msgstr "发送 Tab 键"
|
||||
|
||||
#: ../vnc.html:142
|
||||
#: ../vnc.html:99
|
||||
msgid "Tab"
|
||||
msgstr "Tab"
|
||||
|
||||
#: ../vnc.html:145
|
||||
#: ../vnc.html:102
|
||||
msgid "Esc"
|
||||
msgstr "Esc"
|
||||
|
||||
#: ../vnc.html:145
|
||||
#: ../vnc.html:102
|
||||
msgid "Send Escape"
|
||||
msgstr "发送 Escape 键"
|
||||
|
||||
#: ../vnc.html:148
|
||||
#: ../vnc.html:105
|
||||
msgid "Ctrl+Alt+Del"
|
||||
msgstr "Ctrl+Alt+Del"
|
||||
|
||||
#: ../vnc.html:148
|
||||
#: ../vnc.html:105
|
||||
msgid "Send Ctrl-Alt-Del"
|
||||
msgstr "发送 Ctrl+Alt+Del 键"
|
||||
|
||||
#: ../vnc.html:156
|
||||
#: ../vnc.html:112
|
||||
msgid "Shutdown/Reboot"
|
||||
msgstr "关机/重启"
|
||||
|
||||
#: ../vnc.html:156
|
||||
#: ../vnc.html:112
|
||||
msgid "Shutdown/Reboot..."
|
||||
msgstr "关机/重启..."
|
||||
|
||||
#: ../vnc.html:162
|
||||
#: ../vnc.html:118
|
||||
msgid "Power"
|
||||
msgstr "电源"
|
||||
|
||||
#: ../vnc.html:164
|
||||
#: ../vnc.html:120
|
||||
msgid "Shutdown"
|
||||
msgstr "关机"
|
||||
|
||||
#: ../vnc.html:165
|
||||
#: ../vnc.html:121
|
||||
msgid "Reboot"
|
||||
msgstr "重启"
|
||||
|
||||
#: ../vnc.html:166
|
||||
#: ../vnc.html:122
|
||||
msgid "Reset"
|
||||
msgstr "重置"
|
||||
|
||||
#: ../vnc.html:171 ../vnc.html:177
|
||||
#: ../vnc.html:127 ../vnc.html:133
|
||||
msgid "Clipboard"
|
||||
msgstr "剪贴板"
|
||||
|
||||
#: ../vnc.html:181
|
||||
msgid "Clear"
|
||||
msgstr "清除"
|
||||
#: ../vnc.html:135
|
||||
msgid "Edit clipboard content in the textarea below."
|
||||
msgstr "在下面的文本区域中编辑剪贴板内容。"
|
||||
|
||||
#: ../vnc.html:187
|
||||
msgid "Fullscreen"
|
||||
#: ../vnc.html:143
|
||||
msgid "Full screen"
|
||||
msgstr "全屏"
|
||||
|
||||
#: ../vnc.html:192 ../vnc.html:199
|
||||
#: ../vnc.html:148 ../vnc.html:154
|
||||
msgid "Settings"
|
||||
msgstr "设置"
|
||||
|
||||
#: ../vnc.html:200
|
||||
msgid "Encrypt"
|
||||
msgstr "加密"
|
||||
|
||||
#: ../vnc.html:202
|
||||
msgid "Shared Mode"
|
||||
#: ../vnc.html:158
|
||||
msgid "Shared mode"
|
||||
msgstr "分享模式"
|
||||
|
||||
#: ../vnc.html:205
|
||||
msgid "View Only"
|
||||
#: ../vnc.html:161
|
||||
msgid "View only"
|
||||
msgstr "仅查看"
|
||||
|
||||
#: ../vnc.html:209
|
||||
msgid "Clip to Window"
|
||||
#: ../vnc.html:165
|
||||
msgid "Clip to window"
|
||||
msgstr "限制/裁切窗口大小"
|
||||
|
||||
#: ../vnc.html:212
|
||||
msgid "Scaling Mode:"
|
||||
#: ../vnc.html:168
|
||||
msgid "Scaling mode:"
|
||||
msgstr "缩放模式:"
|
||||
|
||||
#: ../vnc.html:214
|
||||
#: ../vnc.html:170
|
||||
msgid "None"
|
||||
msgstr "无"
|
||||
|
||||
#: ../vnc.html:215
|
||||
msgid "Local Scaling"
|
||||
#: ../vnc.html:171
|
||||
msgid "Local scaling"
|
||||
msgstr "本地缩放"
|
||||
|
||||
#: ../vnc.html:216
|
||||
msgid "Local Downscaling"
|
||||
msgstr "降低本地尺寸"
|
||||
|
||||
#: ../vnc.html:217
|
||||
msgid "Remote Resizing"
|
||||
#: ../vnc.html:172
|
||||
msgid "Remote resizing"
|
||||
msgstr "远程调整大小"
|
||||
|
||||
#: ../vnc.html:222
|
||||
#: ../vnc.html:177
|
||||
msgid "Advanced"
|
||||
msgstr "高级"
|
||||
|
||||
#: ../vnc.html:225
|
||||
msgid "Local Cursor"
|
||||
msgstr "本地光标"
|
||||
#: ../vnc.html:180
|
||||
msgid "Quality:"
|
||||
msgstr "品质:"
|
||||
|
||||
#: ../vnc.html:229
|
||||
#: ../vnc.html:184
|
||||
msgid "Compression level:"
|
||||
msgstr "压缩级别:"
|
||||
|
||||
#: ../vnc.html:189
|
||||
msgid "Repeater ID:"
|
||||
msgstr "中继站 ID"
|
||||
|
||||
#: ../vnc.html:233
|
||||
#: ../vnc.html:193
|
||||
msgid "WebSocket"
|
||||
msgstr "WebSocket"
|
||||
|
||||
#: ../vnc.html:239
|
||||
#: ../vnc.html:196
|
||||
msgid "Encrypt"
|
||||
msgstr "加密"
|
||||
|
||||
#: ../vnc.html:199
|
||||
msgid "Host:"
|
||||
msgstr "主机:"
|
||||
|
||||
#: ../vnc.html:243
|
||||
#: ../vnc.html:203
|
||||
msgid "Port:"
|
||||
msgstr "端口:"
|
||||
|
||||
#: ../vnc.html:247
|
||||
#: ../vnc.html:207
|
||||
msgid "Path:"
|
||||
msgstr "路径:"
|
||||
|
||||
#: ../vnc.html:254
|
||||
msgid "Automatic Reconnect"
|
||||
#: ../vnc.html:214
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "自动重新连接"
|
||||
|
||||
#: ../vnc.html:257
|
||||
msgid "Reconnect Delay (ms):"
|
||||
#: ../vnc.html:217
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "重新连接间隔 (ms):"
|
||||
|
||||
#: ../vnc.html:263
|
||||
#: ../vnc.html:222
|
||||
msgid "Show dot when no cursor"
|
||||
msgstr "无光标时显示点"
|
||||
|
||||
#: ../vnc.html:227
|
||||
msgid "Logging:"
|
||||
msgstr "日志级别:"
|
||||
|
||||
#: ../vnc.html:275
|
||||
#: ../vnc.html:236
|
||||
msgid "Version:"
|
||||
msgstr "版本:"
|
||||
|
||||
#: ../vnc.html:244
|
||||
msgid "Disconnect"
|
||||
msgstr "断开连接"
|
||||
|
||||
#: ../vnc.html:294
|
||||
#: ../vnc.html:267
|
||||
msgid "Connect"
|
||||
msgstr "连接"
|
||||
|
||||
#: ../vnc.html:276
|
||||
msgid "Server identity"
|
||||
msgstr "服务器身份"
|
||||
|
||||
#: ../vnc.html:279
|
||||
msgid "The server has provided the following identifying information:"
|
||||
msgstr "服务器提供了以下识别信息:"
|
||||
|
||||
#: ../vnc.html:283
|
||||
msgid "Fingerprint:"
|
||||
msgstr "指纹:"
|
||||
|
||||
#: ../vnc.html:286
|
||||
msgid ""
|
||||
"Please verify that the information is correct and press \"Approve\". "
|
||||
"Otherwise press \"Reject\"."
|
||||
msgstr "请核实信息是否正确,并按 “同意”,否则按 “拒绝”。"
|
||||
|
||||
#: ../vnc.html:291
|
||||
msgid "Approve"
|
||||
msgstr "同意"
|
||||
|
||||
#: ../vnc.html:292
|
||||
msgid "Reject"
|
||||
msgstr "拒绝"
|
||||
|
||||
#: ../vnc.html:300
|
||||
msgid "Credentials"
|
||||
msgstr "凭证"
|
||||
|
||||
#: ../vnc.html:304
|
||||
msgid "Username:"
|
||||
msgstr "用户名:"
|
||||
|
||||
#: ../vnc.html:308
|
||||
msgid "Password:"
|
||||
msgstr "密码:"
|
||||
|
||||
#: ../vnc.html:318
|
||||
#: ../vnc.html:312
|
||||
msgid "Send credentials"
|
||||
msgstr "发送凭证"
|
||||
|
||||
#: ../vnc.html:321
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
#: ../vnc.html:334
|
||||
msgid "Canvas not supported."
|
||||
msgstr "不支持 Canvas。"
|
||||
#~ msgid "Password is required"
|
||||
#~ msgstr "请提供密码"
|
||||
|
||||
#~ msgid "Disconnect timeout"
|
||||
#~ msgstr "超时断开"
|
||||
|
||||
#~ msgid "viewport drag"
|
||||
#~ msgstr "窗口拖动"
|
||||
|
||||
#~ msgid "Active Mouse Button"
|
||||
#~ msgstr "启动鼠标按键"
|
||||
|
||||
#~ msgid "No mousebutton"
|
||||
#~ msgstr "禁用鼠标按键"
|
||||
|
||||
#~ msgid "Left mousebutton"
|
||||
#~ msgstr "鼠标左键"
|
||||
|
||||
#~ msgid "Middle mousebutton"
|
||||
#~ msgstr "鼠标中键"
|
||||
|
||||
#~ msgid "Right mousebutton"
|
||||
#~ msgstr "鼠标右键"
|
||||
|
||||
#~ msgid "Clear"
|
||||
#~ msgstr "清除"
|
||||
|
||||
#~ msgid "Local Downscaling"
|
||||
#~ msgstr "降低本地尺寸"
|
||||
|
||||
#~ msgid "Local Cursor"
|
||||
#~ msgstr "本地光标"
|
||||
|
||||
#~ msgid "Canvas not supported."
|
||||
#~ msgstr "不支持 Canvas。"
|
||||
|
|
|
|||
24
po/zh_TW.po
24
po/zh_TW.po
|
|
@ -1,5 +1,5 @@
|
|||
# Traditional Chinese translations for noVNC package.
|
||||
# Copyright (C) 2018 The noVNC Authors
|
||||
# Copyright (C) 2018 The noVNC authors
|
||||
# This file is distributed under the same license as the noVNC package.
|
||||
# Peter Dave Hello <hsu@peterdavehello.org>, 2018.
|
||||
#
|
||||
|
|
@ -77,7 +77,7 @@ msgid "Hide/Show the control bar"
|
|||
msgstr "顯示/隱藏控制列"
|
||||
|
||||
#: ../vnc.html:106
|
||||
msgid "Move/Drag Viewport"
|
||||
msgid "Move/Drag viewport"
|
||||
msgstr "拖放顯示範圍"
|
||||
|
||||
#: ../vnc.html:106
|
||||
|
|
@ -109,7 +109,7 @@ msgid "Keyboard"
|
|||
msgstr "鍵盤"
|
||||
|
||||
#: ../vnc.html:124
|
||||
msgid "Show Keyboard"
|
||||
msgid "Show keyboard"
|
||||
msgstr "顯示鍵盤"
|
||||
|
||||
#: ../vnc.html:131
|
||||
|
|
@ -117,7 +117,7 @@ msgid "Extra keys"
|
|||
msgstr "額外按鍵"
|
||||
|
||||
#: ../vnc.html:131
|
||||
msgid "Show Extra Keys"
|
||||
msgid "Show extra keys"
|
||||
msgstr "顯示額外按鍵"
|
||||
|
||||
#: ../vnc.html:136
|
||||
|
|
@ -201,19 +201,19 @@ msgid "Settings"
|
|||
msgstr "設定"
|
||||
|
||||
#: ../vnc.html:202
|
||||
msgid "Shared Mode"
|
||||
msgid "Shared mode"
|
||||
msgstr "分享模式"
|
||||
|
||||
#: ../vnc.html:205
|
||||
msgid "View Only"
|
||||
msgid "View only"
|
||||
msgstr "僅檢視"
|
||||
|
||||
#: ../vnc.html:209
|
||||
msgid "Clip to Window"
|
||||
msgid "Clip to window"
|
||||
msgstr "限制/裁切視窗大小"
|
||||
|
||||
#: ../vnc.html:212
|
||||
msgid "Scaling Mode:"
|
||||
msgid "Scaling mode:"
|
||||
msgstr "縮放模式:"
|
||||
|
||||
#: ../vnc.html:214
|
||||
|
|
@ -221,11 +221,11 @@ msgid "None"
|
|||
msgstr "無"
|
||||
|
||||
#: ../vnc.html:215
|
||||
msgid "Local Scaling"
|
||||
msgid "Local scaling"
|
||||
msgstr "本機縮放"
|
||||
|
||||
#: ../vnc.html:216
|
||||
msgid "Remote Resizing"
|
||||
msgid "Remote resizing"
|
||||
msgstr "遠端調整大小"
|
||||
|
||||
#: ../vnc.html:221
|
||||
|
|
@ -257,11 +257,11 @@ msgid "Path:"
|
|||
msgstr "路徑:"
|
||||
|
||||
#: ../vnc.html:249
|
||||
msgid "Automatic Reconnect"
|
||||
msgid "Automatic reconnect"
|
||||
msgstr "自動重新連線"
|
||||
|
||||
#: ../vnc.html:252
|
||||
msgid "Reconnect Delay (ms):"
|
||||
msgid "Reconnect delay (ms):"
|
||||
msgstr "重新連線間隔 (ms):"
|
||||
|
||||
#: ../vnc.html:258
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
# "vnc": "localhost:5902"
|
||||
#}
|
||||
#}
|
||||
snapctl get services | jq -c '.[]' | while read service; do # for each service the user sepcified..
|
||||
snapctl get services | jq -c '.[]' | while read service; do # for each service the user specified..
|
||||
# get the important data for the service (listen port, VNC host:port)
|
||||
listen_port="$(echo $service | jq --raw-output '.listen')"
|
||||
vnc_host_port="$(echo $service | jq --raw-output '.vnc')" # --raw-output removes any quotation marks from the output
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ parts:
|
|||
- jq
|
||||
|
||||
websockify:
|
||||
source: https://github.com/novnc/websockify/archive/v0.12.0.tar.gz
|
||||
source: https://github.com/novnc/websockify/archive/v0.13.0.tar.gz
|
||||
plugin: python
|
||||
stage-packages:
|
||||
- python3-numpy
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
import * as chai from '../node_modules/chai/chai.js';
|
||||
import sinon from '../node_modules/sinon/pkg/sinon-esm.js';
|
||||
import sinonChai from '../node_modules/sinon-chai/lib/sinon-chai.js';
|
||||
|
||||
window.expect = chai.expect;
|
||||
|
||||
window.sinon = sinon;
|
||||
chai.use(sinonChai);
|
||||
|
||||
// noVNC specific assertions
|
||||
chai.use(function (_chai, utils) {
|
||||
function _equal(a, b) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,15 @@ export default class FakeWebSocket {
|
|||
} else {
|
||||
data = new Uint8Array(data);
|
||||
}
|
||||
if (this.bufferedAmount + data.length > this._sendQueue.length) {
|
||||
let newlen = this._sendQueue.length;
|
||||
while (this.bufferedAmount + data.length > newlen) {
|
||||
newlen *= 2;
|
||||
}
|
||||
let newbuf = new Uint8Array(newlen);
|
||||
newbuf.set(this._sendQueue);
|
||||
this._sendQueue = newbuf;
|
||||
}
|
||||
this._sendQueue.set(data, this.bufferedAmount);
|
||||
this.bufferedAmount += data.length;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* noVNC: HTML5 VNC client
|
||||
* Copyright (C) 2018 The noVNC Authors
|
||||
* Copyright (C) 2018 The noVNC authors
|
||||
* Licensed under MPL 2.0 (see LICENSE.txt)
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
const expect = chai.expect;
|
||||
|
||||
import Base64 from '../core/base64.js';
|
||||
|
||||
describe('Base64 Tools', function () {
|
||||
describe('Base64 tools', function () {
|
||||
"use strict";
|
||||
|
||||
const BIN_ARR = new Array(256);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
const expect = chai.expect;
|
||||
|
||||
import { isMac, isWindows, isIOS, isAndroid, isChromeOS,
|
||||
isSafari, isFirefox, isChrome, isChromium, isOpera, isEdge,
|
||||
isGecko, isWebKit, isBlink } from '../core/util/browser.js';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
const expect = chai.expect;
|
||||
|
||||
import Websock from '../core/websock.js';
|
||||
import Display from '../core/display.js';
|
||||
|
||||
|
|
@ -31,7 +29,7 @@ function testDecodeRect(decoder, x, y, width, height, data, display, depth) {
|
|||
return done;
|
||||
}
|
||||
|
||||
describe('CopyRect Decoder', function () {
|
||||
describe('CopyRect decoder', function () {
|
||||
let decoder;
|
||||
let display;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
const expect = chai.expect;
|
||||
|
||||
import { inflateInit, inflate } from "../vendor/pako/lib/zlib/inflate.js";
|
||||
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
|
||||
import Deflator from "../core/deflator.js";
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
const expect = chai.expect;
|
||||
|
||||
import Base64 from '../core/base64.js';
|
||||
import Display from '../core/display.js';
|
||||
|
||||
describe('Display/Canvas Helper', function () {
|
||||
describe('Display/Canvas helper', function () {
|
||||
const checkedData = new Uint8ClampedArray([
|
||||
0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
|
||||
0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
const expect = chai.expect;
|
||||
|
||||
import EventTargetMixin from '../core/util/eventtarget.js';
|
||||
|
||||
import GestureHandler from '../core/input/gesturehandler.js';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,241 @@
|
|||
import Websock from '../core/websock.js';
|
||||
import Display from '../core/display.js';
|
||||
|
||||
import { H264Parser } from '../core/decoders/h264.js';
|
||||
import H264Decoder from '../core/decoders/h264.js';
|
||||
import Base64 from '../core/base64.js';
|
||||
import { supportsWebCodecsH264Decode } from '../core/util/browser.js';
|
||||
|
||||
import FakeWebSocket from './fake.websocket.js';
|
||||
|
||||
/* This is a 3 frame 16x16 video where the first frame is solid red, the second
|
||||
* is solid green and the third is solid blue.
|
||||
*
|
||||
* The colour space is BT.709. It is encoded into the stream.
|
||||
*/
|
||||
const redGreenBlue16x16Video = new Uint8Array(Base64.decode(
|
||||
'AAAAAWdCwBTZnpuAgICgAAADACAAAAZB4oVNAAAAAWjJYyyAAAABBgX//4HcRem95tlIt5Ys' +
|
||||
'2CDZI+7veDI2NCAtIGNvcmUgMTY0IHIzMTA4IDMxZTE5ZjkgLSBILjI2NC9NUEVHLTQgQVZD' +
|
||||
'IGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDIzIC0gaHR0cDovL3d3dy52aWRlb2xhbi5vcmcv' +
|
||||
'eDI2NC5odG1sIC0gb3B0aW9uczogY2FiYWM9MCByZWY9NSBkZWJsb2NrPTE6MDowIGFuYWx5' +
|
||||
'c2U9MHgxOjB4MTExIG1lPWhleCBzdWJtZT04IHBzeT0xIHBzeV9yZD0xLjAwOjAuMDAgbWl4' +
|
||||
'ZWRfcmVmPTEgbWVfcmFuZ2U9MTYgY2hyb21hX21lPTEgdHJlbGxpcz0yIDh4OGRjdD0wIGNx' +
|
||||
'bT0wIGRlYWR6b25lPTIxLDExIGZhc3RfcHNraXA9MSBjaHJvbWFfcXBfb2Zmc2V0PS0yIHRo' +
|
||||
'cmVhZHM9MSBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNp' +
|
||||
'bWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9' +
|
||||
'MCBiZnJhbWVzPTAgd2VpZ2h0cD0wIGtleWludD1pbmZpbml0ZSBrZXlpbnRfbWluPTI1IHNj' +
|
||||
'ZW5lY3V0PTQwIGludHJhX3JlZnJlc2g9MCByY19sb29rYWhlYWQ9NTAgcmM9YWJyIG1idHJl' +
|
||||
'ZT0xIGJpdHJhdGU9NDAwIHJhdGV0b2w9MS4wIHFjb21wPTAuNjAgcXBtaW49MCBxcG1heD02' +
|
||||
'OSBxcHN0ZXA9NCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAABZYiEBrxmKAAPVccAAS04' +
|
||||
'4AA5DRJMnkycJk4TPwAAAAFBiIga8RigADVVHAAGaGOAANtuAAAAAUGIkBr///wRRQABVf8c' +
|
||||
'AAcho4AAiD4='));
|
||||
|
||||
function createSolidColorFrameBuffer(color, width, height) {
|
||||
const r = (color >> 24) & 0xff;
|
||||
const g = (color >> 16) & 0xff;
|
||||
const b = (color >> 8) & 0xff;
|
||||
const a = (color >> 0) & 0xff;
|
||||
|
||||
const size = width * height * 4;
|
||||
let array = new Uint8ClampedArray(size);
|
||||
|
||||
for (let i = 0; i < size / 4; ++i) {
|
||||
array[i * 4 + 0] = r;
|
||||
array[i * 4 + 1] = g;
|
||||
array[i * 4 + 2] = b;
|
||||
array[i * 4 + 3] = a;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
function makeMessageHeader(length, resetContext, resetAllContexts) {
|
||||
let flags = 0;
|
||||
if (resetContext) {
|
||||
flags |= 1;
|
||||
}
|
||||
if (resetAllContexts) {
|
||||
flags |= 2;
|
||||
}
|
||||
|
||||
let header = new Uint8Array(8);
|
||||
let i = 0;
|
||||
|
||||
let appendU32 = (v) => {
|
||||
header[i++] = (v >> 24) & 0xff;
|
||||
header[i++] = (v >> 16) & 0xff;
|
||||
header[i++] = (v >> 8) & 0xff;
|
||||
header[i++] = v & 0xff;
|
||||
};
|
||||
|
||||
appendU32(length);
|
||||
appendU32(flags);
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
function wrapRectData(data, resetContext, resetAllContexts) {
|
||||
let header = makeMessageHeader(data.length, resetContext, resetAllContexts);
|
||||
return Array.from(header).concat(Array.from(data));
|
||||
}
|
||||
|
||||
function testDecodeRect(decoder, x, y, width, height, data, display, depth) {
|
||||
let sock;
|
||||
let done = false;
|
||||
|
||||
sock = new Websock;
|
||||
sock.open("ws://example.com");
|
||||
|
||||
sock.on('message', () => {
|
||||
done = decoder.decodeRect(x, y, width, height, sock, display, depth);
|
||||
});
|
||||
|
||||
// Empty messages are filtered at multiple layers, so we need to
|
||||
// do a direct call
|
||||
if (data.length === 0) {
|
||||
done = decoder.decodeRect(x, y, width, height, sock, display, depth);
|
||||
} else {
|
||||
sock._websocket._receiveData(new Uint8Array(data));
|
||||
}
|
||||
|
||||
display.flip();
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
function almost(a, b) {
|
||||
let diff = Math.abs(a - b);
|
||||
return diff < 5;
|
||||
}
|
||||
|
||||
describe('H.264 parser', function () {
|
||||
it('should parse constrained baseline video', function () {
|
||||
let parser = new H264Parser(redGreenBlue16x16Video);
|
||||
|
||||
let frame = parser.parse();
|
||||
expect(frame).to.have.property('key', true);
|
||||
|
||||
expect(parser).to.have.property('profileIdc', 66);
|
||||
expect(parser).to.have.property('constraintSet', 192);
|
||||
expect(parser).to.have.property('levelIdc', 20);
|
||||
|
||||
frame = parser.parse();
|
||||
expect(frame).to.have.property('key', false);
|
||||
|
||||
frame = parser.parse();
|
||||
expect(frame).to.have.property('key', false);
|
||||
|
||||
frame = parser.parse();
|
||||
expect(frame).to.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
describe('H.264 decoder unit test', function () {
|
||||
let decoder;
|
||||
|
||||
beforeEach(function () {
|
||||
if (!supportsWebCodecsH264Decode) {
|
||||
this.skip();
|
||||
return;
|
||||
}
|
||||
decoder = new H264Decoder();
|
||||
});
|
||||
|
||||
it('creates and resets context', function () {
|
||||
let context = decoder._getContext(1, 2, 3, 4);
|
||||
expect(context._width).to.equal(3);
|
||||
expect(context._height).to.equal(4);
|
||||
expect(decoder._contexts).to.not.be.empty;
|
||||
decoder._resetContext(1, 2, 3, 4);
|
||||
expect(decoder._contexts).to.be.empty;
|
||||
});
|
||||
|
||||
it('resets all contexts', function () {
|
||||
decoder._getContext(0, 0, 1, 1);
|
||||
decoder._getContext(2, 2, 1, 1);
|
||||
expect(decoder._contexts).to.not.be.empty;
|
||||
decoder._resetAllContexts();
|
||||
expect(decoder._contexts).to.be.empty;
|
||||
});
|
||||
|
||||
it('caches contexts', function () {
|
||||
let c1 = decoder._getContext(1, 2, 3, 4);
|
||||
c1.lastUsed = 1;
|
||||
let c2 = decoder._getContext(1, 2, 3, 4);
|
||||
c2.lastUsed = 2;
|
||||
expect(Object.keys(decoder._contexts).length).to.equal(1);
|
||||
expect(c1.lastUsed).to.equal(c2.lastUsed);
|
||||
});
|
||||
|
||||
it('deletes oldest context', function () {
|
||||
for (let i = 0; i < 65; ++i) {
|
||||
let context = decoder._getContext(i, 0, 1, 1);
|
||||
context.lastUsed = i;
|
||||
}
|
||||
|
||||
expect(decoder._findOldestContextId()).to.equal('1,0,1,1');
|
||||
expect(decoder._contexts[decoder._contextId(0, 0, 1, 1)]).to.be.undefined;
|
||||
expect(decoder._contexts[decoder._contextId(1, 0, 1, 1)]).to.not.be.null;
|
||||
expect(decoder._contexts[decoder._contextId(63, 0, 1, 1)]).to.not.be.null;
|
||||
expect(decoder._contexts[decoder._contextId(64, 0, 1, 1)]).to.not.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
describe('H.264 decoder functional test', function () {
|
||||
let decoder;
|
||||
let display;
|
||||
|
||||
before(FakeWebSocket.replace);
|
||||
after(FakeWebSocket.restore);
|
||||
|
||||
beforeEach(function () {
|
||||
if (!supportsWebCodecsH264Decode) {
|
||||
this.skip();
|
||||
return;
|
||||
}
|
||||
decoder = new H264Decoder();
|
||||
display = new Display(document.createElement('canvas'));
|
||||
display.resize(16, 16);
|
||||
});
|
||||
|
||||
it('should handle H.264 rect', async function () {
|
||||
let data = wrapRectData(redGreenBlue16x16Video, false, false);
|
||||
let done = testDecodeRect(decoder, 0, 0, 16, 16, data, display, 24);
|
||||
expect(done).to.be.true;
|
||||
await display.flush();
|
||||
let targetData = createSolidColorFrameBuffer(0x0000ffff, 16, 16);
|
||||
expect(display).to.have.displayed(targetData, almost);
|
||||
});
|
||||
|
||||
it('should handle specific context reset', async function () {
|
||||
let data = wrapRectData(redGreenBlue16x16Video, false, false);
|
||||
let done = testDecodeRect(decoder, 0, 0, 16, 16, data, display, 24);
|
||||
expect(done).to.be.true;
|
||||
await display.flush();
|
||||
let targetData = createSolidColorFrameBuffer(0x0000ffff, 16, 16);
|
||||
expect(display).to.have.displayed(targetData, almost);
|
||||
|
||||
data = wrapRectData([], true, false);
|
||||
done = testDecodeRect(decoder, 0, 0, 16, 16, data, display, 24);
|
||||
expect(done).to.be.true;
|
||||
await display.flush();
|
||||
|
||||
expect(decoder._contexts[decoder._contextId(0, 0, 16, 16)]._decoder).to.be.null;
|
||||
});
|
||||
|
||||
it('should handle global context reset', async function () {
|
||||
let data = wrapRectData(redGreenBlue16x16Video, false, false);
|
||||
let done = testDecodeRect(decoder, 0, 0, 16, 16, data, display, 24);
|
||||
expect(done).to.be.true;
|
||||
await display.flush();
|
||||
let targetData = createSolidColorFrameBuffer(0x0000ffff, 16, 16);
|
||||
expect(display).to.have.displayed(targetData, almost);
|
||||
|
||||
data = wrapRectData([], false, true);
|
||||
done = testDecodeRect(decoder, 0, 0, 16, 16, data, display, 24);
|
||||
expect(done).to.be.true;
|
||||
await display.flush();
|
||||
|
||||
expect(decoder._contexts[decoder._contextId(0, 0, 16, 16)]._decoder).to.be.null;
|
||||
});
|
||||
});
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
const expect = chai.expect;
|
||||
|
||||
import keysyms from '../core/input/keysymdef.js';
|
||||
import * as KeyboardUtil from "../core/input/util.js";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
const expect = chai.expect;
|
||||
|
||||
import Websock from '../core/websock.js';
|
||||
import Display from '../core/display.js';
|
||||
|
||||
|
|
@ -38,7 +36,7 @@ function push32(arr, num) {
|
|||
num & 0xFF);
|
||||
}
|
||||
|
||||
describe('Hextile Decoder', function () {
|
||||
describe('Hextile decoder', function () {
|
||||
let decoder;
|
||||
let display;
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue