You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by mj...@apache.org on 2020/01/26 22:06:37 UTC
[guacamole-website] branch asf-site updated: Deploy documentation
and draft release notes for 1.1.0-RC1.
This is an automated email from the ASF dual-hosted git repository.
mjumper pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/guacamole-website.git
The following commit(s) were added to refs/heads/asf-site by this push:
new 443b7cc Deploy documentation and draft release notes for 1.1.0-RC1.
443b7cc is described below
commit 443b7cc276df1fe75e159ded10be840117fa8512
Author: Michael Jumper <mj...@apache.org>
AuthorDate: Sun Jan 26 14:06:20 2020 -0800
Deploy documentation and draft release notes for 1.1.0-RC1.
---
.../guacamole-common-js/ArrayBufferReader.js.html | 136 +
.../guacamole-common-js/ArrayBufferWriter.js.html | 184 +
.../AudioContextFactory.js.html | 140 +
.../1.1.0/guacamole-common-js/AudioPlayer.js.html | 566 ++
.../guacamole-common-js/AudioRecorder.js.html | 632 ++
.../1.1.0/guacamole-common-js/BlobReader.js.html | 188 +
.../1.1.0/guacamole-common-js/BlobWriter.js.html | 306 +
.../doc/1.1.0/guacamole-common-js/Client.js.html | 1751 ++++
.../guacamole-common-js/DataURIReader.js.html | 144 +
.../doc/1.1.0/guacamole-common-js/Display.js.html | 1543 ++++
.../Guacamole.ArrayBufferReader.html | 456 +
.../Guacamole.ArrayBufferWriter.html | 758 ++
.../Guacamole.AudioContextFactory.html | 341 +
.../guacamole-common-js/Guacamole.AudioPlayer.html | 734 ++
.../Guacamole.AudioRecorder.html | 828 ++
.../guacamole-common-js/Guacamole.BlobReader.html | 700 ++
.../guacamole-common-js/Guacamole.BlobWriter.html | 1073 +++
.../Guacamole.ChainedTunnel.html | 1527 ++++
.../guacamole-common-js/Guacamole.Client.html | 5195 +++++++++++
.../Guacamole.DataURIReader.html | 435 +
.../Guacamole.Display.VisibleLayer.html | 6600 ++++++++++++++
.../guacamole-common-js/Guacamole.Display.html | 9066 ++++++++++++++++++++
.../guacamole-common-js/Guacamole.HTTPTunnel.html | 1609 ++++
.../guacamole-common-js/Guacamole.InputSink.html | 380 +
.../guacamole-common-js/Guacamole.InputStream.html | 716 ++
.../guacamole-common-js/Guacamole.IntegerPool.html | 504 ++
.../guacamole-common-js/Guacamole.JSONReader.html | 678 ++
.../Guacamole.Keyboard.ModifierState.html | 705 ++
.../guacamole-common-js/Guacamole.Keyboard.html | 1666 ++++
.../guacamole-common-js/Guacamole.Layer.Pixel.html | 554 ++
.../1.1.0/guacamole-common-js/Guacamole.Layer.html | 5716 ++++++++++++
.../guacamole-common-js/Guacamole.Mouse.State.html | 1069 +++
.../Guacamole.Mouse.Touchpad.html | 914 ++
.../Guacamole.Mouse.Touchscreen.html | 980 +++
.../1.1.0/guacamole-common-js/Guacamole.Mouse.html | 1286 +++
.../guacamole-common-js/Guacamole.Object.html | 1120 +++
.../Guacamole.OnScreenKeyboard.Key.html | 656 ++
.../Guacamole.OnScreenKeyboard.Layout.html | 687 ++
.../Guacamole.OnScreenKeyboard.html | 986 +++
.../Guacamole.OutputStream.html | 692 ++
.../guacamole-common-js/Guacamole.Parser.html | 484 ++
.../Guacamole.RawAudioFormat.html | 621 ++
.../Guacamole.RawAudioPlayer.html | 638 ++
.../Guacamole.RawAudioRecorder.html | 814 ++
.../Guacamole.SessionRecording.html | 1715 ++++
.../Guacamole.StaticHTTPTunnel.html | 1611 ++++
.../guacamole-common-js/Guacamole.Status.html | 606 ++
.../Guacamole.StringReader.html | 456 +
.../Guacamole.StringWriter.html | 595 ++
.../guacamole-common-js/Guacamole.Tunnel.html | 1545 ++++
.../guacamole-common-js/Guacamole.VideoPlayer.html | 756 ++
.../Guacamole.WebSocketTunnel.html | 1511 ++++
.../doc/1.1.0/guacamole-common-js/Guacamole.html | 332 +
.../1.1.0/guacamole-common-js/InputSink.js.html | 189 +
.../1.1.0/guacamole-common-js/InputStream.js.html | 131 +
.../1.1.0/guacamole-common-js/IntegerPool.js.html | 137 +
.../1.1.0/guacamole-common-js/JSONReader.js.html | 175 +
.../doc/1.1.0/guacamole-common-js/Keyboard.js.html | 1574 ++++
.../doc/1.1.0/guacamole-common-js/Layer.js.html | 1039 +++
.../doc/1.1.0/guacamole-common-js/Mouse.js.html | 1148 +++
.../1.1.0/guacamole-common-js/Namespace.js.html | 87 +
.../doc/1.1.0/guacamole-common-js/Object.js.html | 271 +
.../guacamole-common-js/OnScreenKeyboard.js.html | 1004 +++
.../1.1.0/guacamole-common-js/OutputStream.js.html | 129 +
.../doc/1.1.0/guacamole-common-js/Parser.js.html | 217 +
.../guacamole-common-js/RawAudioFormat.js.html | 207 +
.../guacamole-common-js/SessionRecording.js.html | 880 ++
.../doc/1.1.0/guacamole-common-js/Status.js.html | 379 +
.../1.1.0/guacamole-common-js/StringReader.js.html | 227 +
.../1.1.0/guacamole-common-js/StringWriter.js.html | 252 +
.../doc/1.1.0/guacamole-common-js/Tunnel.js.html | 1445 ++++
.../doc/1.1.0/guacamole-common-js/Version.js.html | 91 +
.../1.1.0/guacamole-common-js/VideoPlayer.js.html | 169 +
.../fonts/OpenSans-Bold-webfont.eot | Bin 0 -> 19544 bytes
.../fonts/OpenSans-Bold-webfont.svg | 1830 ++++
.../fonts/OpenSans-Bold-webfont.woff | Bin 0 -> 22432 bytes
.../fonts/OpenSans-BoldItalic-webfont.eot | Bin 0 -> 20133 bytes
.../fonts/OpenSans-BoldItalic-webfont.svg | 1830 ++++
.../fonts/OpenSans-BoldItalic-webfont.woff | Bin 0 -> 23048 bytes
.../fonts/OpenSans-Italic-webfont.eot | Bin 0 -> 20265 bytes
.../fonts/OpenSans-Italic-webfont.svg | 1830 ++++
.../fonts/OpenSans-Italic-webfont.woff | Bin 0 -> 23188 bytes
.../fonts/OpenSans-Light-webfont.eot | Bin 0 -> 19514 bytes
.../fonts/OpenSans-Light-webfont.svg | 1831 ++++
.../fonts/OpenSans-Light-webfont.woff | Bin 0 -> 22248 bytes
.../fonts/OpenSans-LightItalic-webfont.eot | Bin 0 -> 20535 bytes
.../fonts/OpenSans-LightItalic-webfont.svg | 1835 ++++
.../fonts/OpenSans-LightItalic-webfont.woff | Bin 0 -> 23400 bytes
.../fonts/OpenSans-Regular-webfont.eot | Bin 0 -> 19836 bytes
.../fonts/OpenSans-Regular-webfont.svg | 1831 ++++
.../fonts/OpenSans-Regular-webfont.woff | Bin 0 -> 22660 bytes
content/doc/1.1.0/guacamole-common-js/index.html | 75 +
.../guacamole-common-js/scripts/linenumber.js | 25 +
.../scripts/prettify/Apache-License-2.0.txt | 202 +
.../scripts/prettify/lang-css.js | 2 +
.../scripts/prettify/prettify.js | 28 +
.../guacamole-common-js/styles/jsdoc-default.css | 358 +
.../guacamole-common-js/styles/prettify-jsdoc.css | 111 +
.../styles/prettify-tomorrow.css | 132 +
.../1.1.0/guacamole-common/allclasses-frame.html | 77 +
.../1.1.0/guacamole-common/allclasses-noframe.html | 77 +
.../1.1.0/guacamole-common/constant-values.html | 200 +
.../1.1.0/guacamole-common/deprecated-list.html | 136 +
content/doc/1.1.0/guacamole-common/help-doc.html | 241 +
content/doc/1.1.0/guacamole-common/index-all.html | 1459 ++++
content/doc/1.1.0/guacamole-common/index.html | 76 +
.../guacamole/GuacamoleClientBadTypeException.html | 389 +
.../apache/guacamole/GuacamoleClientException.html | 389 +
.../guacamole/GuacamoleClientOverrunException.html | 391 +
.../guacamole/GuacamoleClientTimeoutException.html | 388 +
.../guacamole/GuacamoleClientTooManyException.html | 390 +
.../GuacamoleConnectionClosedException.html | 391 +
.../org/apache/guacamole/GuacamoleException.html | 419 +
.../GuacamoleResourceClosedException.html | 389 +
.../GuacamoleResourceConflictException.html | 390 +
.../GuacamoleResourceNotFoundException.html | 391 +
.../guacamole/GuacamoleSecurityException.html | 393 +
.../guacamole/GuacamoleServerBusyException.html | 389 +
.../apache/guacamole/GuacamoleServerException.html | 389 +
.../guacamole/GuacamoleSessionClosedException.html | 389 +
.../GuacamoleSessionConflictException.html | 389 +
.../GuacamoleSessionTimeoutException.html | 389 +
.../guacamole/GuacamoleUnauthorizedException.html | 395 +
.../guacamole/GuacamoleUnsupportedException.html | 389 +
.../guacamole/GuacamoleUpstreamException.html | 390 +
.../GuacamoleUpstreamNotFoundException.html | 389 +
.../GuacamoleUpstreamTimeoutException.html | 391 +
.../GuacamoleUpstreamUnavailableException.html | 393 +
.../class-use/GuacamoleClientBadTypeException.html | 136 +
.../class-use/GuacamoleClientException.html | 240 +
.../class-use/GuacamoleClientOverrunException.html | 136 +
.../class-use/GuacamoleClientTimeoutException.html | 136 +
.../class-use/GuacamoleClientTooManyException.html | 136 +
.../GuacamoleConnectionClosedException.html | 136 +
.../guacamole/class-use/GuacamoleException.html | 684 ++
.../GuacamoleResourceClosedException.html | 136 +
.../GuacamoleResourceConflictException.html | 136 +
.../GuacamoleResourceNotFoundException.html | 136 +
.../class-use/GuacamoleSecurityException.html | 184 +
.../class-use/GuacamoleServerBusyException.html | 136 +
.../class-use/GuacamoleServerException.html | 197 +
.../class-use/GuacamoleSessionClosedException.html | 136 +
.../GuacamoleSessionConflictException.html | 136 +
.../GuacamoleSessionTimeoutException.html | 136 +
.../class-use/GuacamoleUnauthorizedException.html | 136 +
.../class-use/GuacamoleUnsupportedException.html | 136 +
.../class-use/GuacamoleUpstreamException.html | 252 +
.../GuacamoleUpstreamNotFoundException.html | 136 +
.../GuacamoleUpstreamTimeoutException.html | 136 +
.../GuacamoleUpstreamUnavailableException.html | 136 +
.../org/apache/guacamole/io/GuacamoleReader.html | 312 +
.../org/apache/guacamole/io/GuacamoleWriter.html | 312 +
.../apache/guacamole/io/ReaderGuacamoleReader.html | 381 +
.../apache/guacamole/io/WriterGuacamoleWriter.html | 381 +
.../guacamole/io/class-use/GuacamoleReader.html | 299 +
.../guacamole/io/class-use/GuacamoleWriter.html | 299 +
.../io/class-use/ReaderGuacamoleReader.html | 136 +
.../io/class-use/WriterGuacamoleWriter.html | 136 +
.../org/apache/guacamole/io/package-frame.html | 37 +
.../org/apache/guacamole/io/package-summary.html | 198 +
.../org/apache/guacamole/io/package-tree.html | 155 +
.../org/apache/guacamole/io/package-use.html | 241 +
.../guacamole/net/AbstractGuacamoleTunnel.html | 506 ++
.../guacamole/net/DelegatingGuacamoleTunnel.html | 549 ++
.../org/apache/guacamole/net/GuacamoleSocket.html | 320 +
.../org/apache/guacamole/net/GuacamoleTunnel.html | 489 ++
.../apache/guacamole/net/InetGuacamoleSocket.html | 402 +
.../apache/guacamole/net/SSLGuacamoleSocket.html | 402 +
.../guacamole/net/SimpleGuacamoleTunnel.html | 356 +
.../net/class-use/AbstractGuacamoleTunnel.html | 181 +
.../net/class-use/DelegatingGuacamoleTunnel.html | 136 +
.../guacamole/net/class-use/GuacamoleSocket.html | 318 +
.../guacamole/net/class-use/GuacamoleTunnel.html | 292 +
.../net/class-use/InetGuacamoleSocket.html | 136 +
.../net/class-use/SSLGuacamoleSocket.html | 136 +
.../net/class-use/SimpleGuacamoleTunnel.html | 136 +
.../org/apache/guacamole/net/package-frame.html | 40 +
.../org/apache/guacamole/net/package-summary.html | 219 +
.../org/apache/guacamole/net/package-tree.html | 161 +
.../org/apache/guacamole/net/package-use.html | 256 +
.../org/apache/guacamole/package-frame.html | 52 +
.../org/apache/guacamole/package-summary.html | 318 +
.../org/apache/guacamole/package-tree.html | 193 +
.../org/apache/guacamole/package-use.html | 326 +
.../protocol/ConfiguredGuacamoleSocket.html | 516 ++
.../protocol/FailoverGuacamoleSocket.html | 452 +
.../protocol/FilteredGuacamoleReader.html | 387 +
.../protocol/FilteredGuacamoleSocket.html | 404 +
.../protocol/FilteredGuacamoleWriter.html | 387 +
.../protocol/GuacamoleClientInformation.html | 510 ++
.../guacamole/protocol/GuacamoleConfiguration.html | 529 ++
.../apache/guacamole/protocol/GuacamoleFilter.html | 256 +
.../guacamole/protocol/GuacamoleInstruction.html | 380 +
.../apache/guacamole/protocol/GuacamoleParser.html | 479 ++
.../protocol/GuacamoleProtocolCapability.html | 413 +
.../protocol/GuacamoleProtocolVersion.html | 532 ++
.../apache/guacamole/protocol/GuacamoleStatus.html | 759 ++
.../class-use/ConfiguredGuacamoleSocket.html | 136 +
.../class-use/FailoverGuacamoleSocket.html | 136 +
.../class-use/FilteredGuacamoleReader.html | 136 +
.../class-use/FilteredGuacamoleSocket.html | 136 +
.../class-use/FilteredGuacamoleWriter.html | 136 +
.../class-use/GuacamoleClientInformation.html | 182 +
.../protocol/class-use/GuacamoleConfiguration.html | 213 +
.../protocol/class-use/GuacamoleFilter.html | 196 +
.../protocol/class-use/GuacamoleInstruction.html | 262 +
.../protocol/class-use/GuacamoleParser.html | 136 +
.../class-use/GuacamoleProtocolCapability.html | 187 +
.../class-use/GuacamoleProtocolVersion.html | 241 +
.../protocol/class-use/GuacamoleStatus.html | 306 +
.../apache/guacamole/protocol/package-frame.html | 49 +
.../apache/guacamole/protocol/package-summary.html | 270 +
.../apache/guacamole/protocol/package-tree.html | 175 +
.../org/apache/guacamole/protocol/package-use.html | 258 +
.../servlet/GuacamoleHTTPTunnelServlet.html | 606 ++
.../class-use/GuacamoleHTTPTunnelServlet.html | 136 +
.../apache/guacamole/servlet/package-frame.html | 31 +
.../apache/guacamole/servlet/package-summary.html | 168 +
.../org/apache/guacamole/servlet/package-tree.html | 157 +
.../org/apache/guacamole/servlet/package-use.html | 136 +
.../GuacamoleWebSocketTunnelEndpoint.html | 369 +
.../GuacamoleWebSocketTunnelEndpoint.html | 136 +
.../apache/guacamole/websocket/package-frame.html | 31 +
.../guacamole/websocket/package-summary.html | 157 +
.../apache/guacamole/websocket/package-tree.html | 153 +
.../apache/guacamole/websocket/package-use.html | 136 +
.../doc/1.1.0/guacamole-common/overview-frame.html | 37 +
.../1.1.0/guacamole-common/overview-summary.html | 184 +
.../doc/1.1.0/guacamole-common/overview-tree.html | 253 +
content/doc/1.1.0/guacamole-common/package-list | 6 +
content/doc/1.1.0/guacamole-common/script.js | 30 +
.../1.1.0/guacamole-common/serialized-form.html | 318 +
content/doc/1.1.0/guacamole-common/stylesheet.css | 574 ++
.../doc/1.1.0/guacamole-ext/allclasses-frame.html | 149 +
.../1.1.0/guacamole-ext/allclasses-noframe.html | 149 +
.../doc/1.1.0/guacamole-ext/constant-values.html | 280 +
.../doc/1.1.0/guacamole-ext/deprecated-list.html | 298 +
content/doc/1.1.0/guacamole-ext/help-doc.html | 241 +
content/doc/1.1.0/guacamole-ext/index-all.html | 3432 ++++++++
content/doc/1.1.0/guacamole-ext/index.html | 76 +
.../apache/guacamole/environment/Environment.html | 504 ++
.../guacamole/environment/LocalEnvironment.html | 530 ++
.../environment/class-use/Environment.html | 180 +
.../environment/class-use/LocalEnvironment.html | 136 +
.../guacamole/environment/package-frame.html | 35 +
.../guacamole/environment/package-summary.html | 176 +
.../apache/guacamole/environment/package-tree.html | 153 +
.../apache/guacamole/environment/package-use.html | 172 +
.../org/apache/guacamole/form/BooleanField.html | 293 +
.../org/apache/guacamole/form/DateField.html | 402 +
.../org/apache/guacamole/form/EmailField.html | 284 +
.../org/apache/guacamole/form/EnumField.html | 288 +
.../org/apache/guacamole/form/Field.Type.html | 522 ++
.../org/apache/guacamole/form/Field.html | 473 +
.../org/apache/guacamole/form/FieldOption.html | 376 +
.../org/apache/guacamole/form/Form.html | 382 +
.../org/apache/guacamole/form/LanguageField.html | 334 +
.../org/apache/guacamole/form/MultilineField.html | 284 +
.../org/apache/guacamole/form/NumericField.html | 356 +
.../org/apache/guacamole/form/PasswordField.html | 285 +
.../guacamole/form/TerminalColorSchemeField.html | 286 +
.../org/apache/guacamole/form/TextField.html | 354 +
.../org/apache/guacamole/form/TimeField.html | 402 +
.../org/apache/guacamole/form/TimeZoneField.html | 332 +
.../org/apache/guacamole/form/UsernameField.html | 285 +
.../guacamole/form/class-use/BooleanField.html | 136 +
.../apache/guacamole/form/class-use/DateField.html | 136 +
.../guacamole/form/class-use/EmailField.html | 136 +
.../apache/guacamole/form/class-use/EnumField.html | 136 +
.../guacamole/form/class-use/Field.Type.html | 136 +
.../org/apache/guacamole/form/class-use/Field.html | 406 +
.../guacamole/form/class-use/FieldOption.html | 136 +
.../org/apache/guacamole/form/class-use/Form.html | 341 +
.../guacamole/form/class-use/LanguageField.html | 136 +
.../guacamole/form/class-use/MultilineField.html | 136 +
.../guacamole/form/class-use/NumericField.html | 136 +
.../guacamole/form/class-use/PasswordField.html | 136 +
.../form/class-use/TerminalColorSchemeField.html | 136 +
.../apache/guacamole/form/class-use/TextField.html | 136 +
.../apache/guacamole/form/class-use/TimeField.html | 136 +
.../guacamole/form/class-use/TimeZoneField.html | 136 +
.../guacamole/form/class-use/UsernameField.html | 136 +
.../org/apache/guacamole/form/package-frame.html | 47 +
.../org/apache/guacamole/form/package-summary.html | 267 +
.../org/apache/guacamole/form/package-tree.html | 168 +
.../org/apache/guacamole/form/package-use.html | 242 +
.../apache/guacamole/language/Translatable.html | 247 +
.../guacamole/language/TranslatableMessage.html | 355 +
.../guacamole/language/class-use/Translatable.html | 136 +
.../language/class-use/TranslatableMessage.html | 180 +
.../apache/guacamole/language/package-frame.html | 35 +
.../apache/guacamole/language/package-summary.html | 177 +
.../apache/guacamole/language/package-tree.html | 153 +
.../org/apache/guacamole/language/package-use.html | 173 +
.../net/auth/AbstractActiveConnection.html | 608 ++
.../net/auth/AbstractAuthenticatedUser.html | 376 +
.../net/auth/AbstractAuthenticationProvider.html | 660 ++
.../guacamole/net/auth/AbstractConnection.html | 500 ++
.../net/auth/AbstractConnectionGroup.html | 479 ++
.../guacamole/net/auth/AbstractIdentifiable.html | 365 +
.../guacamole/net/auth/AbstractSharingProfile.html | 527 ++
.../apache/guacamole/net/auth/AbstractUser.html | 773 ++
.../guacamole/net/auth/AbstractUserContext.html | 865 ++
.../guacamole/net/auth/AbstractUserGroup.html | 681 ++
.../guacamole/net/auth/ActiveConnection.html | 600 ++
.../apache/guacamole/net/auth/ActivityRecord.html | 337 +
.../auth/ActivityRecordSet.SortableProperty.html | 352 +
.../guacamole/net/auth/ActivityRecordSet.html | 381 +
.../org/apache/guacamole/net/auth/Attributes.html | 283 +
.../guacamole/net/auth/AuthenticatedUser.html | 375 +
.../guacamole/net/auth/AuthenticationProvider.html | 551 ++
.../org/apache/guacamole/net/auth/Connectable.html | 335 +
.../org/apache/guacamole/net/auth/Connection.html | 468 +
.../guacamole/net/auth/ConnectionGroup.Type.html | 371 +
.../apache/guacamole/net/auth/ConnectionGroup.html | 451 +
.../guacamole/net/auth/ConnectionRecord.html | 331 +
.../guacamole/net/auth/ConnectionRecordSet.html | 229 +
.../org/apache/guacamole/net/auth/Credentials.html | 567 ++
.../guacamole/net/auth/DecoratingDirectory.html | 519 ++
.../guacamole/net/auth/DelegatingConnection.html | 758 ++
.../net/auth/DelegatingConnectionGroup.html | 736 ++
.../guacamole/net/auth/DelegatingDirectory.html | 502 ++
.../net/auth/DelegatingSharingProfile.html | 576 ++
.../apache/guacamole/net/auth/DelegatingUser.html | 795 ++
.../guacamole/net/auth/DelegatingUserContext.html | 838 ++
.../guacamole/net/auth/DelegatingUserGroup.html | 705 ++
.../org/apache/guacamole/net/auth/Directory.html | 402 +
...acamoleProxyConfiguration.EncryptionMethod.html | 364 +
.../net/auth/GuacamoleProxyConfiguration.html | 402 +
.../apache/guacamole/net/auth/Identifiable.html | 273 +
.../org/apache/guacamole/net/auth/Permissions.html | 409 +
.../guacamole/net/auth/RelatedObjectSet.html | 350 +
.../org/apache/guacamole/net/auth/Shareable.html | 272 +
.../apache/guacamole/net/auth/SharingProfile.html | 387 +
.../net/auth/TokenInjectingConnection.html | 346 +
.../net/auth/TokenInjectingConnectionGroup.html | 361 +
.../net/auth/TokenInjectingUserContext.html | 454 +
.../apache/guacamole/net/auth/User.Attribute.html | 346 +
.../org/apache/guacamole/net/auth/User.html | 423 +
.../org/apache/guacamole/net/auth/UserContext.html | 696 ++
.../org/apache/guacamole/net/auth/UserGroup.html | 337 +
.../auth/class-use/AbstractActiveConnection.html | 136 +
.../auth/class-use/AbstractAuthenticatedUser.html | 136 +
.../class-use/AbstractAuthenticationProvider.html | 183 +
.../net/auth/class-use/AbstractConnection.html | 183 +
.../auth/class-use/AbstractConnectionGroup.html | 184 +
.../net/auth/class-use/AbstractIdentifiable.html | 265 +
.../net/auth/class-use/AbstractSharingProfile.html | 136 +
.../guacamole/net/auth/class-use/AbstractUser.html | 182 +
.../net/auth/class-use/AbstractUserContext.html | 183 +
.../net/auth/class-use/AbstractUserGroup.html | 183 +
.../net/auth/class-use/ActiveConnection.html | 211 +
.../net/auth/class-use/ActivityRecord.html | 270 +
.../ActivityRecordSet.SortableProperty.html | 239 +
.../net/auth/class-use/ActivityRecordSet.html | 304 +
.../guacamole/net/auth/class-use/Attributes.html | 351 +
.../net/auth/class-use/AuthenticatedUser.html | 462 +
.../net/auth/class-use/AuthenticationProvider.html | 283 +
.../guacamole/net/auth/class-use/Connectable.html | 291 +
.../guacamole/net/auth/class-use/Connection.html | 377 +
.../net/auth/class-use/ConnectionGroup.Type.html | 225 +
.../net/auth/class-use/ConnectionGroup.html | 386 +
.../net/auth/class-use/ConnectionRecord.html | 234 +
.../net/auth/class-use/ConnectionRecordSet.html | 213 +
.../guacamole/net/auth/class-use/Credentials.html | 418 +
.../net/auth/class-use/DecoratingDirectory.html | 136 +
.../net/auth/class-use/DelegatingConnection.html | 183 +
.../auth/class-use/DelegatingConnectionGroup.html | 183 +
.../net/auth/class-use/DelegatingDirectory.html | 182 +
.../auth/class-use/DelegatingSharingProfile.html | 136 +
.../net/auth/class-use/DelegatingUser.html | 136 +
.../net/auth/class-use/DelegatingUserContext.html | 183 +
.../net/auth/class-use/DelegatingUserGroup.html | 136 +
.../guacamole/net/auth/class-use/Directory.html | 418 +
...acamoleProxyConfiguration.EncryptionMethod.html | 210 +
.../class-use/GuacamoleProxyConfiguration.html | 183 +
.../guacamole/net/auth/class-use/Identifiable.html | 446 +
.../guacamole/net/auth/class-use/Permissions.html | 284 +
.../net/auth/class-use/RelatedObjectSet.html | 287 +
.../guacamole/net/auth/class-use/Shareable.html | 198 +
.../net/auth/class-use/SharingProfile.html | 248 +
.../auth/class-use/TokenInjectingConnection.html | 136 +
.../class-use/TokenInjectingConnectionGroup.html | 136 +
.../auth/class-use/TokenInjectingUserContext.html | 136 +
.../net/auth/class-use/User.Attribute.html | 136 +
.../apache/guacamole/net/auth/class-use/User.html | 314 +
.../guacamole/net/auth/class-use/UserContext.html | 435 +
.../guacamole/net/auth/class-use/UserGroup.html | 276 +
.../net/auth/credentials/CredentialsInfo.html | 400 +
.../credentials/GuacamoleCredentialsException.html | 419 +
.../GuacamoleInsufficientCredentialsException.html | 388 +
.../GuacamoleInvalidCredentialsException.html | 386 +
.../net/auth/credentials/UserCredentials.html | 585 ++
.../credentials/class-use/CredentialsInfo.html | 302 +
.../class-use/GuacamoleCredentialsException.html | 186 +
.../GuacamoleInsufficientCredentialsException.html | 136 +
.../GuacamoleInvalidCredentialsException.html | 136 +
.../credentials/class-use/UserCredentials.html | 182 +
.../net/auth/credentials/package-frame.html | 38 +
.../net/auth/credentials/package-summary.html | 194 +
.../net/auth/credentials/package-tree.html | 183 +
.../net/auth/credentials/package-use.html | 201 +
.../apache/guacamole/net/auth/package-frame.html | 83 +
.../apache/guacamole/net/auth/package-summary.html | 507 ++
.../apache/guacamole/net/auth/package-tree.html | 256 +
.../org/apache/guacamole/net/auth/package-use.html | 587 ++
.../net/auth/permission/ObjectPermission.Type.html | 395 +
.../net/auth/permission/ObjectPermission.html | 391 +
.../net/auth/permission/ObjectPermissionSet.html | 488 ++
.../guacamole/net/auth/permission/Permission.html | 251 +
.../net/auth/permission/PermissionSet.html | 311 +
.../net/auth/permission/SystemPermission.Type.html | 429 +
.../net/auth/permission/SystemPermission.html | 364 +
.../net/auth/permission/SystemPermissionSet.html | 432 +
.../class-use/ObjectPermission.Type.html | 323 +
.../permission/class-use/ObjectPermission.html | 259 +
.../permission/class-use/ObjectPermissionSet.html | 412 +
.../net/auth/permission/class-use/Permission.html | 204 +
.../auth/permission/class-use/PermissionSet.html | 224 +
.../class-use/SystemPermission.Type.html | 267 +
.../permission/class-use/SystemPermission.html | 259 +
.../permission/class-use/SystemPermissionSet.html | 258 +
.../net/auth/permission/package-frame.html | 44 +
.../net/auth/permission/package-summary.html | 235 +
.../net/auth/permission/package-tree.html | 173 +
.../guacamole/net/auth/permission/package-use.html | 301 +
.../net/auth/simple/SimpleActivityRecordSet.html | 431 +
.../auth/simple/SimpleAuthenticationProvider.html | 420 +
.../net/auth/simple/SimpleConnection.html | 673 ++
.../net/auth/simple/SimpleConnectionDirectory.html | 354 +
.../net/auth/simple/SimpleConnectionGroup.html | 537 ++
.../simple/SimpleConnectionGroupDirectory.html | 356 +
.../net/auth/simple/SimpleConnectionRecordSet.html | 443 +
.../guacamole/net/auth/simple/SimpleDirectory.html | 616 ++
.../net/auth/simple/SimpleObjectPermissionSet.html | 622 ++
.../net/auth/simple/SimpleRelatedObjectSet.html | 432 +
.../net/auth/simple/SimpleSystemPermissionSet.html | 514 ++
.../guacamole/net/auth/simple/SimpleUser.html | 528 ++
.../net/auth/simple/SimpleUserContext.html | 516 ++
.../net/auth/simple/SimpleUserDirectory.html | 282 +
.../guacamole/net/auth/simple/SimpleUserGroup.html | 309 +
.../simple/class-use/SimpleActivityRecordSet.html | 136 +
.../class-use/SimpleAuthenticationProvider.html | 136 +
.../auth/simple/class-use/SimpleConnection.html | 136 +
.../class-use/SimpleConnectionDirectory.html | 136 +
.../simple/class-use/SimpleConnectionGroup.html | 136 +
.../class-use/SimpleConnectionGroupDirectory.html | 136 +
.../class-use/SimpleConnectionRecordSet.html | 136 +
.../net/auth/simple/class-use/SimpleDirectory.html | 200 +
.../class-use/SimpleObjectPermissionSet.html | 136 +
.../simple/class-use/SimpleRelatedObjectSet.html | 136 +
.../class-use/SimpleSystemPermissionSet.html | 136 +
.../net/auth/simple/class-use/SimpleUser.html | 136 +
.../auth/simple/class-use/SimpleUserContext.html | 136 +
.../auth/simple/class-use/SimpleUserDirectory.html | 136 +
.../net/auth/simple/class-use/SimpleUserGroup.html | 136 +
.../guacamole/net/auth/simple/package-frame.html | 45 +
.../guacamole/net/auth/simple/package-summary.html | 264 +
.../guacamole/net/auth/simple/package-tree.html | 194 +
.../guacamole/net/auth/simple/package-use.html | 176 +
.../net/event/AuthenticationFailureEvent.html | 311 +
.../net/event/AuthenticationSuccessEvent.html | 345 +
.../guacamole/net/event/CredentialEvent.html | 247 +
.../guacamole/net/event/TunnelCloseEvent.html | 375 +
.../guacamole/net/event/TunnelConnectEvent.html | 375 +
.../apache/guacamole/net/event/TunnelEvent.html | 246 +
.../org/apache/guacamole/net/event/UserEvent.html | 249 +
.../class-use/AuthenticationFailureEvent.html | 183 +
.../class-use/AuthenticationSuccessEvent.html | 183 +
.../net/event/class-use/CredentialEvent.html | 201 +
.../net/event/class-use/TunnelCloseEvent.html | 182 +
.../net/event/class-use/TunnelConnectEvent.html | 182 +
.../guacamole/net/event/class-use/TunnelEvent.html | 187 +
.../guacamole/net/event/class-use/UserEvent.html | 194 +
.../listener/AuthenticationFailureListener.html | 258 +
.../listener/AuthenticationSuccessListener.html | 262 +
.../guacamole/net/event/listener/Listener.html | 255 +
.../net/event/listener/TunnelCloseListener.html | 259 +
.../net/event/listener/TunnelConnectListener.html | 260 +
.../class-use/AuthenticationFailureListener.html | 136 +
.../class-use/AuthenticationSuccessListener.html | 136 +
.../net/event/listener/class-use/Listener.html | 136 +
.../listener/class-use/TunnelCloseListener.html | 136 +
.../listener/class-use/TunnelConnectListener.html | 136 +
.../net/event/listener/package-frame.html | 35 +
.../net/event/listener/package-summary.html | 195 +
.../guacamole/net/event/listener/package-tree.html | 149 +
.../guacamole/net/event/listener/package-use.html | 136 +
.../apache/guacamole/net/event/package-frame.html | 40 +
.../guacamole/net/event/package-summary.html | 224 +
.../apache/guacamole/net/event/package-tree.html | 158 +
.../apache/guacamole/net/event/package-use.html | 227 +
.../properties/BooleanGuacamoleProperty.html | 315 +
.../properties/FileGuacamoleProperty.html | 314 +
.../guacamole/properties/GuacamoleProperty.html | 281 +
.../properties/IntegerGuacamoleProperty.html | 314 +
.../properties/LongGuacamoleProperty.html | 314 +
.../properties/StringGuacamoleProperty.html | 314 +
.../class-use/BooleanGuacamoleProperty.html | 178 +
.../class-use/FileGuacamoleProperty.html | 136 +
.../properties/class-use/GuacamoleProperty.html | 258 +
.../class-use/IntegerGuacamoleProperty.html | 178 +
.../class-use/LongGuacamoleProperty.html | 136 +
.../class-use/StringGuacamoleProperty.html | 179 +
.../apache/guacamole/properties/package-frame.html | 39 +
.../guacamole/properties/package-summary.html | 209 +
.../apache/guacamole/properties/package-tree.html | 157 +
.../apache/guacamole/properties/package-use.html | 212 +
.../apache/guacamole/protocols/ProtocolInfo.html | 492 ++
.../protocols/class-use/ProtocolInfo.html | 202 +
.../apache/guacamole/protocols/package-frame.html | 31 +
.../guacamole/protocols/package-summary.html | 157 +
.../apache/guacamole/protocols/package-tree.html | 149 +
.../apache/guacamole/protocols/package-use.html | 172 +
.../org/apache/guacamole/token/StandardTokens.html | 495 ++
.../org/apache/guacamole/token/TokenFilter.html | 465 +
.../org/apache/guacamole/token/TokenName.html | 298 +
.../guacamole/token/class-use/StandardTokens.html | 136 +
.../guacamole/token/class-use/TokenFilter.html | 199 +
.../guacamole/token/class-use/TokenName.html | 136 +
.../org/apache/guacamole/token/package-frame.html | 33 +
.../apache/guacamole/token/package-summary.html | 170 +
.../org/apache/guacamole/token/package-tree.html | 151 +
.../org/apache/guacamole/token/package-use.html | 172 +
.../org/apache/guacamole/xml/DocumentHandler.html | 382 +
.../org/apache/guacamole/xml/TagHandler.html | 303 +
.../guacamole/xml/class-use/DocumentHandler.html | 136 +
.../apache/guacamole/xml/class-use/TagHandler.html | 196 +
.../org/apache/guacamole/xml/package-frame.html | 35 +
.../org/apache/guacamole/xml/package-summary.html | 187 +
.../org/apache/guacamole/xml/package-tree.html | 157 +
.../org/apache/guacamole/xml/package-use.html | 175 +
.../doc/1.1.0/guacamole-ext/overview-frame.html | 44 +
.../doc/1.1.0/guacamole-ext/overview-summary.html | 223 +
content/doc/1.1.0/guacamole-ext/overview-tree.html | 402 +
content/doc/1.1.0/guacamole-ext/package-list | 13 +
content/doc/1.1.0/guacamole-ext/script.js | 30 +
.../doc/1.1.0/guacamole-ext/serialized-form.html | 215 +
content/doc/1.1.0/guacamole-ext/stylesheet.css | 574 ++
content/doc/1.1.0/gug/adhoc-connections.html | 69 +
content/doc/1.1.0/gug/administration.html | 163 +
content/doc/1.1.0/gug/appendices.html | 21 +
content/doc/1.1.0/gug/book-index.html | 21 +
content/doc/1.1.0/gug/cas-auth.html | 59 +
content/doc/1.1.0/gug/configuring-guacamole.html | 2489 ++++++
content/doc/1.1.0/gug/custom-auth.html | 383 +
content/doc/1.1.0/gug/custom-protocols.html | 654 ++
content/doc/1.1.0/gug/developers-guide.html | 21 +
content/doc/1.1.0/gug/duo-auth.html | 102 +
content/doc/1.1.0/gug/event-listeners.html | 292 +
content/doc/1.1.0/gug/faq.html | 86 +
content/doc/1.1.0/gug/guacamole-architecture.html | 83 +
content/doc/1.1.0/gug/guacamole-common-js.html | 263 +
content/doc/1.1.0/gug/guacamole-common.html | 141 +
content/doc/1.1.0/gug/guacamole-docker.html | 413 +
content/doc/1.1.0/gug/guacamole-ext.html | 457 +
content/doc/1.1.0/gug/guacamole-protocol.html | 193 +
content/doc/1.1.0/gug/gug.css | 179 +
content/doc/1.1.0/gug/header-auth.html | 54 +
content/doc/1.1.0/gug/images/duo-add-guacamole.png | Bin 0 -> 7156 bytes
content/doc/1.1.0/gug/images/duo-auth-factor-1.png | Bin 0 -> 12418 bytes
content/doc/1.1.0/gug/images/duo-auth-factor-2.png | Bin 0 -> 28876 bytes
content/doc/1.1.0/gug/images/duo-copy-details.png | Bin 0 -> 19979 bytes
.../doc/1.1.0/gug/images/duo-rename-guacamole.png | Bin 0 -> 13016 bytes
content/doc/1.1.0/gug/images/edit-connection.png | Bin 0 -> 119196 bytes
.../1.1.0/gug/images/edit-group-memberships.png | Bin 0 -> 31653 bytes
content/doc/1.1.0/gug/images/edit-group.png | Bin 0 -> 29614 bytes
.../doc/1.1.0/gug/images/edit-sharing-profile.png | Bin 0 -> 22420 bytes
content/doc/1.1.0/gug/images/edit-user-group.png | Bin 0 -> 129269 bytes
.../doc/1.1.0/gug/images/edit-user-membership.png | Bin 0 -> 8415 bytes
content/doc/1.1.0/gug/images/edit-user.png | Bin 0 -> 72176 bytes
content/doc/1.1.0/gug/images/file-browser.png | Bin 0 -> 97706 bytes
content/doc/1.1.0/gug/images/file-transfers.png | Bin 0 -> 9586 bytes
content/doc/1.1.0/gug/images/guac-arch.png | Bin 0 -> 51821 bytes
.../doc/1.1.0/gug/images/guac-menu-disconnect.png | Bin 0 -> 19486 bytes
.../doc/1.1.0/gug/images/guac-menu-share-link.png | Bin 0 -> 19965 bytes
content/doc/1.1.0/gug/images/guac-menu-share.png | Bin 0 -> 8726 bytes
.../gug/images/guacamole-client-interface.png | Bin 0 -> 309368 bytes
.../1.1.0/gug/images/guacamole-drive-download.png | Bin 0 -> 19149 bytes
content/doc/1.1.0/gug/images/guacamole-drive.png | Bin 0 -> 27334 bytes
.../doc/1.1.0/gug/images/guacamole-home-screen.png | Bin 0 -> 77377 bytes
.../doc/1.1.0/gug/images/guacamole-preferences.png | Bin 0 -> 161522 bytes
.../gug/images/guacamole-settings-sections.png | Bin 0 -> 11928 bytes
content/doc/1.1.0/gug/images/manage-button.png | Bin 0 -> 16773 bytes
.../doc/1.1.0/gug/images/manage-connections.png | Bin 0 -> 87829 bytes
content/doc/1.1.0/gug/images/manage-groups.png | Bin 0 -> 33629 bytes
content/doc/1.1.0/gug/images/manage-history.png | Bin 0 -> 148440 bytes
content/doc/1.1.0/gug/images/manage-sessions.png | Bin 0 -> 61738 bytes
content/doc/1.1.0/gug/images/manage-users.png | Bin 0 -> 33353 bytes
.../1.1.0/gug/images/session-filter-example-1.png | Bin 0 -> 3038 bytes
.../1.1.0/gug/images/session-filter-example-2.png | Bin 0 -> 2055 bytes
.../doc/1.1.0/gug/images/totp-auth-factor-1.png | Bin 0 -> 12418 bytes
.../doc/1.1.0/gug/images/totp-auth-factor-2.png | Bin 0 -> 14088 bytes
.../doc/1.1.0/gug/images/totp-enroll-detail.png | Bin 0 -> 42801 bytes
content/doc/1.1.0/gug/images/totp-enroll.png | Bin 0 -> 33722 bytes
content/doc/1.1.0/gug/images/touchpad.png | Bin 0 -> 16504 bytes
content/doc/1.1.0/gug/images/touchscreen.png | Bin 0 -> 9681 bytes
content/doc/1.1.0/gug/index.html | 29 +
content/doc/1.1.0/gug/installing-guacamole.html | 454 +
content/doc/1.1.0/gug/jdbc-auth.html | 920 ++
content/doc/1.1.0/gug/ldap-auth.html | 315 +
content/doc/1.1.0/gug/libguac.html | 263 +
content/doc/1.1.0/gug/openid-auth.html | 98 +
content/doc/1.1.0/gug/preface.html | 92 +
content/doc/1.1.0/gug/protocol-reference.html | 338 +
content/doc/1.1.0/gug/proxying-guacamole.html | 220 +
content/doc/1.1.0/gug/radius-auth.html | 137 +
content/doc/1.1.0/gug/totp-auth.html | 94 +
content/doc/1.1.0/gug/troubleshooting.html | 407 +
content/doc/1.1.0/gug/users-guide.html | 21 +
content/doc/1.1.0/gug/using-guacamole.html | 204 +
.../1.1.0/gug/writing-you-own-guacamole-app.html | 436 +
content/doc/1.1.0/libguac/annotated.html | 104 +
content/doc/1.1.0/libguac/audio-fntypes_8h.html | 234 +
.../doc/1.1.0/libguac/audio-fntypes_8h_source.html | 100 +
content/doc/1.1.0/libguac/audio-types_8h.html | 98 +
.../doc/1.1.0/libguac/audio-types_8h_source.html | 93 +
content/doc/1.1.0/libguac/audio_8h.html | 388 +
content/doc/1.1.0/libguac/audio_8h_source.html | 124 +
content/doc/1.1.0/libguac/bc_s.png | Bin 0 -> 676 bytes
content/doc/1.1.0/libguac/bdwn.png | Bin 0 -> 147 bytes
content/doc/1.1.0/libguac/classes.html | 107 +
content/doc/1.1.0/libguac/client-constants_8h.html | 189 +
.../1.1.0/libguac/client-constants_8h_source.html | 91 +
content/doc/1.1.0/libguac/client-fntypes_8h.html | 186 +
.../1.1.0/libguac/client-fntypes_8h_source.html | 101 +
content/doc/1.1.0/libguac/client-types_8h.html | 174 +
.../doc/1.1.0/libguac/client-types_8h_source.html | 101 +
content/doc/1.1.0/libguac/client_8h.html | 1336 +++
content/doc/1.1.0/libguac/client_8h_source.html | 156 +
content/doc/1.1.0/libguac/closed.png | Bin 0 -> 132 bytes
content/doc/1.1.0/libguac/deprecated.html | 93 +
.../dir_6bb9fad85c98b48a11165f494b9f53ce.html | 215 +
content/doc/1.1.0/libguac/doc.png | Bin 0 -> 746 bytes
content/doc/1.1.0/libguac/doxygen.css | 1596 ++++
content/doc/1.1.0/libguac/doxygen.png | Bin 0 -> 3779 bytes
content/doc/1.1.0/libguac/dynsections.js | 120 +
content/doc/1.1.0/libguac/error-types_8h.html | 205 +
.../doc/1.1.0/libguac/error-types_8h_source.html | 116 +
content/doc/1.1.0/libguac/error_8h.html | 197 +
content/doc/1.1.0/libguac/error_8h_source.html | 94 +
content/doc/1.1.0/libguac/files.html | 132 +
content/doc/1.1.0/libguac/folderclosed.png | Bin 0 -> 616 bytes
content/doc/1.1.0/libguac/folderopen.png | Bin 0 -> 597 bytes
content/doc/1.1.0/libguac/functions.html | 375 +
content/doc/1.1.0/libguac/functions_vars.html | 375 +
content/doc/1.1.0/libguac/globals.html | 120 +
content/doc/1.1.0/libguac/globals_c.html | 183 +
content/doc/1.1.0/libguac/globals_defs.html | 178 +
content/doc/1.1.0/libguac/globals_e.html | 93 +
content/doc/1.1.0/libguac/globals_enum.html | 115 +
content/doc/1.1.0/libguac/globals_eval.html | 261 +
content/doc/1.1.0/libguac/globals_func.html | 558 ++
content/doc/1.1.0/libguac/globals_g.html | 345 +
content/doc/1.1.0/libguac/globals_h.html | 90 +
content/doc/1.1.0/libguac/globals_l.html | 93 +
content/doc/1.1.0/libguac/globals_p.html | 288 +
content/doc/1.1.0/libguac/globals_s.html | 186 +
content/doc/1.1.0/libguac/globals_t.html | 99 +
content/doc/1.1.0/libguac/globals_type.html | 202 +
content/doc/1.1.0/libguac/globals_u.html | 213 +
content/doc/1.1.0/libguac/globals_vars.html | 88 +
content/doc/1.1.0/libguac/hash_8h.html | 177 +
content/doc/1.1.0/libguac/hash_8h_source.html | 93 +
content/doc/1.1.0/libguac/index.html | 87 +
content/doc/1.1.0/libguac/jquery.js | 115 +
content/doc/1.1.0/libguac/layer-types_8h.html | 98 +
.../doc/1.1.0/libguac/layer-types_8h_source.html | 92 +
content/doc/1.1.0/libguac/layer_8h.html | 107 +
content/doc/1.1.0/libguac/layer_8h_source.html | 94 +
content/doc/1.1.0/libguac/menu.js | 50 +
content/doc/1.1.0/libguac/menudata.js | 107 +
content/doc/1.1.0/libguac/nav_f.png | Bin 0 -> 153 bytes
content/doc/1.1.0/libguac/nav_g.png | Bin 0 -> 95 bytes
content/doc/1.1.0/libguac/nav_h.png | Bin 0 -> 98 bytes
content/doc/1.1.0/libguac/object-types_8h.html | 98 +
.../doc/1.1.0/libguac/object-types_8h_source.html | 92 +
content/doc/1.1.0/libguac/object_8h.html | 107 +
content/doc/1.1.0/libguac/object_8h_source.html | 100 +
content/doc/1.1.0/libguac/open.png | Bin 0 -> 123 bytes
content/doc/1.1.0/libguac/pages.html | 92 +
content/doc/1.1.0/libguac/parser-constants_8h.html | 116 +
.../1.1.0/libguac/parser-constants_8h_source.html | 91 +
content/doc/1.1.0/libguac/parser-types_8h.html | 138 +
.../doc/1.1.0/libguac/parser-types_8h_source.html | 97 +
content/doc/1.1.0/libguac/parser_8h.html | 399 +
content/doc/1.1.0/libguac/parser_8h_source.html | 109 +
content/doc/1.1.0/libguac/plugin-constants_8h.html | 139 +
.../1.1.0/libguac/plugin-constants_8h_source.html | 91 +
content/doc/1.1.0/libguac/plugin_8h.html | 98 +
content/doc/1.1.0/libguac/plugin_8h_source.html | 92 +
content/doc/1.1.0/libguac/pool-types_8h.html | 98 +
.../doc/1.1.0/libguac/pool-types_8h_source.html | 93 +
content/doc/1.1.0/libguac/pool_8h.html | 246 +
content/doc/1.1.0/libguac/pool_8h_source.html | 101 +
.../doc/1.1.0/libguac/protocol-constants_8h.html | 146 +
.../libguac/protocol-constants_8h_source.html | 91 +
content/doc/1.1.0/libguac/protocol-types_8h.html | 295 +
.../1.1.0/libguac/protocol-types_8h_source.html | 117 +
content/doc/1.1.0/libguac/protocol_8h.html | 3178 +++++++
content/doc/1.1.0/libguac/protocol_8h_source.html | 162 +
content/doc/1.1.0/libguac/search/all_0.html | 40 +
content/doc/1.1.0/libguac/search/all_0.js | 14 +
content/doc/1.1.0/libguac/search/all_1.html | 40 +
content/doc/1.1.0/libguac/search/all_1.js | 6 +
content/doc/1.1.0/libguac/search/all_10.html | 40 +
content/doc/1.1.0/libguac/search/all_10.js | 19 +
content/doc/1.1.0/libguac/search/all_11.html | 40 +
content/doc/1.1.0/libguac/search/all_11.js | 6 +
content/doc/1.1.0/libguac/search/all_12.html | 40 +
content/doc/1.1.0/libguac/search/all_12.js | 10 +
content/doc/1.1.0/libguac/search/all_13.html | 40 +
content/doc/1.1.0/libguac/search/all_13.js | 10 +
content/doc/1.1.0/libguac/search/all_14.html | 40 +
content/doc/1.1.0/libguac/search/all_14.js | 4 +
content/doc/1.1.0/libguac/search/all_2.html | 40 +
content/doc/1.1.0/libguac/search/all_2.js | 13 +
content/doc/1.1.0/libguac/search/all_3.html | 40 +
content/doc/1.1.0/libguac/search/all_3.js | 5 +
content/doc/1.1.0/libguac/search/all_4.html | 40 +
content/doc/1.1.0/libguac/search/all_4.js | 7 +
content/doc/1.1.0/libguac/search/all_5.html | 40 +
content/doc/1.1.0/libguac/search/all_5.js | 7 +
content/doc/1.1.0/libguac/search/all_6.html | 40 +
content/doc/1.1.0/libguac/search/all_6.js | 291 +
content/doc/1.1.0/libguac/search/all_7.html | 40 +
content/doc/1.1.0/libguac/search/all_7.js | 4 +
content/doc/1.1.0/libguac/search/all_8.html | 40 +
content/doc/1.1.0/libguac/search/all_8.js | 6 +
content/doc/1.1.0/libguac/search/all_9.html | 40 +
content/doc/1.1.0/libguac/search/all_9.js | 4 +
content/doc/1.1.0/libguac/search/all_a.html | 40 +
content/doc/1.1.0/libguac/search/all_a.js | 4 +
content/doc/1.1.0/libguac/search/all_b.html | 40 +
content/doc/1.1.0/libguac/search/all_b.js | 12 +
content/doc/1.1.0/libguac/search/all_c.html | 40 +
content/doc/1.1.0/libguac/search/all_c.js | 6 +
content/doc/1.1.0/libguac/search/all_d.html | 40 +
content/doc/1.1.0/libguac/search/all_d.js | 10 +
content/doc/1.1.0/libguac/search/all_e.html | 40 +
content/doc/1.1.0/libguac/search/all_e.js | 16 +
content/doc/1.1.0/libguac/search/all_f.html | 40 +
content/doc/1.1.0/libguac/search/all_f.js | 5 +
content/doc/1.1.0/libguac/search/classes_0.html | 40 +
content/doc/1.1.0/libguac/search/classes_0.js | 16 +
content/doc/1.1.0/libguac/search/close.png | Bin 0 -> 273 bytes
content/doc/1.1.0/libguac/search/defines_0.html | 40 +
content/doc/1.1.0/libguac/search/defines_0.js | 32 +
content/doc/1.1.0/libguac/search/enums_0.html | 40 +
content/doc/1.1.0/libguac/search/enums_0.js | 13 +
content/doc/1.1.0/libguac/search/enumvalues_0.html | 40 +
content/doc/1.1.0/libguac/search/enumvalues_0.js | 61 +
content/doc/1.1.0/libguac/search/files_0.html | 40 +
content/doc/1.1.0/libguac/search/files_0.js | 6 +
content/doc/1.1.0/libguac/search/files_1.html | 40 +
content/doc/1.1.0/libguac/search/files_1.js | 7 +
content/doc/1.1.0/libguac/search/files_2.html | 40 +
content/doc/1.1.0/libguac/search/files_2.js | 5 +
content/doc/1.1.0/libguac/search/files_3.html | 40 +
content/doc/1.1.0/libguac/search/files_3.js | 4 +
content/doc/1.1.0/libguac/search/files_4.html | 40 +
content/doc/1.1.0/libguac/search/files_4.js | 5 +
content/doc/1.1.0/libguac/search/files_5.html | 40 +
content/doc/1.1.0/libguac/search/files_5.js | 5 +
content/doc/1.1.0/libguac/search/files_6.html | 40 +
content/doc/1.1.0/libguac/search/files_6.js | 13 +
content/doc/1.1.0/libguac/search/files_7.html | 40 +
content/doc/1.1.0/libguac/search/files_7.js | 12 +
content/doc/1.1.0/libguac/search/files_8.html | 40 +
content/doc/1.1.0/libguac/search/files_8.js | 5 +
content/doc/1.1.0/libguac/search/files_9.html | 40 +
content/doc/1.1.0/libguac/search/files_9.js | 8 +
content/doc/1.1.0/libguac/search/functions_0.html | 40 +
content/doc/1.1.0/libguac/search/functions_0.js | 147 +
content/doc/1.1.0/libguac/search/functions_1.html | 40 +
content/doc/1.1.0/libguac/search/functions_1.js | 8 +
content/doc/1.1.0/libguac/search/mag_sel.png | Bin 0 -> 563 bytes
content/doc/1.1.0/libguac/search/nomatches.html | 22 +
content/doc/1.1.0/libguac/search/pages_0.html | 40 +
content/doc/1.1.0/libguac/search/pages_0.js | 4 +
content/doc/1.1.0/libguac/search/search.css | 271 +
content/doc/1.1.0/libguac/search/search.js | 814 ++
content/doc/1.1.0/libguac/search/search_l.png | Bin 0 -> 604 bytes
content/doc/1.1.0/libguac/search/search_m.png | Bin 0 -> 158 bytes
content/doc/1.1.0/libguac/search/search_r.png | Bin 0 -> 612 bytes
content/doc/1.1.0/libguac/search/searchdata.js | 42 +
content/doc/1.1.0/libguac/search/typedefs_0.html | 40 +
content/doc/1.1.0/libguac/search/typedefs_0.js | 36 +
content/doc/1.1.0/libguac/search/variables_0.html | 40 +
content/doc/1.1.0/libguac/search/variables_0.js | 11 +
content/doc/1.1.0/libguac/search/variables_1.html | 40 +
content/doc/1.1.0/libguac/search/variables_1.js | 6 +
content/doc/1.1.0/libguac/search/variables_10.html | 40 +
content/doc/1.1.0/libguac/search/variables_10.js | 4 +
content/doc/1.1.0/libguac/search/variables_11.html | 40 +
content/doc/1.1.0/libguac/search/variables_11.js | 5 +
content/doc/1.1.0/libguac/search/variables_12.html | 40 +
content/doc/1.1.0/libguac/search/variables_12.js | 5 +
content/doc/1.1.0/libguac/search/variables_13.html | 40 +
content/doc/1.1.0/libguac/search/variables_13.js | 4 +
content/doc/1.1.0/libguac/search/variables_2.html | 40 +
content/doc/1.1.0/libguac/search/variables_2.js | 9 +
content/doc/1.1.0/libguac/search/variables_3.html | 40 +
content/doc/1.1.0/libguac/search/variables_3.js | 4 +
content/doc/1.1.0/libguac/search/variables_4.html | 40 +
content/doc/1.1.0/libguac/search/variables_4.js | 5 +
content/doc/1.1.0/libguac/search/variables_5.html | 40 +
content/doc/1.1.0/libguac/search/variables_5.js | 7 +
content/doc/1.1.0/libguac/search/variables_6.html | 40 +
content/doc/1.1.0/libguac/search/variables_6.js | 5 +
content/doc/1.1.0/libguac/search/variables_7.html | 40 +
content/doc/1.1.0/libguac/search/variables_7.js | 6 +
content/doc/1.1.0/libguac/search/variables_8.html | 40 +
content/doc/1.1.0/libguac/search/variables_8.js | 4 +
content/doc/1.1.0/libguac/search/variables_9.html | 40 +
content/doc/1.1.0/libguac/search/variables_9.js | 4 +
content/doc/1.1.0/libguac/search/variables_a.html | 40 +
content/doc/1.1.0/libguac/search/variables_a.js | 10 +
content/doc/1.1.0/libguac/search/variables_b.html | 40 +
content/doc/1.1.0/libguac/search/variables_b.js | 6 +
content/doc/1.1.0/libguac/search/variables_c.html | 40 +
content/doc/1.1.0/libguac/search/variables_c.js | 8 +
content/doc/1.1.0/libguac/search/variables_d.html | 40 +
content/doc/1.1.0/libguac/search/variables_d.js | 6 +
content/doc/1.1.0/libguac/search/variables_e.html | 40 +
content/doc/1.1.0/libguac/search/variables_e.js | 5 +
content/doc/1.1.0/libguac/search/variables_f.html | 40 +
content/doc/1.1.0/libguac/search/variables_f.js | 10 +
content/doc/1.1.0/libguac/socket-constants_8h.html | 112 +
.../1.1.0/libguac/socket-constants_8h_source.html | 91 +
content/doc/1.1.0/libguac/socket-fntypes_8h.html | 295 +
.../1.1.0/libguac/socket-fntypes_8h_source.html | 100 +
content/doc/1.1.0/libguac/socket-ssl_8h.html | 155 +
.../doc/1.1.0/libguac/socket-ssl_8h_source.html | 98 +
content/doc/1.1.0/libguac/socket-types_8h.html | 133 +
.../doc/1.1.0/libguac/socket-types_8h_source.html | 95 +
content/doc/1.1.0/libguac/socket-wsa_8h.html | 137 +
.../doc/1.1.0/libguac/socket-wsa_8h_source.html | 94 +
content/doc/1.1.0/libguac/socket_8h.html | 746 ++
content/doc/1.1.0/libguac/socket_8h_source.html | 134 +
content/doc/1.1.0/libguac/splitbar.png | Bin 0 -> 314 bytes
content/doc/1.1.0/libguac/stream-types_8h.html | 98 +
.../doc/1.1.0/libguac/stream-types_8h_source.html | 92 +
content/doc/1.1.0/libguac/stream_8h.html | 107 +
content/doc/1.1.0/libguac/stream_8h_source.html | 102 +
content/doc/1.1.0/libguac/string_8h.html | 275 +
content/doc/1.1.0/libguac/string_8h_source.html | 95 +
.../1.1.0/libguac/structguac__audio__encoder.html | 125 +
.../1.1.0/libguac/structguac__audio__stream.html | 163 +
content/doc/1.1.0/libguac/structguac__client.html | 313 +
content/doc/1.1.0/libguac/structguac__layer.html | 105 +
content/doc/1.1.0/libguac/structguac__object.html | 150 +
content/doc/1.1.0/libguac/structguac__parser.html | 117 +
content/doc/1.1.0/libguac/structguac__pool.html | 110 +
.../doc/1.1.0/libguac/structguac__pool__int.html | 105 +
content/doc/1.1.0/libguac/structguac__socket.html | 142 +
.../libguac/structguac__socket__ssl__data.html | 113 +
content/doc/1.1.0/libguac/structguac__stream.html | 170 +
content/doc/1.1.0/libguac/structguac__user.html | 540 ++
.../doc/1.1.0/libguac/structguac__user__info.html | 242 +
content/doc/1.1.0/libguac/sync_off.png | Bin 0 -> 853 bytes
content/doc/1.1.0/libguac/sync_on.png | Bin 0 -> 845 bytes
content/doc/1.1.0/libguac/tab_a.png | Bin 0 -> 142 bytes
content/doc/1.1.0/libguac/tab_b.png | Bin 0 -> 169 bytes
content/doc/1.1.0/libguac/tab_h.png | Bin 0 -> 177 bytes
content/doc/1.1.0/libguac/tab_s.png | Bin 0 -> 184 bytes
content/doc/1.1.0/libguac/tabs.css | 1 +
content/doc/1.1.0/libguac/timestamp-types_8h.html | 108 +
.../1.1.0/libguac/timestamp-types_8h_source.html | 92 +
content/doc/1.1.0/libguac/timestamp_8h.html | 158 +
content/doc/1.1.0/libguac/timestamp_8h_source.html | 95 +
content/doc/1.1.0/libguac/unicode_8h.html | 263 +
content/doc/1.1.0/libguac/unicode_8h_source.html | 95 +
content/doc/1.1.0/libguac/user-constants_8h.html | 149 +
.../1.1.0/libguac/user-constants_8h_source.html | 91 +
content/doc/1.1.0/libguac/user-fntypes_8h.html | 612 ++
.../doc/1.1.0/libguac/user-fntypes_8h_source.html | 118 +
content/doc/1.1.0/libguac/user-types_8h.html | 98 +
.../doc/1.1.0/libguac/user-types_8h_source.html | 93 +
content/doc/1.1.0/libguac/user_8h.html | 1187 +++
content/doc/1.1.0/libguac/user_8h_source.html | 180 +
content/releases/1.1.0/index.html | 1293 +++
882 files changed, 255118 insertions(+)
diff --git a/content/doc/1.1.0/guacamole-common-js/ArrayBufferReader.js.html b/content/doc/1.1.0/guacamole-common-js/ArrayBufferReader.js.html
new file mode 100644
index 0000000..ffa83de
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/ArrayBufferReader.js.html
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: ArrayBufferReader.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: ArrayBufferReader.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * A reader which automatically handles the given input stream, returning
+ * strictly received packets as array buffers. Note that this object will
+ * overwrite any installed event handlers on the given Guacamole.InputStream.
+ *
+ * @constructor
+ * @param {Guacamole.InputStream} stream The stream that data will be read
+ * from.
+ */
+Guacamole.ArrayBufferReader = function(stream) {
+
+ /**
+ * Reference to this Guacamole.InputStream.
+ * @private
+ */
+ var guac_reader = this;
+
+ // Receive blobs as array buffers
+ stream.onblob = function(data) {
+
+ // Convert to ArrayBuffer
+ var binary = window.atob(data);
+ var arrayBuffer = new ArrayBuffer(binary.length);
+ var bufferView = new Uint8Array(arrayBuffer);
+
+ for (var i=0; i<binary.length; i++)
+ bufferView[i] = binary.charCodeAt(i);
+
+ // Call handler, if present
+ if (guac_reader.ondata)
+ guac_reader.ondata(arrayBuffer);
+
+ };
+
+ // Simply call onend when end received
+ stream.onend = function() {
+ if (guac_reader.onend)
+ guac_reader.onend();
+ };
+
+ /**
+ * Fired once for every blob of data received.
+ *
+ * @event
+ * @param {ArrayBuffer} buffer The data packet received.
+ */
+ this.ondata = null;
+
+ /**
+ * Fired once this stream is finished and no further data will be written.
+ * @event
+ */
+ this.onend = null;
+
+};</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
diff --git a/content/doc/1.1.0/guacamole-common-js/ArrayBufferWriter.js.html b/content/doc/1.1.0/guacamole-common-js/ArrayBufferWriter.js.html
new file mode 100644
index 0000000..9849d69
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/ArrayBufferWriter.js.html
@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: ArrayBufferWriter.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: ArrayBufferWriter.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * A writer which automatically writes to the given output stream with arbitrary
+ * binary data, supplied as ArrayBuffers.
+ *
+ * @constructor
+ * @param {Guacamole.OutputStream} stream The stream that data will be written
+ * to.
+ */
+Guacamole.ArrayBufferWriter = function(stream) {
+
+ /**
+ * Reference to this Guacamole.StringWriter.
+ * @private
+ */
+ var guac_writer = this;
+
+ // Simply call onack for acknowledgements
+ stream.onack = function(status) {
+ if (guac_writer.onack)
+ guac_writer.onack(status);
+ };
+
+ /**
+ * Encodes the given data as base64, sending it as a blob. The data must
+ * be small enough to fit into a single blob instruction.
+ *
+ * @private
+ * @param {Uint8Array} bytes The data to send.
+ */
+ function __send_blob(bytes) {
+
+ var binary = "";
+
+ // Produce binary string from bytes in buffer
+ for (var i=0; i<bytes.byteLength; i++)
+ binary += String.fromCharCode(bytes[i]);
+
+ // Send as base64
+ stream.sendBlob(window.btoa(binary));
+
+ }
+
+ /**
+ * The maximum length of any blob sent by this Guacamole.ArrayBufferWriter,
+ * in bytes. Data sent via
+ * [sendData()]{@link Guacamole.ArrayBufferWriter#sendData} which exceeds
+ * this length will be split into multiple blobs. As the Guacamole protocol
+ * limits the maximum size of any instruction or instruction element to
+ * 8192 bytes, and the contents of blobs will be base64-encoded, this value
+ * should only be increased with extreme caution.
+ *
+ * @type {Number}
+ * @default {@link Guacamole.ArrayBufferWriter.DEFAULT_BLOB_LENGTH}
+ */
+ this.blobLength = Guacamole.ArrayBufferWriter.DEFAULT_BLOB_LENGTH;
+
+ /**
+ * Sends the given data.
+ *
+ * @param {ArrayBuffer|TypedArray} data The data to send.
+ */
+ this.sendData = function(data) {
+
+ var bytes = new Uint8Array(data);
+
+ // If small enough to fit into single instruction, send as-is
+ if (bytes.length <= guac_writer.blobLength)
+ __send_blob(bytes);
+
+ // Otherwise, send as multiple instructions
+ else {
+ for (var offset=0; offset<bytes.length; offset += guac_writer.blobLength)
+ __send_blob(bytes.subarray(offset, offset + guac_writer.blobLength));
+ }
+
+ };
+
+ /**
+ * Signals that no further text will be sent, effectively closing the
+ * stream.
+ */
+ this.sendEnd = function() {
+ stream.sendEnd();
+ };
+
+ /**
+ * Fired for received data, if acknowledged by the server.
+ * @event
+ * @param {Guacamole.Status} status The status of the operation.
+ */
+ this.onack = null;
+
+};
+
+/**
+ * The default maximum blob length for new Guacamole.ArrayBufferWriter
+ * instances.
+ *
+ * @constant
+ * @type {Number}
+ */
+Guacamole.ArrayBufferWriter.DEFAULT_BLOB_LENGTH = 6048;
+</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
diff --git a/content/doc/1.1.0/guacamole-common-js/AudioContextFactory.js.html b/content/doc/1.1.0/guacamole-common-js/AudioContextFactory.js.html
new file mode 100644
index 0000000..9305884
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/AudioContextFactory.js.html
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: AudioContextFactory.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: AudioContextFactory.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * Maintains a singleton instance of the Web Audio API AudioContext class,
+ * instantiating the AudioContext only in response to the first call to
+ * getAudioContext(), and only if no existing AudioContext instance has been
+ * provided via the singleton property. Subsequent calls to getAudioContext()
+ * will return the same instance.
+ *
+ * @namespace
+ */
+Guacamole.AudioContextFactory = {
+
+ /**
+ * A singleton instance of a Web Audio API AudioContext object, or null if
+ * no instance has yes been created. This property may be manually set if
+ * you wish to supply your own AudioContext instance, but care must be
+ * taken to do so as early as possible. Assignments to this property will
+ * not retroactively affect the value returned by previous calls to
+ * getAudioContext().
+ *
+ * @type {AudioContext}
+ */
+ 'singleton' : null,
+
+ /**
+ * Returns a singleton instance of a Web Audio API AudioContext object.
+ *
+ * @return {AudioContext}
+ * A singleton instance of a Web Audio API AudioContext object, or null
+ * if the Web Audio API is not supported.
+ */
+ 'getAudioContext' : function getAudioContext() {
+
+ // Fallback to Webkit-specific AudioContext implementation
+ var AudioContext = window.AudioContext || window.webkitAudioContext;
+
+ // Get new AudioContext instance if Web Audio API is supported
+ if (AudioContext) {
+ try {
+
+ // Create new instance if none yet exists
+ if (!Guacamole.AudioContextFactory.singleton)
+ Guacamole.AudioContextFactory.singleton = new AudioContext();
+
+ // Return singleton instance
+ return Guacamole.AudioContextFactory.singleton;
+
+ }
+ catch (e) {
+ // Do not use Web Audio API if not allowed by browser
+ }
+ }
+
+ // Web Audio API not supported
+ return null;
+
+ }
+
+};
+</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
diff --git a/content/doc/1.1.0/guacamole-common-js/AudioPlayer.js.html b/content/doc/1.1.0/guacamole-common-js/AudioPlayer.js.html
new file mode 100644
index 0000000..72f2f81
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/AudioPlayer.js.html
@@ -0,0 +1,566 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: AudioPlayer.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: AudioPlayer.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * Abstract audio player which accepts, queues and plays back arbitrary audio
+ * data. It is up to implementations of this class to provide some means of
+ * handling a provided Guacamole.InputStream. Data received along the provided
+ * stream is to be played back immediately.
+ *
+ * @constructor
+ */
+Guacamole.AudioPlayer = function AudioPlayer() {
+
+ /**
+ * Notifies this Guacamole.AudioPlayer that all audio up to the current
+ * point in time has been given via the underlying stream, and that any
+ * difference in time between queued audio data and the current time can be
+ * considered latency.
+ */
+ this.sync = function sync() {
+ // Default implementation - do nothing
+ };
+
+};
+
+/**
+ * Determines whether the given mimetype is supported by any built-in
+ * implementation of Guacamole.AudioPlayer, and thus will be properly handled
+ * by Guacamole.AudioPlayer.getInstance().
+ *
+ * @param {String} mimetype
+ * The mimetype to check.
+ *
+ * @returns {Boolean}
+ * true if the given mimetype is supported by any built-in
+ * Guacamole.AudioPlayer, false otherwise.
+ */
+Guacamole.AudioPlayer.isSupportedType = function isSupportedType(mimetype) {
+
+ return Guacamole.RawAudioPlayer.isSupportedType(mimetype);
+
+};
+
+/**
+ * Returns a list of all mimetypes supported by any built-in
+ * Guacamole.AudioPlayer, in rough order of priority. Beware that only the core
+ * mimetypes themselves will be listed. Any mimetype parameters, even required
+ * ones, will not be included in the list. For example, "audio/L8" is a
+ * supported raw audio mimetype that is supported, but it is invalid without
+ * additional parameters. Something like "audio/L8;rate=44100" would be valid,
+ * however (see https://tools.ietf.org/html/rfc4856).
+ *
+ * @returns {String[]}
+ * A list of all mimetypes supported by any built-in Guacamole.AudioPlayer,
+ * excluding any parameters.
+ */
+Guacamole.AudioPlayer.getSupportedTypes = function getSupportedTypes() {
+
+ return Guacamole.RawAudioPlayer.getSupportedTypes();
+
+};
+
+/**
+ * Returns an instance of Guacamole.AudioPlayer providing support for the given
+ * audio format. If support for the given audio format is not available, null
+ * is returned.
+ *
+ * @param {Guacamole.InputStream} stream
+ * The Guacamole.InputStream to read audio data from.
+ *
+ * @param {String} mimetype
+ * The mimetype of the audio data in the provided stream.
+ *
+ * @return {Guacamole.AudioPlayer}
+ * A Guacamole.AudioPlayer instance supporting the given mimetype and
+ * reading from the given stream, or null if support for the given mimetype
+ * is absent.
+ */
+Guacamole.AudioPlayer.getInstance = function getInstance(stream, mimetype) {
+
+ // Use raw audio player if possible
+ if (Guacamole.RawAudioPlayer.isSupportedType(mimetype))
+ return new Guacamole.RawAudioPlayer(stream, mimetype);
+
+ // No support for given mimetype
+ return null;
+
+};
+
+/**
+ * Implementation of Guacamole.AudioPlayer providing support for raw PCM format
+ * audio. This player relies only on the Web Audio API and does not require any
+ * browser-level support for its audio formats.
+ *
+ * @constructor
+ * @augments Guacamole.AudioPlayer
+ * @param {Guacamole.InputStream} stream
+ * The Guacamole.InputStream to read audio data from.
+ *
+ * @param {String} mimetype
+ * The mimetype of the audio data in the provided stream, which must be a
+ * "audio/L8" or "audio/L16" mimetype with necessary parameters, such as:
+ * "audio/L16;rate=44100,channels=2".
+ */
+Guacamole.RawAudioPlayer = function RawAudioPlayer(stream, mimetype) {
+
+ /**
+ * The format of audio this player will decode.
+ *
+ * @private
+ * @type {Guacamole.RawAudioFormat}
+ */
+ var format = Guacamole.RawAudioFormat.parse(mimetype);
+
+ /**
+ * An instance of a Web Audio API AudioContext object, or null if the
+ * Web Audio API is not supported.
+ *
+ * @private
+ * @type {AudioContext}
+ */
+ var context = Guacamole.AudioContextFactory.getAudioContext();
+
+ /**
+ * The earliest possible time that the next packet could play without
+ * overlapping an already-playing packet, in seconds. Note that while this
+ * value is in seconds, it is not an integer value and has microsecond
+ * resolution.
+ *
+ * @private
+ * @type {Number}
+ */
+ var nextPacketTime = context.currentTime;
+
+ /**
+ * Guacamole.ArrayBufferReader wrapped around the audio input stream
+ * provided with this Guacamole.RawAudioPlayer was created.
+ *
+ * @private
+ * @type {Guacamole.ArrayBufferReader}
+ */
+ var reader = new Guacamole.ArrayBufferReader(stream);
+
+ /**
+ * The minimum size of an audio packet split by splitAudioPacket(), in
+ * seconds. Audio packets smaller than this will not be split, nor will the
+ * split result of a larger packet ever be smaller in size than this
+ * minimum.
+ *
+ * @private
+ * @constant
+ * @type {Number}
+ */
+ var MIN_SPLIT_SIZE = 0.02;
+
+ /**
+ * The maximum amount of latency to allow between the buffered data stream
+ * and the playback position, in seconds. Initially, this is set to
+ * roughly one third of a second.
+ *
+ * @private
+ * @type {Number}
+ */
+ var maxLatency = 0.3;
+
+ /**
+ * The type of typed array that will be used to represent each audio packet
+ * internally. This will be either Int8Array or Int16Array, depending on
+ * whether the raw audio format is 8-bit or 16-bit.
+ *
+ * @private
+ * @constructor
+ */
+ var SampleArray = (format.bytesPerSample === 1) ? window.Int8Array : window.Int16Array;
+
+ /**
+ * The maximum absolute value of any sample within a raw audio packet
+ * received by this audio player. This depends only on the size of each
+ * sample, and will be 128 for 8-bit audio and 32768 for 16-bit audio.
+ *
+ * @private
+ * @type {Number}
+ */
+ var maxSampleValue = (format.bytesPerSample === 1) ? 128 : 32768;
+
+ /**
+ * The queue of all pending audio packets, as an array of sample arrays.
+ * Audio packets which are pending playback will be added to this queue for
+ * further manipulation prior to scheduling via the Web Audio API. Once an
+ * audio packet leaves this queue and is scheduled via the Web Audio API,
+ * no further modifications can be made to that packet.
+ *
+ * @private
+ * @type {SampleArray[]}
+ */
+ var packetQueue = [];
+
+ /**
+ * Given an array of audio packets, returns a single audio packet
+ * containing the concatenation of those packets.
+ *
+ * @private
+ * @param {SampleArray[]} packets
+ * The array of audio packets to concatenate.
+ *
+ * @returns {SampleArray}
+ * A single audio packet containing the concatenation of all given
+ * audio packets. If no packets are provided, this will be undefined.
+ */
+ var joinAudioPackets = function joinAudioPackets(packets) {
+
+ // Do not bother joining if one or fewer packets are in the queue
+ if (packets.length <= 1)
+ return packets[0];
+
+ // Determine total sample length of the entire queue
+ var totalLength = 0;
+ packets.forEach(function addPacketLengths(packet) {
+ totalLength += packet.length;
+ });
+
+ // Append each packet within queue
+ var offset = 0;
+ var joined = new SampleArray(totalLength);
+ packets.forEach(function appendPacket(packet) {
+ joined.set(packet, offset);
+ offset += packet.length;
+ });
+
+ return joined;
+
+ };
+
+ /**
+ * Given a single packet of audio data, splits off an arbitrary length of
+ * audio data from the beginning of that packet, returning the split result
+ * as an array of two packets. The split location is determined through an
+ * algorithm intended to minimize the liklihood of audible clicking between
+ * packets. If no such split location is possible, an array containing only
+ * the originally-provided audio packet is returned.
+ *
+ * @private
+ * @param {SampleArray} data
+ * The audio packet to split.
+ *
+ * @returns {SampleArray[]}
+ * An array of audio packets containing the result of splitting the
+ * provided audio packet. If splitting is possible, this array will
+ * contain two packets. If splitting is not possible, this array will
+ * contain only the originally-provided packet.
+ */
+ var splitAudioPacket = function splitAudioPacket(data) {
+
+ var minValue = Number.MAX_VALUE;
+ var optimalSplitLength = data.length;
+
+ // Calculate number of whole samples in the provided audio packet AND
+ // in the minimum possible split packet
+ var samples = Math.floor(data.length / format.channels);
+ var minSplitSamples = Math.floor(format.rate * MIN_SPLIT_SIZE);
+
+ // Calculate the beginning of the "end" of the audio packet
+ var start = Math.max(
+ format.channels * minSplitSamples,
+ format.channels * (samples - minSplitSamples)
+ );
+
+ // For all samples at the end of the given packet, find a point where
+ // the perceptible volume across all channels is lowest (and thus is
+ // the optimal point to split)
+ for (var offset = start; offset < data.length; offset += format.channels) {
+
+ // Calculate the sum of all values across all channels (the result
+ // will be proportional to the average volume of a sample)
+ var totalValue = 0;
+ for (var channel = 0; channel < format.channels; channel++) {
+ totalValue += Math.abs(data[offset + channel]);
+ }
+
+ // If this is the smallest average value thus far, set the split
+ // length such that the first packet ends with the current sample
+ if (totalValue <= minValue) {
+ optimalSplitLength = offset + format.channels;
+ minValue = totalValue;
+ }
+
+ }
+
+ // If packet is not split, return the supplied packet untouched
+ if (optimalSplitLength === data.length)
+ return [data];
+
+ // Otherwise, split the packet into two new packets according to the
+ // calculated optimal split length
+ return [
+ new SampleArray(data.buffer.slice(0, optimalSplitLength * format.bytesPerSample)),
+ new SampleArray(data.buffer.slice(optimalSplitLength * format.bytesPerSample))
+ ];
+
+ };
+
+ /**
+ * Pushes the given packet of audio data onto the playback queue. Unlike
+ * other private functions within Guacamole.RawAudioPlayer, the type of the
+ * ArrayBuffer packet of audio data here need not be specific to the type
+ * of audio (as with SampleArray). The ArrayBuffer type provided by a
+ * Guacamole.ArrayBufferReader, for example, is sufficient. Any necessary
+ * conversions will be performed automatically internally.
+ *
+ * @private
+ * @param {ArrayBuffer} data
+ * A raw packet of audio data that should be pushed onto the audio
+ * playback queue.
+ */
+ var pushAudioPacket = function pushAudioPacket(data) {
+ packetQueue.push(new SampleArray(data));
+ };
+
+ /**
+ * Shifts off and returns a packet of audio data from the beginning of the
+ * playback queue. The length of this audio packet is determined
+ * dynamically according to the click-reduction algorithm implemented by
+ * splitAudioPacket().
+ *
+ * @private
+ * @returns {SampleArray}
+ * A packet of audio data pulled from the beginning of the playback
+ * queue.
+ */
+ var shiftAudioPacket = function shiftAudioPacket() {
+
+ // Flatten data in packet queue
+ var data = joinAudioPackets(packetQueue);
+ if (!data)
+ return null;
+
+ // Pull an appropriate amount of data from the front of the queue
+ packetQueue = splitAudioPacket(data);
+ data = packetQueue.shift();
+
+ return data;
+
+ };
+
+ /**
+ * Converts the given audio packet into an AudioBuffer, ready for playback
+ * by the Web Audio API. Unlike the raw audio packets received by this
+ * audio player, AudioBuffers require floating point samples and are split
+ * into isolated planes of channel-specific data.
+ *
+ * @private
+ * @param {SampleArray} data
+ * The raw audio packet that should be converted into a Web Audio API
+ * AudioBuffer.
+ *
+ * @returns {AudioBuffer}
+ * A new Web Audio API AudioBuffer containing the provided audio data,
+ * converted to the format used by the Web Audio API.
+ */
+ var toAudioBuffer = function toAudioBuffer(data) {
+
+ // Calculate total number of samples
+ var samples = data.length / format.channels;
+
+ // Determine exactly when packet CAN play
+ var packetTime = context.currentTime;
+ if (nextPacketTime < packetTime)
+ nextPacketTime = packetTime;
+
+ // Get audio buffer for specified format
+ var audioBuffer = context.createBuffer(format.channels, samples, format.rate);
+
+ // Convert each channel
+ for (var channel = 0; channel < format.channels; channel++) {
+
+ var audioData = audioBuffer.getChannelData(channel);
+
+ // Fill audio buffer with data for channel
+ var offset = channel;
+ for (var i = 0; i < samples; i++) {
+ audioData[i] = data[offset] / maxSampleValue;
+ offset += format.channels;
+ }
+
+ }
+
+ return audioBuffer;
+
+ };
+
+ // Defer playback of received audio packets slightly
+ reader.ondata = function playReceivedAudio(data) {
+
+ // Push received samples onto queue
+ pushAudioPacket(new SampleArray(data));
+
+ // Shift off an arbitrary packet of audio data from the queue (this may
+ // be different in size from the packet just pushed)
+ var packet = shiftAudioPacket();
+ if (!packet)
+ return;
+
+ // Determine exactly when packet CAN play
+ var packetTime = context.currentTime;
+ if (nextPacketTime < packetTime)
+ nextPacketTime = packetTime;
+
+ // Set up buffer source
+ var source = context.createBufferSource();
+ source.connect(context.destination);
+
+ // Use noteOn() instead of start() if necessary
+ if (!source.start)
+ source.start = source.noteOn;
+
+ // Schedule packet
+ source.buffer = toAudioBuffer(packet);
+ source.start(nextPacketTime);
+
+ // Update timeline by duration of scheduled packet
+ nextPacketTime += packet.length / format.channels / format.rate;
+
+ };
+
+ /** @override */
+ this.sync = function sync() {
+
+ // Calculate elapsed time since last sync
+ var now = context.currentTime;
+
+ // Reschedule future playback time such that playback latency is
+ // bounded within a reasonable latency threshold
+ nextPacketTime = Math.min(nextPacketTime, now + maxLatency);
+
+ };
+
+};
+
+Guacamole.RawAudioPlayer.prototype = new Guacamole.AudioPlayer();
+
+/**
+ * Determines whether the given mimetype is supported by
+ * Guacamole.RawAudioPlayer.
+ *
+ * @param {String} mimetype
+ * The mimetype to check.
+ *
+ * @returns {Boolean}
+ * true if the given mimetype is supported by Guacamole.RawAudioPlayer,
+ * false otherwise.
+ */
+Guacamole.RawAudioPlayer.isSupportedType = function isSupportedType(mimetype) {
+
+ // No supported types if no Web Audio API
+ if (!Guacamole.AudioContextFactory.getAudioContext())
+ return false;
+
+ return Guacamole.RawAudioFormat.parse(mimetype) !== null;
+
+};
+
+/**
+ * Returns a list of all mimetypes supported by Guacamole.RawAudioPlayer. Only
+ * the core mimetypes themselves will be listed. Any mimetype parameters, even
+ * required ones, will not be included in the list. For example, "audio/L8" is
+ * a raw audio mimetype that may be supported, but it is invalid without
+ * additional parameters. Something like "audio/L8;rate=44100" would be valid,
+ * however (see https://tools.ietf.org/html/rfc4856).
+ *
+ * @returns {String[]}
+ * A list of all mimetypes supported by Guacamole.RawAudioPlayer, excluding
+ * any parameters. If the necessary JavaScript APIs for playing raw audio
+ * are absent, this list will be empty.
+ */
+Guacamole.RawAudioPlayer.getSupportedTypes = function getSupportedTypes() {
+
+ // No supported types if no Web Audio API
+ if (!Guacamole.AudioContextFactory.getAudioContext())
+ return [];
+
+ // We support 8-bit and 16-bit raw PCM
+ return [
+ 'audio/L8',
+ 'audio/L16'
+ ];
+
+};
+</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
diff --git a/content/doc/1.1.0/guacamole-common-js/AudioRecorder.js.html b/content/doc/1.1.0/guacamole-common-js/AudioRecorder.js.html
new file mode 100644
index 0000000..a118160
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/AudioRecorder.js.html
@@ -0,0 +1,632 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: AudioRecorder.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: AudioRecorder.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * Abstract audio recorder which streams arbitrary audio data to an underlying
+ * Guacamole.OutputStream. It is up to implementations of this class to provide
+ * some means of handling this Guacamole.OutputStream. Data produced by the
+ * recorder is to be sent along the provided stream immediately.
+ *
+ * @constructor
+ */
+Guacamole.AudioRecorder = function AudioRecorder() {
+
+ /**
+ * Callback which is invoked when the audio recording process has stopped
+ * and the underlying Guacamole stream has been closed normally. Audio will
+ * only resume recording if a new Guacamole.AudioRecorder is started. This
+ * Guacamole.AudioRecorder instance MAY NOT be reused.
+ *
+ * @event
+ */
+ this.onclose = null;
+
+ /**
+ * Callback which is invoked when the audio recording process cannot
+ * continue due to an error, if it has started at all. The underlying
+ * Guacamole stream is automatically closed. Future attempts to record
+ * audio should not be made, and this Guacamole.AudioRecorder instance
+ * MAY NOT be reused.
+ *
+ * @event
+ */
+ this.onerror = null;
+
+};
+
+/**
+ * Determines whether the given mimetype is supported by any built-in
+ * implementation of Guacamole.AudioRecorder, and thus will be properly handled
+ * by Guacamole.AudioRecorder.getInstance().
+ *
+ * @param {String} mimetype
+ * The mimetype to check.
+ *
+ * @returns {Boolean}
+ * true if the given mimetype is supported by any built-in
+ * Guacamole.AudioRecorder, false otherwise.
+ */
+Guacamole.AudioRecorder.isSupportedType = function isSupportedType(mimetype) {
+
+ return Guacamole.RawAudioRecorder.isSupportedType(mimetype);
+
+};
+
+/**
+ * Returns a list of all mimetypes supported by any built-in
+ * Guacamole.AudioRecorder, in rough order of priority. Beware that only the
+ * core mimetypes themselves will be listed. Any mimetype parameters, even
+ * required ones, will not be included in the list. For example, "audio/L8" is
+ * a supported raw audio mimetype that is supported, but it is invalid without
+ * additional parameters. Something like "audio/L8;rate=44100" would be valid,
+ * however (see https://tools.ietf.org/html/rfc4856).
+ *
+ * @returns {String[]}
+ * A list of all mimetypes supported by any built-in
+ * Guacamole.AudioRecorder, excluding any parameters.
+ */
+Guacamole.AudioRecorder.getSupportedTypes = function getSupportedTypes() {
+
+ return Guacamole.RawAudioRecorder.getSupportedTypes();
+
+};
+
+/**
+ * Returns an instance of Guacamole.AudioRecorder providing support for the
+ * given audio format. If support for the given audio format is not available,
+ * null is returned.
+ *
+ * @param {Guacamole.OutputStream} stream
+ * The Guacamole.OutputStream to send audio data through.
+ *
+ * @param {String} mimetype
+ * The mimetype of the audio data to be sent along the provided stream.
+ *
+ * @return {Guacamole.AudioRecorder}
+ * A Guacamole.AudioRecorder instance supporting the given mimetype and
+ * writing to the given stream, or null if support for the given mimetype
+ * is absent.
+ */
+Guacamole.AudioRecorder.getInstance = function getInstance(stream, mimetype) {
+
+ // Use raw audio recorder if possible
+ if (Guacamole.RawAudioRecorder.isSupportedType(mimetype))
+ return new Guacamole.RawAudioRecorder(stream, mimetype);
+
+ // No support for given mimetype
+ return null;
+
+};
+
+/**
+ * Implementation of Guacamole.AudioRecorder providing support for raw PCM
+ * format audio. This recorder relies only on the Web Audio API and does not
+ * require any browser-level support for its audio formats.
+ *
+ * @constructor
+ * @augments Guacamole.AudioRecorder
+ * @param {Guacamole.OutputStream} stream
+ * The Guacamole.OutputStream to write audio data to.
+ *
+ * @param {String} mimetype
+ * The mimetype of the audio data to send along the provided stream, which
+ * must be a "audio/L8" or "audio/L16" mimetype with necessary parameters,
+ * such as: "audio/L16;rate=44100,channels=2".
+ */
+Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) {
+
+ /**
+ * Reference to this RawAudioRecorder.
+ *
+ * @private
+ * @type {Guacamole.RawAudioRecorder}
+ */
+ var recorder = this;
+
+ /**
+ * The size of audio buffer to request from the Web Audio API when
+ * recording or processing audio, in sample-frames. This must be a power of
+ * two between 256 and 16384 inclusive, as required by
+ * AudioContext.createScriptProcessor().
+ *
+ * @private
+ * @constant
+ * @type {Number}
+ */
+ var BUFFER_SIZE = 2048;
+
+ /**
+ * The window size to use when applying Lanczos interpolation, commonly
+ * denoted by the variable "a".
+ * See: https://en.wikipedia.org/wiki/Lanczos_resampling
+ *
+ * @private
+ * @contant
+ * @type Number
+ */
+ var LANCZOS_WINDOW_SIZE = 3;
+
+ /**
+ * The format of audio this recorder will encode.
+ *
+ * @private
+ * @type {Guacamole.RawAudioFormat}
+ */
+ var format = Guacamole.RawAudioFormat.parse(mimetype);
+
+ /**
+ * An instance of a Web Audio API AudioContext object, or null if the
+ * Web Audio API is not supported.
+ *
+ * @private
+ * @type {AudioContext}
+ */
+ var context = Guacamole.AudioContextFactory.getAudioContext();
+
+ // Some browsers do not implement navigator.mediaDevices - this
+ // shims in this functionality to ensure code compatibility.
+ if (!navigator.mediaDevices)
+ navigator.mediaDevices = {};
+
+ // Browsers that either do not implement navigator.mediaDevices
+ // at all or do not implement it completely need the getUserMedia
+ // method defined. This shims in this function by detecting
+ // one of the supported legacy methods.
+ if (!navigator.mediaDevices.getUserMedia)
+ navigator.mediaDevices.getUserMedia = (navigator.getUserMedia
+ || navigator.webkitGetUserMedia
+ || navigator.mozGetUserMedia
+ || navigator.msGetUserMedia).bind(navigator);
+
+ /**
+ * Guacamole.ArrayBufferWriter wrapped around the audio output stream
+ * provided when this Guacamole.RawAudioRecorder was created.
+ *
+ * @private
+ * @type {Guacamole.ArrayBufferWriter}
+ */
+ var writer = new Guacamole.ArrayBufferWriter(stream);
+
+ /**
+ * The type of typed array that will be used to represent each audio packet
+ * internally. This will be either Int8Array or Int16Array, depending on
+ * whether the raw audio format is 8-bit or 16-bit.
+ *
+ * @private
+ * @constructor
+ */
+ var SampleArray = (format.bytesPerSample === 1) ? window.Int8Array : window.Int16Array;
+
+ /**
+ * The maximum absolute value of any sample within a raw audio packet sent
+ * by this audio recorder. This depends only on the size of each sample,
+ * and will be 128 for 8-bit audio and 32768 for 16-bit audio.
+ *
+ * @private
+ * @type {Number}
+ */
+ var maxSampleValue = (format.bytesPerSample === 1) ? 128 : 32768;
+
+ /**
+ * The total number of audio samples read from the local audio input device
+ * over the life of this audio recorder.
+ *
+ * @private
+ * @type {Number}
+ */
+ var readSamples = 0;
+
+ /**
+ * The total number of audio samples written to the underlying Guacamole
+ * connection over the life of this audio recorder.
+ *
+ * @private
+ * @type {Number}
+ */
+ var writtenSamples = 0;
+
+ /**
+ * The audio stream provided by the browser, if allowed. If no stream has
+ * yet been received, this will be null.
+ *
+ * @type MediaStream
+ */
+ var mediaStream = null;
+
+ /**
+ * The source node providing access to the local audio input device.
+ *
+ * @private
+ * @type {MediaStreamAudioSourceNode}
+ */
+ var source = null;
+
+ /**
+ * The script processing node which receives audio input from the media
+ * stream source node as individual audio buffers.
+ *
+ * @private
+ * @type {ScriptProcessorNode}
+ */
+ var processor = null;
+
+ /**
+ * The normalized sinc function. The normalized sinc function is defined as
+ * 1 for x=0 and sin(PI * x) / (PI * x) for all other values of x.
+ *
+ * See: https://en.wikipedia.org/wiki/Sinc_function
+ *
+ * @private
+ * @param {Number} x
+ * The point at which the normalized sinc function should be computed.
+ *
+ * @returns {Number}
+ * The value of the normalized sinc function at x.
+ */
+ var sinc = function sinc(x) {
+
+ // The value of sinc(0) is defined as 1
+ if (x === 0)
+ return 1;
+
+ // Otherwise, normlized sinc(x) is sin(PI * x) / (PI * x)
+ var piX = Math.PI * x;
+ return Math.sin(piX) / piX;
+
+ };
+
+ /**
+ * Calculates the value of the Lanczos kernal at point x for a given window
+ * size. See: https://en.wikipedia.org/wiki/Lanczos_resampling
+ *
+ * @private
+ * @param {Number} x
+ * The point at which the value of the Lanczos kernel should be
+ * computed.
+ *
+ * @param {Number} a
+ * The window size to use for the Lanczos kernel.
+ *
+ * @returns {Number}
+ * The value of the Lanczos kernel at the given point for the given
+ * window size.
+ */
+ var lanczos = function lanczos(x, a) {
+
+ // Lanczos is sinc(x) * sinc(x / a) for -a < x < a ...
+ if (-a < x && x < a)
+ return sinc(x) * sinc(x / a);
+
+ // ... and 0 otherwise
+ return 0;
+
+ };
+
+ /**
+ * Determines the value of the waveform represented by the audio data at
+ * the given location. If the value cannot be determined exactly as it does
+ * not correspond to an exact sample within the audio data, the value will
+ * be derived through interpolating nearby samples.
+ *
+ * @private
+ * @param {Float32Array} audioData
+ * An array of audio data, as returned by AudioBuffer.getChannelData().
+ *
+ * @param {Number} t
+ * The relative location within the waveform from which the value
+ * should be retrieved, represented as a floating point number between
+ * 0 and 1 inclusive, where 0 represents the earliest point in time and
+ * 1 represents the latest.
+ *
+ * @returns {Number}
+ * The value of the waveform at the given location.
+ */
+ var interpolateSample = function getValueAt(audioData, t) {
+
+ // Convert [0, 1] range to [0, audioData.length - 1]
+ var index = (audioData.length - 1) * t;
+
+ // Determine the start and end points for the summation used by the
+ // Lanczos interpolation algorithm (see: https://en.wikipedia.org/wiki/Lanczos_resampling)
+ var start = Math.floor(index) - LANCZOS_WINDOW_SIZE + 1;
+ var end = Math.floor(index) + LANCZOS_WINDOW_SIZE;
+
+ // Calculate the value of the Lanczos interpolation function for the
+ // required range
+ var sum = 0;
+ for (var i = start; i <= end; i++) {
+ sum += (audioData[i] || 0) * lanczos(index - i, LANCZOS_WINDOW_SIZE);
+ }
+
+ return sum;
+
+ };
+
+ /**
+ * Converts the given AudioBuffer into an audio packet, ready for streaming
+ * along the underlying output stream. Unlike the raw audio packets used by
+ * this audio recorder, AudioBuffers require floating point samples and are
+ * split into isolated planes of channel-specific data.
+ *
+ * @private
+ * @param {AudioBuffer} audioBuffer
+ * The Web Audio API AudioBuffer that should be converted to a raw
+ * audio packet.
+ *
+ * @returns {SampleArray}
+ * A new raw audio packet containing the audio data from the provided
+ * AudioBuffer.
+ */
+ var toSampleArray = function toSampleArray(audioBuffer) {
+
+ // Track overall amount of data read
+ var inSamples = audioBuffer.length;
+ readSamples += inSamples;
+
+ // Calculate the total number of samples that should be written as of
+ // the audio data just received and adjust the size of the output
+ // packet accordingly
+ var expectedWrittenSamples = Math.round(readSamples * format.rate / audioBuffer.sampleRate);
+ var outSamples = expectedWrittenSamples - writtenSamples;
+
+ // Update number of samples written
+ writtenSamples += outSamples;
+
+ // Get array for raw PCM storage
+ var data = new SampleArray(outSamples * format.channels);
+
+ // Convert each channel
+ for (var channel = 0; channel < format.channels; channel++) {
+
+ var audioData = audioBuffer.getChannelData(channel);
+
+ // Fill array with data from audio buffer channel
+ var offset = channel;
+ for (var i = 0; i < outSamples; i++) {
+ data[offset] = interpolateSample(audioData, i / (outSamples - 1)) * maxSampleValue;
+ offset += format.channels;
+ }
+
+ }
+
+ return data;
+
+ };
+
+ /**
+ * Requests access to the user's microphone and begins capturing audio. All
+ * received audio data is resampled as necessary and forwarded to the
+ * Guacamole stream underlying this Guacamole.RawAudioRecorder. This
+ * function must be invoked ONLY ONCE per instance of
+ * Guacamole.RawAudioRecorder.
+ *
+ * @private
+ */
+ var beginAudioCapture = function beginAudioCapture() {
+
+ // Attempt to retrieve an audio input stream from the browser
+ navigator.mediaDevices.getUserMedia({ 'audio' : true }, function streamReceived(stream) {
+
+ // Create processing node which receives appropriately-sized audio buffers
+ processor = context.createScriptProcessor(BUFFER_SIZE, format.channels, format.channels);
+ processor.connect(context.destination);
+
+ // Send blobs when audio buffers are received
+ processor.onaudioprocess = function processAudio(e) {
+ writer.sendData(toSampleArray(e.inputBuffer).buffer);
+ };
+
+ // Connect processing node to user's audio input source
+ source = context.createMediaStreamSource(stream);
+ source.connect(processor);
+
+ // Save stream for later cleanup
+ mediaStream = stream;
+
+ }, function streamDenied() {
+
+ // Simply end stream if audio access is not allowed
+ writer.sendEnd();
+
+ // Notify of closure
+ if (recorder.onerror)
+ recorder.onerror();
+
+ });
+
+ };
+
+ /**
+ * Stops capturing audio, if the capture has started, freeing all associated
+ * resources. If the capture has not started, this function simply ends the
+ * underlying Guacamole stream.
+ *
+ * @private
+ */
+ var stopAudioCapture = function stopAudioCapture() {
+
+ // Disconnect media source node from script processor
+ if (source)
+ source.disconnect();
+
+ // Disconnect associated script processor node
+ if (processor)
+ processor.disconnect();
+
+ // Stop capture
+ if (mediaStream) {
+ var tracks = mediaStream.getTracks();
+ for (var i = 0; i < tracks.length; i++)
+ tracks[i].stop();
+ }
+
+ // Remove references to now-unneeded components
+ processor = null;
+ source = null;
+ mediaStream = null;
+
+ // End stream
+ writer.sendEnd();
+
+ };
+
+ // Once audio stream is successfully open, request and begin reading audio
+ writer.onack = function audioStreamAcknowledged(status) {
+
+ // Begin capture if successful response and not yet started
+ if (status.code === Guacamole.Status.Code.SUCCESS && !mediaStream)
+ beginAudioCapture();
+
+ // Otherwise stop capture and cease handling any further acks
+ else {
+
+ // Stop capturing audio
+ stopAudioCapture();
+ writer.onack = null;
+
+ // Notify if stream has closed normally
+ if (status.code === Guacamole.Status.Code.RESOURCE_CLOSED) {
+ if (recorder.onclose)
+ recorder.onclose();
+ }
+
+ // Otherwise notify of closure due to error
+ else {
+ if (recorder.onerror)
+ recorder.onerror();
+ }
+
+ }
+
+ };
+
+};
+
+Guacamole.RawAudioRecorder.prototype = new Guacamole.AudioRecorder();
+
+/**
+ * Determines whether the given mimetype is supported by
+ * Guacamole.RawAudioRecorder.
+ *
+ * @param {String} mimetype
+ * The mimetype to check.
+ *
+ * @returns {Boolean}
+ * true if the given mimetype is supported by Guacamole.RawAudioRecorder,
+ * false otherwise.
+ */
+Guacamole.RawAudioRecorder.isSupportedType = function isSupportedType(mimetype) {
+
+ // No supported types if no Web Audio API
+ if (!Guacamole.AudioContextFactory.getAudioContext())
+ return false;
+
+ return Guacamole.RawAudioFormat.parse(mimetype) !== null;
+
+};
+
+/**
+ * Returns a list of all mimetypes supported by Guacamole.RawAudioRecorder. Only
+ * the core mimetypes themselves will be listed. Any mimetype parameters, even
+ * required ones, will not be included in the list. For example, "audio/L8" is
+ * a raw audio mimetype that may be supported, but it is invalid without
+ * additional parameters. Something like "audio/L8;rate=44100" would be valid,
+ * however (see https://tools.ietf.org/html/rfc4856).
+ *
+ * @returns {String[]}
+ * A list of all mimetypes supported by Guacamole.RawAudioRecorder,
+ * excluding any parameters. If the necessary JavaScript APIs for recording
+ * raw audio are absent, this list will be empty.
+ */
+Guacamole.RawAudioRecorder.getSupportedTypes = function getSupportedTypes() {
+
+ // No supported types if no Web Audio API
+ if (!Guacamole.AudioContextFactory.getAudioContext())
+ return [];
+
+ // We support 8-bit and 16-bit raw PCM
+ return [
+ 'audio/L8',
+ 'audio/L16'
+ ];
+
+};
+</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
diff --git a/content/doc/1.1.0/guacamole-common-js/BlobReader.js.html b/content/doc/1.1.0/guacamole-common-js/BlobReader.js.html
new file mode 100644
index 0000000..a582911
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/BlobReader.js.html
@@ -0,0 +1,188 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: BlobReader.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: BlobReader.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * A reader which automatically handles the given input stream, assembling all
+ * received blobs into a single blob by appending them to each other in order.
+ * Note that this object will overwrite any installed event handlers on the
+ * given Guacamole.InputStream.
+ *
+ * @constructor
+ * @param {Guacamole.InputStream} stream The stream that data will be read
+ * from.
+ * @param {String} mimetype The mimetype of the blob being built.
+ */
+Guacamole.BlobReader = function(stream, mimetype) {
+
+ /**
+ * Reference to this Guacamole.InputStream.
+ * @private
+ */
+ var guac_reader = this;
+
+ /**
+ * The length of this Guacamole.InputStream in bytes.
+ * @private
+ */
+ var length = 0;
+
+ // Get blob builder
+ var blob_builder;
+ if (window.BlobBuilder) blob_builder = new BlobBuilder();
+ else if (window.WebKitBlobBuilder) blob_builder = new WebKitBlobBuilder();
+ else if (window.MozBlobBuilder) blob_builder = new MozBlobBuilder();
+ else
+ blob_builder = new (function() {
+
+ var blobs = [];
+
+ /** @ignore */
+ this.append = function(data) {
+ blobs.push(new Blob([data], {"type": mimetype}));
+ };
+
+ /** @ignore */
+ this.getBlob = function() {
+ return new Blob(blobs, {"type": mimetype});
+ };
+
+ })();
+
+ // Append received blobs
+ stream.onblob = function(data) {
+
+ // Convert to ArrayBuffer
+ var binary = window.atob(data);
+ var arrayBuffer = new ArrayBuffer(binary.length);
+ var bufferView = new Uint8Array(arrayBuffer);
+
+ for (var i=0; i<binary.length; i++)
+ bufferView[i] = binary.charCodeAt(i);
+
+ blob_builder.append(arrayBuffer);
+ length += arrayBuffer.byteLength;
+
+ // Call handler, if present
+ if (guac_reader.onprogress)
+ guac_reader.onprogress(arrayBuffer.byteLength);
+
+ // Send success response
+ stream.sendAck("OK", 0x0000);
+
+ };
+
+ // Simply call onend when end received
+ stream.onend = function() {
+ if (guac_reader.onend)
+ guac_reader.onend();
+ };
+
+ /**
+ * Returns the current length of this Guacamole.InputStream, in bytes.
+ * @return {Number} The current length of this Guacamole.InputStream.
+ */
+ this.getLength = function() {
+ return length;
+ };
+
+ /**
+ * Returns the contents of this Guacamole.BlobReader as a Blob.
+ * @return {Blob} The contents of this Guacamole.BlobReader.
+ */
+ this.getBlob = function() {
+ return blob_builder.getBlob();
+ };
+
+ /**
+ * Fired once for every blob of data received.
+ *
+ * @event
+ * @param {Number} length The number of bytes received.
+ */
+ this.onprogress = null;
+
+ /**
+ * Fired once this stream is finished and no further data will be written.
+ * @event
+ */
+ this.onend = null;
+
+};</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
diff --git a/content/doc/1.1.0/guacamole-common-js/BlobWriter.js.html b/content/doc/1.1.0/guacamole-common-js/BlobWriter.js.html
new file mode 100644
index 0000000..d9f7878
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/BlobWriter.js.html
@@ -0,0 +1,306 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: BlobWriter.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: BlobWriter.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * A writer which automatically writes to the given output stream with the
+ * contents of provided Blob objects.
+ *
+ * @constructor
+ * @param {Guacamole.OutputStream} stream
+ * The stream that data will be written to.
+ */
+Guacamole.BlobWriter = function BlobWriter(stream) {
+
+ /**
+ * Reference to this Guacamole.BlobWriter.
+ *
+ * @private
+ * @type {Guacamole.BlobWriter}
+ */
+ var guacWriter = this;
+
+ /**
+ * Wrapped Guacamole.ArrayBufferWriter which will be used to send any
+ * provided file data.
+ *
+ * @private
+ * @type {Guacamole.ArrayBufferWriter}
+ */
+ var arrayBufferWriter = new Guacamole.ArrayBufferWriter(stream);
+
+ // Initially, simply call onack for acknowledgements
+ arrayBufferWriter.onack = function(status) {
+ if (guacWriter.onack)
+ guacWriter.onack(status);
+ };
+
+ /**
+ * Browser-independent implementation of Blob.slice() which uses an end
+ * offset to determine the span of the resulting slice, rather than a
+ * length.
+ *
+ * @private
+ * @param {Blob} blob
+ * The Blob to slice.
+ *
+ * @param {Number} start
+ * The starting offset of the slice, in bytes, inclusive.
+ *
+ * @param {Number} end
+ * The ending offset of the slice, in bytes, exclusive.
+ *
+ * @returns {Blob}
+ * A Blob containing the data within the given Blob starting at
+ * <code>start</code> and ending at <code>end - 1</code>.
+ */
+ var slice = function slice(blob, start, end) {
+
+ // Use prefixed implementations if necessary
+ var sliceImplementation = (
+ blob.slice
+ || blob.webkitSlice
+ || blob.mozSlice
+ ).bind(blob);
+
+ var length = end - start;
+
+ // The old Blob.slice() was length-based (not end-based). Try the
+ // length version first, if the two calls are not equivalent.
+ if (length !== end) {
+
+ // If the result of the slice() call matches the expected length,
+ // trust that result. It must be correct.
+ var sliceResult = sliceImplementation(start, length);
+ if (sliceResult.size === length)
+ return sliceResult;
+
+ }
+
+ // Otherwise, use the most-recent standard: end-based slice()
+ return sliceImplementation(start, end);
+
+ };
+
+ /**
+ * Sends the contents of the given blob over the underlying stream.
+ *
+ * @param {Blob} blob
+ * The blob to send.
+ */
+ this.sendBlob = function sendBlob(blob) {
+
+ var offset = 0;
+ var reader = new FileReader();
+
+ /**
+ * Reads the next chunk of the blob provided to
+ * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}. The chunk itself
+ * is read asynchronously, and will not be available until
+ * reader.onload fires.
+ *
+ * @private
+ */
+ var readNextChunk = function readNextChunk() {
+
+ // If no further chunks remain, inform of completion and stop
+ if (offset >= blob.size) {
+
+ // Fire completion event for completed blob
+ if (guacWriter.oncomplete)
+ guacWriter.oncomplete(blob);
+
+ // No further chunks to read
+ return;
+
+ }
+
+ // Obtain reference to next chunk as a new blob
+ var chunk = slice(blob, offset, offset + arrayBufferWriter.blobLength);
+ offset += arrayBufferWriter.blobLength;
+
+ // Attempt to read the blob contents represented by the blob into
+ // a new array buffer
+ reader.readAsArrayBuffer(chunk);
+
+ };
+
+ // Send each chunk over the stream, continue reading the next chunk
+ reader.onload = function chunkLoadComplete() {
+
+ // Send the successfully-read chunk
+ arrayBufferWriter.sendData(reader.result);
+
+ // Continue sending more chunks after the latest chunk is
+ // acknowledged
+ arrayBufferWriter.onack = function sendMoreChunks(status) {
+
+ if (guacWriter.onack)
+ guacWriter.onack(status);
+
+ // Abort transfer if an error occurs
+ if (status.isError())
+ return;
+
+ // Inform of blob upload progress via progress events
+ if (guacWriter.onprogress)
+ guacWriter.onprogress(blob, offset - arrayBufferWriter.blobLength);
+
+ // Queue the next chunk for reading
+ readNextChunk();
+
+ };
+
+ };
+
+ // If an error prevents further reading, inform of error and stop
+ reader.onerror = function chunkLoadFailed() {
+
+ // Fire error event, including the context of the error
+ if (guacWriter.onerror)
+ guacWriter.onerror(blob, offset, reader.error);
+
+ };
+
+ // Begin reading the first chunk
+ readNextChunk();
+
+ };
+
+ /**
+ * Signals that no further text will be sent, effectively closing the
+ * stream.
+ */
+ this.sendEnd = function sendEnd() {
+ arrayBufferWriter.sendEnd();
+ };
+
+ /**
+ * Fired for received data, if acknowledged by the server.
+ *
+ * @event
+ * @param {Guacamole.Status} status
+ * The status of the operation.
+ */
+ this.onack = null;
+
+ /**
+ * Fired when an error occurs reading a blob passed to
+ * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}. The transfer for the
+ * the given blob will cease, but the stream will remain open.
+ *
+ * @event
+ * @param {Blob} blob
+ * The blob that was being read when the error occurred.
+ *
+ * @param {Number} offset
+ * The offset of the failed read attempt within the blob, in bytes.
+ *
+ * @param {DOMError} error
+ * The error that occurred.
+ */
+ this.onerror = null;
+
+ /**
+ * Fired for each successfully-read chunk of data as a blob is being sent
+ * via [sendBlob()]{@link Guacamole.BlobWriter#sendBlob}.
+ *
+ * @event
+ * @param {Blob} blob
+ * The blob that is being read.
+ *
+ * @param {Number} offset
+ * The offset of the read that just succeeded.
+ */
+ this.onprogress = null;
+
+ /**
+ * Fired when a blob passed to
+ * [sendBlob()]{@link Guacamole.BlobWriter#sendBlob} has finished being
+ * sent.
+ *
+ * @event
+ * @param {Blob} blob
+ * The blob that was sent.
+ */
+ this.oncomplete = null;
+
+};
+</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
diff --git a/content/doc/1.1.0/guacamole-common-js/Client.js.html b/content/doc/1.1.0/guacamole-common-js/Client.js.html
new file mode 100644
index 0000000..e1c1f4d
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/Client.js.html
@@ -0,0 +1,1751 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: Client.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: Client.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * Guacamole protocol client. Given a {@link Guacamole.Tunnel},
+ * automatically handles incoming and outgoing Guacamole instructions via the
+ * provided tunnel, updating its display using one or more canvas elements.
+ *
+ * @constructor
+ * @param {Guacamole.Tunnel} tunnel The tunnel to use to send and receive
+ * Guacamole instructions.
+ */
+Guacamole.Client = function(tunnel) {
+
+ var guac_client = this;
+
+ var STATE_IDLE = 0;
+ var STATE_CONNECTING = 1;
+ var STATE_WAITING = 2;
+ var STATE_CONNECTED = 3;
+ var STATE_DISCONNECTING = 4;
+ var STATE_DISCONNECTED = 5;
+
+ var currentState = STATE_IDLE;
+
+ var currentTimestamp = 0;
+ var pingInterval = null;
+
+ /**
+ * Translation from Guacamole protocol line caps to Layer line caps.
+ * @private
+ */
+ var lineCap = {
+ 0: "butt",
+ 1: "round",
+ 2: "square"
+ };
+
+ /**
+ * Translation from Guacamole protocol line caps to Layer line caps.
+ * @private
+ */
+ var lineJoin = {
+ 0: "bevel",
+ 1: "miter",
+ 2: "round"
+ };
+
+ /**
+ * The underlying Guacamole display.
+ *
+ * @private
+ * @type {Guacamole.Display}
+ */
+ var display = new Guacamole.Display();
+
+ /**
+ * All available layers and buffers
+ *
+ * @private
+ * @type {Object.<Number, (Guacamole.Display.VisibleLayer|Guacamole.Layer)>}
+ */
+ var layers = {};
+
+ /**
+ * All audio players currently in use by the client. Initially, this will
+ * be empty, but audio players may be allocated by the server upon request.
+ *
+ * @private
+ * @type {Object.<Number, Guacamole.AudioPlayer>}
+ */
+ var audioPlayers = {};
+
+ /**
+ * All video players currently in use by the client. Initially, this will
+ * be empty, but video players may be allocated by the server upon request.
+ *
+ * @private
+ * @type {Object.<Number, Guacamole.VideoPlayer>}
+ */
+ var videoPlayers = {};
+
+ // No initial parsers
+ var parsers = [];
+
+ // No initial streams
+ var streams = [];
+
+ /**
+ * All current objects. The index of each object is dictated by the
+ * Guacamole server.
+ *
+ * @private
+ * @type {Guacamole.Object[]}
+ */
+ var objects = [];
+
+ // Pool of available stream indices
+ var stream_indices = new Guacamole.IntegerPool();
+
+ // Array of allocated output streams by index
+ var output_streams = [];
+
+ function setState(state) {
+ if (state != currentState) {
+ currentState = state;
+ if (guac_client.onstatechange)
+ guac_client.onstatechange(currentState);
+ }
+ }
+
+ function isConnected() {
+ return currentState == STATE_CONNECTED
+ || currentState == STATE_WAITING;
+ }
+
+ /**
+ * Produces an opaque representation of Guacamole.Client state which can be
+ * later imported through a call to importState(). This object is
+ * effectively an independent, compressed snapshot of protocol and display
+ * state. Invoking this function implicitly flushes the display.
+ *
+ * @param {function} callback
+ * Callback which should be invoked once the state object is ready. The
+ * state object will be passed to the callback as the sole parameter.
+ * This callback may be invoked immediately, or later as the display
+ * finishes rendering and becomes ready.
+ */
+ this.exportState = function exportState(callback) {
+
+ // Start with empty state
+ var state = {
+ 'currentState' : currentState,
+ 'currentTimestamp' : currentTimestamp,
+ 'layers' : {}
+ };
+
+ var layersSnapshot = {};
+
+ // Make a copy of all current layers (protocol state)
+ for (var key in layers) {
+ layersSnapshot[key] = layers[key];
+ }
+
+ // Populate layers once data is available (display state, requires flush)
+ display.flush(function populateLayers() {
+
+ // Export each defined layer/buffer
+ for (var key in layersSnapshot) {
+
+ var index = parseInt(key);
+ var layer = layersSnapshot[key];
+ var canvas = layer.toCanvas();
+
+ // Store layer/buffer dimensions
+ var exportLayer = {
+ 'width' : layer.width,
+ 'height' : layer.height
+ };
+
+ // Store layer/buffer image data, if it can be generated
+ if (layer.width && layer.height)
+ exportLayer.url = canvas.toDataURL('image/png');
+
+ // Add layer properties if not a buffer nor the default layer
+ if (index > 0) {
+ exportLayer.x = layer.x;
+ exportLayer.y = layer.y;
+ exportLayer.z = layer.z;
+ exportLayer.alpha = layer.alpha;
+ exportLayer.matrix = layer.matrix;
+ exportLayer.parent = getLayerIndex(layer.parent);
+ }
+
+ // Store exported layer
+ state.layers[key] = exportLayer;
+
+ }
+
+ // Invoke callback now that the state is ready
+ callback(state);
+
+ });
+
+ };
+
+ /**
+ * Restores Guacamole.Client protocol and display state based on an opaque
+ * object from a prior call to exportState(). The Guacamole.Client instance
+ * used to export that state need not be the same as this instance.
+ *
+ * @param {Object} state
+ * An opaque representation of Guacamole.Client state from a prior call
+ * to exportState().
+ *
+ * @param {function} [callback]
+ * The function to invoke when state has finished being imported. This
+ * may happen immediately, or later as images within the provided state
+ * object are loaded.
+ */
+ this.importState = function importState(state, callback) {
+
+ var key;
+ var index;
+
+ currentState = state.currentState;
+ currentTimestamp = state.currentTimestamp;
+
+ // Dispose of all layers
+ for (key in layers) {
+ index = parseInt(key);
+ if (index > 0)
+ display.dispose(layers[key]);
+ }
+
+ layers = {};
+
+ // Import state of each layer/buffer
+ for (key in state.layers) {
+
+ index = parseInt(key);
+
+ var importLayer = state.layers[key];
+ var layer = getLayer(index);
+
+ // Reset layer size
+ display.resize(layer, importLayer.width, importLayer.height);
+
+ // Initialize new layer if it has associated data
+ if (importLayer.url) {
+ display.setChannelMask(layer, Guacamole.Layer.SRC);
+ display.draw(layer, 0, 0, importLayer.url);
+ }
+
+ // Set layer-specific properties if not a buffer nor the default layer
+ if (index > 0 && importLayer.parent >= 0) {
+
+ // Apply layer position and set parent
+ var parent = getLayer(importLayer.parent);
+ display.move(layer, parent, importLayer.x, importLayer.y, importLayer.z);
+
+ // Set layer transparency
+ display.shade(layer, importLayer.alpha);
+
+ // Apply matrix transform
+ var matrix = importLayer.matrix;
+ display.distort(layer,
+ matrix[0], matrix[1], matrix[2],
+ matrix[3], matrix[4], matrix[5]);
+
+ }
+
+ }
+
+ // Flush changes to display
+ display.flush(callback);
+
+ };
+
+ /**
+ * Returns the underlying display of this Guacamole.Client. The display
+ * contains an Element which can be added to the DOM, causing the
+ * display to become visible.
+ *
+ * @return {Guacamole.Display} The underlying display of this
+ * Guacamole.Client.
+ */
+ this.getDisplay = function() {
+ return display;
+ };
+
+ /**
+ * Sends the current size of the screen.
+ *
+ * @param {Number} width The width of the screen.
+ * @param {Number} height The height of the screen.
+ */
+ this.sendSize = function(width, height) {
+
+ // Do not send requests if not connected
+ if (!isConnected())
+ return;
+
+ tunnel.sendMessage("size", width, height);
+
+ };
+
+ /**
+ * Sends a key event having the given properties as if the user
+ * pressed or released a key.
+ *
+ * @param {Boolean} pressed Whether the key is pressed (true) or released
+ * (false).
+ * @param {Number} keysym The keysym of the key being pressed or released.
+ */
+ this.sendKeyEvent = function(pressed, keysym) {
+ // Do not send requests if not connected
+ if (!isConnected())
+ return;
+
+ tunnel.sendMessage("key", keysym, pressed);
+ };
+
+ /**
+ * Sends a mouse event having the properties provided by the given mouse
+ * state.
+ *
+ * @param {Guacamole.Mouse.State} mouseState The state of the mouse to send
+ * in the mouse event.
+ */
+ this.sendMouseState = function(mouseState) {
+
+ // Do not send requests if not connected
+ if (!isConnected())
+ return;
+
+ // Update client-side cursor
+ display.moveCursor(
+ Math.floor(mouseState.x),
+ Math.floor(mouseState.y)
+ );
+
+ // Build mask
+ var buttonMask = 0;
+ if (mouseState.left) buttonMask |= 1;
+ if (mouseState.middle) buttonMask |= 2;
+ if (mouseState.right) buttonMask |= 4;
+ if (mouseState.up) buttonMask |= 8;
+ if (mouseState.down) buttonMask |= 16;
+
+ // Send message
+ tunnel.sendMessage("mouse", Math.floor(mouseState.x), Math.floor(mouseState.y), buttonMask);
+ };
+
+ /**
+ * Allocates an available stream index and creates a new
+ * Guacamole.OutputStream using that index, associating the resulting
+ * stream with this Guacamole.Client. Note that this stream will not yet
+ * exist as far as the other end of the Guacamole connection is concerned.
+ * Streams exist within the Guacamole protocol only when referenced by an
+ * instruction which creates the stream, such as a "clipboard", "file", or
+ * "pipe" instruction.
+ *
+ * @returns {Guacamole.OutputStream}
+ * A new Guacamole.OutputStream with a newly-allocated index and
+ * associated with this Guacamole.Client.
+ */
+ this.createOutputStream = function createOutputStream() {
+
+ // Allocate index
+ var index = stream_indices.next();
+
+ // Return new stream
+ var stream = output_streams[index] = new Guacamole.OutputStream(guac_client, index);
+ return stream;
+
+ };
+
+ /**
+ * Opens a new audio stream for writing, where audio data having the give
+ * mimetype will be sent along the returned stream. The instruction
+ * necessary to create this stream will automatically be sent.
+ *
+ * @param {String} mimetype
+ * The mimetype of the audio data that will be sent along the returned
+ * stream.
+ *
+ * @return {Guacamole.OutputStream}
+ * The created audio stream.
+ */
+ this.createAudioStream = function(mimetype) {
+
+ // Allocate and associate stream with audio metadata
+ var stream = guac_client.createOutputStream();
+ tunnel.sendMessage("audio", stream.index, mimetype);
+ return stream;
+
+ };
+
+ /**
+ * Opens a new file for writing, having the given index, mimetype and
+ * filename. The instruction necessary to create this stream will
+ * automatically be sent.
+ *
+ * @param {String} mimetype The mimetype of the file being sent.
+ * @param {String} filename The filename of the file being sent.
+ * @return {Guacamole.OutputStream} The created file stream.
+ */
+ this.createFileStream = function(mimetype, filename) {
+
+ // Allocate and associate stream with file metadata
+ var stream = guac_client.createOutputStream();
+ tunnel.sendMessage("file", stream.index, mimetype, filename);
+ return stream;
+
+ };
+
+ /**
+ * Opens a new pipe for writing, having the given name and mimetype. The
+ * instruction necessary to create this stream will automatically be sent.
+ *
+ * @param {String} mimetype The mimetype of the data being sent.
+ * @param {String} name The name of the pipe.
+ * @return {Guacamole.OutputStream} The created file stream.
+ */
+ this.createPipeStream = function(mimetype, name) {
+
+ // Allocate and associate stream with pipe metadata
+ var stream = guac_client.createOutputStream();
+ tunnel.sendMessage("pipe", stream.index, mimetype, name);
+ return stream;
+
+ };
+
+ /**
+ * Opens a new clipboard object for writing, having the given mimetype. The
+ * instruction necessary to create this stream will automatically be sent.
+ *
+ * @param {String} mimetype The mimetype of the data being sent.
+ * @param {String} name The name of the pipe.
+ * @return {Guacamole.OutputStream} The created file stream.
+ */
+ this.createClipboardStream = function(mimetype) {
+
+ // Allocate and associate stream with clipboard metadata
+ var stream = guac_client.createOutputStream();
+ tunnel.sendMessage("clipboard", stream.index, mimetype);
+ return stream;
+
+ };
+
+ /**
+ * Opens a new argument value stream for writing, having the given
+ * parameter name and mimetype, requesting that the connection parameter
+ * with the given name be updated to the value described by the contents
+ * of the following stream. The instruction necessary to create this stream
+ * will automatically be sent.
+ *
+ * @param {String} mimetype
+ * The mimetype of the data being sent.
+ *
+ * @param {String} name
+ * The name of the connection parameter to attempt to update.
+ *
+ * @return {Guacamole.OutputStream}
+ * The created argument value stream.
+ */
+ this.createArgumentValueStream = function createArgumentValueStream(mimetype, name) {
+
+ // Allocate and associate stream with argument value metadata
+ var stream = guac_client.createOutputStream();
+ tunnel.sendMessage("argv", stream.index, mimetype, name);
+ return stream;
+
+ };
+
+ /**
+ * Creates a new output stream associated with the given object and having
+ * the given mimetype and name. The legality of a mimetype and name is
+ * dictated by the object itself. The instruction necessary to create this
+ * stream will automatically be sent.
+ *
+ * @param {Number} index
+ * The index of the object for which the output stream is being
+ * created.
+ *
+ * @param {String} mimetype
+ * The mimetype of the data which will be sent to the output stream.
+ *
+ * @param {String} name
+ * The defined name of an output stream within the given object.
+ *
+ * @returns {Guacamole.OutputStream}
+ * An output stream which will write blobs to the named output stream
+ * of the given object.
+ */
+ this.createObjectOutputStream = function createObjectOutputStream(index, mimetype, name) {
+
+ // Allocate and ssociate stream with object metadata
+ var stream = guac_client.createOutputStream();
+ tunnel.sendMessage("put", index, stream.index, mimetype, name);
+ return stream;
+
+ };
+
+ /**
+ * Requests read access to the input stream having the given name. If
+ * successful, a new input stream will be created.
+ *
+ * @param {Number} index
+ * The index of the object from which the input stream is being
+ * requested.
+ *
+ * @param {String} name
+ * The name of the input stream to request.
+ */
+ this.requestObjectInputStream = function requestObjectInputStream(index, name) {
+
+ // Do not send requests if not connected
+ if (!isConnected())
+ return;
+
+ tunnel.sendMessage("get", index, name);
+ };
+
+ /**
+ * Acknowledge receipt of a blob on the stream with the given index.
+ *
+ * @param {Number} index The index of the stream associated with the
+ * received blob.
+ * @param {String} message A human-readable message describing the error
+ * or status.
+ * @param {Number} code The error code, if any, or 0 for success.
+ */
+ this.sendAck = function(index, message, code) {
+
+ // Do not send requests if not connected
+ if (!isConnected())
+ return;
+
+ tunnel.sendMessage("ack", index, message, code);
+ };
+
+ /**
+ * Given the index of a file, writes a blob of data to that file.
+ *
+ * @param {Number} index The index of the file to write to.
+ * @param {String} data Base64-encoded data to write to the file.
+ */
+ this.sendBlob = function(index, data) {
+
+ // Do not send requests if not connected
+ if (!isConnected())
+ return;
+
+ tunnel.sendMessage("blob", index, data);
+ };
+
+ /**
+ * Marks a currently-open stream as complete. The other end of the
+ * Guacamole connection will be notified via an "end" instruction that the
+ * stream is closed, and the index will be made available for reuse in
+ * future streams.
+ *
+ * @param {Number} index
+ * The index of the stream to end.
+ */
+ this.endStream = function(index) {
+
+ // Do not send requests if not connected
+ if (!isConnected())
+ return;
+
+ // Explicitly close stream by sending "end" instruction
+ tunnel.sendMessage("end", index);
+
+ // Free associated index and stream if they exist
+ if (output_streams[index]) {
+ stream_indices.free(index);
+ delete output_streams[index];
+ }
+
+ };
+
+ /**
+ * Fired whenever the state of this Guacamole.Client changes.
+ *
+ * @event
+ * @param {Number} state The new state of the client.
+ */
+ this.onstatechange = null;
+
+ /**
+ * Fired when the remote client sends a name update.
+ *
+ * @event
+ * @param {String} name The new name of this client.
+ */
+ this.onname = null;
+
+ /**
+ * Fired when an error is reported by the remote client, and the connection
+ * is being closed.
+ *
+ * @event
+ * @param {Guacamole.Status} status A status object which describes the
+ * error.
+ */
+ this.onerror = null;
+
+ /**
+ * Fired when a audio stream is created. The stream provided to this event
+ * handler will contain its own event handlers for received data.
+ *
+ * @event
+ * @param {Guacamole.InputStream} stream
+ * The stream that will receive audio data from the server.
+ *
+ * @param {String} mimetype
+ * The mimetype of the audio data which will be received.
+ *
+ * @return {Guacamole.AudioPlayer}
+ * An object which implements the Guacamole.AudioPlayer interface and
+ * has been initialied to play the data in the provided stream, or null
+ * if the built-in audio players of the Guacamole client should be
+ * used.
+ */
+ this.onaudio = null;
+
+ /**
+ * Fired when a video stream is created. The stream provided to this event
+ * handler will contain its own event handlers for received data.
+ *
+ * @event
+ * @param {Guacamole.InputStream} stream
+ * The stream that will receive video data from the server.
+ *
+ * @param {Guacamole.Display.VisibleLayer} layer
+ * The destination layer on which the received video data should be
+ * played. It is the responsibility of the Guacamole.VideoPlayer
+ * implementation to play the received data within this layer.
+ *
+ * @param {String} mimetype
+ * The mimetype of the video data which will be received.
+ *
+ * @return {Guacamole.VideoPlayer}
+ * An object which implements the Guacamole.VideoPlayer interface and
+ * has been initialied to play the data in the provided stream, or null
+ * if the built-in video players of the Guacamole client should be
+ * used.
+ */
+ this.onvideo = null;
+
+ /**
+ * Fired when the current value of a connection parameter is being exposed
+ * by the server.
+ *
+ * @event
+ * @param {Guacamole.InputStream} stream
+ * The stream that will receive connection parameter data from the
+ * server.
+ *
+ * @param {String} mimetype
+ * The mimetype of the data which will be received.
+ *
+ * @param {String} name
+ * The name of the connection parameter whose value is being exposed.
+ */
+ this.onargv = null;
+
+ /**
+ * Fired when the clipboard of the remote client is changing.
+ *
+ * @event
+ * @param {Guacamole.InputStream} stream The stream that will receive
+ * clipboard data from the server.
+ * @param {String} mimetype The mimetype of the data which will be received.
+ */
+ this.onclipboard = null;
+
+ /**
+ * Fired when a file stream is created. The stream provided to this event
+ * handler will contain its own event handlers for received data.
+ *
+ * @event
+ * @param {Guacamole.InputStream} stream The stream that will receive data
+ * from the server.
+ * @param {String} mimetype The mimetype of the file received.
+ * @param {String} filename The name of the file received.
+ */
+ this.onfile = null;
+
+ /**
+ * Fired when a filesystem object is created. The object provided to this
+ * event handler will contain its own event handlers and functions for
+ * requesting and handling data.
+ *
+ * @event
+ * @param {Guacamole.Object} object
+ * The created filesystem object.
+ *
+ * @param {String} name
+ * The name of the filesystem.
+ */
+ this.onfilesystem = null;
+
+ /**
+ * Fired when a pipe stream is created. The stream provided to this event
+ * handler will contain its own event handlers for received data;
+ *
+ * @event
+ * @param {Guacamole.InputStream} stream The stream that will receive data
+ * from the server.
+ * @param {String} mimetype The mimetype of the data which will be received.
+ * @param {String} name The name of the pipe.
+ */
+ this.onpipe = null;
+
+ /**
+ * Fired whenever a sync instruction is received from the server, indicating
+ * that the server is finished processing any input from the client and
+ * has sent any results.
+ *
+ * @event
+ * @param {Number} timestamp The timestamp associated with the sync
+ * instruction.
+ */
+ this.onsync = null;
+
+ /**
+ * Returns the layer with the given index, creating it if necessary.
+ * Positive indices refer to visible layers, an index of zero refers to
+ * the default layer, and negative indices refer to buffers.
+ *
+ * @private
+ * @param {Number} index
+ * The index of the layer to retrieve.
+ *
+ * @return {Guacamole.Display.VisibleLayer|Guacamole.Layer}
+ * The layer having the given index.
+ */
+ var getLayer = function getLayer(index) {
+
+ // Get layer, create if necessary
+ var layer = layers[index];
+ if (!layer) {
+
+ // Create layer based on index
+ if (index === 0)
+ layer = display.getDefaultLayer();
+ else if (index > 0)
+ layer = display.createLayer();
+ else
+ layer = display.createBuffer();
+
+ // Add new layer
+ layers[index] = layer;
+
+ }
+
+ return layer;
+
+ };
+
+ /**
+ * Returns the index passed to getLayer() when the given layer was created.
+ * Positive indices refer to visible layers, an index of zero refers to the
+ * default layer, and negative indices refer to buffers.
+ *
+ * @param {Guacamole.Display.VisibleLayer|Guacamole.Layer} layer
+ * The layer whose index should be determined.
+ *
+ * @returns {Number}
+ * The index of the given layer, or null if no such layer is associated
+ * with this client.
+ */
+ var getLayerIndex = function getLayerIndex(layer) {
+
+ // Avoid searching if there clearly is no such layer
+ if (!layer)
+ return null;
+
+ // Search through each layer, returning the index of the given layer
+ // once found
+ for (var key in layers) {
+ if (layer === layers[key])
+ return parseInt(key);
+ }
+
+ // Otherwise, no such index
+ return null;
+
+ };
+
+ function getParser(index) {
+
+ var parser = parsers[index];
+
+ // If parser not yet created, create it, and tie to the
+ // oninstruction handler of the tunnel.
+ if (parser == null) {
+ parser = parsers[index] = new Guacamole.Parser();
+ parser.oninstruction = tunnel.oninstruction;
+ }
+
+ return parser;
+
+ }
+
+ /**
+ * Handlers for all defined layer properties.
+ * @private
+ */
+ var layerPropertyHandlers = {
+
+ "miter-limit": function(layer, value) {
+ display.setMiterLimit(layer, parseFloat(value));
+ }
+
+ };
+
+ /**
+ * Handlers for all instruction opcodes receivable by a Guacamole protocol
+ * client.
+ * @private
+ */
+ var instructionHandlers = {
+
+ "ack": function(parameters) {
+
+ var stream_index = parseInt(parameters[0]);
+ var reason = parameters[1];
+ var code = parseInt(parameters[2]);
+
+ // Get stream
+ var stream = output_streams[stream_index];
+ if (stream) {
+
+ // Signal ack if handler defined
+ if (stream.onack)
+ stream.onack(new Guacamole.Status(code, reason));
+
+ // If code is an error, invalidate stream if not already
+ // invalidated by onack handler
+ if (code >= 0x0100 && output_streams[stream_index] === stream) {
+ stream_indices.free(stream_index);
+ delete output_streams[stream_index];
+ }
+
+ }
+
+ },
+
+ "arc": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+ var x = parseInt(parameters[1]);
+ var y = parseInt(parameters[2]);
+ var radius = parseInt(parameters[3]);
+ var startAngle = parseFloat(parameters[4]);
+ var endAngle = parseFloat(parameters[5]);
+ var negative = parseInt(parameters[6]);
+
+ display.arc(layer, x, y, radius, startAngle, endAngle, negative != 0);
+
+ },
+
+ "argv": function(parameters) {
+
+ var stream_index = parseInt(parameters[0]);
+ var mimetype = parameters[1];
+ var name = parameters[2];
+
+ // Create stream
+ if (guac_client.onargv) {
+ var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
+ guac_client.onargv(stream, mimetype, name);
+ }
+
+ // Otherwise, unsupported
+ else
+ guac_client.sendAck(stream_index, "Receiving argument values unsupported", 0x0100);
+
+ },
+
+ "audio": function(parameters) {
+
+ var stream_index = parseInt(parameters[0]);
+ var mimetype = parameters[1];
+
+ // Create stream
+ var stream = streams[stream_index] =
+ new Guacamole.InputStream(guac_client, stream_index);
+
+ // Get player instance via callback
+ var audioPlayer = null;
+ if (guac_client.onaudio)
+ audioPlayer = guac_client.onaudio(stream, mimetype);
+
+ // If unsuccessful, try to use a default implementation
+ if (!audioPlayer)
+ audioPlayer = Guacamole.AudioPlayer.getInstance(stream, mimetype);
+
+ // If we have successfully retrieved an audio player, send success response
+ if (audioPlayer) {
+ audioPlayers[stream_index] = audioPlayer;
+ guac_client.sendAck(stream_index, "OK", 0x0000);
+ }
+
+ // Otherwise, mimetype must be unsupported
+ else
+ guac_client.sendAck(stream_index, "BAD TYPE", 0x030F);
+
+ },
+
+ "blob": function(parameters) {
+
+ // Get stream
+ var stream_index = parseInt(parameters[0]);
+ var data = parameters[1];
+ var stream = streams[stream_index];
+
+ // Write data
+ if (stream && stream.onblob)
+ stream.onblob(data);
+
+ },
+
+ "body" : function handleBody(parameters) {
+
+ // Get object
+ var objectIndex = parseInt(parameters[0]);
+ var object = objects[objectIndex];
+
+ var streamIndex = parseInt(parameters[1]);
+ var mimetype = parameters[2];
+ var name = parameters[3];
+
+ // Create stream if handler defined
+ if (object && object.onbody) {
+ var stream = streams[streamIndex] = new Guacamole.InputStream(guac_client, streamIndex);
+ object.onbody(stream, mimetype, name);
+ }
+
+ // Otherwise, unsupported
+ else
+ guac_client.sendAck(streamIndex, "Receipt of body unsupported", 0x0100);
+
+ },
+
+ "cfill": function(parameters) {
+
+ var channelMask = parseInt(parameters[0]);
+ var layer = getLayer(parseInt(parameters[1]));
+ var r = parseInt(parameters[2]);
+ var g = parseInt(parameters[3]);
+ var b = parseInt(parameters[4]);
+ var a = parseInt(parameters[5]);
+
+ display.setChannelMask(layer, channelMask);
+ display.fillColor(layer, r, g, b, a);
+
+ },
+
+ "clip": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+
+ display.clip(layer);
+
+ },
+
+ "clipboard": function(parameters) {
+
+ var stream_index = parseInt(parameters[0]);
+ var mimetype = parameters[1];
+
+ // Create stream
+ if (guac_client.onclipboard) {
+ var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
+ guac_client.onclipboard(stream, mimetype);
+ }
+
+ // Otherwise, unsupported
+ else
+ guac_client.sendAck(stream_index, "Clipboard unsupported", 0x0100);
+
+ },
+
+ "close": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+
+ display.close(layer);
+
+ },
+
+ "copy": function(parameters) {
+
+ var srcL = getLayer(parseInt(parameters[0]));
+ var srcX = parseInt(parameters[1]);
+ var srcY = parseInt(parameters[2]);
+ var srcWidth = parseInt(parameters[3]);
+ var srcHeight = parseInt(parameters[4]);
+ var channelMask = parseInt(parameters[5]);
+ var dstL = getLayer(parseInt(parameters[6]));
+ var dstX = parseInt(parameters[7]);
+ var dstY = parseInt(parameters[8]);
+
+ display.setChannelMask(dstL, channelMask);
+ display.copy(srcL, srcX, srcY, srcWidth, srcHeight,
+ dstL, dstX, dstY);
+
+ },
+
+ "cstroke": function(parameters) {
+
+ var channelMask = parseInt(parameters[0]);
+ var layer = getLayer(parseInt(parameters[1]));
+ var cap = lineCap[parseInt(parameters[2])];
+ var join = lineJoin[parseInt(parameters[3])];
+ var thickness = parseInt(parameters[4]);
+ var r = parseInt(parameters[5]);
+ var g = parseInt(parameters[6]);
+ var b = parseInt(parameters[7]);
+ var a = parseInt(parameters[8]);
+
+ display.setChannelMask(layer, channelMask);
+ display.strokeColor(layer, cap, join, thickness, r, g, b, a);
+
+ },
+
+ "cursor": function(parameters) {
+
+ var cursorHotspotX = parseInt(parameters[0]);
+ var cursorHotspotY = parseInt(parameters[1]);
+ var srcL = getLayer(parseInt(parameters[2]));
+ var srcX = parseInt(parameters[3]);
+ var srcY = parseInt(parameters[4]);
+ var srcWidth = parseInt(parameters[5]);
+ var srcHeight = parseInt(parameters[6]);
+
+ display.setCursor(cursorHotspotX, cursorHotspotY,
+ srcL, srcX, srcY, srcWidth, srcHeight);
+
+ },
+
+ "curve": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+ var cp1x = parseInt(parameters[1]);
+ var cp1y = parseInt(parameters[2]);
+ var cp2x = parseInt(parameters[3]);
+ var cp2y = parseInt(parameters[4]);
+ var x = parseInt(parameters[5]);
+ var y = parseInt(parameters[6]);
+
+ display.curveTo(layer, cp1x, cp1y, cp2x, cp2y, x, y);
+
+ },
+
+ "disconnect" : function handleDisconnect(parameters) {
+
+ // Explicitly tear down connection
+ guac_client.disconnect();
+
+ },
+
+ "dispose": function(parameters) {
+
+ var layer_index = parseInt(parameters[0]);
+
+ // If visible layer, remove from parent
+ if (layer_index > 0) {
+
+ // Remove from parent
+ var layer = getLayer(layer_index);
+ display.dispose(layer);
+
+ // Delete reference
+ delete layers[layer_index];
+
+ }
+
+ // If buffer, just delete reference
+ else if (layer_index < 0)
+ delete layers[layer_index];
+
+ // Attempting to dispose the root layer currently has no effect.
+
+ },
+
+ "distort": function(parameters) {
+
+ var layer_index = parseInt(parameters[0]);
+ var a = parseFloat(parameters[1]);
+ var b = parseFloat(parameters[2]);
+ var c = parseFloat(parameters[3]);
+ var d = parseFloat(parameters[4]);
+ var e = parseFloat(parameters[5]);
+ var f = parseFloat(parameters[6]);
+
+ // Only valid for visible layers (not buffers)
+ if (layer_index >= 0) {
+ var layer = getLayer(layer_index);
+ display.distort(layer, a, b, c, d, e, f);
+ }
+
+ },
+
+ "error": function(parameters) {
+
+ var reason = parameters[0];
+ var code = parseInt(parameters[1]);
+
+ // Call handler if defined
+ if (guac_client.onerror)
+ guac_client.onerror(new Guacamole.Status(code, reason));
+
+ guac_client.disconnect();
+
+ },
+
+ "end": function(parameters) {
+
+ var stream_index = parseInt(parameters[0]);
+
+ // Get stream
+ var stream = streams[stream_index];
+ if (stream) {
+
+ // Signal end of stream if handler defined
+ if (stream.onend)
+ stream.onend();
+
+ // Invalidate stream
+ delete streams[stream_index];
+
+ }
+
+ },
+
+ "file": function(parameters) {
+
+ var stream_index = parseInt(parameters[0]);
+ var mimetype = parameters[1];
+ var filename = parameters[2];
+
+ // Create stream
+ if (guac_client.onfile) {
+ var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
+ guac_client.onfile(stream, mimetype, filename);
+ }
+
+ // Otherwise, unsupported
+ else
+ guac_client.sendAck(stream_index, "File transfer unsupported", 0x0100);
+
+ },
+
+ "filesystem" : function handleFilesystem(parameters) {
+
+ var objectIndex = parseInt(parameters[0]);
+ var name = parameters[1];
+
+ // Create object, if supported
+ if (guac_client.onfilesystem) {
+ var object = objects[objectIndex] = new Guacamole.Object(guac_client, objectIndex);
+ guac_client.onfilesystem(object, name);
+ }
+
+ // If unsupported, simply ignore the availability of the filesystem
+
+ },
+
+ "identity": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+
+ display.setTransform(layer, 1, 0, 0, 1, 0, 0);
+
+ },
+
+ "img": function(parameters) {
+
+ var stream_index = parseInt(parameters[0]);
+ var channelMask = parseInt(parameters[1]);
+ var layer = getLayer(parseInt(parameters[2]));
+ var mimetype = parameters[3];
+ var x = parseInt(parameters[4]);
+ var y = parseInt(parameters[5]);
+
+ // Create stream
+ var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
+ var reader = new Guacamole.DataURIReader(stream, mimetype);
+
+ // Draw image when stream is complete
+ reader.onend = function drawImageBlob() {
+ display.setChannelMask(layer, channelMask);
+ display.draw(layer, x, y, reader.getURI());
+ };
+
+ },
+
+ "jpeg": function(parameters) {
+
+ var channelMask = parseInt(parameters[0]);
+ var layer = getLayer(parseInt(parameters[1]));
+ var x = parseInt(parameters[2]);
+ var y = parseInt(parameters[3]);
+ var data = parameters[4];
+
+ display.setChannelMask(layer, channelMask);
+ display.draw(layer, x, y, "data:image/jpeg;base64," + data);
+
+ },
+
+ "lfill": function(parameters) {
+
+ var channelMask = parseInt(parameters[0]);
+ var layer = getLayer(parseInt(parameters[1]));
+ var srcLayer = getLayer(parseInt(parameters[2]));
+
+ display.setChannelMask(layer, channelMask);
+ display.fillLayer(layer, srcLayer);
+
+ },
+
+ "line": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+ var x = parseInt(parameters[1]);
+ var y = parseInt(parameters[2]);
+
+ display.lineTo(layer, x, y);
+
+ },
+
+ "lstroke": function(parameters) {
+
+ var channelMask = parseInt(parameters[0]);
+ var layer = getLayer(parseInt(parameters[1]));
+ var srcLayer = getLayer(parseInt(parameters[2]));
+
+ display.setChannelMask(layer, channelMask);
+ display.strokeLayer(layer, srcLayer);
+
+ },
+
+ "mouse" : function handleMouse(parameters) {
+
+ var x = parseInt(parameters[0]);
+ var y = parseInt(parameters[1]);
+
+ // Display and move software cursor to received coordinates
+ display.showCursor(true);
+ display.moveCursor(x, y);
+
+ },
+
+ "move": function(parameters) {
+
+ var layer_index = parseInt(parameters[0]);
+ var parent_index = parseInt(parameters[1]);
+ var x = parseInt(parameters[2]);
+ var y = parseInt(parameters[3]);
+ var z = parseInt(parameters[4]);
+
+ // Only valid for non-default layers
+ if (layer_index > 0 && parent_index >= 0) {
+ var layer = getLayer(layer_index);
+ var parent = getLayer(parent_index);
+ display.move(layer, parent, x, y, z);
+ }
+
+ },
+
+ "name": function(parameters) {
+ if (guac_client.onname) guac_client.onname(parameters[0]);
+ },
+
+ "nest": function(parameters) {
+ var parser = getParser(parseInt(parameters[0]));
+ parser.receive(parameters[1]);
+ },
+
+ "pipe": function(parameters) {
+
+ var stream_index = parseInt(parameters[0]);
+ var mimetype = parameters[1];
+ var name = parameters[2];
+
+ // Create stream
+ if (guac_client.onpipe) {
+ var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
+ guac_client.onpipe(stream, mimetype, name);
+ }
+
+ // Otherwise, unsupported
+ else
+ guac_client.sendAck(stream_index, "Named pipes unsupported", 0x0100);
+
+ },
+
+ "png": function(parameters) {
+
+ var channelMask = parseInt(parameters[0]);
+ var layer = getLayer(parseInt(parameters[1]));
+ var x = parseInt(parameters[2]);
+ var y = parseInt(parameters[3]);
+ var data = parameters[4];
+
+ display.setChannelMask(layer, channelMask);
+ display.draw(layer, x, y, "data:image/png;base64," + data);
+
+ },
+
+ "pop": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+
+ display.pop(layer);
+
+ },
+
+ "push": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+
+ display.push(layer);
+
+ },
+
+ "rect": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+ var x = parseInt(parameters[1]);
+ var y = parseInt(parameters[2]);
+ var w = parseInt(parameters[3]);
+ var h = parseInt(parameters[4]);
+
+ display.rect(layer, x, y, w, h);
+
+ },
+
+ "reset": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+
+ display.reset(layer);
+
+ },
+
+ "set": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+ var name = parameters[1];
+ var value = parameters[2];
+
+ // Call property handler if defined
+ var handler = layerPropertyHandlers[name];
+ if (handler)
+ handler(layer, value);
+
+ },
+
+ "shade": function(parameters) {
+
+ var layer_index = parseInt(parameters[0]);
+ var a = parseInt(parameters[1]);
+
+ // Only valid for visible layers (not buffers)
+ if (layer_index >= 0) {
+ var layer = getLayer(layer_index);
+ display.shade(layer, a);
+ }
+
+ },
+
+ "size": function(parameters) {
+
+ var layer_index = parseInt(parameters[0]);
+ var layer = getLayer(layer_index);
+ var width = parseInt(parameters[1]);
+ var height = parseInt(parameters[2]);
+
+ display.resize(layer, width, height);
+
+ },
+
+ "start": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+ var x = parseInt(parameters[1]);
+ var y = parseInt(parameters[2]);
+
+ display.moveTo(layer, x, y);
+
+ },
+
+ "sync": function(parameters) {
+
+ var timestamp = parseInt(parameters[0]);
+
+ // Flush display, send sync when done
+ display.flush(function displaySyncComplete() {
+
+ // Synchronize all audio players
+ for (var index in audioPlayers) {
+ var audioPlayer = audioPlayers[index];
+ if (audioPlayer)
+ audioPlayer.sync();
+ }
+
+ // Send sync response to server
+ if (timestamp !== currentTimestamp) {
+ tunnel.sendMessage("sync", timestamp);
+ currentTimestamp = timestamp;
+ }
+
+ });
+
+ // If received first update, no longer waiting.
+ if (currentState === STATE_WAITING)
+ setState(STATE_CONNECTED);
+
+ // Call sync handler if defined
+ if (guac_client.onsync)
+ guac_client.onsync(timestamp);
+
+ },
+
+ "transfer": function(parameters) {
+
+ var srcL = getLayer(parseInt(parameters[0]));
+ var srcX = parseInt(parameters[1]);
+ var srcY = parseInt(parameters[2]);
+ var srcWidth = parseInt(parameters[3]);
+ var srcHeight = parseInt(parameters[4]);
+ var function_index = parseInt(parameters[5]);
+ var dstL = getLayer(parseInt(parameters[6]));
+ var dstX = parseInt(parameters[7]);
+ var dstY = parseInt(parameters[8]);
+
+ /* SRC */
+ if (function_index === 0x3)
+ display.put(srcL, srcX, srcY, srcWidth, srcHeight,
+ dstL, dstX, dstY);
+
+ /* Anything else that isn't a NO-OP */
+ else if (function_index !== 0x5)
+ display.transfer(srcL, srcX, srcY, srcWidth, srcHeight,
+ dstL, dstX, dstY, Guacamole.Client.DefaultTransferFunction[function_index]);
+
+ },
+
+ "transform": function(parameters) {
+
+ var layer = getLayer(parseInt(parameters[0]));
+ var a = parseFloat(parameters[1]);
+ var b = parseFloat(parameters[2]);
+ var c = parseFloat(parameters[3]);
+ var d = parseFloat(parameters[4]);
+ var e = parseFloat(parameters[5]);
+ var f = parseFloat(parameters[6]);
+
+ display.transform(layer, a, b, c, d, e, f);
+
+ },
+
+ "undefine" : function handleUndefine(parameters) {
+
+ // Get object
+ var objectIndex = parseInt(parameters[0]);
+ var object = objects[objectIndex];
+
+ // Signal end of object definition
+ if (object && object.onundefine)
+ object.onundefine();
+
+ },
+
+ "video": function(parameters) {
+
+ var stream_index = parseInt(parameters[0]);
+ var layer = getLayer(parseInt(parameters[1]));
+ var mimetype = parameters[2];
+
+ // Create stream
+ var stream = streams[stream_index] =
+ new Guacamole.InputStream(guac_client, stream_index);
+
+ // Get player instance via callback
+ var videoPlayer = null;
+ if (guac_client.onvideo)
+ videoPlayer = guac_client.onvideo(stream, layer, mimetype);
+
+ // If unsuccessful, try to use a default implementation
+ if (!videoPlayer)
+ videoPlayer = Guacamole.VideoPlayer.getInstance(stream, layer, mimetype);
+
+ // If we have successfully retrieved an video player, send success response
+ if (videoPlayer) {
+ videoPlayers[stream_index] = videoPlayer;
+ guac_client.sendAck(stream_index, "OK", 0x0000);
+ }
+
+ // Otherwise, mimetype must be unsupported
+ else
+ guac_client.sendAck(stream_index, "BAD TYPE", 0x030F);
+
+ }
+
+ };
+
+ tunnel.oninstruction = function(opcode, parameters) {
+
+ var handler = instructionHandlers[opcode];
+ if (handler)
+ handler(parameters);
+
+ };
+
+ /**
+ * Sends a disconnect instruction to the server and closes the tunnel.
+ */
+ this.disconnect = function() {
+
+ // Only attempt disconnection not disconnected.
+ if (currentState != STATE_DISCONNECTED
+ && currentState != STATE_DISCONNECTING) {
+
+ setState(STATE_DISCONNECTING);
+
+ // Stop ping
+ if (pingInterval)
+ window.clearInterval(pingInterval);
+
+ // Send disconnect message and disconnect
+ tunnel.sendMessage("disconnect");
+ tunnel.disconnect();
+ setState(STATE_DISCONNECTED);
+
+ }
+
+ };
+
+ /**
+ * Connects the underlying tunnel of this Guacamole.Client, passing the
+ * given arbitrary data to the tunnel during the connection process.
+ *
+ * @param data Arbitrary connection data to be sent to the underlying
+ * tunnel during the connection process.
+ * @throws {Guacamole.Status} If an error occurs during connection.
+ */
+ this.connect = function(data) {
+
+ setState(STATE_CONNECTING);
+
+ try {
+ tunnel.connect(data);
+ }
+ catch (status) {
+ setState(STATE_IDLE);
+ throw status;
+ }
+
+ // Ping every 5 seconds (ensure connection alive)
+ pingInterval = window.setInterval(function() {
+ tunnel.sendMessage("nop");
+ }, 5000);
+
+ setState(STATE_WAITING);
+ };
+
+};
+
+/**
+ * Map of all Guacamole binary raster operations to transfer functions.
+ * @private
+ */
+Guacamole.Client.DefaultTransferFunction = {
+
+ /* BLACK */
+ 0x0: function (src, dst) {
+ dst.red = dst.green = dst.blue = 0x00;
+ },
+
+ /* WHITE */
+ 0xF: function (src, dst) {
+ dst.red = dst.green = dst.blue = 0xFF;
+ },
+
+ /* SRC */
+ 0x3: function (src, dst) {
+ dst.red = src.red;
+ dst.green = src.green;
+ dst.blue = src.blue;
+ dst.alpha = src.alpha;
+ },
+
+ /* DEST (no-op) */
+ 0x5: function (src, dst) {
+ // Do nothing
+ },
+
+ /* Invert SRC */
+ 0xC: function (src, dst) {
+ dst.red = 0xFF & ~src.red;
+ dst.green = 0xFF & ~src.green;
+ dst.blue = 0xFF & ~src.blue;
+ dst.alpha = src.alpha;
+ },
+
+ /* Invert DEST */
+ 0xA: function (src, dst) {
+ dst.red = 0xFF & ~dst.red;
+ dst.green = 0xFF & ~dst.green;
+ dst.blue = 0xFF & ~dst.blue;
+ },
+
+ /* AND */
+ 0x1: function (src, dst) {
+ dst.red = ( src.red & dst.red);
+ dst.green = ( src.green & dst.green);
+ dst.blue = ( src.blue & dst.blue);
+ },
+
+ /* NAND */
+ 0xE: function (src, dst) {
+ dst.red = 0xFF & ~( src.red & dst.red);
+ dst.green = 0xFF & ~( src.green & dst.green);
+ dst.blue = 0xFF & ~( src.blue & dst.blue);
+ },
+
+ /* OR */
+ 0x7: function (src, dst) {
+ dst.red = ( src.red | dst.red);
+ dst.green = ( src.green | dst.green);
+ dst.blue = ( src.blue | dst.blue);
+ },
+
+ /* NOR */
+ 0x8: function (src, dst) {
+ dst.red = 0xFF & ~( src.red | dst.red);
+ dst.green = 0xFF & ~( src.green | dst.green);
+ dst.blue = 0xFF & ~( src.blue | dst.blue);
+ },
+
+ /* XOR */
+ 0x6: function (src, dst) {
+ dst.red = ( src.red ^ dst.red);
+ dst.green = ( src.green ^ dst.green);
+ dst.blue = ( src.blue ^ dst.blue);
+ },
+
+ /* XNOR */
+ 0x9: function (src, dst) {
+ dst.red = 0xFF & ~( src.red ^ dst.red);
+ dst.green = 0xFF & ~( src.green ^ dst.green);
+ dst.blue = 0xFF & ~( src.blue ^ dst.blue);
+ },
+
+ /* AND inverted source */
+ 0x4: function (src, dst) {
+ dst.red = 0xFF & (~src.red & dst.red);
+ dst.green = 0xFF & (~src.green & dst.green);
+ dst.blue = 0xFF & (~src.blue & dst.blue);
+ },
+
+ /* OR inverted source */
+ 0xD: function (src, dst) {
+ dst.red = 0xFF & (~src.red | dst.red);
+ dst.green = 0xFF & (~src.green | dst.green);
+ dst.blue = 0xFF & (~src.blue | dst.blue);
+ },
+
+ /* AND inverted destination */
+ 0x2: function (src, dst) {
+ dst.red = 0xFF & ( src.red & ~dst.red);
+ dst.green = 0xFF & ( src.green & ~dst.green);
+ dst.blue = 0xFF & ( src.blue & ~dst.blue);
+ },
+
+ /* OR inverted destination */
+ 0xB: function (src, dst) {
+ dst.red = 0xFF & ( src.red | ~dst.red);
+ dst.green = 0xFF & ( src.green | ~dst.green);
+ dst.blue = 0xFF & ( src.blue | ~dst.blue);
+ }
+
+};
+</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
diff --git a/content/doc/1.1.0/guacamole-common-js/DataURIReader.js.html b/content/doc/1.1.0/guacamole-common-js/DataURIReader.js.html
new file mode 100644
index 0000000..2c30509
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/DataURIReader.js.html
@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: DataURIReader.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: DataURIReader.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * A reader which automatically handles the given input stream, returning
+ * received blobs as a single data URI built over the course of the stream.
+ * Note that this object will overwrite any installed event handlers on the
+ * given Guacamole.InputStream.
+ *
+ * @constructor
+ * @param {Guacamole.InputStream} stream
+ * The stream that data will be read from.
+ */
+Guacamole.DataURIReader = function(stream, mimetype) {
+
+ /**
+ * Reference to this Guacamole.DataURIReader.
+ * @private
+ */
+ var guac_reader = this;
+
+ /**
+ * Current data URI.
+ *
+ * @private
+ * @type {String}
+ */
+ var uri = 'data:' + mimetype + ';base64,';
+
+ // Receive blobs as array buffers
+ stream.onblob = function dataURIReaderBlob(data) {
+
+ // Currently assuming data will ALWAYS be safe to simply append. This
+ // will not be true if the received base64 data encodes a number of
+ // bytes that isn't a multiple of three (as base64 expands in a ratio
+ // of exactly 3:4).
+ uri += data;
+
+ };
+
+ // Simply call onend when end received
+ stream.onend = function dataURIReaderEnd() {
+ if (guac_reader.onend)
+ guac_reader.onend();
+ };
+
+ /**
+ * Returns the data URI of all data received through the underlying stream
+ * thus far.
+ *
+ * @returns {String}
+ * The data URI of all data received through the underlying stream thus
+ * far.
+ */
+ this.getURI = function getURI() {
+ return uri;
+ };
+
+ /**
+ * Fired once this stream is finished and no further data will be written.
+ *
+ * @event
+ */
+ this.onend = null;
+
+};</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
diff --git a/content/doc/1.1.0/guacamole-common-js/Display.js.html b/content/doc/1.1.0/guacamole-common-js/Display.js.html
new file mode 100644
index 0000000..ab16f26
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/Display.js.html
@@ -0,0 +1,1543 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Source: Display.js</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Source: Display.js</h1>
+
+
+
+
+
+
+ <section>
+ <article>
+ <pre class="prettyprint source linenums"><code>/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var Guacamole = Guacamole || {};
+
+/**
+ * The Guacamole display. The display does not deal with the Guacamole
+ * protocol, and instead implements a set of graphical operations which
+ * embody the set of operations present in the protocol. The order operations
+ * are executed is guaranteed to be in the same order as their corresponding
+ * functions are called.
+ *
+ * @constructor
+ */
+Guacamole.Display = function() {
+
+ /**
+ * Reference to this Guacamole.Display.
+ * @private
+ */
+ var guac_display = this;
+
+ var displayWidth = 0;
+ var displayHeight = 0;
+ var displayScale = 1;
+
+ // Create display
+ var display = document.createElement("div");
+ display.style.position = "relative";
+ display.style.width = displayWidth + "px";
+ display.style.height = displayHeight + "px";
+
+ // Ensure transformations on display originate at 0,0
+ display.style.transformOrigin =
+ display.style.webkitTransformOrigin =
+ display.style.MozTransformOrigin =
+ display.style.OTransformOrigin =
+ display.style.msTransformOrigin =
+ "0 0";
+
+ // Create default layer
+ var default_layer = new Guacamole.Display.VisibleLayer(displayWidth, displayHeight);
+
+ // Create cursor layer
+ var cursor = new Guacamole.Display.VisibleLayer(0, 0);
+ cursor.setChannelMask(Guacamole.Layer.SRC);
+
+ // Add default layer and cursor to display
+ display.appendChild(default_layer.getElement());
+ display.appendChild(cursor.getElement());
+
+ // Create bounding div
+ var bounds = document.createElement("div");
+ bounds.style.position = "relative";
+ bounds.style.width = (displayWidth*displayScale) + "px";
+ bounds.style.height = (displayHeight*displayScale) + "px";
+
+ // Add display to bounds
+ bounds.appendChild(display);
+
+ /**
+ * The X coordinate of the hotspot of the mouse cursor. The hotspot is
+ * the relative location within the image of the mouse cursor at which
+ * each click occurs.
+ *
+ * @type {Number}
+ */
+ this.cursorHotspotX = 0;
+
+ /**
+ * The Y coordinate of the hotspot of the mouse cursor. The hotspot is
+ * the relative location within the image of the mouse cursor at which
+ * each click occurs.
+ *
+ * @type {Number}
+ */
+ this.cursorHotspotY = 0;
+
+ /**
+ * The current X coordinate of the local mouse cursor. This is not
+ * necessarily the location of the actual mouse - it refers only to
+ * the location of the cursor image within the Guacamole display, as
+ * last set by moveCursor().
+ *
+ * @type {Number}
+ */
+ this.cursorX = 0;
+
+ /**
+ * The current X coordinate of the local mouse cursor. This is not
+ * necessarily the location of the actual mouse - it refers only to
+ * the location of the cursor image within the Guacamole display, as
+ * last set by moveCursor().
+ *
+ * @type {Number}
+ */
+ this.cursorY = 0;
+
+ /**
+ * Fired when the default layer (and thus the entire Guacamole display)
+ * is resized.
+ *
+ * @event
+ * @param {Number} width The new width of the Guacamole display.
+ * @param {Number} height The new height of the Guacamole display.
+ */
+ this.onresize = null;
+
+ /**
+ * Fired whenever the local cursor image is changed. This can be used to
+ * implement special handling of the client-side cursor, or to override
+ * the default use of a software cursor layer.
+ *
+ * @event
+ * @param {HTMLCanvasElement} canvas The cursor image.
+ * @param {Number} x The X-coordinate of the cursor hotspot.
+ * @param {Number} y The Y-coordinate of the cursor hotspot.
+ */
+ this.oncursor = null;
+
+ /**
+ * The queue of all pending Tasks. Tasks will be run in order, with new
+ * tasks added at the end of the queue and old tasks removed from the
+ * front of the queue (FIFO). These tasks will eventually be grouped
+ * into a Frame.
+ * @private
+ * @type {Task[]}
+ */
+ var tasks = [];
+
+ /**
+ * The queue of all frames. Each frame is a pairing of an array of tasks
+ * and a callback which must be called when the frame is rendered.
+ * @private
+ * @type {Frame[]}
+ */
+ var frames = [];
+
+ /**
+ * Flushes all pending frames.
+ * @private
+ */
+ function __flush_frames() {
+
+ var rendered_frames = 0;
+
+ // Draw all pending frames, if ready
+ while (rendered_frames < frames.length) {
+
+ var frame = frames[rendered_frames];
+ if (!frame.isReady())
+ break;
+
+ frame.flush();
+ rendered_frames++;
+
+ }
+
+ // Remove rendered frames from array
+ frames.splice(0, rendered_frames);
+
+ }
+
+ /**
+ * An ordered list of tasks which must be executed atomically. Once
+ * executed, an associated (and optional) callback will be called.
+ *
+ * @private
+ * @constructor
+ * @param {function} callback The function to call when this frame is
+ * rendered.
+ * @param {Task[]} tasks The set of tasks which must be executed to render
+ * this frame.
+ */
+ function Frame(callback, tasks) {
+
+ /**
+ * Returns whether this frame is ready to be rendered. This function
+ * returns true if and only if ALL underlying tasks are unblocked.
+ *
+ * @returns {Boolean} true if all underlying tasks are unblocked,
+ * false otherwise.
+ */
+ this.isReady = function() {
+
+ // Search for blocked tasks
+ for (var i=0; i < tasks.length; i++) {
+ if (tasks[i].blocked)
+ return false;
+ }
+
+ // If no blocked tasks, the frame is ready
+ return true;
+
+ };
+
+ /**
+ * Renders this frame, calling the associated callback, if any, after
+ * the frame is complete. This function MUST only be called when no
+ * blocked tasks exist. Calling this function with blocked tasks
+ * will result in undefined behavior.
+ */
+ this.flush = function() {
+
+ // Draw all pending tasks.
+ for (var i=0; i < tasks.length; i++)
+ tasks[i].execute();
+
+ // Call callback
+ if (callback) callback();
+
+ };
+
+ }
+
+ /**
+ * A container for an task handler. Each operation which must be ordered
+ * is associated with a Task that goes into a task queue. Tasks in this
+ * queue are executed in order once their handlers are set, while Tasks
+ * without handlers block themselves and any following Tasks from running.
+ *
+ * @constructor
+ * @private
+ * @param {function} taskHandler The function to call when this task
+ * runs, if any.
+ * @param {boolean} blocked Whether this task should start blocked.
+ */
+ function Task(taskHandler, blocked) {
+
+ var task = this;
+
+ /**
+ * Whether this Task is blocked.
+ *
+ * @type {boolean}
+ */
+ this.blocked = blocked;
+
+ /**
+ * Unblocks this Task, allowing it to run.
+ */
+ this.unblock = function() {
+ if (task.blocked) {
+ task.blocked = false;
+ __flush_frames();
+ }
+ };
+
+ /**
+ * Calls the handler associated with this task IMMEDIATELY. This
+ * function does not track whether this task is marked as blocked.
+ * Enforcing the blocked status of tasks is up to the caller.
+ */
+ this.execute = function() {
+ if (taskHandler) taskHandler();
+ };
+
+ }
+
+ /**
+ * Schedules a task for future execution. The given handler will execute
+ * immediately after all previous tasks upon frame flush, unless this
+ * task is blocked. If any tasks is blocked, the entire frame will not
+ * render (and no tasks within will execute) until all tasks are unblocked.
+ *
+ * @private
+ * @param {function} handler The function to call when possible, if any.
+ * @param {boolean} blocked Whether the task should start blocked.
+ * @returns {Task} The Task created and added to the queue for future
+ * running.
+ */
+ function scheduleTask(handler, blocked) {
+ var task = new Task(handler, blocked);
+ tasks.push(task);
+ return task;
+ }
+
+ /**
+ * Returns the element which contains the Guacamole display.
+ *
+ * @return {Element} The element containing the Guacamole display.
+ */
+ this.getElement = function() {
+ return bounds;
+ };
+
+ /**
+ * Returns the width of this display.
+ *
+ * @return {Number} The width of this display;
+ */
+ this.getWidth = function() {
+ return displayWidth;
+ };
+
+ /**
+ * Returns the height of this display.
+ *
+ * @return {Number} The height of this display;
+ */
+ this.getHeight = function() {
+ return displayHeight;
+ };
+
+ /**
+ * Returns the default layer of this display. Each Guacamole display always
+ * has at least one layer. Other layers can optionally be created within
+ * this layer, but the default layer cannot be removed and is the absolute
+ * ancestor of all other layers.
+ *
+ * @return {Guacamole.Display.VisibleLayer} The default layer.
+ */
+ this.getDefaultLayer = function() {
+ return default_layer;
+ };
+
+ /**
+ * Returns the cursor layer of this display. Each Guacamole display contains
+ * a layer for the image of the mouse cursor. This layer is a special case
+ * and exists above all other layers, similar to the hardware mouse cursor.
+ *
+ * @return {Guacamole.Display.VisibleLayer} The cursor layer.
+ */
+ this.getCursorLayer = function() {
+ return cursor;
+ };
+
+ /**
+ * Creates a new layer. The new layer will be a direct child of the default
+ * layer, but can be moved to be a child of any other layer. Layers returned
+ * by this function are visible.
+ *
+ * @return {Guacamole.Display.VisibleLayer} The newly-created layer.
+ */
+ this.createLayer = function() {
+ var layer = new Guacamole.Display.VisibleLayer(displayWidth, displayHeight);
+ layer.move(default_layer, 0, 0, 0);
+ return layer;
+ };
+
+ /**
+ * Creates a new buffer. Buffers are invisible, off-screen surfaces. They
+ * are implemented in the same manner as layers, but do not provide the
+ * same nesting semantics.
+ *
+ * @return {Guacamole.Layer} The newly-created buffer.
+ */
+ this.createBuffer = function() {
+ var buffer = new Guacamole.Layer(0, 0);
+ buffer.autosize = 1;
+ return buffer;
+ };
+
+ /**
+ * Flush all pending draw tasks, if possible, as a new frame. If the entire
+ * frame is not ready, the flush will wait until all required tasks are
+ * unblocked.
+ *
+ * @param {function} callback The function to call when this frame is
+ * flushed. This may happen immediately, or
+ * later when blocked tasks become unblocked.
+ */
+ this.flush = function(callback) {
+
+ // Add frame, reset tasks
+ frames.push(new Frame(callback, tasks));
+ tasks = [];
+
+ // Attempt flush
+ __flush_frames();
+
+ };
+
+ /**
+ * Sets the hotspot and image of the mouse cursor displayed within the
+ * Guacamole display.
+ *
+ * @param {Number} hotspotX The X coordinate of the cursor hotspot.
+ * @param {Number} hotspotY The Y coordinate of the cursor hotspot.
+ * @param {Guacamole.Layer} layer The source layer containing the data which
+ * should be used as the mouse cursor image.
+ * @param {Number} srcx The X coordinate of the upper-left corner of the
+ * rectangle within the source layer's coordinate
+ * space to copy data from.
+ * @param {Number} srcy The Y coordinate of the upper-left corner of the
+ * rectangle within the source layer's coordinate
+ * space to copy data from.
+ * @param {Number} srcw The width of the rectangle within the source layer's
+ * coordinate space to copy data from.
+ * @param {Number} srch The height of the rectangle within the source
+ * layer's coordinate space to copy data from.
+
+ */
+ this.setCursor = function(hotspotX, hotspotY, layer, srcx, srcy, srcw, srch) {
+ scheduleTask(function __display_set_cursor() {
+
+ // Set hotspot
+ guac_display.cursorHotspotX = hotspotX;
+ guac_display.cursorHotspotY = hotspotY;
+
+ // Reset cursor size
+ cursor.resize(srcw, srch);
+
+ // Draw cursor to cursor layer
+ cursor.copy(layer, srcx, srcy, srcw, srch, 0, 0);
+ guac_display.moveCursor(guac_display.cursorX, guac_display.cursorY);
+
+ // Fire cursor change event
+ if (guac_display.oncursor)
+ guac_display.oncursor(cursor.toCanvas(), hotspotX, hotspotY);
+
+ });
+ };
+
+ /**
+ * Sets whether the software-rendered cursor is shown. This cursor differs
+ * from the hardware cursor in that it is built into the Guacamole.Display,
+ * and relies on its own Guacamole layer to render.
+ *
+ * @param {Boolean} [shown=true] Whether to show the software cursor.
+ */
+ this.showCursor = function(shown) {
+
+ var element = cursor.getElement();
+ var parent = element.parentNode;
+
+ // Remove from DOM if hidden
+ if (shown === false) {
+ if (parent)
+ parent.removeChild(element);
+ }
+
+ // Otherwise, ensure cursor is child of display
+ else if (parent !== display)
+ display.appendChild(element);
+
+ };
+
+ /**
+ * Sets the location of the local cursor to the given coordinates. For the
+ * sake of responsiveness, this function performs its action immediately.
+ * Cursor motion is not maintained within atomic frames.
+ *
+ * @param {Number} x The X coordinate to move the cursor to.
+ * @param {Number} y The Y coordinate to move the cursor to.
+ */
+ this.moveCursor = function(x, y) {
+
+ // Move cursor layer
+ cursor.translate(x - guac_display.cursorHotspotX,
+ y - guac_display.cursorHotspotY);
+
+ // Update stored position
+ guac_display.cursorX = x;
+ guac_display.cursorY = y;
+
+ };
+
+ /**
+ * Changes the size of the given Layer to the given width and height.
+ * Resizing is only attempted if the new size provided is actually different
+ * from the current size.
+ *
+ * @param {Guacamole.Layer} layer The layer to resize.
+ * @param {Number} width The new width.
+ * @param {Number} height The new height.
+ */
+ this.resize = function(layer, width, height) {
+ scheduleTask(function __display_resize() {
+
+ layer.resize(width, height);
+
+ // Resize display if default layer is resized
+ if (layer === default_layer) {
+
+ // Update (set) display size
+ displayWidth = width;
+ displayHeight = height;
+ display.style.width = displayWidth + "px";
+ display.style.height = displayHeight + "px";
+
+ // Update bounds size
+ bounds.style.width = (displayWidth*displayScale) + "px";
+ bounds.style.height = (displayHeight*displayScale) + "px";
+
+ // Notify of resize
+ if (guac_display.onresize)
+ guac_display.onresize(width, height);
+
+ }
+
+ });
+ };
+
+ /**
+ * Draws the specified image at the given coordinates. The image specified
+ * must already be loaded.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {Number} x The destination X coordinate.
+ * @param {Number} y The destination Y coordinate.
+ * @param {Image} image The image to draw. Note that this is an Image
+ * object - not a URL.
+ */
+ this.drawImage = function(layer, x, y, image) {
+ scheduleTask(function __display_drawImage() {
+ layer.drawImage(x, y, image);
+ });
+ };
+
+ /**
+ * Draws the image contained within the specified Blob at the given
+ * coordinates. The Blob specified must already be populated with image
+ * data.
+ *
+ * @param {Guacamole.Layer} layer
+ * The layer to draw upon.
+ *
+ * @param {Number} x
+ * The destination X coordinate.
+ *
+ * @param {Number} y
+ * The destination Y coordinate.
+ *
+ * @param {Blob} blob
+ * The Blob containing the image data to draw.
+ */
+ this.drawBlob = function(layer, x, y, blob) {
+
+ // Create URL for blob
+ var url = URL.createObjectURL(blob);
+
+ // Draw and free blob URL when ready
+ var task = scheduleTask(function __display_drawBlob() {
+
+ // Draw the image only if it loaded without errors
+ if (image.width && image.height)
+ layer.drawImage(x, y, image);
+
+ // Blob URL no longer needed
+ URL.revokeObjectURL(url);
+
+ }, true);
+
+ // Load image from URL
+ var image = new Image();
+ image.onload = task.unblock;
+ image.onerror = task.unblock;
+ image.src = url;
+
+ };
+
+ /**
+ * Draws the image at the specified URL at the given coordinates. The image
+ * will be loaded automatically, and this and any future operations will
+ * wait for the image to finish loading.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {Number} x The destination X coordinate.
+ * @param {Number} y The destination Y coordinate.
+ * @param {String} url The URL of the image to draw.
+ */
+ this.draw = function(layer, x, y, url) {
+
+ var task = scheduleTask(function __display_draw() {
+
+ // Draw the image only if it loaded without errors
+ if (image.width && image.height)
+ layer.drawImage(x, y, image);
+
+ }, true);
+
+ var image = new Image();
+ image.onload = task.unblock;
+ image.onerror = task.unblock;
+ image.src = url;
+
+ };
+
+ /**
+ * Plays the video at the specified URL within this layer. The video
+ * will be loaded automatically, and this and any future operations will
+ * wait for the video to finish loading. Future operations will not be
+ * executed until the video finishes playing.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {String} mimetype The mimetype of the video to play.
+ * @param {Number} duration The duration of the video in milliseconds.
+ * @param {String} url The URL of the video to play.
+ */
+ this.play = function(layer, mimetype, duration, url) {
+
+ // Start loading the video
+ var video = document.createElement("video");
+ video.type = mimetype;
+ video.src = url;
+
+ // Start copying frames when playing
+ video.addEventListener("play", function() {
+
+ function render_callback() {
+ layer.drawImage(0, 0, video);
+ if (!video.ended)
+ window.setTimeout(render_callback, 20);
+ }
+
+ render_callback();
+
+ }, false);
+
+ scheduleTask(video.play);
+
+ };
+
+ /**
+ * Transfer a rectangle of image data from one Layer to this Layer using the
+ * specified transfer function.
+ *
+ * @param {Guacamole.Layer} srcLayer The Layer to copy image data from.
+ * @param {Number} srcx The X coordinate of the upper-left corner of the
+ * rectangle within the source Layer's coordinate
+ * space to copy data from.
+ * @param {Number} srcy The Y coordinate of the upper-left corner of the
+ * rectangle within the source Layer's coordinate
+ * space to copy data from.
+ * @param {Number} srcw The width of the rectangle within the source Layer's
+ * coordinate space to copy data from.
+ * @param {Number} srch The height of the rectangle within the source
+ * Layer's coordinate space to copy data from.
+ * @param {Guacamole.Layer} dstLayer The layer to draw upon.
+ * @param {Number} x The destination X coordinate.
+ * @param {Number} y The destination Y coordinate.
+ * @param {Function} transferFunction The transfer function to use to
+ * transfer data from source to
+ * destination.
+ */
+ this.transfer = function(srcLayer, srcx, srcy, srcw, srch, dstLayer, x, y, transferFunction) {
+ scheduleTask(function __display_transfer() {
+ dstLayer.transfer(srcLayer, srcx, srcy, srcw, srch, x, y, transferFunction);
+ });
+ };
+
+ /**
+ * Put a rectangle of image data from one Layer to this Layer directly
+ * without performing any alpha blending. Simply copy the data.
+ *
+ * @param {Guacamole.Layer} srcLayer The Layer to copy image data from.
+ * @param {Number} srcx The X coordinate of the upper-left corner of the
+ * rectangle within the source Layer's coordinate
+ * space to copy data from.
+ * @param {Number} srcy The Y coordinate of the upper-left corner of the
+ * rectangle within the source Layer's coordinate
+ * space to copy data from.
+ * @param {Number} srcw The width of the rectangle within the source Layer's
+ * coordinate space to copy data from.
+ * @param {Number} srch The height of the rectangle within the source
+ * Layer's coordinate space to copy data from.
+ * @param {Guacamole.Layer} dstLayer The layer to draw upon.
+ * @param {Number} x The destination X coordinate.
+ * @param {Number} y The destination Y coordinate.
+ */
+ this.put = function(srcLayer, srcx, srcy, srcw, srch, dstLayer, x, y) {
+ scheduleTask(function __display_put() {
+ dstLayer.put(srcLayer, srcx, srcy, srcw, srch, x, y);
+ });
+ };
+
+ /**
+ * Copy a rectangle of image data from one Layer to this Layer. This
+ * operation will copy exactly the image data that will be drawn once all
+ * operations of the source Layer that were pending at the time this
+ * function was called are complete. This operation will not alter the
+ * size of the source Layer even if its autosize property is set to true.
+ *
+ * @param {Guacamole.Layer} srcLayer The Layer to copy image data from.
+ * @param {Number} srcx The X coordinate of the upper-left corner of the
+ * rectangle within the source Layer's coordinate
+ * space to copy data from.
+ * @param {Number} srcy The Y coordinate of the upper-left corner of the
+ * rectangle within the source Layer's coordinate
+ * space to copy data from.
+ * @param {Number} srcw The width of the rectangle within the source Layer's
+ * coordinate space to copy data from.
+ * @param {Number} srch The height of the rectangle within the source
+ * Layer's coordinate space to copy data from.
+ * @param {Guacamole.Layer} dstLayer The layer to draw upon.
+ * @param {Number} x The destination X coordinate.
+ * @param {Number} y The destination Y coordinate.
+ */
+ this.copy = function(srcLayer, srcx, srcy, srcw, srch, dstLayer, x, y) {
+ scheduleTask(function __display_copy() {
+ dstLayer.copy(srcLayer, srcx, srcy, srcw, srch, x, y);
+ });
+ };
+
+ /**
+ * Starts a new path at the specified point.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {Number} x The X coordinate of the point to draw.
+ * @param {Number} y The Y coordinate of the point to draw.
+ */
+ this.moveTo = function(layer, x, y) {
+ scheduleTask(function __display_moveTo() {
+ layer.moveTo(x, y);
+ });
+ };
+
+ /**
+ * Add the specified line to the current path.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {Number} x The X coordinate of the endpoint of the line to draw.
+ * @param {Number} y The Y coordinate of the endpoint of the line to draw.
+ */
+ this.lineTo = function(layer, x, y) {
+ scheduleTask(function __display_lineTo() {
+ layer.lineTo(x, y);
+ });
+ };
+
+ /**
+ * Add the specified arc to the current path.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {Number} x The X coordinate of the center of the circle which
+ * will contain the arc.
+ * @param {Number} y The Y coordinate of the center of the circle which
+ * will contain the arc.
+ * @param {Number} radius The radius of the circle.
+ * @param {Number} startAngle The starting angle of the arc, in radians.
+ * @param {Number} endAngle The ending angle of the arc, in radians.
+ * @param {Boolean} negative Whether the arc should be drawn in order of
+ * decreasing angle.
+ */
+ this.arc = function(layer, x, y, radius, startAngle, endAngle, negative) {
+ scheduleTask(function __display_arc() {
+ layer.arc(x, y, radius, startAngle, endAngle, negative);
+ });
+ };
+
+ /**
+ * Starts a new path at the specified point.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {Number} cp1x The X coordinate of the first control point.
+ * @param {Number} cp1y The Y coordinate of the first control point.
+ * @param {Number} cp2x The X coordinate of the second control point.
+ * @param {Number} cp2y The Y coordinate of the second control point.
+ * @param {Number} x The X coordinate of the endpoint of the curve.
+ * @param {Number} y The Y coordinate of the endpoint of the curve.
+ */
+ this.curveTo = function(layer, cp1x, cp1y, cp2x, cp2y, x, y) {
+ scheduleTask(function __display_curveTo() {
+ layer.curveTo(cp1x, cp1y, cp2x, cp2y, x, y);
+ });
+ };
+
+ /**
+ * Closes the current path by connecting the end point with the start
+ * point (if any) with a straight line.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ */
+ this.close = function(layer) {
+ scheduleTask(function __display_close() {
+ layer.close();
+ });
+ };
+
+ /**
+ * Add the specified rectangle to the current path.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {Number} x The X coordinate of the upper-left corner of the
+ * rectangle to draw.
+ * @param {Number} y The Y coordinate of the upper-left corner of the
+ * rectangle to draw.
+ * @param {Number} w The width of the rectangle to draw.
+ * @param {Number} h The height of the rectangle to draw.
+ */
+ this.rect = function(layer, x, y, w, h) {
+ scheduleTask(function __display_rect() {
+ layer.rect(x, y, w, h);
+ });
+ };
+
+ /**
+ * Clip all future drawing operations by the current path. The current path
+ * is implicitly closed. The current path can continue to be reused
+ * for other operations (such as fillColor()) but a new path will be started
+ * once a path drawing operation (path() or rect()) is used.
+ *
+ * @param {Guacamole.Layer} layer The layer to affect.
+ */
+ this.clip = function(layer) {
+ scheduleTask(function __display_clip() {
+ layer.clip();
+ });
+ };
+
+ /**
+ * Stroke the current path with the specified color. The current path
+ * is implicitly closed. The current path can continue to be reused
+ * for other operations (such as clip()) but a new path will be started
+ * once a path drawing operation (path() or rect()) is used.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {String} cap The line cap style. Can be "round", "square",
+ * or "butt".
+ * @param {String} join The line join style. Can be "round", "bevel",
+ * or "miter".
+ * @param {Number} thickness The line thickness in pixels.
+ * @param {Number} r The red component of the color to fill.
+ * @param {Number} g The green component of the color to fill.
+ * @param {Number} b The blue component of the color to fill.
+ * @param {Number} a The alpha component of the color to fill.
+ */
+ this.strokeColor = function(layer, cap, join, thickness, r, g, b, a) {
+ scheduleTask(function __display_strokeColor() {
+ layer.strokeColor(cap, join, thickness, r, g, b, a);
+ });
+ };
+
+ /**
+ * Fills the current path with the specified color. The current path
+ * is implicitly closed. The current path can continue to be reused
+ * for other operations (such as clip()) but a new path will be started
+ * once a path drawing operation (path() or rect()) is used.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {Number} r The red component of the color to fill.
+ * @param {Number} g The green component of the color to fill.
+ * @param {Number} b The blue component of the color to fill.
+ * @param {Number} a The alpha component of the color to fill.
+ */
+ this.fillColor = function(layer, r, g, b, a) {
+ scheduleTask(function __display_fillColor() {
+ layer.fillColor(r, g, b, a);
+ });
+ };
+
+ /**
+ * Stroke the current path with the image within the specified layer. The
+ * image data will be tiled infinitely within the stroke. The current path
+ * is implicitly closed. The current path can continue to be reused
+ * for other operations (such as clip()) but a new path will be started
+ * once a path drawing operation (path() or rect()) is used.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {String} cap The line cap style. Can be "round", "square",
+ * or "butt".
+ * @param {String} join The line join style. Can be "round", "bevel",
+ * or "miter".
+ * @param {Number} thickness The line thickness in pixels.
+ * @param {Guacamole.Layer} srcLayer The layer to use as a repeating pattern
+ * within the stroke.
+ */
+ this.strokeLayer = function(layer, cap, join, thickness, srcLayer) {
+ scheduleTask(function __display_strokeLayer() {
+ layer.strokeLayer(cap, join, thickness, srcLayer);
+ });
+ };
+
+ /**
+ * Fills the current path with the image within the specified layer. The
+ * image data will be tiled infinitely within the stroke. The current path
+ * is implicitly closed. The current path can continue to be reused
+ * for other operations (such as clip()) but a new path will be started
+ * once a path drawing operation (path() or rect()) is used.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ * @param {Guacamole.Layer} srcLayer The layer to use as a repeating pattern
+ * within the fill.
+ */
+ this.fillLayer = function(layer, srcLayer) {
+ scheduleTask(function __display_fillLayer() {
+ layer.fillLayer(srcLayer);
+ });
+ };
+
+ /**
+ * Push current layer state onto stack.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ */
+ this.push = function(layer) {
+ scheduleTask(function __display_push() {
+ layer.push();
+ });
+ };
+
+ /**
+ * Pop layer state off stack.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ */
+ this.pop = function(layer) {
+ scheduleTask(function __display_pop() {
+ layer.pop();
+ });
+ };
+
+ /**
+ * Reset the layer, clearing the stack, the current path, and any transform
+ * matrix.
+ *
+ * @param {Guacamole.Layer} layer The layer to draw upon.
+ */
+ this.reset = function(layer) {
+ scheduleTask(function __display_reset() {
+ layer.reset();
+ });
+ };
+
+ /**
+ * Sets the given affine transform (defined with six values from the
+ * transform's matrix).
+ *
+ * @param {Guacamole.Layer} layer The layer to modify.
+ * @param {Number} a The first value in the affine transform's matrix.
+ * @param {Number} b The second value in the affine transform's matrix.
+ * @param {Number} c The third value in the affine transform's matrix.
+ * @param {Number} d The fourth value in the affine transform's matrix.
+ * @param {Number} e The fifth value in the affine transform's matrix.
+ * @param {Number} f The sixth value in the affine transform's matrix.
+ */
+ this.setTransform = function(layer, a, b, c, d, e, f) {
+ scheduleTask(function __display_setTransform() {
+ layer.setTransform(a, b, c, d, e, f);
+ });
+ };
+
+ /**
+ * Applies the given affine transform (defined with six values from the
+ * transform's matrix).
+ *
+ * @param {Guacamole.Layer} layer The layer to modify.
+ * @param {Number} a The first value in the affine transform's matrix.
+ * @param {Number} b The second value in the affine transform's matrix.
+ * @param {Number} c The third value in the affine transform's matrix.
+ * @param {Number} d The fourth value in the affine transform's matrix.
+ * @param {Number} e The fifth value in the affine transform's matrix.
+ * @param {Number} f The sixth value in the affine transform's matrix.
+ */
+ this.transform = function(layer, a, b, c, d, e, f) {
+ scheduleTask(function __display_transform() {
+ layer.transform(a, b, c, d, e, f);
+ });
+ };
+
+ /**
+ * Sets the channel mask for future operations on this Layer.
+ *
+ * The channel mask is a Guacamole-specific compositing operation identifier
+ * with a single bit representing each of four channels (in order): source
+ * image where destination transparent, source where destination opaque,
+ * destination where source transparent, and destination where source
+ * opaque.
+ *
+ * @param {Guacamole.Layer} layer The layer to modify.
+ * @param {Number} mask The channel mask for future operations on this
+ * Layer.
+ */
+ this.setChannelMask = function(layer, mask) {
+ scheduleTask(function __display_setChannelMask() {
+ layer.setChannelMask(mask);
+ });
+ };
+
+ /**
+ * Sets the miter limit for stroke operations using the miter join. This
+ * limit is the maximum ratio of the size of the miter join to the stroke
+ * width. If this ratio is exceeded, the miter will not be drawn for that
+ * joint of the path.
+ *
+ * @param {Guacamole.Layer} layer The layer to modify.
+ * @param {Number} limit The miter limit for stroke operations using the
+ * miter join.
+ */
+ this.setMiterLimit = function(layer, limit) {
+ scheduleTask(function __display_setMiterLimit() {
+ layer.setMiterLimit(limit);
+ });
+ };
+
+ /**
+ * Removes the given layer container entirely, such that it is no longer
+ * contained within its parent layer, if any.
+ *
+ * @param {Guacamole.Display.VisibleLayer} layer
+ * The layer being removed from its parent.
+ */
+ this.dispose = function dispose(layer) {
+ scheduleTask(function disposeLayer() {
+ layer.dispose();
+ });
+ };
+
+ /**
+ * Applies the given affine transform (defined with six values from the
+ * transform's matrix) to the given layer.
+ *
+ * @param {Guacamole.Display.VisibleLayer} layer
+ * The layer being distorted.
+ *
+ * @param {Number} a
+ * The first value in the affine transform's matrix.
+ *
+ * @param {Number} b
+ * The second value in the affine transform's matrix.
+ *
+ * @param {Number} c
+ * The third value in the affine transform's matrix.
+ *
+ * @param {Number} d
+ * The fourth value in the affine transform's matrix.
+ *
+ * @param {Number} e
+ * The fifth value in the affine transform's matrix.
+ *
+ * @param {Number} f
+ * The sixth value in the affine transform's matrix.
+ */
+ this.distort = function distort(layer, a, b, c, d, e, f) {
+ scheduleTask(function distortLayer() {
+ layer.distort(a, b, c, d, e, f);
+ });
+ };
+
+ /**
+ * Moves the upper-left corner of the given layer to the given X and Y
+ * coordinate, sets the Z stacking order, and reparents the layer
+ * to the given parent layer.
+ *
+ * @param {Guacamole.Display.VisibleLayer} layer
+ * The layer being moved.
+ *
+ * @param {Guacamole.Display.VisibleLayer} parent
+ * The parent to set.
+ *
+ * @param {Number} x
+ * The X coordinate to move to.
+ *
+ * @param {Number} y
+ * The Y coordinate to move to.
+ *
+ * @param {Number} z
+ * The Z coordinate to move to.
+ */
+ this.move = function move(layer, parent, x, y, z) {
+ scheduleTask(function moveLayer() {
+ layer.move(parent, x, y, z);
+ });
+ };
+
+ /**
+ * Sets the opacity of the given layer to the given value, where 255 is
+ * fully opaque and 0 is fully transparent.
+ *
+ * @param {Guacamole.Display.VisibleLayer} layer
+ * The layer whose opacity should be set.
+ *
+ * @param {Number} alpha
+ * The opacity to set.
+ */
+ this.shade = function shade(layer, alpha) {
+ scheduleTask(function shadeLayer() {
+ layer.shade(alpha);
+ });
+ };
+
+ /**
+ * Sets the scale of the client display element such that it renders at
+ * a relatively smaller or larger size, without affecting the true
+ * resolution of the display.
+ *
+ * @param {Number} scale The scale to resize to, where 1.0 is normal
+ * size (1:1 scale).
+ */
+ this.scale = function(scale) {
+
+ display.style.transform =
+ display.style.WebkitTransform =
+ display.style.MozTransform =
+ display.style.OTransform =
+ display.style.msTransform =
+
+ "scale(" + scale + "," + scale + ")";
+
+ displayScale = scale;
+
+ // Update bounds size
+ bounds.style.width = (displayWidth*displayScale) + "px";
+ bounds.style.height = (displayHeight*displayScale) + "px";
+
+ };
+
+ /**
+ * Returns the scale of the display.
+ *
+ * @return {Number} The scale of the display.
+ */
+ this.getScale = function() {
+ return displayScale;
+ };
+
+ /**
+ * Returns a canvas element containing the entire display, with all child
+ * layers composited within.
+ *
+ * @return {HTMLCanvasElement} A new canvas element containing a copy of
+ * the display.
+ */
+ this.flatten = function() {
+
+ // Get destination canvas
+ var canvas = document.createElement("canvas");
+ canvas.width = default_layer.width;
+ canvas.height = default_layer.height;
+
+ var context = canvas.getContext("2d");
+
+ // Returns sorted array of children
+ function get_children(layer) {
+
+ // Build array of children
+ var children = [];
+ for (var index in layer.children)
+ children.push(layer.children[index]);
+
+ // Sort
+ children.sort(function children_comparator(a, b) {
+
+ // Compare based on Z order
+ var diff = a.z - b.z;
+ if (diff !== 0)
+ return diff;
+
+ // If Z order identical, use document order
+ var a_element = a.getElement();
+ var b_element = b.getElement();
+ var position = b_element.compareDocumentPosition(a_element);
+
+ if (position & Node.DOCUMENT_POSITION_PRECEDING) return -1;
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING) return 1;
+
+ // Otherwise, assume same
+ return 0;
+
+ });
+
+ // Done
+ return children;
+
+ }
+
+ // Draws the contents of the given layer at the given coordinates
+ function draw_layer(layer, x, y) {
+
+ // Draw layer
+ if (layer.width > 0 && layer.height > 0) {
+
+ // Save and update alpha
+ var initial_alpha = context.globalAlpha;
+ context.globalAlpha *= layer.alpha / 255.0;
+
+ // Copy data
+ context.drawImage(layer.getCanvas(), x, y);
+
+ // Draw all children
+ var children = get_children(layer);
+ for (var i=0; i<children.length; i++) {
+ var child = children[i];
+ draw_layer(child, x + child.x, y + child.y);
+ }
+
+ // Restore alpha
+ context.globalAlpha = initial_alpha;
+
+ }
+
+ }
+
+ // Draw default layer and all children
+ draw_layer(default_layer, 0, 0);
+
+ // Return new canvas copy
+ return canvas;
+
+ };
+
+};
+
+/**
+ * Simple container for Guacamole.Layer, allowing layers to be easily
+ * repositioned and nested. This allows certain operations to be accelerated
+ * through DOM manipulation, rather than raster operations.
+ *
+ * @constructor
+ * @augments Guacamole.Layer
+ * @param {Number} width The width of the Layer, in pixels. The canvas element
+ * backing this Layer will be given this width.
+ * @param {Number} height The height of the Layer, in pixels. The canvas element
+ * backing this Layer will be given this height.
+ */
+Guacamole.Display.VisibleLayer = function(width, height) {
+
+ Guacamole.Layer.apply(this, [width, height]);
+
+ /**
+ * Reference to this layer.
+ * @private
+ */
+ var layer = this;
+
+ /**
+ * Identifier which uniquely identifies this layer. This is COMPLETELY
+ * UNRELATED to the index of the underlying layer, which is specific
+ * to the Guacamole protocol, and not relevant at this level.
+ *
+ * @private
+ * @type {Number}
+ */
+ this.__unique_id = Guacamole.Display.VisibleLayer.__next_id++;
+
+ /**
+ * The opacity of the layer container, where 255 is fully opaque and 0 is
+ * fully transparent.
+ */
+ this.alpha = 0xFF;
+
+ /**
+ * X coordinate of the upper-left corner of this layer container within
+ * its parent, in pixels.
+ * @type {Number}
+ */
+ this.x = 0;
+
+ /**
+ * Y coordinate of the upper-left corner of this layer container within
+ * its parent, in pixels.
+ * @type {Number}
+ */
+ this.y = 0;
+
+ /**
+ * Z stacking order of this layer relative to other sibling layers.
+ * @type {Number}
+ */
+ this.z = 0;
+
+ /**
+ * The affine transformation applied to this layer container. Each element
+ * corresponds to a value from the transformation matrix, with the first
+ * three values being the first row, and the last three values being the
+ * second row. There are six values total.
+ *
+ * @type {Number[]}
+ */
+ this.matrix = [1, 0, 0, 1, 0, 0];
+
+ /**
+ * The parent layer container of this layer, if any.
+ * @type {Guacamole.Display.VisibleLayer}
+ */
+ this.parent = null;
+
+ /**
+ * Set of all children of this layer, indexed by layer index. This object
+ * will have one property per child.
+ */
+ this.children = {};
+
+ // Set layer position
+ var canvas = layer.getCanvas();
+ canvas.style.position = "absolute";
+ canvas.style.left = "0px";
+ canvas.style.top = "0px";
+
+ // Create div with given size
+ var div = document.createElement("div");
+ div.appendChild(canvas);
+ div.style.width = width + "px";
+ div.style.height = height + "px";
+ div.style.position = "absolute";
+ div.style.left = "0px";
+ div.style.top = "0px";
+ div.style.overflow = "hidden";
+
+ /**
+ * Superclass resize() function.
+ * @private
+ */
+ var __super_resize = this.resize;
+
+ this.resize = function(width, height) {
+
+ // Resize containing div
+ div.style.width = width + "px";
+ div.style.height = height + "px";
+
+ __super_resize(width, height);
+
+ };
+
+ /**
+ * Returns the element containing the canvas and any other elements
+ * associated with this layer.
+ * @returns {Element} The element containing this layer's canvas.
+ */
+ this.getElement = function() {
+ return div;
+ };
+
+ /**
+ * The translation component of this layer's transform.
+ * @private
+ */
+ var translate = "translate(0px, 0px)"; // (0, 0)
+
+ /**
+ * The arbitrary matrix component of this layer's transform.
+ * @private
+ */
+ var matrix = "matrix(1, 0, 0, 1, 0, 0)"; // Identity
+
+ /**
+ * Moves the upper-left corner of this layer to the given X and Y
+ * coordinate.
+ *
+ * @param {Number} x The X coordinate to move to.
+ * @param {Number} y The Y coordinate to move to.
+ */
+ this.translate = function(x, y) {
+
+ layer.x = x;
+ layer.y = y;
+
+ // Generate translation
+ translate = "translate("
+ + x + "px,"
+ + y + "px)";
+
+ // Set layer transform
+ div.style.transform =
+ div.style.WebkitTransform =
+ div.style.MozTransform =
+ div.style.OTransform =
+ div.style.msTransform =
+
+ translate + " " + matrix;
+
+ };
+
+ /**
+ * Moves the upper-left corner of this VisibleLayer to the given X and Y
+ * coordinate, sets the Z stacking order, and reparents this VisibleLayer
+ * to the given VisibleLayer.
+ *
+ * @param {Guacamole.Display.VisibleLayer} parent The parent to set.
+ * @param {Number} x The X coordinate to move to.
+ * @param {Number} y The Y coordinate to move to.
+ * @param {Number} z The Z coordinate to move to.
+ */
+ this.move = function(parent, x, y, z) {
+
+ // Set parent if necessary
+ if (layer.parent !== parent) {
+
+ // Maintain relationship
+ if (layer.parent)
+ delete layer.parent.children[layer.__unique_id];
+ layer.parent = parent;
+ parent.children[layer.__unique_id] = layer;
+
+ // Reparent element
+ var parent_element = parent.getElement();
+ parent_element.appendChild(div);
+
+ }
+
+ // Set location
+ layer.translate(x, y);
+ layer.z = z;
+ div.style.zIndex = z;
+
+ };
+
+ /**
+ * Sets the opacity of this layer to the given value, where 255 is fully
+ * opaque and 0 is fully transparent.
+ *
+ * @param {Number} a The opacity to set.
+ */
+ this.shade = function(a) {
+ layer.alpha = a;
+ div.style.opacity = a/255.0;
+ };
+
+ /**
+ * Removes this layer container entirely, such that it is no longer
+ * contained within its parent layer, if any.
+ */
+ this.dispose = function() {
+
+ // Remove from parent container
+ if (layer.parent) {
+ delete layer.parent.children[layer.__unique_id];
+ layer.parent = null;
+ }
+
+ // Remove from parent element
+ if (div.parentNode)
+ div.parentNode.removeChild(div);
+
+ };
+
+ /**
+ * Applies the given affine transform (defined with six values from the
+ * transform's matrix).
+ *
+ * @param {Number} a The first value in the affine transform's matrix.
+ * @param {Number} b The second value in the affine transform's matrix.
+ * @param {Number} c The third value in the affine transform's matrix.
+ * @param {Number} d The fourth value in the affine transform's matrix.
+ * @param {Number} e The fifth value in the affine transform's matrix.
+ * @param {Number} f The sixth value in the affine transform's matrix.
+ */
+ this.distort = function(a, b, c, d, e, f) {
+
+ // Store matrix
+ layer.matrix = [a, b, c, d, e, f];
+
+ // Generate matrix transformation
+ matrix =
+
+ /* a c e
+ * b d f
+ * 0 0 1
+ */
+
+ "matrix(" + a + "," + b + "," + c + "," + d + "," + e + "," + f + ")";
+
+ // Set layer transform
+ div.style.transform =
+ div.style.WebkitTransform =
+ div.style.MozTransform =
+ div.style.OTransform =
+ div.style.msTransform =
+
+ translate + " " + matrix;
+
+ };
+
+};
+
+/**
+ * The next identifier to be assigned to the layer container. This identifier
+ * uniquely identifies each VisibleLayer, but is unrelated to the index of
+ * the layer, which exists at the protocol/client level only.
+ *
+ * @private
+ * @type {Number}
+ */
+Guacamole.Display.VisibleLayer.__next_id = 0;
+</code></pre>
+ </article>
+ </section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
diff --git a/content/doc/1.1.0/guacamole-common-js/Guacamole.ArrayBufferReader.html b/content/doc/1.1.0/guacamole-common-js/Guacamole.ArrayBufferReader.html
new file mode 100644
index 0000000..1cdf113
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/Guacamole.ArrayBufferReader.html
@@ -0,0 +1,456 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Class: ArrayBufferReader</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Class: ArrayBufferReader</h1>
+
+
+
+
+
+
+<section>
+
+<header>
+
+ <h2><span class="attribs"><span class="type-signature"></span></span>
+ <span class="ancestors"><a href="Guacamole.html">Guacamole</a>.</span>ArrayBufferReader<span class="signature">(stream)</span><span class="type-signature"></span></h2>
+
+
+</header>
+
+<article>
+ <div class="container-overview">
+
+
+
+
+
+
+ <h4 class="name" id="ArrayBufferReader"><span class="type-signature"></span>new ArrayBufferReader<span class="signature">(stream)</span><span class="type-signature"></span></h4>
+
+
+
+
+
+
+<div class="description">
+ A reader which automatically handles the given input stream, returning
+strictly received packets as array buffers. Note that this object will
+overwrite any installed event handlers on the given Guacamole.InputStream.
+</div>
+
+
+
+
+
+
+
+
+
+ <h5>Parameters:</h5>
+
+
+<table class="params">
+ <thead>
+ <tr>
+
+ <th>Name</th>
+
+
+ <th>Type</th>
+
+
+
+
+
+ <th class="last">Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr>
+
+ <td class="name"><code>stream</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type"><a href="Guacamole.InputStream.html">Guacamole.InputStream</a></span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The stream that data will be read
+ from.</td>
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="ArrayBufferReader.js.html">ArrayBufferReader.js</a>, <a href="ArrayBufferReader.js.html#line31">line 31</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h3 class="subsection-title">Events</h3>
+
+
+
+
+
+
+
+ <h4 class="name" id="event:ondata">ondata</h4>
+
+
+
+
+
+
+<div class="description">
+ Fired once for every blob of data received.
+</div>
+
+
+
+
+
+
+
+
+
+ <h5>Parameters:</h5>
+
+
+<table class="params">
+ <thead>
+ <tr>
+
+ <th>Name</th>
+
+
+ <th>Type</th>
+
+
+
+
+
+ <th class="last">Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr>
+
+ <td class="name"><code>buffer</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type">ArrayBuffer</span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The data packet received.</td>
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="ArrayBufferReader.js.html">ArrayBufferReader.js</a>, <a href="ArrayBufferReader.js.html#line68">line 68</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h4 class="name" id="event:onend">onend</h4>
+
+
+
+
+
+
+<div class="description">
+ Fired once this stream is finished and no further data will be written.
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="ArrayBufferReader.js.html">ArrayBufferReader.js</a>, <a href="ArrayBufferReader.js.html#line74">line 74</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</article>
+
+</section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/content/doc/1.1.0/guacamole-common-js/Guacamole.ArrayBufferWriter.html b/content/doc/1.1.0/guacamole-common-js/Guacamole.ArrayBufferWriter.html
new file mode 100644
index 0000000..5c2a3a5
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/Guacamole.ArrayBufferWriter.html
@@ -0,0 +1,758 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Class: ArrayBufferWriter</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Class: ArrayBufferWriter</h1>
+
+
+
+
+
+
+<section>
+
+<header>
+
+ <h2><span class="attribs"><span class="type-signature"></span></span>
+ <span class="ancestors"><a href="Guacamole.html">Guacamole</a>.</span>ArrayBufferWriter<span class="signature">(stream)</span><span class="type-signature"></span></h2>
+
+
+</header>
+
+<article>
+ <div class="container-overview">
+
+
+
+
+
+
+ <h4 class="name" id="ArrayBufferWriter"><span class="type-signature"></span>new ArrayBufferWriter<span class="signature">(stream)</span><span class="type-signature"></span></h4>
+
+
+
+
+
+
+<div class="description">
+ A writer which automatically writes to the given output stream with arbitrary
+binary data, supplied as ArrayBuffers.
+</div>
+
+
+
+
+
+
+
+
+
+ <h5>Parameters:</h5>
+
+
+<table class="params">
+ <thead>
+ <tr>
+
+ <th>Name</th>
+
+
+ <th>Type</th>
+
+
+
+
+
+ <th class="last">Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr>
+
+ <td class="name"><code>stream</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type"><a href="Guacamole.OutputStream.html">Guacamole.OutputStream</a></span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The stream that data will be written
+ to.</td>
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="ArrayBufferWriter.js.html">ArrayBufferWriter.js</a>, <a href="ArrayBufferWriter.js.html#line30">line 30</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h3 class="subsection-title">Members</h3>
+
+
+
+<h4 class="name" id=".DEFAULT_BLOB_LENGTH"><span class="type-signature">(static, constant) </span>DEFAULT_BLOB_LENGTH<span class="type-signature"> :Number</span></h4>
+
+
+
+
+<div class="description">
+ The default maximum blob length for new Guacamole.ArrayBufferWriter
+instances.
+</div>
+
+
+
+ <h5>Type:</h5>
+ <ul>
+ <li>
+
+<span class="param-type">Number</span>
+
+
+ </li>
+ </ul>
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="ArrayBufferWriter.js.html">ArrayBufferWriter.js</a>, <a href="ArrayBufferWriter.js.html#line123">line 123</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+<h4 class="name" id="blobLength"><span class="type-signature"></span>blobLength<span class="type-signature"> :Number</span></h4>
+
+
+
+
+<div class="description">
+ The maximum length of any blob sent by this Guacamole.ArrayBufferWriter,
+in bytes. Data sent via
+<a href="Guacamole.ArrayBufferWriter.html#sendData">sendData()</a> which exceeds
+this length will be split into multiple blobs. As the Guacamole protocol
+limits the maximum size of any instruction or instruction element to
+8192 bytes, and the contents of blobs will be base64-encoded, this value
+should only be increased with extreme caution.
+</div>
+
+
+
+ <h5>Type:</h5>
+ <ul>
+ <li>
+
+<span class="param-type">Number</span>
+
+
+ </li>
+ </ul>
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-default">Default Value:</dt>
+ <dd class="tag-default"><ul class="dummy">
+ <li><a href="Guacamole.ArrayBufferWriter.html#.DEFAULT_BLOB_LENGTH">Guacamole.ArrayBufferWriter.DEFAULT_BLOB_LENGTH</a></li>
+ </ul></dd>
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="ArrayBufferWriter.js.html">ArrayBufferWriter.js</a>, <a href="ArrayBufferWriter.js.html#line76">line 76</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+ <h3 class="subsection-title">Methods</h3>
+
+
+
+
+
+
+
+ <h4 class="name" id="sendData"><span class="type-signature"></span>sendData<span class="signature">(data)</span><span class="type-signature"></span></h4>
+
+
+
+
+
+
+<div class="description">
+ Sends the given data.
+</div>
+
+
+
+
+
+
+
+
+
+ <h5>Parameters:</h5>
+
+
+<table class="params">
+ <thead>
+ <tr>
+
+ <th>Name</th>
+
+
+ <th>Type</th>
+
+
+
+
+
+ <th class="last">Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr>
+
+ <td class="name"><code>data</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type">ArrayBuffer</span>
+|
+
+<span class="param-type">TypedArray</span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The data to send.</td>
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="ArrayBufferWriter.js.html">ArrayBufferWriter.js</a>, <a href="ArrayBufferWriter.js.html#line83">line 83</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h4 class="name" id="sendEnd"><span class="type-signature"></span>sendEnd<span class="signature">()</span><span class="type-signature"></span></h4>
+
+
+
+
+
+
+<div class="description">
+ Signals that no further text will be sent, effectively closing the
+stream.
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="ArrayBufferWriter.js.html">ArrayBufferWriter.js</a>, <a href="ArrayBufferWriter.js.html#line103">line 103</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h3 class="subsection-title">Events</h3>
+
+
+
+
+
+
+
+ <h4 class="name" id="event:onack">onack</h4>
+
+
+
+
+
+
+<div class="description">
+ Fired for received data, if acknowledged by the server.
+</div>
+
+
+
+
+
+
+
+
+
+ <h5>Parameters:</h5>
+
+
+<table class="params">
+ <thead>
+ <tr>
+
+ <th>Name</th>
+
+
+ <th>Type</th>
+
+
+
+
+
+ <th class="last">Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr>
+
+ <td class="name"><code>status</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type"><a href="Guacamole.Status.html">Guacamole.Status</a></span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The status of the operation.</td>
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="ArrayBufferWriter.js.html">ArrayBufferWriter.js</a>, <a href="ArrayBufferWriter.js.html#line112">line 112</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</article>
+
+</section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/content/doc/1.1.0/guacamole-common-js/Guacamole.AudioContextFactory.html b/content/doc/1.1.0/guacamole-common-js/Guacamole.AudioContextFactory.html
new file mode 100644
index 0000000..6596baa
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/Guacamole.AudioContextFactory.html
@@ -0,0 +1,341 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Namespace: AudioContextFactory</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Namespace: AudioContextFactory</h1>
+
+
+
+
+
+
+<section>
+
+<header>
+
+ <h2>
+ <span class="ancestors"><a href="Guacamole.html">Guacamole</a>.</span>AudioContextFactory</h2>
+
+
+</header>
+
+<article>
+ <div class="container-overview">
+
+
+ <div class="description">Maintains a singleton instance of the Web Audio API AudioContext class,
+instantiating the AudioContext only in response to the first call to
+getAudioContext(), and only if no existing AudioContext instance has been
+provided via the singleton property. Subsequent calls to getAudioContext()
+will return the same instance.</div>
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioContextFactory.js.html">AudioContextFactory.js</a>, <a href="AudioContextFactory.js.html#line31">line 31</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h3 class="subsection-title">Members</h3>
+
+
+
+<h4 class="name" id=".singleton"><span class="type-signature">(static) </span>singleton<span class="type-signature"> :AudioContext</span></h4>
+
+
+
+
+<div class="description">
+ A singleton instance of a Web Audio API AudioContext object, or null if
+no instance has yes been created. This property may be manually set if
+you wish to supply your own AudioContext instance, but care must be
+taken to do so as early as possible. Assignments to this property will
+not retroactively affect the value returned by previous calls to
+getAudioContext().
+</div>
+
+
+
+ <h5>Type:</h5>
+ <ul>
+ <li>
+
+<span class="param-type">AudioContext</span>
+
+
+ </li>
+ </ul>
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioContextFactory.js.html">AudioContextFactory.js</a>, <a href="AudioContextFactory.js.html#line43">line 43</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+ <h3 class="subsection-title">Methods</h3>
+
+
+
+
+
+
+
+ <h4 class="name" id=".getAudioContext"><span class="type-signature">(static) </span>getAudioContext<span class="signature">()</span><span class="type-signature"> → {AudioContext}</span></h4>
+
+
+
+
+
+
+<div class="description">
+ Returns a singleton instance of a Web Audio API AudioContext object.
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioContextFactory.js.html">AudioContextFactory.js</a>, <a href="AudioContextFactory.js.html#line52">line 52</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h5>Returns:</h5>
+
+
+<div class="param-desc">
+ A singleton instance of a Web Audio API AudioContext object, or null
+ if the Web Audio API is not supported.
+</div>
+
+
+
+<dl>
+ <dt>
+ Type
+ </dt>
+ <dd>
+
+<span class="param-type">AudioContext</span>
+
+
+ </dd>
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+</article>
+
+</section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/content/doc/1.1.0/guacamole-common-js/Guacamole.AudioPlayer.html b/content/doc/1.1.0/guacamole-common-js/Guacamole.AudioPlayer.html
new file mode 100644
index 0000000..32bc538
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/Guacamole.AudioPlayer.html
@@ -0,0 +1,734 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Class: AudioPlayer</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Class: AudioPlayer</h1>
+
+
+
+
+
+
+<section>
+
+<header>
+
+ <h2><span class="attribs"><span class="type-signature"></span></span>
+ <span class="ancestors"><a href="Guacamole.html">Guacamole</a>.</span>AudioPlayer<span class="signature">()</span><span class="type-signature"></span></h2>
+
+
+</header>
+
+<article>
+ <div class="container-overview">
+
+
+
+
+
+
+ <h4 class="name" id="AudioPlayer"><span class="type-signature"></span>new AudioPlayer<span class="signature">()</span><span class="type-signature"></span></h4>
+
+
+
+
+
+
+<div class="description">
+ Abstract audio player which accepts, queues and plays back arbitrary audio
+data. It is up to implementations of this class to provide some means of
+handling a provided Guacamole.InputStream. Data received along the provided
+stream is to be played back immediately.
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioPlayer.js.html">AudioPlayer.js</a>, <a href="AudioPlayer.js.html#line30">line 30</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h3 class="subsection-title">Methods</h3>
+
+
+
+
+
+
+
+ <h4 class="name" id=".getInstance"><span class="type-signature">(static) </span>getInstance<span class="signature">(stream, mimetype)</span><span class="type-signature"> → {<a href="Guacamole.AudioPlayer.html">Guacamole.AudioPlayer</a>}</span></h4>
+
+
+
+
+
+
+<div class="description">
+ Returns an instance of Guacamole.AudioPlayer providing support for the given
+audio format. If support for the given audio format is not available, null
+is returned.
+</div>
+
+
+
+
+
+
+
+
+
+ <h5>Parameters:</h5>
+
+
+<table class="params">
+ <thead>
+ <tr>
+
+ <th>Name</th>
+
+
+ <th>Type</th>
+
+
+
+
+
+ <th class="last">Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr>
+
+ <td class="name"><code>stream</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type"><a href="Guacamole.InputStream.html">Guacamole.InputStream</a></span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The Guacamole.InputStream to read audio data from.</td>
+ </tr>
+
+
+
+ <tr>
+
+ <td class="name"><code>mimetype</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type">String</span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The mimetype of the audio data in the provided stream.</td>
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioPlayer.js.html">AudioPlayer.js</a>, <a href="AudioPlayer.js.html#line97">line 97</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h5>Returns:</h5>
+
+
+<div class="param-desc">
+ A Guacamole.AudioPlayer instance supporting the given mimetype and
+ reading from the given stream, or null if support for the given mimetype
+ is absent.
+</div>
+
+
+
+<dl>
+ <dt>
+ Type
+ </dt>
+ <dd>
+
+<span class="param-type"><a href="Guacamole.AudioPlayer.html">Guacamole.AudioPlayer</a></span>
+
+
+ </dd>
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h4 class="name" id=".getSupportedTypes"><span class="type-signature">(static) </span>getSupportedTypes<span class="signature">()</span><span class="type-signature"> → {Array.<String>}</span></h4>
+
+
+
+
+
+
+<div class="description">
+ Returns a list of all mimetypes supported by any built-in
+Guacamole.AudioPlayer, in rough order of priority. Beware that only the core
+mimetypes themselves will be listed. Any mimetype parameters, even required
+ones, will not be included in the list. For example, "audio/L8" is a
+supported raw audio mimetype that is supported, but it is invalid without
+additional parameters. Something like "audio/L8;rate=44100" would be valid,
+however (see https://tools.ietf.org/html/rfc4856).
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioPlayer.js.html">AudioPlayer.js</a>, <a href="AudioPlayer.js.html#line75">line 75</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h5>Returns:</h5>
+
+
+<div class="param-desc">
+ A list of all mimetypes supported by any built-in Guacamole.AudioPlayer,
+ excluding any parameters.
+</div>
+
+
+
+<dl>
+ <dt>
+ Type
+ </dt>
+ <dd>
+
+<span class="param-type">Array.<String></span>
+
+
+ </dd>
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h4 class="name" id=".isSupportedType"><span class="type-signature">(static) </span>isSupportedType<span class="signature">(mimetype)</span><span class="type-signature"> → {Boolean}</span></h4>
+
+
+
+
+
+
+<div class="description">
+ Determines whether the given mimetype is supported by any built-in
+implementation of Guacamole.AudioPlayer, and thus will be properly handled
+by Guacamole.AudioPlayer.getInstance().
+</div>
+
+
+
+
+
+
+
+
+
+ <h5>Parameters:</h5>
+
+
+<table class="params">
+ <thead>
+ <tr>
+
+ <th>Name</th>
+
+
+ <th>Type</th>
+
+
+
+
+
+ <th class="last">Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr>
+
+ <td class="name"><code>mimetype</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type">String</span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The mimetype to check.</td>
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioPlayer.js.html">AudioPlayer.js</a>, <a href="AudioPlayer.js.html#line56">line 56</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h5>Returns:</h5>
+
+
+<div class="param-desc">
+ true if the given mimetype is supported by any built-in
+ Guacamole.AudioPlayer, false otherwise.
+</div>
+
+
+
+<dl>
+ <dt>
+ Type
+ </dt>
+ <dd>
+
+<span class="param-type">Boolean</span>
+
+
+ </dd>
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h4 class="name" id="sync"><span class="type-signature"></span>sync<span class="signature">()</span><span class="type-signature"></span></h4>
+
+
+
+
+
+
+<div class="description">
+ Notifies this Guacamole.AudioPlayer that all audio up to the current
+point in time has been given via the underlying stream, and that any
+difference in time between queued audio data and the current time can be
+considered latency.
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioPlayer.js.html">AudioPlayer.js</a>, <a href="AudioPlayer.js.html#line38">line 38</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</article>
+
+</section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/content/doc/1.1.0/guacamole-common-js/Guacamole.AudioRecorder.html b/content/doc/1.1.0/guacamole-common-js/Guacamole.AudioRecorder.html
new file mode 100644
index 0000000..667c264
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/Guacamole.AudioRecorder.html
@@ -0,0 +1,828 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Class: AudioRecorder</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Class: AudioRecorder</h1>
+
+
+
+
+
+
+<section>
+
+<header>
+
+ <h2><span class="attribs"><span class="type-signature"></span></span>
+ <span class="ancestors"><a href="Guacamole.html">Guacamole</a>.</span>AudioRecorder<span class="signature">()</span><span class="type-signature"></span></h2>
+
+
+</header>
+
+<article>
+ <div class="container-overview">
+
+
+
+
+
+
+ <h4 class="name" id="AudioRecorder"><span class="type-signature"></span>new AudioRecorder<span class="signature">()</span><span class="type-signature"></span></h4>
+
+
+
+
+
+
+<div class="description">
+ Abstract audio recorder which streams arbitrary audio data to an underlying
+Guacamole.OutputStream. It is up to implementations of this class to provide
+some means of handling this Guacamole.OutputStream. Data produced by the
+recorder is to be sent along the provided stream immediately.
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioRecorder.js.html">AudioRecorder.js</a>, <a href="AudioRecorder.js.html#line30">line 30</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h3 class="subsection-title">Methods</h3>
+
+
+
+
+
+
+
+ <h4 class="name" id=".getInstance"><span class="type-signature">(static) </span>getInstance<span class="signature">(stream, mimetype)</span><span class="type-signature"> → {<a href="Guacamole.AudioRecorder.html">Guacamole.AudioRecorder</a>}</span></h4>
+
+
+
+
+
+
+<div class="description">
+ Returns an instance of Guacamole.AudioRecorder providing support for the
+given audio format. If support for the given audio format is not available,
+null is returned.
+</div>
+
+
+
+
+
+
+
+
+
+ <h5>Parameters:</h5>
+
+
+<table class="params">
+ <thead>
+ <tr>
+
+ <th>Name</th>
+
+
+ <th>Type</th>
+
+
+
+
+
+ <th class="last">Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr>
+
+ <td class="name"><code>stream</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type"><a href="Guacamole.OutputStream.html">Guacamole.OutputStream</a></span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The Guacamole.OutputStream to send audio data through.</td>
+ </tr>
+
+
+
+ <tr>
+
+ <td class="name"><code>mimetype</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type">String</span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The mimetype of the audio data to be sent along the provided stream.</td>
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioRecorder.js.html">AudioRecorder.js</a>, <a href="AudioRecorder.js.html#line108">line 108</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h5>Returns:</h5>
+
+
+<div class="param-desc">
+ A Guacamole.AudioRecorder instance supporting the given mimetype and
+ writing to the given stream, or null if support for the given mimetype
+ is absent.
+</div>
+
+
+
+<dl>
+ <dt>
+ Type
+ </dt>
+ <dd>
+
+<span class="param-type"><a href="Guacamole.AudioRecorder.html">Guacamole.AudioRecorder</a></span>
+
+
+ </dd>
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h4 class="name" id=".getSupportedTypes"><span class="type-signature">(static) </span>getSupportedTypes<span class="signature">()</span><span class="type-signature"> → {Array.<String>}</span></h4>
+
+
+
+
+
+
+<div class="description">
+ Returns a list of all mimetypes supported by any built-in
+Guacamole.AudioRecorder, in rough order of priority. Beware that only the
+core mimetypes themselves will be listed. Any mimetype parameters, even
+required ones, will not be included in the list. For example, "audio/L8" is
+a supported raw audio mimetype that is supported, but it is invalid without
+additional parameters. Something like "audio/L8;rate=44100" would be valid,
+however (see https://tools.ietf.org/html/rfc4856).
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioRecorder.js.html">AudioRecorder.js</a>, <a href="AudioRecorder.js.html#line86">line 86</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h5>Returns:</h5>
+
+
+<div class="param-desc">
+ A list of all mimetypes supported by any built-in
+ Guacamole.AudioRecorder, excluding any parameters.
+</div>
+
+
+
+<dl>
+ <dt>
+ Type
+ </dt>
+ <dd>
+
+<span class="param-type">Array.<String></span>
+
+
+ </dd>
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h4 class="name" id=".isSupportedType"><span class="type-signature">(static) </span>isSupportedType<span class="signature">(mimetype)</span><span class="type-signature"> → {Boolean}</span></h4>
+
+
+
+
+
+
+<div class="description">
+ Determines whether the given mimetype is supported by any built-in
+implementation of Guacamole.AudioRecorder, and thus will be properly handled
+by Guacamole.AudioRecorder.getInstance().
+</div>
+
+
+
+
+
+
+
+
+
+ <h5>Parameters:</h5>
+
+
+<table class="params">
+ <thead>
+ <tr>
+
+ <th>Name</th>
+
+
+ <th>Type</th>
+
+
+
+
+
+ <th class="last">Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr>
+
+ <td class="name"><code>mimetype</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type">String</span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The mimetype to check.</td>
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioRecorder.js.html">AudioRecorder.js</a>, <a href="AudioRecorder.js.html#line67">line 67</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h5>Returns:</h5>
+
+
+<div class="param-desc">
+ true if the given mimetype is supported by any built-in
+ Guacamole.AudioRecorder, false otherwise.
+</div>
+
+
+
+<dl>
+ <dt>
+ Type
+ </dt>
+ <dd>
+
+<span class="param-type">Boolean</span>
+
+
+ </dd>
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h3 class="subsection-title">Events</h3>
+
+
+
+
+
+
+
+ <h4 class="name" id="event:onclose">onclose</h4>
+
+
+
+
+
+
+<div class="description">
+ Callback which is invoked when the audio recording process has stopped
+and the underlying Guacamole stream has been closed normally. Audio will
+only resume recording if a new Guacamole.AudioRecorder is started. This
+Guacamole.AudioRecorder instance MAY NOT be reused.
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioRecorder.js.html">AudioRecorder.js</a>, <a href="AudioRecorder.js.html#line40">line 40</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h4 class="name" id="event:onerror">onerror</h4>
+
+
+
+
+
+
+<div class="description">
+ Callback which is invoked when the audio recording process cannot
+continue due to an error, if it has started at all. The underlying
+Guacamole stream is automatically closed. Future attempts to record
+audio should not be made, and this Guacamole.AudioRecorder instance
+MAY NOT be reused.
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="AudioRecorder.js.html">AudioRecorder.js</a>, <a href="AudioRecorder.js.html#line51">line 51</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</article>
+
+</section>
+
+
+
+
+</div>
+
+<nav>
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.htm [...]
+</nav>
+
+<br class="clear">
+
+<footer>
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sun Jan 26 2020 10:17:42 GMT-0800 (PST)
+</footer>
+
+<script> prettyPrint(); </script>
+<script src="scripts/linenumber.js"> </script>
+ <!-- Google Analytics -->
+ <script type="text/javascript">
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-75289145-1', 'auto');
+ ga('send', 'pageview');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/content/doc/1.1.0/guacamole-common-js/Guacamole.BlobReader.html b/content/doc/1.1.0/guacamole-common-js/Guacamole.BlobReader.html
new file mode 100644
index 0000000..8bff3b1
--- /dev/null
+++ b/content/doc/1.1.0/guacamole-common-js/Guacamole.BlobReader.html
@@ -0,0 +1,700 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>JSDoc: Class: BlobReader</title>
+
+ <script src="scripts/prettify/prettify.js"> </script>
+ <script src="scripts/prettify/lang-css.js"> </script>
+ <!--[if lt IE 9]>
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
+ <![endif]-->
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
+</head>
+
+<body>
+
+<div id="main">
+
+ <h1 class="page-title">Class: BlobReader</h1>
+
+
+
+
+
+
+<section>
+
+<header>
+
+ <h2><span class="attribs"><span class="type-signature"></span></span>
+ <span class="ancestors"><a href="Guacamole.html">Guacamole</a>.</span>BlobReader<span class="signature">(stream, mimetype)</span><span class="type-signature"></span></h2>
+
+
+</header>
+
+<article>
+ <div class="container-overview">
+
+
+
+
+
+
+ <h4 class="name" id="BlobReader"><span class="type-signature"></span>new BlobReader<span class="signature">(stream, mimetype)</span><span class="type-signature"></span></h4>
+
+
+
+
+
+
+<div class="description">
+ A reader which automatically handles the given input stream, assembling all
+received blobs into a single blob by appending them to each other in order.
+Note that this object will overwrite any installed event handlers on the
+given Guacamole.InputStream.
+</div>
+
+
+
+
+
+
+
+
+
+ <h5>Parameters:</h5>
+
+
+<table class="params">
+ <thead>
+ <tr>
+
+ <th>Name</th>
+
+
+ <th>Type</th>
+
+
+
+
+
+ <th class="last">Description</th>
+ </tr>
+ </thead>
+
+ <tbody>
+
+
+ <tr>
+
+ <td class="name"><code>stream</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type"><a href="Guacamole.InputStream.html">Guacamole.InputStream</a></span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The stream that data will be read
+ from.</td>
+ </tr>
+
+
+
+ <tr>
+
+ <td class="name"><code>mimetype</code></td>
+
+
+ <td class="type">
+
+
+<span class="param-type">String</span>
+
+
+
+ </td>
+
+
+
+
+
+ <td class="description last">The mimetype of the blob being built.</td>
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="BlobReader.js.html">BlobReader.js</a>, <a href="BlobReader.js.html#line33">line 33</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ </div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h3 class="subsection-title">Methods</h3>
+
+
+
+
+
+
+
+ <h4 class="name" id="getBlob"><span class="type-signature"></span>getBlob<span class="signature">()</span><span class="type-signature"> → {Blob}</span></h4>
+
+
+
+
+
+
+<div class="description">
+ Returns the contents of this Guacamole.BlobReader as a Blob.
+</div>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<dl class="details">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <dt class="tag-source">Source:</dt>
+ <dd class="tag-source"><ul class="dummy"><li>
+ <a href="BlobReader.js.html">BlobReader.js</a>, <a href="BlobReader.js.html#line110">line 110</a>
+ </li></ul></dd>
+
+
+
+
+
+
+
+</dl>
+
+
+
+
+
+
+
+
+
+
... 251243 lines suppressed ...