From 5d4b557e22e59655ee51cf5d5f84142f5df5647f Mon Sep 17 00:00:00 2001 From: open-trade Date: Mon, 17 Jan 2022 15:45:42 +0800 Subject: [PATCH 01/66] init --- .gitattributes | 1 + .gitignore | 5 ++ favicon.svg | 15 ++++ index.html | 13 +++ package.json | 13 +++ src/main.ts | 8 ++ src/style.css | 8 ++ src/vite-env.d.ts | 1 + tsconfig.json | 18 +++++ yarn.lock | 202 ++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 284 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 favicon.svg create mode 100644 index.html create mode 100644 package.json create mode 100644 src/main.ts create mode 100644 src/style.css create mode 100644 src/vite-env.d.ts create mode 100644 tsconfig.json create mode 100644 yarn.lock diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..176a458f9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..53f7466ac --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local \ No newline at end of file diff --git a/favicon.svg b/favicon.svg new file mode 100644 index 000000000..de4aeddc1 --- /dev/null +++ b/favicon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/index.html b/index.html new file mode 100644 index 000000000..867581c51 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite App + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 000000000..ec6b7fac4 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "web_hbb", + "version": "1.0.0", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "typescript": "^4.4.4", + "vite": "^2.7.2" + } +} diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 000000000..f77db7a8f --- /dev/null +++ b/src/main.ts @@ -0,0 +1,8 @@ +import './style.css' + +const app = document.querySelector('#app')! + +app.innerHTML = ` +

Hello Vite!

+ Documentation +` diff --git a/src/style.css b/src/style.css new file mode 100644 index 000000000..852de7aa2 --- /dev/null +++ b/src/style.css @@ -0,0 +1,8 @@ +#app { + font-family: Avenir, Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-align: center; + color: #2c3e50; + margin-top: 60px; +} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..8cdbb2ac9 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ESNext", "DOM"], + "moduleResolution": "Node", + "strict": true, + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "noEmit": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true + }, + "include": ["./src"] +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..2cfb703a5 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,202 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +esbuild-android-arm64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz#3fc3ff0bab76fe35dd237476b5d2b32bb20a3d44" + integrity sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg== + +esbuild-darwin-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz#8e9169c16baf444eacec60d09b24d11b255a8e72" + integrity sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ== + +esbuild-darwin-arm64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz#1b07f893b632114f805e188ddfca41b2b778229a" + integrity sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ== + +esbuild-freebsd-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz#0b8b7eca1690c8ec94c75680c38c07269c1f4a85" + integrity sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA== + +esbuild-freebsd-arm64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz#2e1a6c696bfdcd20a99578b76350b41db1934e52" + integrity sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ== + +esbuild-linux-32@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz#6fd39f36fc66dd45b6b5f515728c7bbebc342a69" + integrity sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g== + +esbuild-linux-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz#9cb8e4bcd7574e67946e4ee5f1f1e12386bb6dd3" + integrity sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA== + +esbuild-linux-arm64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz#3891aa3704ec579a1b92d2a586122e5b6a2bfba1" + integrity sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA== + +esbuild-linux-arm@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz#8a00e99e6a0c6c9a6b7f334841364d8a2b4aecfe" + integrity sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA== + +esbuild-linux-mips64le@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz#36b07cc47c3d21e48db3bb1f4d9ef8f46aead4f7" + integrity sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg== + +esbuild-linux-ppc64le@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz#f7e6bba40b9a11eb9dcae5b01550ea04670edad2" + integrity sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ== + +esbuild-netbsd-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz#a2fedc549c2b629d580a732d840712b08d440038" + integrity sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w== + +esbuild-openbsd-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz#b22c0e5806d3a1fbf0325872037f885306b05cd7" + integrity sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g== + +esbuild-sunos-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz#d0b6454a88375ee8d3964daeff55c85c91c7cef4" + integrity sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw== + +esbuild-windows-32@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz#c96d0b9bbb52f3303322582ef8e4847c5ad375a7" + integrity sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw== + +esbuild-windows-64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz#1f79cb9b1e1bb02fb25cd414cb90d4ea2892c294" + integrity sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ== + +esbuild-windows-arm64@0.13.15: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz#482173070810df22a752c686509c370c3be3b3c3" + integrity sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA== + +esbuild@^0.13.12: + version "0.13.15" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.13.15.tgz#db56a88166ee373f87dbb2d8798ff449e0450cdf" + integrity sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw== + optionalDependencies: + esbuild-android-arm64 "0.13.15" + esbuild-darwin-64 "0.13.15" + esbuild-darwin-arm64 "0.13.15" + esbuild-freebsd-64 "0.13.15" + esbuild-freebsd-arm64 "0.13.15" + esbuild-linux-32 "0.13.15" + esbuild-linux-64 "0.13.15" + esbuild-linux-arm "0.13.15" + esbuild-linux-arm64 "0.13.15" + esbuild-linux-mips64le "0.13.15" + esbuild-linux-ppc64le "0.13.15" + esbuild-netbsd-64 "0.13.15" + esbuild-openbsd-64 "0.13.15" + esbuild-sunos-64 "0.13.15" + esbuild-windows-32 "0.13.15" + esbuild-windows-64 "0.13.15" + esbuild-windows-arm64 "0.13.15" + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +is-core-module@^2.8.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + +nanoid@^3.1.30: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +postcss@^8.4.5: + version "8.4.5" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" + integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== + dependencies: + nanoid "^3.1.30" + picocolors "^1.0.0" + source-map-js "^1.0.1" + +resolve@^1.20.0: + version "1.21.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f" + integrity sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA== + dependencies: + is-core-module "^2.8.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +rollup@^2.59.0: + version "2.64.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.64.0.tgz#f0f59774e21fbb56de438a37d06a2189632b207a" + integrity sha512-+c+lbw1lexBKSMb1yxGDVfJ+vchJH3qLbmavR+awDinTDA2C5Ug9u7lkOzj62SCu0PKUExsW36tpgW7Fmpn3yQ== + optionalDependencies: + fsevents "~2.3.2" + +source-map-js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" + integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +typescript@^4.4.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" + integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== + +vite@^2.7.2: + version "2.7.12" + resolved "https://registry.yarnpkg.com/vite/-/vite-2.7.12.tgz#7784ab19e7ff98f6a192d2d7d877480a8c2b7e7d" + integrity sha512-KvPYToRQWhRfBeVkyhkZ5hASuHQkqZUUdUcE3xyYtq5oYEPIJ0h9LWiWTO6v990glmSac2cEPeYeXzpX5Z6qKQ== + dependencies: + esbuild "^0.13.12" + postcss "^8.4.5" + resolve "^1.20.0" + rollup "^2.59.0" + optionalDependencies: + fsevents "~2.3.2" From 8168745965e5566cfd1ae31eb7e9cdbf5050744d Mon Sep 17 00:00:00 2001 From: open-trade Date: Mon, 17 Jan 2022 17:51:18 +0800 Subject: [PATCH 02/66] protobuf --- package.json | 3 + src/message.ts | 4969 +++++++++++++++++++++++++++++++++++++++++++++ src/rendezvous.ts | 2252 ++++++++++++++++++++ ts_proto.py | 20 + yarn.lock | 140 ++ 5 files changed, 7384 insertions(+) create mode 100644 src/message.ts create mode 100644 src/rendezvous.ts create mode 100644 ts_proto.py diff --git a/package.json b/package.json index ec6b7fac4..abe5dd151 100644 --- a/package.json +++ b/package.json @@ -9,5 +9,8 @@ "devDependencies": { "typescript": "^4.4.4", "vite": "^2.7.2" + }, + "dependencies": { + "ts-proto": "^1.101.0" } } diff --git a/src/message.ts b/src/message.ts new file mode 100644 index 000000000..9c0532dec --- /dev/null +++ b/src/message.ts @@ -0,0 +1,4969 @@ +/* eslint-disable */ +import { util, configure, Writer, Reader } from "protobufjs/minimal"; +import * as Long from "long"; + +export const protobufPackage = "hbb"; + +export enum ControlKey { + Unknown = 0, + Alt = 1, + Backspace = 2, + CapsLock = 3, + Control = 4, + Delete = 5, + DownArrow = 6, + End = 7, + Escape = 8, + F1 = 9, + F10 = 10, + F11 = 11, + F12 = 12, + F2 = 13, + F3 = 14, + F4 = 15, + F5 = 16, + F6 = 17, + F7 = 18, + F8 = 19, + F9 = 20, + Home = 21, + LeftArrow = 22, + /** Meta - / meta key (also known as "windows"; "super"; and "command") */ + Meta = 23, + /** Option - / option key on macOS (alt key on Linux and Windows) */ + Option = 24, + PageDown = 25, + PageUp = 26, + Return = 27, + RightArrow = 28, + Shift = 29, + Space = 30, + Tab = 31, + UpArrow = 32, + Numpad0 = 33, + Numpad1 = 34, + Numpad2 = 35, + Numpad3 = 36, + Numpad4 = 37, + Numpad5 = 38, + Numpad6 = 39, + Numpad7 = 40, + Numpad8 = 41, + Numpad9 = 42, + Cancel = 43, + Clear = 44, + /** Menu - deprecated, use Alt instead */ + Menu = 45, + Pause = 46, + Kana = 47, + Hangul = 48, + Junja = 49, + Final = 50, + Hanja = 51, + Kanji = 52, + Convert = 53, + Select = 54, + Print = 55, + Execute = 56, + Snapshot = 57, + Insert = 58, + Help = 59, + Sleep = 60, + Separator = 61, + Scroll = 62, + NumLock = 63, + RWin = 64, + Apps = 65, + Multiply = 66, + Add = 67, + Subtract = 68, + Decimal = 69, + Divide = 70, + Equals = 71, + NumpadEnter = 72, + RShift = 73, + RControl = 74, + RAlt = 75, + CtrlAltDel = 100, + LockScreen = 101, + UNRECOGNIZED = -1, +} + +export function controlKeyFromJSON(object: any): ControlKey { + switch (object) { + case 0: + case "Unknown": + return ControlKey.Unknown; + case 1: + case "Alt": + return ControlKey.Alt; + case 2: + case "Backspace": + return ControlKey.Backspace; + case 3: + case "CapsLock": + return ControlKey.CapsLock; + case 4: + case "Control": + return ControlKey.Control; + case 5: + case "Delete": + return ControlKey.Delete; + case 6: + case "DownArrow": + return ControlKey.DownArrow; + case 7: + case "End": + return ControlKey.End; + case 8: + case "Escape": + return ControlKey.Escape; + case 9: + case "F1": + return ControlKey.F1; + case 10: + case "F10": + return ControlKey.F10; + case 11: + case "F11": + return ControlKey.F11; + case 12: + case "F12": + return ControlKey.F12; + case 13: + case "F2": + return ControlKey.F2; + case 14: + case "F3": + return ControlKey.F3; + case 15: + case "F4": + return ControlKey.F4; + case 16: + case "F5": + return ControlKey.F5; + case 17: + case "F6": + return ControlKey.F6; + case 18: + case "F7": + return ControlKey.F7; + case 19: + case "F8": + return ControlKey.F8; + case 20: + case "F9": + return ControlKey.F9; + case 21: + case "Home": + return ControlKey.Home; + case 22: + case "LeftArrow": + return ControlKey.LeftArrow; + case 23: + case "Meta": + return ControlKey.Meta; + case 24: + case "Option": + return ControlKey.Option; + case 25: + case "PageDown": + return ControlKey.PageDown; + case 26: + case "PageUp": + return ControlKey.PageUp; + case 27: + case "Return": + return ControlKey.Return; + case 28: + case "RightArrow": + return ControlKey.RightArrow; + case 29: + case "Shift": + return ControlKey.Shift; + case 30: + case "Space": + return ControlKey.Space; + case 31: + case "Tab": + return ControlKey.Tab; + case 32: + case "UpArrow": + return ControlKey.UpArrow; + case 33: + case "Numpad0": + return ControlKey.Numpad0; + case 34: + case "Numpad1": + return ControlKey.Numpad1; + case 35: + case "Numpad2": + return ControlKey.Numpad2; + case 36: + case "Numpad3": + return ControlKey.Numpad3; + case 37: + case "Numpad4": + return ControlKey.Numpad4; + case 38: + case "Numpad5": + return ControlKey.Numpad5; + case 39: + case "Numpad6": + return ControlKey.Numpad6; + case 40: + case "Numpad7": + return ControlKey.Numpad7; + case 41: + case "Numpad8": + return ControlKey.Numpad8; + case 42: + case "Numpad9": + return ControlKey.Numpad9; + case 43: + case "Cancel": + return ControlKey.Cancel; + case 44: + case "Clear": + return ControlKey.Clear; + case 45: + case "Menu": + return ControlKey.Menu; + case 46: + case "Pause": + return ControlKey.Pause; + case 47: + case "Kana": + return ControlKey.Kana; + case 48: + case "Hangul": + return ControlKey.Hangul; + case 49: + case "Junja": + return ControlKey.Junja; + case 50: + case "Final": + return ControlKey.Final; + case 51: + case "Hanja": + return ControlKey.Hanja; + case 52: + case "Kanji": + return ControlKey.Kanji; + case 53: + case "Convert": + return ControlKey.Convert; + case 54: + case "Select": + return ControlKey.Select; + case 55: + case "Print": + return ControlKey.Print; + case 56: + case "Execute": + return ControlKey.Execute; + case 57: + case "Snapshot": + return ControlKey.Snapshot; + case 58: + case "Insert": + return ControlKey.Insert; + case 59: + case "Help": + return ControlKey.Help; + case 60: + case "Sleep": + return ControlKey.Sleep; + case 61: + case "Separator": + return ControlKey.Separator; + case 62: + case "Scroll": + return ControlKey.Scroll; + case 63: + case "NumLock": + return ControlKey.NumLock; + case 64: + case "RWin": + return ControlKey.RWin; + case 65: + case "Apps": + return ControlKey.Apps; + case 66: + case "Multiply": + return ControlKey.Multiply; + case 67: + case "Add": + return ControlKey.Add; + case 68: + case "Subtract": + return ControlKey.Subtract; + case 69: + case "Decimal": + return ControlKey.Decimal; + case 70: + case "Divide": + return ControlKey.Divide; + case 71: + case "Equals": + return ControlKey.Equals; + case 72: + case "NumpadEnter": + return ControlKey.NumpadEnter; + case 73: + case "RShift": + return ControlKey.RShift; + case 74: + case "RControl": + return ControlKey.RControl; + case 75: + case "RAlt": + return ControlKey.RAlt; + case 100: + case "CtrlAltDel": + return ControlKey.CtrlAltDel; + case 101: + case "LockScreen": + return ControlKey.LockScreen; + case -1: + case "UNRECOGNIZED": + default: + return ControlKey.UNRECOGNIZED; + } +} + +export function controlKeyToJSON(object: ControlKey): string { + switch (object) { + case ControlKey.Unknown: + return "Unknown"; + case ControlKey.Alt: + return "Alt"; + case ControlKey.Backspace: + return "Backspace"; + case ControlKey.CapsLock: + return "CapsLock"; + case ControlKey.Control: + return "Control"; + case ControlKey.Delete: + return "Delete"; + case ControlKey.DownArrow: + return "DownArrow"; + case ControlKey.End: + return "End"; + case ControlKey.Escape: + return "Escape"; + case ControlKey.F1: + return "F1"; + case ControlKey.F10: + return "F10"; + case ControlKey.F11: + return "F11"; + case ControlKey.F12: + return "F12"; + case ControlKey.F2: + return "F2"; + case ControlKey.F3: + return "F3"; + case ControlKey.F4: + return "F4"; + case ControlKey.F5: + return "F5"; + case ControlKey.F6: + return "F6"; + case ControlKey.F7: + return "F7"; + case ControlKey.F8: + return "F8"; + case ControlKey.F9: + return "F9"; + case ControlKey.Home: + return "Home"; + case ControlKey.LeftArrow: + return "LeftArrow"; + case ControlKey.Meta: + return "Meta"; + case ControlKey.Option: + return "Option"; + case ControlKey.PageDown: + return "PageDown"; + case ControlKey.PageUp: + return "PageUp"; + case ControlKey.Return: + return "Return"; + case ControlKey.RightArrow: + return "RightArrow"; + case ControlKey.Shift: + return "Shift"; + case ControlKey.Space: + return "Space"; + case ControlKey.Tab: + return "Tab"; + case ControlKey.UpArrow: + return "UpArrow"; + case ControlKey.Numpad0: + return "Numpad0"; + case ControlKey.Numpad1: + return "Numpad1"; + case ControlKey.Numpad2: + return "Numpad2"; + case ControlKey.Numpad3: + return "Numpad3"; + case ControlKey.Numpad4: + return "Numpad4"; + case ControlKey.Numpad5: + return "Numpad5"; + case ControlKey.Numpad6: + return "Numpad6"; + case ControlKey.Numpad7: + return "Numpad7"; + case ControlKey.Numpad8: + return "Numpad8"; + case ControlKey.Numpad9: + return "Numpad9"; + case ControlKey.Cancel: + return "Cancel"; + case ControlKey.Clear: + return "Clear"; + case ControlKey.Menu: + return "Menu"; + case ControlKey.Pause: + return "Pause"; + case ControlKey.Kana: + return "Kana"; + case ControlKey.Hangul: + return "Hangul"; + case ControlKey.Junja: + return "Junja"; + case ControlKey.Final: + return "Final"; + case ControlKey.Hanja: + return "Hanja"; + case ControlKey.Kanji: + return "Kanji"; + case ControlKey.Convert: + return "Convert"; + case ControlKey.Select: + return "Select"; + case ControlKey.Print: + return "Print"; + case ControlKey.Execute: + return "Execute"; + case ControlKey.Snapshot: + return "Snapshot"; + case ControlKey.Insert: + return "Insert"; + case ControlKey.Help: + return "Help"; + case ControlKey.Sleep: + return "Sleep"; + case ControlKey.Separator: + return "Separator"; + case ControlKey.Scroll: + return "Scroll"; + case ControlKey.NumLock: + return "NumLock"; + case ControlKey.RWin: + return "RWin"; + case ControlKey.Apps: + return "Apps"; + case ControlKey.Multiply: + return "Multiply"; + case ControlKey.Add: + return "Add"; + case ControlKey.Subtract: + return "Subtract"; + case ControlKey.Decimal: + return "Decimal"; + case ControlKey.Divide: + return "Divide"; + case ControlKey.Equals: + return "Equals"; + case ControlKey.NumpadEnter: + return "NumpadEnter"; + case ControlKey.RShift: + return "RShift"; + case ControlKey.RControl: + return "RControl"; + case ControlKey.RAlt: + return "RAlt"; + case ControlKey.CtrlAltDel: + return "CtrlAltDel"; + case ControlKey.LockScreen: + return "LockScreen"; + default: + return "UNKNOWN"; + } +} + +export enum FileType { + UnknownFileType = 0, + Dir = 1, + DirLink = 2, + DirDrive = 3, + File = 4, + FileLink = 5, + UNRECOGNIZED = -1, +} + +export function fileTypeFromJSON(object: any): FileType { + switch (object) { + case 0: + case "UnknownFileType": + return FileType.UnknownFileType; + case 1: + case "Dir": + return FileType.Dir; + case 2: + case "DirLink": + return FileType.DirLink; + case 3: + case "DirDrive": + return FileType.DirDrive; + case 4: + case "File": + return FileType.File; + case 5: + case "FileLink": + return FileType.FileLink; + case -1: + case "UNRECOGNIZED": + default: + return FileType.UNRECOGNIZED; + } +} + +export function fileTypeToJSON(object: FileType): string { + switch (object) { + case FileType.UnknownFileType: + return "UnknownFileType"; + case FileType.Dir: + return "Dir"; + case FileType.DirLink: + return "DirLink"; + case FileType.DirDrive: + return "DirDrive"; + case FileType.File: + return "File"; + case FileType.FileLink: + return "FileLink"; + default: + return "UNKNOWN"; + } +} + +export enum ImageQuality { + NotSet = 0, + Low = 2, + Balanced = 3, + Best = 4, + UNRECOGNIZED = -1, +} + +export function imageQualityFromJSON(object: any): ImageQuality { + switch (object) { + case 0: + case "NotSet": + return ImageQuality.NotSet; + case 2: + case "Low": + return ImageQuality.Low; + case 3: + case "Balanced": + return ImageQuality.Balanced; + case 4: + case "Best": + return ImageQuality.Best; + case -1: + case "UNRECOGNIZED": + default: + return ImageQuality.UNRECOGNIZED; + } +} + +export function imageQualityToJSON(object: ImageQuality): string { + switch (object) { + case ImageQuality.NotSet: + return "NotSet"; + case ImageQuality.Low: + return "Low"; + case ImageQuality.Balanced: + return "Balanced"; + case ImageQuality.Best: + return "Best"; + default: + return "UNKNOWN"; + } +} + +export interface VP9 { + data: Uint8Array; + key: boolean; + pts: number; +} + +export interface VP9s { + frames: VP9[]; +} + +export interface RGB { + compress: boolean; +} + +/** planes data send directly in binary for better use arraybuffer on web */ +export interface YUV { + compress: boolean; + stride: number; +} + +export interface VideoFrame { + vp9s: VP9s | undefined; + rgb: RGB | undefined; + yuv: YUV | undefined; +} + +export interface DisplayInfo { + x: number; + y: number; + width: number; + height: number; + name: string; + online: boolean; +} + +export interface PortForward { + host: string; + port: number; +} + +export interface FileTransfer { + dir: string; + showHidden: boolean; +} + +export interface LoginRequest { + username: string; + password: Uint8Array; + myId: string; + myName: string; + option: OptionMessage | undefined; + fileTransfer: FileTransfer | undefined; + portForward: PortForward | undefined; +} + +export interface ChatMessage { + text: string; +} + +export interface PeerInfo { + username: string; + hostname: string; + platform: string; + displays: DisplayInfo[]; + currentDisplay: number; + sasEnabled: boolean; + version: string; +} + +export interface LoginResponse { + error: string | undefined; + peerInfo: PeerInfo | undefined; +} + +export interface MouseEvent { + mask: number; + x: number; + y: number; + modifiers: ControlKey[]; +} + +export interface KeyEvent { + down: boolean; + press: boolean; + controlKey: ControlKey | undefined; + chr: number | undefined; + unicode: number | undefined; + seq: string | undefined; + modifiers: ControlKey[]; +} + +export interface CursorData { + id: number; + hotx: number; + hoty: number; + width: number; + height: number; + colors: Uint8Array; +} + +export interface CursorPosition { + x: number; + y: number; +} + +export interface Hash { + salt: string; + challenge: string; +} + +export interface Clipboard { + compress: boolean; + content: Uint8Array; +} + +export interface FileEntry { + entryType: FileType; + name: string; + isHidden: boolean; + size: number; + modifiedTime: number; +} + +export interface FileDirectory { + id: number; + path: string; + entries: FileEntry[]; +} + +export interface ReadDir { + path: string; + includeHidden: boolean; +} + +export interface ReadAllFiles { + id: number; + path: string; + includeHidden: boolean; +} + +export interface FileAction { + readDir: ReadDir | undefined; + send: FileTransferSendRequest | undefined; + receive: FileTransferReceiveRequest | undefined; + create: FileDirCreate | undefined; + removeDir: FileRemoveDir | undefined; + removeFile: FileRemoveFile | undefined; + allFiles: ReadAllFiles | undefined; + cancel: FileTransferCancel | undefined; +} + +export interface FileTransferCancel { + id: number; +} + +export interface FileResponse { + dir: FileDirectory | undefined; + block: FileTransferBlock | undefined; + error: FileTransferError | undefined; + done: FileTransferDone | undefined; +} + +export interface FileTransferBlock { + id: number; + fileNum: number; + data: Uint8Array; + compressed: boolean; +} + +export interface FileTransferError { + id: number; + error: string; + fileNum: number; +} + +export interface FileTransferSendRequest { + id: number; + path: string; + includeHidden: boolean; +} + +export interface FileTransferDone { + id: number; + fileNum: number; +} + +export interface FileTransferReceiveRequest { + id: number; + /** path written to */ + path: string; + files: FileEntry[]; +} + +export interface FileRemoveDir { + id: number; + path: string; + recursive: boolean; +} + +export interface FileRemoveFile { + id: number; + path: string; + fileNum: number; +} + +export interface FileDirCreate { + id: number; + path: string; +} + +export interface SwitchDisplay { + display: number; + x: number; + y: number; + width: number; + height: number; +} + +export interface PermissionInfo { + permission: PermissionInfo_Permission; + enabled: boolean; +} + +export enum PermissionInfo_Permission { + Unknown = 0, + Keyboard = 1, + Clipboard = 2, + Audio = 3, + UNRECOGNIZED = -1, +} + +export function permissionInfo_PermissionFromJSON( + object: any +): PermissionInfo_Permission { + switch (object) { + case 0: + case "Unknown": + return PermissionInfo_Permission.Unknown; + case 1: + case "Keyboard": + return PermissionInfo_Permission.Keyboard; + case 2: + case "Clipboard": + return PermissionInfo_Permission.Clipboard; + case 3: + case "Audio": + return PermissionInfo_Permission.Audio; + case -1: + case "UNRECOGNIZED": + default: + return PermissionInfo_Permission.UNRECOGNIZED; + } +} + +export function permissionInfo_PermissionToJSON( + object: PermissionInfo_Permission +): string { + switch (object) { + case PermissionInfo_Permission.Unknown: + return "Unknown"; + case PermissionInfo_Permission.Keyboard: + return "Keyboard"; + case PermissionInfo_Permission.Clipboard: + return "Clipboard"; + case PermissionInfo_Permission.Audio: + return "Audio"; + default: + return "UNKNOWN"; + } +} + +export interface OptionMessage { + imageQuality: ImageQuality; + lockAfterSessionEnd: OptionMessage_BoolOption; + showRemoteCursor: OptionMessage_BoolOption; + privacyMode: OptionMessage_BoolOption; + blockInput: OptionMessage_BoolOption; + customImageQuality: number; + disableAudio: OptionMessage_BoolOption; + disableClipboard: OptionMessage_BoolOption; +} + +export enum OptionMessage_BoolOption { + NotSet = 0, + No = 1, + Yes = 2, + UNRECOGNIZED = -1, +} + +export function optionMessage_BoolOptionFromJSON( + object: any +): OptionMessage_BoolOption { + switch (object) { + case 0: + case "NotSet": + return OptionMessage_BoolOption.NotSet; + case 1: + case "No": + return OptionMessage_BoolOption.No; + case 2: + case "Yes": + return OptionMessage_BoolOption.Yes; + case -1: + case "UNRECOGNIZED": + default: + return OptionMessage_BoolOption.UNRECOGNIZED; + } +} + +export function optionMessage_BoolOptionToJSON( + object: OptionMessage_BoolOption +): string { + switch (object) { + case OptionMessage_BoolOption.NotSet: + return "NotSet"; + case OptionMessage_BoolOption.No: + return "No"; + case OptionMessage_BoolOption.Yes: + return "Yes"; + default: + return "UNKNOWN"; + } +} + +export interface OptionResponse { + opt: OptionMessage | undefined; + error: string; +} + +export interface TestDelay { + time: number; + fromClient: boolean; +} + +export interface PublicKey { + asymmetricValue: Uint8Array; + symmetricValue: Uint8Array; +} + +export interface SignedId { + id: Uint8Array; +} + +export interface AudioFormat { + sampleRate: number; + channels: number; +} + +export interface AudioFrame { + data: Uint8Array; +} + +export interface Misc { + chatMessage: ChatMessage | undefined; + switchDisplay: SwitchDisplay | undefined; + permissionInfo: PermissionInfo | undefined; + option: OptionMessage | undefined; + audioFormat: AudioFormat | undefined; + closeReason: string | undefined; + refreshVideo: boolean | undefined; + optionResponse: OptionResponse | undefined; +} + +export interface Message { + signedId: SignedId | undefined; + publicKey: PublicKey | undefined; + testDelay: TestDelay | undefined; + videoFrame: VideoFrame | undefined; + loginRequest: LoginRequest | undefined; + loginResponse: LoginResponse | undefined; + hash: Hash | undefined; + mouseEvent: MouseEvent | undefined; + audioFrame: AudioFrame | undefined; + cursorData: CursorData | undefined; + cursorPosition: CursorPosition | undefined; + cursorId: number | undefined; + keyEvent: KeyEvent | undefined; + clipboard: Clipboard | undefined; + fileAction: FileAction | undefined; + fileResponse: FileResponse | undefined; + misc: Misc | undefined; +} + +function createBaseVP9(): VP9 { + return { data: new Uint8Array(), key: false, pts: 0 }; +} + +export const VP9 = { + encode(message: VP9, writer: Writer = Writer.create()): Writer { + if (message.data.length !== 0) { + writer.uint32(10).bytes(message.data); + } + if (message.key === true) { + writer.uint32(16).bool(message.key); + } + if (message.pts !== 0) { + writer.uint32(24).int64(message.pts); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): VP9 { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVP9(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.data = reader.bytes(); + break; + case 2: + message.key = reader.bool(); + break; + case 3: + message.pts = longToNumber(reader.int64() as Long); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): VP9 { + return { + data: isSet(object.data) + ? bytesFromBase64(object.data) + : new Uint8Array(), + key: isSet(object.key) ? Boolean(object.key) : false, + pts: isSet(object.pts) ? Number(object.pts) : 0, + }; + }, + + toJSON(message: VP9): unknown { + const obj: any = {}; + message.data !== undefined && + (obj.data = base64FromBytes( + message.data !== undefined ? message.data : new Uint8Array() + )); + message.key !== undefined && (obj.key = message.key); + message.pts !== undefined && (obj.pts = Math.round(message.pts)); + return obj; + }, + + fromPartial, I>>(object: I): VP9 { + const message = createBaseVP9(); + message.data = object.data ?? new Uint8Array(); + message.key = object.key ?? false; + message.pts = object.pts ?? 0; + return message; + }, +}; + +function createBaseVP9s(): VP9s { + return { frames: [] }; +} + +export const VP9s = { + encode(message: VP9s, writer: Writer = Writer.create()): Writer { + for (const v of message.frames) { + VP9.encode(v!, writer.uint32(10).fork()).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): VP9s { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVP9s(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.frames.push(VP9.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): VP9s { + return { + frames: Array.isArray(object?.frames) + ? object.frames.map((e: any) => VP9.fromJSON(e)) + : [], + }; + }, + + toJSON(message: VP9s): unknown { + const obj: any = {}; + if (message.frames) { + obj.frames = message.frames.map((e) => (e ? VP9.toJSON(e) : undefined)); + } else { + obj.frames = []; + } + return obj; + }, + + fromPartial, I>>(object: I): VP9s { + const message = createBaseVP9s(); + message.frames = object.frames?.map((e) => VP9.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseRGB(): RGB { + return { compress: false }; +} + +export const RGB = { + encode(message: RGB, writer: Writer = Writer.create()): Writer { + if (message.compress === true) { + writer.uint32(8).bool(message.compress); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): RGB { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRGB(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.compress = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): RGB { + return { + compress: isSet(object.compress) ? Boolean(object.compress) : false, + }; + }, + + toJSON(message: RGB): unknown { + const obj: any = {}; + message.compress !== undefined && (obj.compress = message.compress); + return obj; + }, + + fromPartial, I>>(object: I): RGB { + const message = createBaseRGB(); + message.compress = object.compress ?? false; + return message; + }, +}; + +function createBaseYUV(): YUV { + return { compress: false, stride: 0 }; +} + +export const YUV = { + encode(message: YUV, writer: Writer = Writer.create()): Writer { + if (message.compress === true) { + writer.uint32(8).bool(message.compress); + } + if (message.stride !== 0) { + writer.uint32(16).int32(message.stride); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): YUV { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseYUV(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.compress = reader.bool(); + break; + case 2: + message.stride = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): YUV { + return { + compress: isSet(object.compress) ? Boolean(object.compress) : false, + stride: isSet(object.stride) ? Number(object.stride) : 0, + }; + }, + + toJSON(message: YUV): unknown { + const obj: any = {}; + message.compress !== undefined && (obj.compress = message.compress); + message.stride !== undefined && (obj.stride = Math.round(message.stride)); + return obj; + }, + + fromPartial, I>>(object: I): YUV { + const message = createBaseYUV(); + message.compress = object.compress ?? false; + message.stride = object.stride ?? 0; + return message; + }, +}; + +function createBaseVideoFrame(): VideoFrame { + return { vp9s: undefined, rgb: undefined, yuv: undefined }; +} + +export const VideoFrame = { + encode(message: VideoFrame, writer: Writer = Writer.create()): Writer { + if (message.vp9s !== undefined) { + VP9s.encode(message.vp9s, writer.uint32(50).fork()).ldelim(); + } + if (message.rgb !== undefined) { + RGB.encode(message.rgb, writer.uint32(58).fork()).ldelim(); + } + if (message.yuv !== undefined) { + YUV.encode(message.yuv, writer.uint32(66).fork()).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): VideoFrame { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVideoFrame(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 6: + message.vp9s = VP9s.decode(reader, reader.uint32()); + break; + case 7: + message.rgb = RGB.decode(reader, reader.uint32()); + break; + case 8: + message.yuv = YUV.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): VideoFrame { + return { + vp9s: isSet(object.vp9s) ? VP9s.fromJSON(object.vp9s) : undefined, + rgb: isSet(object.rgb) ? RGB.fromJSON(object.rgb) : undefined, + yuv: isSet(object.yuv) ? YUV.fromJSON(object.yuv) : undefined, + }; + }, + + toJSON(message: VideoFrame): unknown { + const obj: any = {}; + message.vp9s !== undefined && + (obj.vp9s = message.vp9s ? VP9s.toJSON(message.vp9s) : undefined); + message.rgb !== undefined && + (obj.rgb = message.rgb ? RGB.toJSON(message.rgb) : undefined); + message.yuv !== undefined && + (obj.yuv = message.yuv ? YUV.toJSON(message.yuv) : undefined); + return obj; + }, + + fromPartial, I>>( + object: I + ): VideoFrame { + const message = createBaseVideoFrame(); + message.vp9s = + object.vp9s !== undefined && object.vp9s !== null + ? VP9s.fromPartial(object.vp9s) + : undefined; + message.rgb = + object.rgb !== undefined && object.rgb !== null + ? RGB.fromPartial(object.rgb) + : undefined; + message.yuv = + object.yuv !== undefined && object.yuv !== null + ? YUV.fromPartial(object.yuv) + : undefined; + return message; + }, +}; + +function createBaseDisplayInfo(): DisplayInfo { + return { x: 0, y: 0, width: 0, height: 0, name: "", online: false }; +} + +export const DisplayInfo = { + encode(message: DisplayInfo, writer: Writer = Writer.create()): Writer { + if (message.x !== 0) { + writer.uint32(8).sint32(message.x); + } + if (message.y !== 0) { + writer.uint32(16).sint32(message.y); + } + if (message.width !== 0) { + writer.uint32(24).int32(message.width); + } + if (message.height !== 0) { + writer.uint32(32).int32(message.height); + } + if (message.name !== "") { + writer.uint32(42).string(message.name); + } + if (message.online === true) { + writer.uint32(48).bool(message.online); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): DisplayInfo { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDisplayInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.x = reader.sint32(); + break; + case 2: + message.y = reader.sint32(); + break; + case 3: + message.width = reader.int32(); + break; + case 4: + message.height = reader.int32(); + break; + case 5: + message.name = reader.string(); + break; + case 6: + message.online = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): DisplayInfo { + return { + x: isSet(object.x) ? Number(object.x) : 0, + y: isSet(object.y) ? Number(object.y) : 0, + width: isSet(object.width) ? Number(object.width) : 0, + height: isSet(object.height) ? Number(object.height) : 0, + name: isSet(object.name) ? String(object.name) : "", + online: isSet(object.online) ? Boolean(object.online) : false, + }; + }, + + toJSON(message: DisplayInfo): unknown { + const obj: any = {}; + message.x !== undefined && (obj.x = Math.round(message.x)); + message.y !== undefined && (obj.y = Math.round(message.y)); + message.width !== undefined && (obj.width = Math.round(message.width)); + message.height !== undefined && (obj.height = Math.round(message.height)); + message.name !== undefined && (obj.name = message.name); + message.online !== undefined && (obj.online = message.online); + return obj; + }, + + fromPartial, I>>( + object: I + ): DisplayInfo { + const message = createBaseDisplayInfo(); + message.x = object.x ?? 0; + message.y = object.y ?? 0; + message.width = object.width ?? 0; + message.height = object.height ?? 0; + message.name = object.name ?? ""; + message.online = object.online ?? false; + return message; + }, +}; + +function createBasePortForward(): PortForward { + return { host: "", port: 0 }; +} + +export const PortForward = { + encode(message: PortForward, writer: Writer = Writer.create()): Writer { + if (message.host !== "") { + writer.uint32(10).string(message.host); + } + if (message.port !== 0) { + writer.uint32(16).int32(message.port); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): PortForward { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePortForward(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.host = reader.string(); + break; + case 2: + message.port = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): PortForward { + return { + host: isSet(object.host) ? String(object.host) : "", + port: isSet(object.port) ? Number(object.port) : 0, + }; + }, + + toJSON(message: PortForward): unknown { + const obj: any = {}; + message.host !== undefined && (obj.host = message.host); + message.port !== undefined && (obj.port = Math.round(message.port)); + return obj; + }, + + fromPartial, I>>( + object: I + ): PortForward { + const message = createBasePortForward(); + message.host = object.host ?? ""; + message.port = object.port ?? 0; + return message; + }, +}; + +function createBaseFileTransfer(): FileTransfer { + return { dir: "", showHidden: false }; +} + +export const FileTransfer = { + encode(message: FileTransfer, writer: Writer = Writer.create()): Writer { + if (message.dir !== "") { + writer.uint32(10).string(message.dir); + } + if (message.showHidden === true) { + writer.uint32(16).bool(message.showHidden); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileTransfer { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileTransfer(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.dir = reader.string(); + break; + case 2: + message.showHidden = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileTransfer { + return { + dir: isSet(object.dir) ? String(object.dir) : "", + showHidden: isSet(object.showHidden) ? Boolean(object.showHidden) : false, + }; + }, + + toJSON(message: FileTransfer): unknown { + const obj: any = {}; + message.dir !== undefined && (obj.dir = message.dir); + message.showHidden !== undefined && (obj.showHidden = message.showHidden); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileTransfer { + const message = createBaseFileTransfer(); + message.dir = object.dir ?? ""; + message.showHidden = object.showHidden ?? false; + return message; + }, +}; + +function createBaseLoginRequest(): LoginRequest { + return { + username: "", + password: new Uint8Array(), + myId: "", + myName: "", + option: undefined, + fileTransfer: undefined, + portForward: undefined, + }; +} + +export const LoginRequest = { + encode(message: LoginRequest, writer: Writer = Writer.create()): Writer { + if (message.username !== "") { + writer.uint32(10).string(message.username); + } + if (message.password.length !== 0) { + writer.uint32(18).bytes(message.password); + } + if (message.myId !== "") { + writer.uint32(34).string(message.myId); + } + if (message.myName !== "") { + writer.uint32(42).string(message.myName); + } + if (message.option !== undefined) { + OptionMessage.encode(message.option, writer.uint32(50).fork()).ldelim(); + } + if (message.fileTransfer !== undefined) { + FileTransfer.encode( + message.fileTransfer, + writer.uint32(58).fork() + ).ldelim(); + } + if (message.portForward !== undefined) { + PortForward.encode( + message.portForward, + writer.uint32(66).fork() + ).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): LoginRequest { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLoginRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.username = reader.string(); + break; + case 2: + message.password = reader.bytes(); + break; + case 4: + message.myId = reader.string(); + break; + case 5: + message.myName = reader.string(); + break; + case 6: + message.option = OptionMessage.decode(reader, reader.uint32()); + break; + case 7: + message.fileTransfer = FileTransfer.decode(reader, reader.uint32()); + break; + case 8: + message.portForward = PortForward.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): LoginRequest { + return { + username: isSet(object.username) ? String(object.username) : "", + password: isSet(object.password) + ? bytesFromBase64(object.password) + : new Uint8Array(), + myId: isSet(object.myId) ? String(object.myId) : "", + myName: isSet(object.myName) ? String(object.myName) : "", + option: isSet(object.option) + ? OptionMessage.fromJSON(object.option) + : undefined, + fileTransfer: isSet(object.fileTransfer) + ? FileTransfer.fromJSON(object.fileTransfer) + : undefined, + portForward: isSet(object.portForward) + ? PortForward.fromJSON(object.portForward) + : undefined, + }; + }, + + toJSON(message: LoginRequest): unknown { + const obj: any = {}; + message.username !== undefined && (obj.username = message.username); + message.password !== undefined && + (obj.password = base64FromBytes( + message.password !== undefined ? message.password : new Uint8Array() + )); + message.myId !== undefined && (obj.myId = message.myId); + message.myName !== undefined && (obj.myName = message.myName); + message.option !== undefined && + (obj.option = message.option + ? OptionMessage.toJSON(message.option) + : undefined); + message.fileTransfer !== undefined && + (obj.fileTransfer = message.fileTransfer + ? FileTransfer.toJSON(message.fileTransfer) + : undefined); + message.portForward !== undefined && + (obj.portForward = message.portForward + ? PortForward.toJSON(message.portForward) + : undefined); + return obj; + }, + + fromPartial, I>>( + object: I + ): LoginRequest { + const message = createBaseLoginRequest(); + message.username = object.username ?? ""; + message.password = object.password ?? new Uint8Array(); + message.myId = object.myId ?? ""; + message.myName = object.myName ?? ""; + message.option = + object.option !== undefined && object.option !== null + ? OptionMessage.fromPartial(object.option) + : undefined; + message.fileTransfer = + object.fileTransfer !== undefined && object.fileTransfer !== null + ? FileTransfer.fromPartial(object.fileTransfer) + : undefined; + message.portForward = + object.portForward !== undefined && object.portForward !== null + ? PortForward.fromPartial(object.portForward) + : undefined; + return message; + }, +}; + +function createBaseChatMessage(): ChatMessage { + return { text: "" }; +} + +export const ChatMessage = { + encode(message: ChatMessage, writer: Writer = Writer.create()): Writer { + if (message.text !== "") { + writer.uint32(10).string(message.text); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): ChatMessage { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseChatMessage(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.text = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): ChatMessage { + return { + text: isSet(object.text) ? String(object.text) : "", + }; + }, + + toJSON(message: ChatMessage): unknown { + const obj: any = {}; + message.text !== undefined && (obj.text = message.text); + return obj; + }, + + fromPartial, I>>( + object: I + ): ChatMessage { + const message = createBaseChatMessage(); + message.text = object.text ?? ""; + return message; + }, +}; + +function createBasePeerInfo(): PeerInfo { + return { + username: "", + hostname: "", + platform: "", + displays: [], + currentDisplay: 0, + sasEnabled: false, + version: "", + }; +} + +export const PeerInfo = { + encode(message: PeerInfo, writer: Writer = Writer.create()): Writer { + if (message.username !== "") { + writer.uint32(10).string(message.username); + } + if (message.hostname !== "") { + writer.uint32(18).string(message.hostname); + } + if (message.platform !== "") { + writer.uint32(26).string(message.platform); + } + for (const v of message.displays) { + DisplayInfo.encode(v!, writer.uint32(34).fork()).ldelim(); + } + if (message.currentDisplay !== 0) { + writer.uint32(40).int32(message.currentDisplay); + } + if (message.sasEnabled === true) { + writer.uint32(48).bool(message.sasEnabled); + } + if (message.version !== "") { + writer.uint32(58).string(message.version); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): PeerInfo { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePeerInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.username = reader.string(); + break; + case 2: + message.hostname = reader.string(); + break; + case 3: + message.platform = reader.string(); + break; + case 4: + message.displays.push(DisplayInfo.decode(reader, reader.uint32())); + break; + case 5: + message.currentDisplay = reader.int32(); + break; + case 6: + message.sasEnabled = reader.bool(); + break; + case 7: + message.version = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): PeerInfo { + return { + username: isSet(object.username) ? String(object.username) : "", + hostname: isSet(object.hostname) ? String(object.hostname) : "", + platform: isSet(object.platform) ? String(object.platform) : "", + displays: Array.isArray(object?.displays) + ? object.displays.map((e: any) => DisplayInfo.fromJSON(e)) + : [], + currentDisplay: isSet(object.currentDisplay) + ? Number(object.currentDisplay) + : 0, + sasEnabled: isSet(object.sasEnabled) ? Boolean(object.sasEnabled) : false, + version: isSet(object.version) ? String(object.version) : "", + }; + }, + + toJSON(message: PeerInfo): unknown { + const obj: any = {}; + message.username !== undefined && (obj.username = message.username); + message.hostname !== undefined && (obj.hostname = message.hostname); + message.platform !== undefined && (obj.platform = message.platform); + if (message.displays) { + obj.displays = message.displays.map((e) => + e ? DisplayInfo.toJSON(e) : undefined + ); + } else { + obj.displays = []; + } + message.currentDisplay !== undefined && + (obj.currentDisplay = Math.round(message.currentDisplay)); + message.sasEnabled !== undefined && (obj.sasEnabled = message.sasEnabled); + message.version !== undefined && (obj.version = message.version); + return obj; + }, + + fromPartial, I>>(object: I): PeerInfo { + const message = createBasePeerInfo(); + message.username = object.username ?? ""; + message.hostname = object.hostname ?? ""; + message.platform = object.platform ?? ""; + message.displays = + object.displays?.map((e) => DisplayInfo.fromPartial(e)) || []; + message.currentDisplay = object.currentDisplay ?? 0; + message.sasEnabled = object.sasEnabled ?? false; + message.version = object.version ?? ""; + return message; + }, +}; + +function createBaseLoginResponse(): LoginResponse { + return { error: undefined, peerInfo: undefined }; +} + +export const LoginResponse = { + encode(message: LoginResponse, writer: Writer = Writer.create()): Writer { + if (message.error !== undefined) { + writer.uint32(10).string(message.error); + } + if (message.peerInfo !== undefined) { + PeerInfo.encode(message.peerInfo, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): LoginResponse { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLoginResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.error = reader.string(); + break; + case 2: + message.peerInfo = PeerInfo.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): LoginResponse { + return { + error: isSet(object.error) ? String(object.error) : undefined, + peerInfo: isSet(object.peerInfo) + ? PeerInfo.fromJSON(object.peerInfo) + : undefined, + }; + }, + + toJSON(message: LoginResponse): unknown { + const obj: any = {}; + message.error !== undefined && (obj.error = message.error); + message.peerInfo !== undefined && + (obj.peerInfo = message.peerInfo + ? PeerInfo.toJSON(message.peerInfo) + : undefined); + return obj; + }, + + fromPartial, I>>( + object: I + ): LoginResponse { + const message = createBaseLoginResponse(); + message.error = object.error ?? undefined; + message.peerInfo = + object.peerInfo !== undefined && object.peerInfo !== null + ? PeerInfo.fromPartial(object.peerInfo) + : undefined; + return message; + }, +}; + +function createBaseMouseEvent(): MouseEvent { + return { mask: 0, x: 0, y: 0, modifiers: [] }; +} + +export const MouseEvent = { + encode(message: MouseEvent, writer: Writer = Writer.create()): Writer { + if (message.mask !== 0) { + writer.uint32(8).int32(message.mask); + } + if (message.x !== 0) { + writer.uint32(16).sint32(message.x); + } + if (message.y !== 0) { + writer.uint32(24).sint32(message.y); + } + writer.uint32(34).fork(); + for (const v of message.modifiers) { + writer.int32(v); + } + writer.ldelim(); + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): MouseEvent { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMouseEvent(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.mask = reader.int32(); + break; + case 2: + message.x = reader.sint32(); + break; + case 3: + message.y = reader.sint32(); + break; + case 4: + if ((tag & 7) === 2) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.modifiers.push(reader.int32() as any); + } + } else { + message.modifiers.push(reader.int32() as any); + } + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): MouseEvent { + return { + mask: isSet(object.mask) ? Number(object.mask) : 0, + x: isSet(object.x) ? Number(object.x) : 0, + y: isSet(object.y) ? Number(object.y) : 0, + modifiers: Array.isArray(object?.modifiers) + ? object.modifiers.map((e: any) => controlKeyFromJSON(e)) + : [], + }; + }, + + toJSON(message: MouseEvent): unknown { + const obj: any = {}; + message.mask !== undefined && (obj.mask = Math.round(message.mask)); + message.x !== undefined && (obj.x = Math.round(message.x)); + message.y !== undefined && (obj.y = Math.round(message.y)); + if (message.modifiers) { + obj.modifiers = message.modifiers.map((e) => controlKeyToJSON(e)); + } else { + obj.modifiers = []; + } + return obj; + }, + + fromPartial, I>>( + object: I + ): MouseEvent { + const message = createBaseMouseEvent(); + message.mask = object.mask ?? 0; + message.x = object.x ?? 0; + message.y = object.y ?? 0; + message.modifiers = object.modifiers?.map((e) => e) || []; + return message; + }, +}; + +function createBaseKeyEvent(): KeyEvent { + return { + down: false, + press: false, + controlKey: undefined, + chr: undefined, + unicode: undefined, + seq: undefined, + modifiers: [], + }; +} + +export const KeyEvent = { + encode(message: KeyEvent, writer: Writer = Writer.create()): Writer { + if (message.down === true) { + writer.uint32(8).bool(message.down); + } + if (message.press === true) { + writer.uint32(16).bool(message.press); + } + if (message.controlKey !== undefined) { + writer.uint32(24).int32(message.controlKey); + } + if (message.chr !== undefined) { + writer.uint32(32).uint32(message.chr); + } + if (message.unicode !== undefined) { + writer.uint32(40).uint32(message.unicode); + } + if (message.seq !== undefined) { + writer.uint32(50).string(message.seq); + } + writer.uint32(66).fork(); + for (const v of message.modifiers) { + writer.int32(v); + } + writer.ldelim(); + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): KeyEvent { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseKeyEvent(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.down = reader.bool(); + break; + case 2: + message.press = reader.bool(); + break; + case 3: + message.controlKey = reader.int32() as any; + break; + case 4: + message.chr = reader.uint32(); + break; + case 5: + message.unicode = reader.uint32(); + break; + case 6: + message.seq = reader.string(); + break; + case 8: + if ((tag & 7) === 2) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.modifiers.push(reader.int32() as any); + } + } else { + message.modifiers.push(reader.int32() as any); + } + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): KeyEvent { + return { + down: isSet(object.down) ? Boolean(object.down) : false, + press: isSet(object.press) ? Boolean(object.press) : false, + controlKey: isSet(object.controlKey) + ? controlKeyFromJSON(object.controlKey) + : undefined, + chr: isSet(object.chr) ? Number(object.chr) : undefined, + unicode: isSet(object.unicode) ? Number(object.unicode) : undefined, + seq: isSet(object.seq) ? String(object.seq) : undefined, + modifiers: Array.isArray(object?.modifiers) + ? object.modifiers.map((e: any) => controlKeyFromJSON(e)) + : [], + }; + }, + + toJSON(message: KeyEvent): unknown { + const obj: any = {}; + message.down !== undefined && (obj.down = message.down); + message.press !== undefined && (obj.press = message.press); + message.controlKey !== undefined && + (obj.controlKey = + message.controlKey !== undefined + ? controlKeyToJSON(message.controlKey) + : undefined); + message.chr !== undefined && (obj.chr = Math.round(message.chr)); + message.unicode !== undefined && + (obj.unicode = Math.round(message.unicode)); + message.seq !== undefined && (obj.seq = message.seq); + if (message.modifiers) { + obj.modifiers = message.modifiers.map((e) => controlKeyToJSON(e)); + } else { + obj.modifiers = []; + } + return obj; + }, + + fromPartial, I>>(object: I): KeyEvent { + const message = createBaseKeyEvent(); + message.down = object.down ?? false; + message.press = object.press ?? false; + message.controlKey = object.controlKey ?? undefined; + message.chr = object.chr ?? undefined; + message.unicode = object.unicode ?? undefined; + message.seq = object.seq ?? undefined; + message.modifiers = object.modifiers?.map((e) => e) || []; + return message; + }, +}; + +function createBaseCursorData(): CursorData { + return { + id: 0, + hotx: 0, + hoty: 0, + width: 0, + height: 0, + colors: new Uint8Array(), + }; +} + +export const CursorData = { + encode(message: CursorData, writer: Writer = Writer.create()): Writer { + if (message.id !== 0) { + writer.uint32(8).uint64(message.id); + } + if (message.hotx !== 0) { + writer.uint32(16).sint32(message.hotx); + } + if (message.hoty !== 0) { + writer.uint32(24).sint32(message.hoty); + } + if (message.width !== 0) { + writer.uint32(32).int32(message.width); + } + if (message.height !== 0) { + writer.uint32(40).int32(message.height); + } + if (message.colors.length !== 0) { + writer.uint32(50).bytes(message.colors); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): CursorData { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCursorData(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = longToNumber(reader.uint64() as Long); + break; + case 2: + message.hotx = reader.sint32(); + break; + case 3: + message.hoty = reader.sint32(); + break; + case 4: + message.width = reader.int32(); + break; + case 5: + message.height = reader.int32(); + break; + case 6: + message.colors = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): CursorData { + return { + id: isSet(object.id) ? Number(object.id) : 0, + hotx: isSet(object.hotx) ? Number(object.hotx) : 0, + hoty: isSet(object.hoty) ? Number(object.hoty) : 0, + width: isSet(object.width) ? Number(object.width) : 0, + height: isSet(object.height) ? Number(object.height) : 0, + colors: isSet(object.colors) + ? bytesFromBase64(object.colors) + : new Uint8Array(), + }; + }, + + toJSON(message: CursorData): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.hotx !== undefined && (obj.hotx = Math.round(message.hotx)); + message.hoty !== undefined && (obj.hoty = Math.round(message.hoty)); + message.width !== undefined && (obj.width = Math.round(message.width)); + message.height !== undefined && (obj.height = Math.round(message.height)); + message.colors !== undefined && + (obj.colors = base64FromBytes( + message.colors !== undefined ? message.colors : new Uint8Array() + )); + return obj; + }, + + fromPartial, I>>( + object: I + ): CursorData { + const message = createBaseCursorData(); + message.id = object.id ?? 0; + message.hotx = object.hotx ?? 0; + message.hoty = object.hoty ?? 0; + message.width = object.width ?? 0; + message.height = object.height ?? 0; + message.colors = object.colors ?? new Uint8Array(); + return message; + }, +}; + +function createBaseCursorPosition(): CursorPosition { + return { x: 0, y: 0 }; +} + +export const CursorPosition = { + encode(message: CursorPosition, writer: Writer = Writer.create()): Writer { + if (message.x !== 0) { + writer.uint32(8).sint32(message.x); + } + if (message.y !== 0) { + writer.uint32(16).sint32(message.y); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): CursorPosition { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCursorPosition(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.x = reader.sint32(); + break; + case 2: + message.y = reader.sint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): CursorPosition { + return { + x: isSet(object.x) ? Number(object.x) : 0, + y: isSet(object.y) ? Number(object.y) : 0, + }; + }, + + toJSON(message: CursorPosition): unknown { + const obj: any = {}; + message.x !== undefined && (obj.x = Math.round(message.x)); + message.y !== undefined && (obj.y = Math.round(message.y)); + return obj; + }, + + fromPartial, I>>( + object: I + ): CursorPosition { + const message = createBaseCursorPosition(); + message.x = object.x ?? 0; + message.y = object.y ?? 0; + return message; + }, +}; + +function createBaseHash(): Hash { + return { salt: "", challenge: "" }; +} + +export const Hash = { + encode(message: Hash, writer: Writer = Writer.create()): Writer { + if (message.salt !== "") { + writer.uint32(10).string(message.salt); + } + if (message.challenge !== "") { + writer.uint32(18).string(message.challenge); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): Hash { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHash(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.salt = reader.string(); + break; + case 2: + message.challenge = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): Hash { + return { + salt: isSet(object.salt) ? String(object.salt) : "", + challenge: isSet(object.challenge) ? String(object.challenge) : "", + }; + }, + + toJSON(message: Hash): unknown { + const obj: any = {}; + message.salt !== undefined && (obj.salt = message.salt); + message.challenge !== undefined && (obj.challenge = message.challenge); + return obj; + }, + + fromPartial, I>>(object: I): Hash { + const message = createBaseHash(); + message.salt = object.salt ?? ""; + message.challenge = object.challenge ?? ""; + return message; + }, +}; + +function createBaseClipboard(): Clipboard { + return { compress: false, content: new Uint8Array() }; +} + +export const Clipboard = { + encode(message: Clipboard, writer: Writer = Writer.create()): Writer { + if (message.compress === true) { + writer.uint32(8).bool(message.compress); + } + if (message.content.length !== 0) { + writer.uint32(18).bytes(message.content); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): Clipboard { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseClipboard(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.compress = reader.bool(); + break; + case 2: + message.content = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): Clipboard { + return { + compress: isSet(object.compress) ? Boolean(object.compress) : false, + content: isSet(object.content) + ? bytesFromBase64(object.content) + : new Uint8Array(), + }; + }, + + toJSON(message: Clipboard): unknown { + const obj: any = {}; + message.compress !== undefined && (obj.compress = message.compress); + message.content !== undefined && + (obj.content = base64FromBytes( + message.content !== undefined ? message.content : new Uint8Array() + )); + return obj; + }, + + fromPartial, I>>( + object: I + ): Clipboard { + const message = createBaseClipboard(); + message.compress = object.compress ?? false; + message.content = object.content ?? new Uint8Array(); + return message; + }, +}; + +function createBaseFileEntry(): FileEntry { + return { entryType: 0, name: "", isHidden: false, size: 0, modifiedTime: 0 }; +} + +export const FileEntry = { + encode(message: FileEntry, writer: Writer = Writer.create()): Writer { + if (message.entryType !== 0) { + writer.uint32(8).int32(message.entryType); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.isHidden === true) { + writer.uint32(24).bool(message.isHidden); + } + if (message.size !== 0) { + writer.uint32(32).uint64(message.size); + } + if (message.modifiedTime !== 0) { + writer.uint32(40).uint64(message.modifiedTime); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileEntry { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileEntry(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.entryType = reader.int32() as any; + break; + case 2: + message.name = reader.string(); + break; + case 3: + message.isHidden = reader.bool(); + break; + case 4: + message.size = longToNumber(reader.uint64() as Long); + break; + case 5: + message.modifiedTime = longToNumber(reader.uint64() as Long); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileEntry { + return { + entryType: isSet(object.entryType) + ? fileTypeFromJSON(object.entryType) + : 0, + name: isSet(object.name) ? String(object.name) : "", + isHidden: isSet(object.isHidden) ? Boolean(object.isHidden) : false, + size: isSet(object.size) ? Number(object.size) : 0, + modifiedTime: isSet(object.modifiedTime) + ? Number(object.modifiedTime) + : 0, + }; + }, + + toJSON(message: FileEntry): unknown { + const obj: any = {}; + message.entryType !== undefined && + (obj.entryType = fileTypeToJSON(message.entryType)); + message.name !== undefined && (obj.name = message.name); + message.isHidden !== undefined && (obj.isHidden = message.isHidden); + message.size !== undefined && (obj.size = Math.round(message.size)); + message.modifiedTime !== undefined && + (obj.modifiedTime = Math.round(message.modifiedTime)); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileEntry { + const message = createBaseFileEntry(); + message.entryType = object.entryType ?? 0; + message.name = object.name ?? ""; + message.isHidden = object.isHidden ?? false; + message.size = object.size ?? 0; + message.modifiedTime = object.modifiedTime ?? 0; + return message; + }, +}; + +function createBaseFileDirectory(): FileDirectory { + return { id: 0, path: "", entries: [] }; +} + +export const FileDirectory = { + encode(message: FileDirectory, writer: Writer = Writer.create()): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + if (message.path !== "") { + writer.uint32(18).string(message.path); + } + for (const v of message.entries) { + FileEntry.encode(v!, writer.uint32(26).fork()).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileDirectory { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileDirectory(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + case 2: + message.path = reader.string(); + break; + case 3: + message.entries.push(FileEntry.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileDirectory { + return { + id: isSet(object.id) ? Number(object.id) : 0, + path: isSet(object.path) ? String(object.path) : "", + entries: Array.isArray(object?.entries) + ? object.entries.map((e: any) => FileEntry.fromJSON(e)) + : [], + }; + }, + + toJSON(message: FileDirectory): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.path !== undefined && (obj.path = message.path); + if (message.entries) { + obj.entries = message.entries.map((e) => + e ? FileEntry.toJSON(e) : undefined + ); + } else { + obj.entries = []; + } + return obj; + }, + + fromPartial, I>>( + object: I + ): FileDirectory { + const message = createBaseFileDirectory(); + message.id = object.id ?? 0; + message.path = object.path ?? ""; + message.entries = + object.entries?.map((e) => FileEntry.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseReadDir(): ReadDir { + return { path: "", includeHidden: false }; +} + +export const ReadDir = { + encode(message: ReadDir, writer: Writer = Writer.create()): Writer { + if (message.path !== "") { + writer.uint32(10).string(message.path); + } + if (message.includeHidden === true) { + writer.uint32(16).bool(message.includeHidden); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): ReadDir { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseReadDir(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.path = reader.string(); + break; + case 2: + message.includeHidden = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): ReadDir { + return { + path: isSet(object.path) ? String(object.path) : "", + includeHidden: isSet(object.includeHidden) + ? Boolean(object.includeHidden) + : false, + }; + }, + + toJSON(message: ReadDir): unknown { + const obj: any = {}; + message.path !== undefined && (obj.path = message.path); + message.includeHidden !== undefined && + (obj.includeHidden = message.includeHidden); + return obj; + }, + + fromPartial, I>>(object: I): ReadDir { + const message = createBaseReadDir(); + message.path = object.path ?? ""; + message.includeHidden = object.includeHidden ?? false; + return message; + }, +}; + +function createBaseReadAllFiles(): ReadAllFiles { + return { id: 0, path: "", includeHidden: false }; +} + +export const ReadAllFiles = { + encode(message: ReadAllFiles, writer: Writer = Writer.create()): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + if (message.path !== "") { + writer.uint32(18).string(message.path); + } + if (message.includeHidden === true) { + writer.uint32(24).bool(message.includeHidden); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): ReadAllFiles { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseReadAllFiles(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + case 2: + message.path = reader.string(); + break; + case 3: + message.includeHidden = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): ReadAllFiles { + return { + id: isSet(object.id) ? Number(object.id) : 0, + path: isSet(object.path) ? String(object.path) : "", + includeHidden: isSet(object.includeHidden) + ? Boolean(object.includeHidden) + : false, + }; + }, + + toJSON(message: ReadAllFiles): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.path !== undefined && (obj.path = message.path); + message.includeHidden !== undefined && + (obj.includeHidden = message.includeHidden); + return obj; + }, + + fromPartial, I>>( + object: I + ): ReadAllFiles { + const message = createBaseReadAllFiles(); + message.id = object.id ?? 0; + message.path = object.path ?? ""; + message.includeHidden = object.includeHidden ?? false; + return message; + }, +}; + +function createBaseFileAction(): FileAction { + return { + readDir: undefined, + send: undefined, + receive: undefined, + create: undefined, + removeDir: undefined, + removeFile: undefined, + allFiles: undefined, + cancel: undefined, + }; +} + +export const FileAction = { + encode(message: FileAction, writer: Writer = Writer.create()): Writer { + if (message.readDir !== undefined) { + ReadDir.encode(message.readDir, writer.uint32(10).fork()).ldelim(); + } + if (message.send !== undefined) { + FileTransferSendRequest.encode( + message.send, + writer.uint32(18).fork() + ).ldelim(); + } + if (message.receive !== undefined) { + FileTransferReceiveRequest.encode( + message.receive, + writer.uint32(26).fork() + ).ldelim(); + } + if (message.create !== undefined) { + FileDirCreate.encode(message.create, writer.uint32(34).fork()).ldelim(); + } + if (message.removeDir !== undefined) { + FileRemoveDir.encode( + message.removeDir, + writer.uint32(42).fork() + ).ldelim(); + } + if (message.removeFile !== undefined) { + FileRemoveFile.encode( + message.removeFile, + writer.uint32(50).fork() + ).ldelim(); + } + if (message.allFiles !== undefined) { + ReadAllFiles.encode(message.allFiles, writer.uint32(58).fork()).ldelim(); + } + if (message.cancel !== undefined) { + FileTransferCancel.encode( + message.cancel, + writer.uint32(66).fork() + ).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileAction { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileAction(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.readDir = ReadDir.decode(reader, reader.uint32()); + break; + case 2: + message.send = FileTransferSendRequest.decode( + reader, + reader.uint32() + ); + break; + case 3: + message.receive = FileTransferReceiveRequest.decode( + reader, + reader.uint32() + ); + break; + case 4: + message.create = FileDirCreate.decode(reader, reader.uint32()); + break; + case 5: + message.removeDir = FileRemoveDir.decode(reader, reader.uint32()); + break; + case 6: + message.removeFile = FileRemoveFile.decode(reader, reader.uint32()); + break; + case 7: + message.allFiles = ReadAllFiles.decode(reader, reader.uint32()); + break; + case 8: + message.cancel = FileTransferCancel.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileAction { + return { + readDir: isSet(object.readDir) + ? ReadDir.fromJSON(object.readDir) + : undefined, + send: isSet(object.send) + ? FileTransferSendRequest.fromJSON(object.send) + : undefined, + receive: isSet(object.receive) + ? FileTransferReceiveRequest.fromJSON(object.receive) + : undefined, + create: isSet(object.create) + ? FileDirCreate.fromJSON(object.create) + : undefined, + removeDir: isSet(object.removeDir) + ? FileRemoveDir.fromJSON(object.removeDir) + : undefined, + removeFile: isSet(object.removeFile) + ? FileRemoveFile.fromJSON(object.removeFile) + : undefined, + allFiles: isSet(object.allFiles) + ? ReadAllFiles.fromJSON(object.allFiles) + : undefined, + cancel: isSet(object.cancel) + ? FileTransferCancel.fromJSON(object.cancel) + : undefined, + }; + }, + + toJSON(message: FileAction): unknown { + const obj: any = {}; + message.readDir !== undefined && + (obj.readDir = message.readDir + ? ReadDir.toJSON(message.readDir) + : undefined); + message.send !== undefined && + (obj.send = message.send + ? FileTransferSendRequest.toJSON(message.send) + : undefined); + message.receive !== undefined && + (obj.receive = message.receive + ? FileTransferReceiveRequest.toJSON(message.receive) + : undefined); + message.create !== undefined && + (obj.create = message.create + ? FileDirCreate.toJSON(message.create) + : undefined); + message.removeDir !== undefined && + (obj.removeDir = message.removeDir + ? FileRemoveDir.toJSON(message.removeDir) + : undefined); + message.removeFile !== undefined && + (obj.removeFile = message.removeFile + ? FileRemoveFile.toJSON(message.removeFile) + : undefined); + message.allFiles !== undefined && + (obj.allFiles = message.allFiles + ? ReadAllFiles.toJSON(message.allFiles) + : undefined); + message.cancel !== undefined && + (obj.cancel = message.cancel + ? FileTransferCancel.toJSON(message.cancel) + : undefined); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileAction { + const message = createBaseFileAction(); + message.readDir = + object.readDir !== undefined && object.readDir !== null + ? ReadDir.fromPartial(object.readDir) + : undefined; + message.send = + object.send !== undefined && object.send !== null + ? FileTransferSendRequest.fromPartial(object.send) + : undefined; + message.receive = + object.receive !== undefined && object.receive !== null + ? FileTransferReceiveRequest.fromPartial(object.receive) + : undefined; + message.create = + object.create !== undefined && object.create !== null + ? FileDirCreate.fromPartial(object.create) + : undefined; + message.removeDir = + object.removeDir !== undefined && object.removeDir !== null + ? FileRemoveDir.fromPartial(object.removeDir) + : undefined; + message.removeFile = + object.removeFile !== undefined && object.removeFile !== null + ? FileRemoveFile.fromPartial(object.removeFile) + : undefined; + message.allFiles = + object.allFiles !== undefined && object.allFiles !== null + ? ReadAllFiles.fromPartial(object.allFiles) + : undefined; + message.cancel = + object.cancel !== undefined && object.cancel !== null + ? FileTransferCancel.fromPartial(object.cancel) + : undefined; + return message; + }, +}; + +function createBaseFileTransferCancel(): FileTransferCancel { + return { id: 0 }; +} + +export const FileTransferCancel = { + encode( + message: FileTransferCancel, + writer: Writer = Writer.create() + ): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileTransferCancel { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileTransferCancel(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileTransferCancel { + return { + id: isSet(object.id) ? Number(object.id) : 0, + }; + }, + + toJSON(message: FileTransferCancel): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileTransferCancel { + const message = createBaseFileTransferCancel(); + message.id = object.id ?? 0; + return message; + }, +}; + +function createBaseFileResponse(): FileResponse { + return { + dir: undefined, + block: undefined, + error: undefined, + done: undefined, + }; +} + +export const FileResponse = { + encode(message: FileResponse, writer: Writer = Writer.create()): Writer { + if (message.dir !== undefined) { + FileDirectory.encode(message.dir, writer.uint32(10).fork()).ldelim(); + } + if (message.block !== undefined) { + FileTransferBlock.encode( + message.block, + writer.uint32(18).fork() + ).ldelim(); + } + if (message.error !== undefined) { + FileTransferError.encode( + message.error, + writer.uint32(26).fork() + ).ldelim(); + } + if (message.done !== undefined) { + FileTransferDone.encode(message.done, writer.uint32(34).fork()).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileResponse { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.dir = FileDirectory.decode(reader, reader.uint32()); + break; + case 2: + message.block = FileTransferBlock.decode(reader, reader.uint32()); + break; + case 3: + message.error = FileTransferError.decode(reader, reader.uint32()); + break; + case 4: + message.done = FileTransferDone.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileResponse { + return { + dir: isSet(object.dir) ? FileDirectory.fromJSON(object.dir) : undefined, + block: isSet(object.block) + ? FileTransferBlock.fromJSON(object.block) + : undefined, + error: isSet(object.error) + ? FileTransferError.fromJSON(object.error) + : undefined, + done: isSet(object.done) + ? FileTransferDone.fromJSON(object.done) + : undefined, + }; + }, + + toJSON(message: FileResponse): unknown { + const obj: any = {}; + message.dir !== undefined && + (obj.dir = message.dir ? FileDirectory.toJSON(message.dir) : undefined); + message.block !== undefined && + (obj.block = message.block + ? FileTransferBlock.toJSON(message.block) + : undefined); + message.error !== undefined && + (obj.error = message.error + ? FileTransferError.toJSON(message.error) + : undefined); + message.done !== undefined && + (obj.done = message.done + ? FileTransferDone.toJSON(message.done) + : undefined); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileResponse { + const message = createBaseFileResponse(); + message.dir = + object.dir !== undefined && object.dir !== null + ? FileDirectory.fromPartial(object.dir) + : undefined; + message.block = + object.block !== undefined && object.block !== null + ? FileTransferBlock.fromPartial(object.block) + : undefined; + message.error = + object.error !== undefined && object.error !== null + ? FileTransferError.fromPartial(object.error) + : undefined; + message.done = + object.done !== undefined && object.done !== null + ? FileTransferDone.fromPartial(object.done) + : undefined; + return message; + }, +}; + +function createBaseFileTransferBlock(): FileTransferBlock { + return { id: 0, fileNum: 0, data: new Uint8Array(), compressed: false }; +} + +export const FileTransferBlock = { + encode(message: FileTransferBlock, writer: Writer = Writer.create()): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + if (message.fileNum !== 0) { + writer.uint32(16).sint32(message.fileNum); + } + if (message.data.length !== 0) { + writer.uint32(26).bytes(message.data); + } + if (message.compressed === true) { + writer.uint32(32).bool(message.compressed); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileTransferBlock { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileTransferBlock(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + case 2: + message.fileNum = reader.sint32(); + break; + case 3: + message.data = reader.bytes(); + break; + case 4: + message.compressed = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileTransferBlock { + return { + id: isSet(object.id) ? Number(object.id) : 0, + fileNum: isSet(object.fileNum) ? Number(object.fileNum) : 0, + data: isSet(object.data) + ? bytesFromBase64(object.data) + : new Uint8Array(), + compressed: isSet(object.compressed) ? Boolean(object.compressed) : false, + }; + }, + + toJSON(message: FileTransferBlock): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.fileNum !== undefined && + (obj.fileNum = Math.round(message.fileNum)); + message.data !== undefined && + (obj.data = base64FromBytes( + message.data !== undefined ? message.data : new Uint8Array() + )); + message.compressed !== undefined && (obj.compressed = message.compressed); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileTransferBlock { + const message = createBaseFileTransferBlock(); + message.id = object.id ?? 0; + message.fileNum = object.fileNum ?? 0; + message.data = object.data ?? new Uint8Array(); + message.compressed = object.compressed ?? false; + return message; + }, +}; + +function createBaseFileTransferError(): FileTransferError { + return { id: 0, error: "", fileNum: 0 }; +} + +export const FileTransferError = { + encode(message: FileTransferError, writer: Writer = Writer.create()): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + if (message.error !== "") { + writer.uint32(18).string(message.error); + } + if (message.fileNum !== 0) { + writer.uint32(24).sint32(message.fileNum); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileTransferError { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileTransferError(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + case 2: + message.error = reader.string(); + break; + case 3: + message.fileNum = reader.sint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileTransferError { + return { + id: isSet(object.id) ? Number(object.id) : 0, + error: isSet(object.error) ? String(object.error) : "", + fileNum: isSet(object.fileNum) ? Number(object.fileNum) : 0, + }; + }, + + toJSON(message: FileTransferError): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.error !== undefined && (obj.error = message.error); + message.fileNum !== undefined && + (obj.fileNum = Math.round(message.fileNum)); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileTransferError { + const message = createBaseFileTransferError(); + message.id = object.id ?? 0; + message.error = object.error ?? ""; + message.fileNum = object.fileNum ?? 0; + return message; + }, +}; + +function createBaseFileTransferSendRequest(): FileTransferSendRequest { + return { id: 0, path: "", includeHidden: false }; +} + +export const FileTransferSendRequest = { + encode( + message: FileTransferSendRequest, + writer: Writer = Writer.create() + ): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + if (message.path !== "") { + writer.uint32(18).string(message.path); + } + if (message.includeHidden === true) { + writer.uint32(24).bool(message.includeHidden); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileTransferSendRequest { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileTransferSendRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + case 2: + message.path = reader.string(); + break; + case 3: + message.includeHidden = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileTransferSendRequest { + return { + id: isSet(object.id) ? Number(object.id) : 0, + path: isSet(object.path) ? String(object.path) : "", + includeHidden: isSet(object.includeHidden) + ? Boolean(object.includeHidden) + : false, + }; + }, + + toJSON(message: FileTransferSendRequest): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.path !== undefined && (obj.path = message.path); + message.includeHidden !== undefined && + (obj.includeHidden = message.includeHidden); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileTransferSendRequest { + const message = createBaseFileTransferSendRequest(); + message.id = object.id ?? 0; + message.path = object.path ?? ""; + message.includeHidden = object.includeHidden ?? false; + return message; + }, +}; + +function createBaseFileTransferDone(): FileTransferDone { + return { id: 0, fileNum: 0 }; +} + +export const FileTransferDone = { + encode(message: FileTransferDone, writer: Writer = Writer.create()): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + if (message.fileNum !== 0) { + writer.uint32(16).sint32(message.fileNum); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileTransferDone { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileTransferDone(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + case 2: + message.fileNum = reader.sint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileTransferDone { + return { + id: isSet(object.id) ? Number(object.id) : 0, + fileNum: isSet(object.fileNum) ? Number(object.fileNum) : 0, + }; + }, + + toJSON(message: FileTransferDone): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.fileNum !== undefined && + (obj.fileNum = Math.round(message.fileNum)); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileTransferDone { + const message = createBaseFileTransferDone(); + message.id = object.id ?? 0; + message.fileNum = object.fileNum ?? 0; + return message; + }, +}; + +function createBaseFileTransferReceiveRequest(): FileTransferReceiveRequest { + return { id: 0, path: "", files: [] }; +} + +export const FileTransferReceiveRequest = { + encode( + message: FileTransferReceiveRequest, + writer: Writer = Writer.create() + ): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + if (message.path !== "") { + writer.uint32(18).string(message.path); + } + for (const v of message.files) { + FileEntry.encode(v!, writer.uint32(26).fork()).ldelim(); + } + return writer; + }, + + decode( + input: Reader | Uint8Array, + length?: number + ): FileTransferReceiveRequest { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileTransferReceiveRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + case 2: + message.path = reader.string(); + break; + case 3: + message.files.push(FileEntry.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileTransferReceiveRequest { + return { + id: isSet(object.id) ? Number(object.id) : 0, + path: isSet(object.path) ? String(object.path) : "", + files: Array.isArray(object?.files) + ? object.files.map((e: any) => FileEntry.fromJSON(e)) + : [], + }; + }, + + toJSON(message: FileTransferReceiveRequest): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.path !== undefined && (obj.path = message.path); + if (message.files) { + obj.files = message.files.map((e) => + e ? FileEntry.toJSON(e) : undefined + ); + } else { + obj.files = []; + } + return obj; + }, + + fromPartial, I>>( + object: I + ): FileTransferReceiveRequest { + const message = createBaseFileTransferReceiveRequest(); + message.id = object.id ?? 0; + message.path = object.path ?? ""; + message.files = object.files?.map((e) => FileEntry.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseFileRemoveDir(): FileRemoveDir { + return { id: 0, path: "", recursive: false }; +} + +export const FileRemoveDir = { + encode(message: FileRemoveDir, writer: Writer = Writer.create()): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + if (message.path !== "") { + writer.uint32(18).string(message.path); + } + if (message.recursive === true) { + writer.uint32(24).bool(message.recursive); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileRemoveDir { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileRemoveDir(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + case 2: + message.path = reader.string(); + break; + case 3: + message.recursive = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileRemoveDir { + return { + id: isSet(object.id) ? Number(object.id) : 0, + path: isSet(object.path) ? String(object.path) : "", + recursive: isSet(object.recursive) ? Boolean(object.recursive) : false, + }; + }, + + toJSON(message: FileRemoveDir): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.path !== undefined && (obj.path = message.path); + message.recursive !== undefined && (obj.recursive = message.recursive); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileRemoveDir { + const message = createBaseFileRemoveDir(); + message.id = object.id ?? 0; + message.path = object.path ?? ""; + message.recursive = object.recursive ?? false; + return message; + }, +}; + +function createBaseFileRemoveFile(): FileRemoveFile { + return { id: 0, path: "", fileNum: 0 }; +} + +export const FileRemoveFile = { + encode(message: FileRemoveFile, writer: Writer = Writer.create()): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + if (message.path !== "") { + writer.uint32(18).string(message.path); + } + if (message.fileNum !== 0) { + writer.uint32(24).sint32(message.fileNum); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileRemoveFile { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileRemoveFile(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + case 2: + message.path = reader.string(); + break; + case 3: + message.fileNum = reader.sint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileRemoveFile { + return { + id: isSet(object.id) ? Number(object.id) : 0, + path: isSet(object.path) ? String(object.path) : "", + fileNum: isSet(object.fileNum) ? Number(object.fileNum) : 0, + }; + }, + + toJSON(message: FileRemoveFile): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.path !== undefined && (obj.path = message.path); + message.fileNum !== undefined && + (obj.fileNum = Math.round(message.fileNum)); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileRemoveFile { + const message = createBaseFileRemoveFile(); + message.id = object.id ?? 0; + message.path = object.path ?? ""; + message.fileNum = object.fileNum ?? 0; + return message; + }, +}; + +function createBaseFileDirCreate(): FileDirCreate { + return { id: 0, path: "" }; +} + +export const FileDirCreate = { + encode(message: FileDirCreate, writer: Writer = Writer.create()): Writer { + if (message.id !== 0) { + writer.uint32(8).int32(message.id); + } + if (message.path !== "") { + writer.uint32(18).string(message.path); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FileDirCreate { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileDirCreate(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int32(); + break; + case 2: + message.path = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileDirCreate { + return { + id: isSet(object.id) ? Number(object.id) : 0, + path: isSet(object.path) ? String(object.path) : "", + }; + }, + + toJSON(message: FileDirCreate): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = Math.round(message.id)); + message.path !== undefined && (obj.path = message.path); + return obj; + }, + + fromPartial, I>>( + object: I + ): FileDirCreate { + const message = createBaseFileDirCreate(); + message.id = object.id ?? 0; + message.path = object.path ?? ""; + return message; + }, +}; + +function createBaseSwitchDisplay(): SwitchDisplay { + return { display: 0, x: 0, y: 0, width: 0, height: 0 }; +} + +export const SwitchDisplay = { + encode(message: SwitchDisplay, writer: Writer = Writer.create()): Writer { + if (message.display !== 0) { + writer.uint32(8).int32(message.display); + } + if (message.x !== 0) { + writer.uint32(16).sint32(message.x); + } + if (message.y !== 0) { + writer.uint32(24).sint32(message.y); + } + if (message.width !== 0) { + writer.uint32(32).int32(message.width); + } + if (message.height !== 0) { + writer.uint32(40).int32(message.height); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): SwitchDisplay { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSwitchDisplay(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.display = reader.int32(); + break; + case 2: + message.x = reader.sint32(); + break; + case 3: + message.y = reader.sint32(); + break; + case 4: + message.width = reader.int32(); + break; + case 5: + message.height = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): SwitchDisplay { + return { + display: isSet(object.display) ? Number(object.display) : 0, + x: isSet(object.x) ? Number(object.x) : 0, + y: isSet(object.y) ? Number(object.y) : 0, + width: isSet(object.width) ? Number(object.width) : 0, + height: isSet(object.height) ? Number(object.height) : 0, + }; + }, + + toJSON(message: SwitchDisplay): unknown { + const obj: any = {}; + message.display !== undefined && + (obj.display = Math.round(message.display)); + message.x !== undefined && (obj.x = Math.round(message.x)); + message.y !== undefined && (obj.y = Math.round(message.y)); + message.width !== undefined && (obj.width = Math.round(message.width)); + message.height !== undefined && (obj.height = Math.round(message.height)); + return obj; + }, + + fromPartial, I>>( + object: I + ): SwitchDisplay { + const message = createBaseSwitchDisplay(); + message.display = object.display ?? 0; + message.x = object.x ?? 0; + message.y = object.y ?? 0; + message.width = object.width ?? 0; + message.height = object.height ?? 0; + return message; + }, +}; + +function createBasePermissionInfo(): PermissionInfo { + return { permission: 0, enabled: false }; +} + +export const PermissionInfo = { + encode(message: PermissionInfo, writer: Writer = Writer.create()): Writer { + if (message.permission !== 0) { + writer.uint32(8).int32(message.permission); + } + if (message.enabled === true) { + writer.uint32(16).bool(message.enabled); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): PermissionInfo { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePermissionInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.permission = reader.int32() as any; + break; + case 2: + message.enabled = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): PermissionInfo { + return { + permission: isSet(object.permission) + ? permissionInfo_PermissionFromJSON(object.permission) + : 0, + enabled: isSet(object.enabled) ? Boolean(object.enabled) : false, + }; + }, + + toJSON(message: PermissionInfo): unknown { + const obj: any = {}; + message.permission !== undefined && + (obj.permission = permissionInfo_PermissionToJSON(message.permission)); + message.enabled !== undefined && (obj.enabled = message.enabled); + return obj; + }, + + fromPartial, I>>( + object: I + ): PermissionInfo { + const message = createBasePermissionInfo(); + message.permission = object.permission ?? 0; + message.enabled = object.enabled ?? false; + return message; + }, +}; + +function createBaseOptionMessage(): OptionMessage { + return { + imageQuality: 0, + lockAfterSessionEnd: 0, + showRemoteCursor: 0, + privacyMode: 0, + blockInput: 0, + customImageQuality: 0, + disableAudio: 0, + disableClipboard: 0, + }; +} + +export const OptionMessage = { + encode(message: OptionMessage, writer: Writer = Writer.create()): Writer { + if (message.imageQuality !== 0) { + writer.uint32(8).int32(message.imageQuality); + } + if (message.lockAfterSessionEnd !== 0) { + writer.uint32(16).int32(message.lockAfterSessionEnd); + } + if (message.showRemoteCursor !== 0) { + writer.uint32(24).int32(message.showRemoteCursor); + } + if (message.privacyMode !== 0) { + writer.uint32(32).int32(message.privacyMode); + } + if (message.blockInput !== 0) { + writer.uint32(40).int32(message.blockInput); + } + if (message.customImageQuality !== 0) { + writer.uint32(48).int32(message.customImageQuality); + } + if (message.disableAudio !== 0) { + writer.uint32(56).int32(message.disableAudio); + } + if (message.disableClipboard !== 0) { + writer.uint32(64).int32(message.disableClipboard); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): OptionMessage { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseOptionMessage(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.imageQuality = reader.int32() as any; + break; + case 2: + message.lockAfterSessionEnd = reader.int32() as any; + break; + case 3: + message.showRemoteCursor = reader.int32() as any; + break; + case 4: + message.privacyMode = reader.int32() as any; + break; + case 5: + message.blockInput = reader.int32() as any; + break; + case 6: + message.customImageQuality = reader.int32(); + break; + case 7: + message.disableAudio = reader.int32() as any; + break; + case 8: + message.disableClipboard = reader.int32() as any; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): OptionMessage { + return { + imageQuality: isSet(object.imageQuality) + ? imageQualityFromJSON(object.imageQuality) + : 0, + lockAfterSessionEnd: isSet(object.lockAfterSessionEnd) + ? optionMessage_BoolOptionFromJSON(object.lockAfterSessionEnd) + : 0, + showRemoteCursor: isSet(object.showRemoteCursor) + ? optionMessage_BoolOptionFromJSON(object.showRemoteCursor) + : 0, + privacyMode: isSet(object.privacyMode) + ? optionMessage_BoolOptionFromJSON(object.privacyMode) + : 0, + blockInput: isSet(object.blockInput) + ? optionMessage_BoolOptionFromJSON(object.blockInput) + : 0, + customImageQuality: isSet(object.customImageQuality) + ? Number(object.customImageQuality) + : 0, + disableAudio: isSet(object.disableAudio) + ? optionMessage_BoolOptionFromJSON(object.disableAudio) + : 0, + disableClipboard: isSet(object.disableClipboard) + ? optionMessage_BoolOptionFromJSON(object.disableClipboard) + : 0, + }; + }, + + toJSON(message: OptionMessage): unknown { + const obj: any = {}; + message.imageQuality !== undefined && + (obj.imageQuality = imageQualityToJSON(message.imageQuality)); + message.lockAfterSessionEnd !== undefined && + (obj.lockAfterSessionEnd = optionMessage_BoolOptionToJSON( + message.lockAfterSessionEnd + )); + message.showRemoteCursor !== undefined && + (obj.showRemoteCursor = optionMessage_BoolOptionToJSON( + message.showRemoteCursor + )); + message.privacyMode !== undefined && + (obj.privacyMode = optionMessage_BoolOptionToJSON(message.privacyMode)); + message.blockInput !== undefined && + (obj.blockInput = optionMessage_BoolOptionToJSON(message.blockInput)); + message.customImageQuality !== undefined && + (obj.customImageQuality = Math.round(message.customImageQuality)); + message.disableAudio !== undefined && + (obj.disableAudio = optionMessage_BoolOptionToJSON(message.disableAudio)); + message.disableClipboard !== undefined && + (obj.disableClipboard = optionMessage_BoolOptionToJSON( + message.disableClipboard + )); + return obj; + }, + + fromPartial, I>>( + object: I + ): OptionMessage { + const message = createBaseOptionMessage(); + message.imageQuality = object.imageQuality ?? 0; + message.lockAfterSessionEnd = object.lockAfterSessionEnd ?? 0; + message.showRemoteCursor = object.showRemoteCursor ?? 0; + message.privacyMode = object.privacyMode ?? 0; + message.blockInput = object.blockInput ?? 0; + message.customImageQuality = object.customImageQuality ?? 0; + message.disableAudio = object.disableAudio ?? 0; + message.disableClipboard = object.disableClipboard ?? 0; + return message; + }, +}; + +function createBaseOptionResponse(): OptionResponse { + return { opt: undefined, error: "" }; +} + +export const OptionResponse = { + encode(message: OptionResponse, writer: Writer = Writer.create()): Writer { + if (message.opt !== undefined) { + OptionMessage.encode(message.opt, writer.uint32(10).fork()).ldelim(); + } + if (message.error !== "") { + writer.uint32(18).string(message.error); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): OptionResponse { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseOptionResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.opt = OptionMessage.decode(reader, reader.uint32()); + break; + case 2: + message.error = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): OptionResponse { + return { + opt: isSet(object.opt) ? OptionMessage.fromJSON(object.opt) : undefined, + error: isSet(object.error) ? String(object.error) : "", + }; + }, + + toJSON(message: OptionResponse): unknown { + const obj: any = {}; + message.opt !== undefined && + (obj.opt = message.opt ? OptionMessage.toJSON(message.opt) : undefined); + message.error !== undefined && (obj.error = message.error); + return obj; + }, + + fromPartial, I>>( + object: I + ): OptionResponse { + const message = createBaseOptionResponse(); + message.opt = + object.opt !== undefined && object.opt !== null + ? OptionMessage.fromPartial(object.opt) + : undefined; + message.error = object.error ?? ""; + return message; + }, +}; + +function createBaseTestDelay(): TestDelay { + return { time: 0, fromClient: false }; +} + +export const TestDelay = { + encode(message: TestDelay, writer: Writer = Writer.create()): Writer { + if (message.time !== 0) { + writer.uint32(8).int64(message.time); + } + if (message.fromClient === true) { + writer.uint32(16).bool(message.fromClient); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): TestDelay { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseTestDelay(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.time = longToNumber(reader.int64() as Long); + break; + case 2: + message.fromClient = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): TestDelay { + return { + time: isSet(object.time) ? Number(object.time) : 0, + fromClient: isSet(object.fromClient) ? Boolean(object.fromClient) : false, + }; + }, + + toJSON(message: TestDelay): unknown { + const obj: any = {}; + message.time !== undefined && (obj.time = Math.round(message.time)); + message.fromClient !== undefined && (obj.fromClient = message.fromClient); + return obj; + }, + + fromPartial, I>>( + object: I + ): TestDelay { + const message = createBaseTestDelay(); + message.time = object.time ?? 0; + message.fromClient = object.fromClient ?? false; + return message; + }, +}; + +function createBasePublicKey(): PublicKey { + return { + asymmetricValue: new Uint8Array(), + symmetricValue: new Uint8Array(), + }; +} + +export const PublicKey = { + encode(message: PublicKey, writer: Writer = Writer.create()): Writer { + if (message.asymmetricValue.length !== 0) { + writer.uint32(10).bytes(message.asymmetricValue); + } + if (message.symmetricValue.length !== 0) { + writer.uint32(18).bytes(message.symmetricValue); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): PublicKey { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePublicKey(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.asymmetricValue = reader.bytes(); + break; + case 2: + message.symmetricValue = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): PublicKey { + return { + asymmetricValue: isSet(object.asymmetricValue) + ? bytesFromBase64(object.asymmetricValue) + : new Uint8Array(), + symmetricValue: isSet(object.symmetricValue) + ? bytesFromBase64(object.symmetricValue) + : new Uint8Array(), + }; + }, + + toJSON(message: PublicKey): unknown { + const obj: any = {}; + message.asymmetricValue !== undefined && + (obj.asymmetricValue = base64FromBytes( + message.asymmetricValue !== undefined + ? message.asymmetricValue + : new Uint8Array() + )); + message.symmetricValue !== undefined && + (obj.symmetricValue = base64FromBytes( + message.symmetricValue !== undefined + ? message.symmetricValue + : new Uint8Array() + )); + return obj; + }, + + fromPartial, I>>( + object: I + ): PublicKey { + const message = createBasePublicKey(); + message.asymmetricValue = object.asymmetricValue ?? new Uint8Array(); + message.symmetricValue = object.symmetricValue ?? new Uint8Array(); + return message; + }, +}; + +function createBaseSignedId(): SignedId { + return { id: new Uint8Array() }; +} + +export const SignedId = { + encode(message: SignedId, writer: Writer = Writer.create()): Writer { + if (message.id.length !== 0) { + writer.uint32(10).bytes(message.id); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): SignedId { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSignedId(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): SignedId { + return { + id: isSet(object.id) ? bytesFromBase64(object.id) : new Uint8Array(), + }; + }, + + toJSON(message: SignedId): unknown { + const obj: any = {}; + message.id !== undefined && + (obj.id = base64FromBytes( + message.id !== undefined ? message.id : new Uint8Array() + )); + return obj; + }, + + fromPartial, I>>(object: I): SignedId { + const message = createBaseSignedId(); + message.id = object.id ?? new Uint8Array(); + return message; + }, +}; + +function createBaseAudioFormat(): AudioFormat { + return { sampleRate: 0, channels: 0 }; +} + +export const AudioFormat = { + encode(message: AudioFormat, writer: Writer = Writer.create()): Writer { + if (message.sampleRate !== 0) { + writer.uint32(8).uint32(message.sampleRate); + } + if (message.channels !== 0) { + writer.uint32(16).uint32(message.channels); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): AudioFormat { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAudioFormat(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.sampleRate = reader.uint32(); + break; + case 2: + message.channels = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): AudioFormat { + return { + sampleRate: isSet(object.sampleRate) ? Number(object.sampleRate) : 0, + channels: isSet(object.channels) ? Number(object.channels) : 0, + }; + }, + + toJSON(message: AudioFormat): unknown { + const obj: any = {}; + message.sampleRate !== undefined && + (obj.sampleRate = Math.round(message.sampleRate)); + message.channels !== undefined && + (obj.channels = Math.round(message.channels)); + return obj; + }, + + fromPartial, I>>( + object: I + ): AudioFormat { + const message = createBaseAudioFormat(); + message.sampleRate = object.sampleRate ?? 0; + message.channels = object.channels ?? 0; + return message; + }, +}; + +function createBaseAudioFrame(): AudioFrame { + return { data: new Uint8Array() }; +} + +export const AudioFrame = { + encode(message: AudioFrame, writer: Writer = Writer.create()): Writer { + if (message.data.length !== 0) { + writer.uint32(10).bytes(message.data); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): AudioFrame { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseAudioFrame(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.data = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): AudioFrame { + return { + data: isSet(object.data) + ? bytesFromBase64(object.data) + : new Uint8Array(), + }; + }, + + toJSON(message: AudioFrame): unknown { + const obj: any = {}; + message.data !== undefined && + (obj.data = base64FromBytes( + message.data !== undefined ? message.data : new Uint8Array() + )); + return obj; + }, + + fromPartial, I>>( + object: I + ): AudioFrame { + const message = createBaseAudioFrame(); + message.data = object.data ?? new Uint8Array(); + return message; + }, +}; + +function createBaseMisc(): Misc { + return { + chatMessage: undefined, + switchDisplay: undefined, + permissionInfo: undefined, + option: undefined, + audioFormat: undefined, + closeReason: undefined, + refreshVideo: undefined, + optionResponse: undefined, + }; +} + +export const Misc = { + encode(message: Misc, writer: Writer = Writer.create()): Writer { + if (message.chatMessage !== undefined) { + ChatMessage.encode( + message.chatMessage, + writer.uint32(34).fork() + ).ldelim(); + } + if (message.switchDisplay !== undefined) { + SwitchDisplay.encode( + message.switchDisplay, + writer.uint32(42).fork() + ).ldelim(); + } + if (message.permissionInfo !== undefined) { + PermissionInfo.encode( + message.permissionInfo, + writer.uint32(50).fork() + ).ldelim(); + } + if (message.option !== undefined) { + OptionMessage.encode(message.option, writer.uint32(58).fork()).ldelim(); + } + if (message.audioFormat !== undefined) { + AudioFormat.encode( + message.audioFormat, + writer.uint32(66).fork() + ).ldelim(); + } + if (message.closeReason !== undefined) { + writer.uint32(74).string(message.closeReason); + } + if (message.refreshVideo !== undefined) { + writer.uint32(80).bool(message.refreshVideo); + } + if (message.optionResponse !== undefined) { + OptionResponse.encode( + message.optionResponse, + writer.uint32(90).fork() + ).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): Misc { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMisc(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 4: + message.chatMessage = ChatMessage.decode(reader, reader.uint32()); + break; + case 5: + message.switchDisplay = SwitchDisplay.decode(reader, reader.uint32()); + break; + case 6: + message.permissionInfo = PermissionInfo.decode( + reader, + reader.uint32() + ); + break; + case 7: + message.option = OptionMessage.decode(reader, reader.uint32()); + break; + case 8: + message.audioFormat = AudioFormat.decode(reader, reader.uint32()); + break; + case 9: + message.closeReason = reader.string(); + break; + case 10: + message.refreshVideo = reader.bool(); + break; + case 11: + message.optionResponse = OptionResponse.decode( + reader, + reader.uint32() + ); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): Misc { + return { + chatMessage: isSet(object.chatMessage) + ? ChatMessage.fromJSON(object.chatMessage) + : undefined, + switchDisplay: isSet(object.switchDisplay) + ? SwitchDisplay.fromJSON(object.switchDisplay) + : undefined, + permissionInfo: isSet(object.permissionInfo) + ? PermissionInfo.fromJSON(object.permissionInfo) + : undefined, + option: isSet(object.option) + ? OptionMessage.fromJSON(object.option) + : undefined, + audioFormat: isSet(object.audioFormat) + ? AudioFormat.fromJSON(object.audioFormat) + : undefined, + closeReason: isSet(object.closeReason) + ? String(object.closeReason) + : undefined, + refreshVideo: isSet(object.refreshVideo) + ? Boolean(object.refreshVideo) + : undefined, + optionResponse: isSet(object.optionResponse) + ? OptionResponse.fromJSON(object.optionResponse) + : undefined, + }; + }, + + toJSON(message: Misc): unknown { + const obj: any = {}; + message.chatMessage !== undefined && + (obj.chatMessage = message.chatMessage + ? ChatMessage.toJSON(message.chatMessage) + : undefined); + message.switchDisplay !== undefined && + (obj.switchDisplay = message.switchDisplay + ? SwitchDisplay.toJSON(message.switchDisplay) + : undefined); + message.permissionInfo !== undefined && + (obj.permissionInfo = message.permissionInfo + ? PermissionInfo.toJSON(message.permissionInfo) + : undefined); + message.option !== undefined && + (obj.option = message.option + ? OptionMessage.toJSON(message.option) + : undefined); + message.audioFormat !== undefined && + (obj.audioFormat = message.audioFormat + ? AudioFormat.toJSON(message.audioFormat) + : undefined); + message.closeReason !== undefined && + (obj.closeReason = message.closeReason); + message.refreshVideo !== undefined && + (obj.refreshVideo = message.refreshVideo); + message.optionResponse !== undefined && + (obj.optionResponse = message.optionResponse + ? OptionResponse.toJSON(message.optionResponse) + : undefined); + return obj; + }, + + fromPartial, I>>(object: I): Misc { + const message = createBaseMisc(); + message.chatMessage = + object.chatMessage !== undefined && object.chatMessage !== null + ? ChatMessage.fromPartial(object.chatMessage) + : undefined; + message.switchDisplay = + object.switchDisplay !== undefined && object.switchDisplay !== null + ? SwitchDisplay.fromPartial(object.switchDisplay) + : undefined; + message.permissionInfo = + object.permissionInfo !== undefined && object.permissionInfo !== null + ? PermissionInfo.fromPartial(object.permissionInfo) + : undefined; + message.option = + object.option !== undefined && object.option !== null + ? OptionMessage.fromPartial(object.option) + : undefined; + message.audioFormat = + object.audioFormat !== undefined && object.audioFormat !== null + ? AudioFormat.fromPartial(object.audioFormat) + : undefined; + message.closeReason = object.closeReason ?? undefined; + message.refreshVideo = object.refreshVideo ?? undefined; + message.optionResponse = + object.optionResponse !== undefined && object.optionResponse !== null + ? OptionResponse.fromPartial(object.optionResponse) + : undefined; + return message; + }, +}; + +function createBaseMessage(): Message { + return { + signedId: undefined, + publicKey: undefined, + testDelay: undefined, + videoFrame: undefined, + loginRequest: undefined, + loginResponse: undefined, + hash: undefined, + mouseEvent: undefined, + audioFrame: undefined, + cursorData: undefined, + cursorPosition: undefined, + cursorId: undefined, + keyEvent: undefined, + clipboard: undefined, + fileAction: undefined, + fileResponse: undefined, + misc: undefined, + }; +} + +export const Message = { + encode(message: Message, writer: Writer = Writer.create()): Writer { + if (message.signedId !== undefined) { + SignedId.encode(message.signedId, writer.uint32(26).fork()).ldelim(); + } + if (message.publicKey !== undefined) { + PublicKey.encode(message.publicKey, writer.uint32(34).fork()).ldelim(); + } + if (message.testDelay !== undefined) { + TestDelay.encode(message.testDelay, writer.uint32(42).fork()).ldelim(); + } + if (message.videoFrame !== undefined) { + VideoFrame.encode(message.videoFrame, writer.uint32(50).fork()).ldelim(); + } + if (message.loginRequest !== undefined) { + LoginRequest.encode( + message.loginRequest, + writer.uint32(58).fork() + ).ldelim(); + } + if (message.loginResponse !== undefined) { + LoginResponse.encode( + message.loginResponse, + writer.uint32(66).fork() + ).ldelim(); + } + if (message.hash !== undefined) { + Hash.encode(message.hash, writer.uint32(74).fork()).ldelim(); + } + if (message.mouseEvent !== undefined) { + MouseEvent.encode(message.mouseEvent, writer.uint32(82).fork()).ldelim(); + } + if (message.audioFrame !== undefined) { + AudioFrame.encode(message.audioFrame, writer.uint32(90).fork()).ldelim(); + } + if (message.cursorData !== undefined) { + CursorData.encode(message.cursorData, writer.uint32(98).fork()).ldelim(); + } + if (message.cursorPosition !== undefined) { + CursorPosition.encode( + message.cursorPosition, + writer.uint32(106).fork() + ).ldelim(); + } + if (message.cursorId !== undefined) { + writer.uint32(112).uint64(message.cursorId); + } + if (message.keyEvent !== undefined) { + KeyEvent.encode(message.keyEvent, writer.uint32(122).fork()).ldelim(); + } + if (message.clipboard !== undefined) { + Clipboard.encode(message.clipboard, writer.uint32(130).fork()).ldelim(); + } + if (message.fileAction !== undefined) { + FileAction.encode(message.fileAction, writer.uint32(138).fork()).ldelim(); + } + if (message.fileResponse !== undefined) { + FileResponse.encode( + message.fileResponse, + writer.uint32(146).fork() + ).ldelim(); + } + if (message.misc !== undefined) { + Misc.encode(message.misc, writer.uint32(154).fork()).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): Message { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMessage(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 3: + message.signedId = SignedId.decode(reader, reader.uint32()); + break; + case 4: + message.publicKey = PublicKey.decode(reader, reader.uint32()); + break; + case 5: + message.testDelay = TestDelay.decode(reader, reader.uint32()); + break; + case 6: + message.videoFrame = VideoFrame.decode(reader, reader.uint32()); + break; + case 7: + message.loginRequest = LoginRequest.decode(reader, reader.uint32()); + break; + case 8: + message.loginResponse = LoginResponse.decode(reader, reader.uint32()); + break; + case 9: + message.hash = Hash.decode(reader, reader.uint32()); + break; + case 10: + message.mouseEvent = MouseEvent.decode(reader, reader.uint32()); + break; + case 11: + message.audioFrame = AudioFrame.decode(reader, reader.uint32()); + break; + case 12: + message.cursorData = CursorData.decode(reader, reader.uint32()); + break; + case 13: + message.cursorPosition = CursorPosition.decode( + reader, + reader.uint32() + ); + break; + case 14: + message.cursorId = longToNumber(reader.uint64() as Long); + break; + case 15: + message.keyEvent = KeyEvent.decode(reader, reader.uint32()); + break; + case 16: + message.clipboard = Clipboard.decode(reader, reader.uint32()); + break; + case 17: + message.fileAction = FileAction.decode(reader, reader.uint32()); + break; + case 18: + message.fileResponse = FileResponse.decode(reader, reader.uint32()); + break; + case 19: + message.misc = Misc.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): Message { + return { + signedId: isSet(object.signedId) + ? SignedId.fromJSON(object.signedId) + : undefined, + publicKey: isSet(object.publicKey) + ? PublicKey.fromJSON(object.publicKey) + : undefined, + testDelay: isSet(object.testDelay) + ? TestDelay.fromJSON(object.testDelay) + : undefined, + videoFrame: isSet(object.videoFrame) + ? VideoFrame.fromJSON(object.videoFrame) + : undefined, + loginRequest: isSet(object.loginRequest) + ? LoginRequest.fromJSON(object.loginRequest) + : undefined, + loginResponse: isSet(object.loginResponse) + ? LoginResponse.fromJSON(object.loginResponse) + : undefined, + hash: isSet(object.hash) ? Hash.fromJSON(object.hash) : undefined, + mouseEvent: isSet(object.mouseEvent) + ? MouseEvent.fromJSON(object.mouseEvent) + : undefined, + audioFrame: isSet(object.audioFrame) + ? AudioFrame.fromJSON(object.audioFrame) + : undefined, + cursorData: isSet(object.cursorData) + ? CursorData.fromJSON(object.cursorData) + : undefined, + cursorPosition: isSet(object.cursorPosition) + ? CursorPosition.fromJSON(object.cursorPosition) + : undefined, + cursorId: isSet(object.cursorId) ? Number(object.cursorId) : undefined, + keyEvent: isSet(object.keyEvent) + ? KeyEvent.fromJSON(object.keyEvent) + : undefined, + clipboard: isSet(object.clipboard) + ? Clipboard.fromJSON(object.clipboard) + : undefined, + fileAction: isSet(object.fileAction) + ? FileAction.fromJSON(object.fileAction) + : undefined, + fileResponse: isSet(object.fileResponse) + ? FileResponse.fromJSON(object.fileResponse) + : undefined, + misc: isSet(object.misc) ? Misc.fromJSON(object.misc) : undefined, + }; + }, + + toJSON(message: Message): unknown { + const obj: any = {}; + message.signedId !== undefined && + (obj.signedId = message.signedId + ? SignedId.toJSON(message.signedId) + : undefined); + message.publicKey !== undefined && + (obj.publicKey = message.publicKey + ? PublicKey.toJSON(message.publicKey) + : undefined); + message.testDelay !== undefined && + (obj.testDelay = message.testDelay + ? TestDelay.toJSON(message.testDelay) + : undefined); + message.videoFrame !== undefined && + (obj.videoFrame = message.videoFrame + ? VideoFrame.toJSON(message.videoFrame) + : undefined); + message.loginRequest !== undefined && + (obj.loginRequest = message.loginRequest + ? LoginRequest.toJSON(message.loginRequest) + : undefined); + message.loginResponse !== undefined && + (obj.loginResponse = message.loginResponse + ? LoginResponse.toJSON(message.loginResponse) + : undefined); + message.hash !== undefined && + (obj.hash = message.hash ? Hash.toJSON(message.hash) : undefined); + message.mouseEvent !== undefined && + (obj.mouseEvent = message.mouseEvent + ? MouseEvent.toJSON(message.mouseEvent) + : undefined); + message.audioFrame !== undefined && + (obj.audioFrame = message.audioFrame + ? AudioFrame.toJSON(message.audioFrame) + : undefined); + message.cursorData !== undefined && + (obj.cursorData = message.cursorData + ? CursorData.toJSON(message.cursorData) + : undefined); + message.cursorPosition !== undefined && + (obj.cursorPosition = message.cursorPosition + ? CursorPosition.toJSON(message.cursorPosition) + : undefined); + message.cursorId !== undefined && + (obj.cursorId = Math.round(message.cursorId)); + message.keyEvent !== undefined && + (obj.keyEvent = message.keyEvent + ? KeyEvent.toJSON(message.keyEvent) + : undefined); + message.clipboard !== undefined && + (obj.clipboard = message.clipboard + ? Clipboard.toJSON(message.clipboard) + : undefined); + message.fileAction !== undefined && + (obj.fileAction = message.fileAction + ? FileAction.toJSON(message.fileAction) + : undefined); + message.fileResponse !== undefined && + (obj.fileResponse = message.fileResponse + ? FileResponse.toJSON(message.fileResponse) + : undefined); + message.misc !== undefined && + (obj.misc = message.misc ? Misc.toJSON(message.misc) : undefined); + return obj; + }, + + fromPartial, I>>(object: I): Message { + const message = createBaseMessage(); + message.signedId = + object.signedId !== undefined && object.signedId !== null + ? SignedId.fromPartial(object.signedId) + : undefined; + message.publicKey = + object.publicKey !== undefined && object.publicKey !== null + ? PublicKey.fromPartial(object.publicKey) + : undefined; + message.testDelay = + object.testDelay !== undefined && object.testDelay !== null + ? TestDelay.fromPartial(object.testDelay) + : undefined; + message.videoFrame = + object.videoFrame !== undefined && object.videoFrame !== null + ? VideoFrame.fromPartial(object.videoFrame) + : undefined; + message.loginRequest = + object.loginRequest !== undefined && object.loginRequest !== null + ? LoginRequest.fromPartial(object.loginRequest) + : undefined; + message.loginResponse = + object.loginResponse !== undefined && object.loginResponse !== null + ? LoginResponse.fromPartial(object.loginResponse) + : undefined; + message.hash = + object.hash !== undefined && object.hash !== null + ? Hash.fromPartial(object.hash) + : undefined; + message.mouseEvent = + object.mouseEvent !== undefined && object.mouseEvent !== null + ? MouseEvent.fromPartial(object.mouseEvent) + : undefined; + message.audioFrame = + object.audioFrame !== undefined && object.audioFrame !== null + ? AudioFrame.fromPartial(object.audioFrame) + : undefined; + message.cursorData = + object.cursorData !== undefined && object.cursorData !== null + ? CursorData.fromPartial(object.cursorData) + : undefined; + message.cursorPosition = + object.cursorPosition !== undefined && object.cursorPosition !== null + ? CursorPosition.fromPartial(object.cursorPosition) + : undefined; + message.cursorId = object.cursorId ?? undefined; + message.keyEvent = + object.keyEvent !== undefined && object.keyEvent !== null + ? KeyEvent.fromPartial(object.keyEvent) + : undefined; + message.clipboard = + object.clipboard !== undefined && object.clipboard !== null + ? Clipboard.fromPartial(object.clipboard) + : undefined; + message.fileAction = + object.fileAction !== undefined && object.fileAction !== null + ? FileAction.fromPartial(object.fileAction) + : undefined; + message.fileResponse = + object.fileResponse !== undefined && object.fileResponse !== null + ? FileResponse.fromPartial(object.fileResponse) + : undefined; + message.misc = + object.misc !== undefined && object.misc !== null + ? Misc.fromPartial(object.misc) + : undefined; + return message; + }, +}; + +declare var self: any | undefined; +declare var window: any | undefined; +declare var global: any | undefined; +var globalThis: any = (() => { + if (typeof globalThis !== "undefined") return globalThis; + if (typeof self !== "undefined") return self; + if (typeof window !== "undefined") return window; + if (typeof global !== "undefined") return global; + throw "Unable to locate global object"; +})(); + +const atob: (b64: string) => string = + globalThis.atob || + ((b64) => globalThis.Buffer.from(b64, "base64").toString("binary")); +function bytesFromBase64(b64: string): Uint8Array { + const bin = atob(b64); + const arr = new Uint8Array(bin.length); + for (let i = 0; i < bin.length; ++i) { + arr[i] = bin.charCodeAt(i); + } + return arr; +} + +const btoa: (bin: string) => string = + globalThis.btoa || + ((bin) => globalThis.Buffer.from(bin, "binary").toString("base64")); +function base64FromBytes(arr: Uint8Array): string { + const bin: string[] = []; + for (const byte of arr) { + bin.push(String.fromCharCode(byte)); + } + return btoa(bin.join("")); +} + +type Builtin = + | Date + | Function + | Uint8Array + | string + | number + | boolean + | undefined; + +export type DeepPartial = T extends Builtin + ? T + : T extends Array + ? Array> + : T extends ReadonlyArray + ? ReadonlyArray> + : T extends {} + ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin + ? P + : P & { [K in keyof P]: Exact } & Record< + Exclude>, + never + >; + +function longToNumber(long: Long): number { + if (long.gt(Number.MAX_SAFE_INTEGER)) { + throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER"); + } + return long.toNumber(); +} + +// If you get a compile-error about 'Constructor and ... have no overlap', +// add '--ts_proto_opt=esModuleInterop=true' as a flag when calling 'protoc'. +if (util.Long !== Long) { + util.Long = Long as any; + configure(); +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} diff --git a/src/rendezvous.ts b/src/rendezvous.ts new file mode 100644 index 000000000..9af1a4a44 --- /dev/null +++ b/src/rendezvous.ts @@ -0,0 +1,2252 @@ +/* eslint-disable */ +import { util, configure, Writer, Reader } from "protobufjs/minimal"; +import * as Long from "long"; + +export const protobufPackage = "hbb"; + +export enum ConnType { + DEFAULT_CONN = 0, + FILE_TRANSFER = 1, + PORT_FORWARD = 2, + RDP = 3, + UNRECOGNIZED = -1, +} + +export function connTypeFromJSON(object: any): ConnType { + switch (object) { + case 0: + case "DEFAULT_CONN": + return ConnType.DEFAULT_CONN; + case 1: + case "FILE_TRANSFER": + return ConnType.FILE_TRANSFER; + case 2: + case "PORT_FORWARD": + return ConnType.PORT_FORWARD; + case 3: + case "RDP": + return ConnType.RDP; + case -1: + case "UNRECOGNIZED": + default: + return ConnType.UNRECOGNIZED; + } +} + +export function connTypeToJSON(object: ConnType): string { + switch (object) { + case ConnType.DEFAULT_CONN: + return "DEFAULT_CONN"; + case ConnType.FILE_TRANSFER: + return "FILE_TRANSFER"; + case ConnType.PORT_FORWARD: + return "PORT_FORWARD"; + case ConnType.RDP: + return "RDP"; + default: + return "UNKNOWN"; + } +} + +export enum NatType { + UNKNOWN_NAT = 0, + ASYMMETRIC = 1, + SYMMETRIC = 2, + UNRECOGNIZED = -1, +} + +export function natTypeFromJSON(object: any): NatType { + switch (object) { + case 0: + case "UNKNOWN_NAT": + return NatType.UNKNOWN_NAT; + case 1: + case "ASYMMETRIC": + return NatType.ASYMMETRIC; + case 2: + case "SYMMETRIC": + return NatType.SYMMETRIC; + case -1: + case "UNRECOGNIZED": + default: + return NatType.UNRECOGNIZED; + } +} + +export function natTypeToJSON(object: NatType): string { + switch (object) { + case NatType.UNKNOWN_NAT: + return "UNKNOWN_NAT"; + case NatType.ASYMMETRIC: + return "ASYMMETRIC"; + case NatType.SYMMETRIC: + return "SYMMETRIC"; + default: + return "UNKNOWN"; + } +} + +export interface RegisterPeer { + id: string; + serial: number; +} + +export interface RegisterPeerResponse { + requestPk: boolean; +} + +export interface PunchHoleRequest { + id: string; + natType: NatType; + licenceKey: string; + connType: ConnType; +} + +export interface PunchHole { + socketAddr: Uint8Array; + relayServer: string; + natType: NatType; +} + +export interface TestNatRequest { + serial: number; +} + +/** per my test, uint/int has no difference in encoding, int not good for negative, use sint for negative */ +export interface TestNatResponse { + port: number; + /** for mobile */ + cu: ConfigUpdate | undefined; +} + +export interface PunchHoleSent { + socketAddr: Uint8Array; + id: string; + relayServer: string; + natType: NatType; + version: string; +} + +export interface RegisterPk { + id: string; + uuid: Uint8Array; + pk: Uint8Array; + oldId: string; +} + +export interface RegisterPkResponse { + result: RegisterPkResponse_Result; +} + +export enum RegisterPkResponse_Result { + UNKNOWN = 0, + OK = 1, + UUID_MISMATCH = 2, + ID_EXISTS = 3, + TOO_FREQUENT = 4, + INVALID_ID_FORMAT = 5, + NOT_SUPPORT = 6, + SERVER_ERROR = 7, + UNRECOGNIZED = -1, +} + +export function registerPkResponse_ResultFromJSON( + object: any +): RegisterPkResponse_Result { + switch (object) { + case 0: + case "UNKNOWN": + return RegisterPkResponse_Result.UNKNOWN; + case 1: + case "OK": + return RegisterPkResponse_Result.OK; + case 2: + case "UUID_MISMATCH": + return RegisterPkResponse_Result.UUID_MISMATCH; + case 3: + case "ID_EXISTS": + return RegisterPkResponse_Result.ID_EXISTS; + case 4: + case "TOO_FREQUENT": + return RegisterPkResponse_Result.TOO_FREQUENT; + case 5: + case "INVALID_ID_FORMAT": + return RegisterPkResponse_Result.INVALID_ID_FORMAT; + case 6: + case "NOT_SUPPORT": + return RegisterPkResponse_Result.NOT_SUPPORT; + case 7: + case "SERVER_ERROR": + return RegisterPkResponse_Result.SERVER_ERROR; + case -1: + case "UNRECOGNIZED": + default: + return RegisterPkResponse_Result.UNRECOGNIZED; + } +} + +export function registerPkResponse_ResultToJSON( + object: RegisterPkResponse_Result +): string { + switch (object) { + case RegisterPkResponse_Result.UNKNOWN: + return "UNKNOWN"; + case RegisterPkResponse_Result.OK: + return "OK"; + case RegisterPkResponse_Result.UUID_MISMATCH: + return "UUID_MISMATCH"; + case RegisterPkResponse_Result.ID_EXISTS: + return "ID_EXISTS"; + case RegisterPkResponse_Result.TOO_FREQUENT: + return "TOO_FREQUENT"; + case RegisterPkResponse_Result.INVALID_ID_FORMAT: + return "INVALID_ID_FORMAT"; + case RegisterPkResponse_Result.NOT_SUPPORT: + return "NOT_SUPPORT"; + case RegisterPkResponse_Result.SERVER_ERROR: + return "SERVER_ERROR"; + default: + return "UNKNOWN"; + } +} + +export interface PunchHoleResponse { + socketAddr: Uint8Array; + pk: Uint8Array; + failure: PunchHoleResponse_Failure; + relayServer: string; + natType: NatType | undefined; + isLocal: boolean | undefined; + otherFailure: string; +} + +export enum PunchHoleResponse_Failure { + UNKNOWN = 0, + ID_NOT_EXIST = 1, + OFFLINE = 2, + LICENSE_MISMATCH = 3, + LICENSE_OVERUSE = 4, + UNRECOGNIZED = -1, +} + +export function punchHoleResponse_FailureFromJSON( + object: any +): PunchHoleResponse_Failure { + switch (object) { + case 0: + case "UNKNOWN": + return PunchHoleResponse_Failure.UNKNOWN; + case 1: + case "ID_NOT_EXIST": + return PunchHoleResponse_Failure.ID_NOT_EXIST; + case 2: + case "OFFLINE": + return PunchHoleResponse_Failure.OFFLINE; + case 3: + case "LICENSE_MISMATCH": + return PunchHoleResponse_Failure.LICENSE_MISMATCH; + case 4: + case "LICENSE_OVERUSE": + return PunchHoleResponse_Failure.LICENSE_OVERUSE; + case -1: + case "UNRECOGNIZED": + default: + return PunchHoleResponse_Failure.UNRECOGNIZED; + } +} + +export function punchHoleResponse_FailureToJSON( + object: PunchHoleResponse_Failure +): string { + switch (object) { + case PunchHoleResponse_Failure.UNKNOWN: + return "UNKNOWN"; + case PunchHoleResponse_Failure.ID_NOT_EXIST: + return "ID_NOT_EXIST"; + case PunchHoleResponse_Failure.OFFLINE: + return "OFFLINE"; + case PunchHoleResponse_Failure.LICENSE_MISMATCH: + return "LICENSE_MISMATCH"; + case PunchHoleResponse_Failure.LICENSE_OVERUSE: + return "LICENSE_OVERUSE"; + default: + return "UNKNOWN"; + } +} + +export interface ConfigUpdate { + serial: number; + rendezvousServers: string[]; +} + +export interface RequestRelay { + id: string; + uuid: string; + socketAddr: Uint8Array; + relayServer: string; + secure: boolean; + licenceKey: string; + connType: ConnType; +} + +export interface RelayResponse { + socketAddr: Uint8Array; + uuid: string; + relayServer: string; + id: string | undefined; + pk: Uint8Array | undefined; + refuseReason: string; + version: string; +} + +export interface SoftwareUpdate { + url: string; +} + +/** + * if in same intranet, punch hole won't work both for udp and tcp, + * even some router has below connection error if we connect itself, + * { kind: Other, error: "could not resolve to any address" }, + * so we request local address to connect. + */ +export interface FetchLocalAddr { + socketAddr: Uint8Array; + relayServer: string; +} + +export interface LocalAddr { + socketAddr: Uint8Array; + localAddr: Uint8Array; + relayServer: string; + id: string; + version: string; +} + +export interface PeerDiscovery { + cmd: string; + mac: string; + id: string; + username: string; + hostname: string; + platform: string; + misc: string; +} + +export interface RendezvousMessage { + registerPeer: RegisterPeer | undefined; + registerPeerResponse: RegisterPeerResponse | undefined; + punchHoleRequest: PunchHoleRequest | undefined; + punchHole: PunchHole | undefined; + punchHoleSent: PunchHoleSent | undefined; + punchHoleResponse: PunchHoleResponse | undefined; + fetchLocalAddr: FetchLocalAddr | undefined; + localAddr: LocalAddr | undefined; + configureUpdate: ConfigUpdate | undefined; + registerPk: RegisterPk | undefined; + registerPkResponse: RegisterPkResponse | undefined; + softwareUpdate: SoftwareUpdate | undefined; + requestRelay: RequestRelay | undefined; + relayResponse: RelayResponse | undefined; + testNatRequest: TestNatRequest | undefined; + testNatResponse: TestNatResponse | undefined; + peerDiscovery: PeerDiscovery | undefined; +} + +function createBaseRegisterPeer(): RegisterPeer { + return { id: "", serial: 0 }; +} + +export const RegisterPeer = { + encode(message: RegisterPeer, writer: Writer = Writer.create()): Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.serial !== 0) { + writer.uint32(16).int32(message.serial); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): RegisterPeer { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRegisterPeer(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.serial = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): RegisterPeer { + return { + id: isSet(object.id) ? String(object.id) : "", + serial: isSet(object.serial) ? Number(object.serial) : 0, + }; + }, + + toJSON(message: RegisterPeer): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = message.id); + message.serial !== undefined && (obj.serial = Math.round(message.serial)); + return obj; + }, + + fromPartial, I>>( + object: I + ): RegisterPeer { + const message = createBaseRegisterPeer(); + message.id = object.id ?? ""; + message.serial = object.serial ?? 0; + return message; + }, +}; + +function createBaseRegisterPeerResponse(): RegisterPeerResponse { + return { requestPk: false }; +} + +export const RegisterPeerResponse = { + encode( + message: RegisterPeerResponse, + writer: Writer = Writer.create() + ): Writer { + if (message.requestPk === true) { + writer.uint32(16).bool(message.requestPk); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): RegisterPeerResponse { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRegisterPeerResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + message.requestPk = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): RegisterPeerResponse { + return { + requestPk: isSet(object.requestPk) ? Boolean(object.requestPk) : false, + }; + }, + + toJSON(message: RegisterPeerResponse): unknown { + const obj: any = {}; + message.requestPk !== undefined && (obj.requestPk = message.requestPk); + return obj; + }, + + fromPartial, I>>( + object: I + ): RegisterPeerResponse { + const message = createBaseRegisterPeerResponse(); + message.requestPk = object.requestPk ?? false; + return message; + }, +}; + +function createBasePunchHoleRequest(): PunchHoleRequest { + return { id: "", natType: 0, licenceKey: "", connType: 0 }; +} + +export const PunchHoleRequest = { + encode(message: PunchHoleRequest, writer: Writer = Writer.create()): Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.natType !== 0) { + writer.uint32(16).int32(message.natType); + } + if (message.licenceKey !== "") { + writer.uint32(26).string(message.licenceKey); + } + if (message.connType !== 0) { + writer.uint32(32).int32(message.connType); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): PunchHoleRequest { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePunchHoleRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.natType = reader.int32() as any; + break; + case 3: + message.licenceKey = reader.string(); + break; + case 4: + message.connType = reader.int32() as any; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): PunchHoleRequest { + return { + id: isSet(object.id) ? String(object.id) : "", + natType: isSet(object.natType) ? natTypeFromJSON(object.natType) : 0, + licenceKey: isSet(object.licenceKey) ? String(object.licenceKey) : "", + connType: isSet(object.connType) ? connTypeFromJSON(object.connType) : 0, + }; + }, + + toJSON(message: PunchHoleRequest): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = message.id); + message.natType !== undefined && + (obj.natType = natTypeToJSON(message.natType)); + message.licenceKey !== undefined && (obj.licenceKey = message.licenceKey); + message.connType !== undefined && + (obj.connType = connTypeToJSON(message.connType)); + return obj; + }, + + fromPartial, I>>( + object: I + ): PunchHoleRequest { + const message = createBasePunchHoleRequest(); + message.id = object.id ?? ""; + message.natType = object.natType ?? 0; + message.licenceKey = object.licenceKey ?? ""; + message.connType = object.connType ?? 0; + return message; + }, +}; + +function createBasePunchHole(): PunchHole { + return { socketAddr: new Uint8Array(), relayServer: "", natType: 0 }; +} + +export const PunchHole = { + encode(message: PunchHole, writer: Writer = Writer.create()): Writer { + if (message.socketAddr.length !== 0) { + writer.uint32(10).bytes(message.socketAddr); + } + if (message.relayServer !== "") { + writer.uint32(18).string(message.relayServer); + } + if (message.natType !== 0) { + writer.uint32(24).int32(message.natType); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): PunchHole { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePunchHole(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.socketAddr = reader.bytes(); + break; + case 2: + message.relayServer = reader.string(); + break; + case 3: + message.natType = reader.int32() as any; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): PunchHole { + return { + socketAddr: isSet(object.socketAddr) + ? bytesFromBase64(object.socketAddr) + : new Uint8Array(), + relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + natType: isSet(object.natType) ? natTypeFromJSON(object.natType) : 0, + }; + }, + + toJSON(message: PunchHole): unknown { + const obj: any = {}; + message.socketAddr !== undefined && + (obj.socketAddr = base64FromBytes( + message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + )); + message.relayServer !== undefined && + (obj.relayServer = message.relayServer); + message.natType !== undefined && + (obj.natType = natTypeToJSON(message.natType)); + return obj; + }, + + fromPartial, I>>( + object: I + ): PunchHole { + const message = createBasePunchHole(); + message.socketAddr = object.socketAddr ?? new Uint8Array(); + message.relayServer = object.relayServer ?? ""; + message.natType = object.natType ?? 0; + return message; + }, +}; + +function createBaseTestNatRequest(): TestNatRequest { + return { serial: 0 }; +} + +export const TestNatRequest = { + encode(message: TestNatRequest, writer: Writer = Writer.create()): Writer { + if (message.serial !== 0) { + writer.uint32(8).int32(message.serial); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): TestNatRequest { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseTestNatRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.serial = reader.int32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): TestNatRequest { + return { + serial: isSet(object.serial) ? Number(object.serial) : 0, + }; + }, + + toJSON(message: TestNatRequest): unknown { + const obj: any = {}; + message.serial !== undefined && (obj.serial = Math.round(message.serial)); + return obj; + }, + + fromPartial, I>>( + object: I + ): TestNatRequest { + const message = createBaseTestNatRequest(); + message.serial = object.serial ?? 0; + return message; + }, +}; + +function createBaseTestNatResponse(): TestNatResponse { + return { port: 0, cu: undefined }; +} + +export const TestNatResponse = { + encode(message: TestNatResponse, writer: Writer = Writer.create()): Writer { + if (message.port !== 0) { + writer.uint32(8).int32(message.port); + } + if (message.cu !== undefined) { + ConfigUpdate.encode(message.cu, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): TestNatResponse { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseTestNatResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.port = reader.int32(); + break; + case 2: + message.cu = ConfigUpdate.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): TestNatResponse { + return { + port: isSet(object.port) ? Number(object.port) : 0, + cu: isSet(object.cu) ? ConfigUpdate.fromJSON(object.cu) : undefined, + }; + }, + + toJSON(message: TestNatResponse): unknown { + const obj: any = {}; + message.port !== undefined && (obj.port = Math.round(message.port)); + message.cu !== undefined && + (obj.cu = message.cu ? ConfigUpdate.toJSON(message.cu) : undefined); + return obj; + }, + + fromPartial, I>>( + object: I + ): TestNatResponse { + const message = createBaseTestNatResponse(); + message.port = object.port ?? 0; + message.cu = + object.cu !== undefined && object.cu !== null + ? ConfigUpdate.fromPartial(object.cu) + : undefined; + return message; + }, +}; + +function createBasePunchHoleSent(): PunchHoleSent { + return { + socketAddr: new Uint8Array(), + id: "", + relayServer: "", + natType: 0, + version: "", + }; +} + +export const PunchHoleSent = { + encode(message: PunchHoleSent, writer: Writer = Writer.create()): Writer { + if (message.socketAddr.length !== 0) { + writer.uint32(10).bytes(message.socketAddr); + } + if (message.id !== "") { + writer.uint32(18).string(message.id); + } + if (message.relayServer !== "") { + writer.uint32(26).string(message.relayServer); + } + if (message.natType !== 0) { + writer.uint32(32).int32(message.natType); + } + if (message.version !== "") { + writer.uint32(42).string(message.version); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): PunchHoleSent { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePunchHoleSent(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.socketAddr = reader.bytes(); + break; + case 2: + message.id = reader.string(); + break; + case 3: + message.relayServer = reader.string(); + break; + case 4: + message.natType = reader.int32() as any; + break; + case 5: + message.version = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): PunchHoleSent { + return { + socketAddr: isSet(object.socketAddr) + ? bytesFromBase64(object.socketAddr) + : new Uint8Array(), + id: isSet(object.id) ? String(object.id) : "", + relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + natType: isSet(object.natType) ? natTypeFromJSON(object.natType) : 0, + version: isSet(object.version) ? String(object.version) : "", + }; + }, + + toJSON(message: PunchHoleSent): unknown { + const obj: any = {}; + message.socketAddr !== undefined && + (obj.socketAddr = base64FromBytes( + message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + )); + message.id !== undefined && (obj.id = message.id); + message.relayServer !== undefined && + (obj.relayServer = message.relayServer); + message.natType !== undefined && + (obj.natType = natTypeToJSON(message.natType)); + message.version !== undefined && (obj.version = message.version); + return obj; + }, + + fromPartial, I>>( + object: I + ): PunchHoleSent { + const message = createBasePunchHoleSent(); + message.socketAddr = object.socketAddr ?? new Uint8Array(); + message.id = object.id ?? ""; + message.relayServer = object.relayServer ?? ""; + message.natType = object.natType ?? 0; + message.version = object.version ?? ""; + return message; + }, +}; + +function createBaseRegisterPk(): RegisterPk { + return { id: "", uuid: new Uint8Array(), pk: new Uint8Array(), oldId: "" }; +} + +export const RegisterPk = { + encode(message: RegisterPk, writer: Writer = Writer.create()): Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.uuid.length !== 0) { + writer.uint32(18).bytes(message.uuid); + } + if (message.pk.length !== 0) { + writer.uint32(26).bytes(message.pk); + } + if (message.oldId !== "") { + writer.uint32(34).string(message.oldId); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): RegisterPk { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRegisterPk(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.uuid = reader.bytes(); + break; + case 3: + message.pk = reader.bytes(); + break; + case 4: + message.oldId = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): RegisterPk { + return { + id: isSet(object.id) ? String(object.id) : "", + uuid: isSet(object.uuid) + ? bytesFromBase64(object.uuid) + : new Uint8Array(), + pk: isSet(object.pk) ? bytesFromBase64(object.pk) : new Uint8Array(), + oldId: isSet(object.oldId) ? String(object.oldId) : "", + }; + }, + + toJSON(message: RegisterPk): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = message.id); + message.uuid !== undefined && + (obj.uuid = base64FromBytes( + message.uuid !== undefined ? message.uuid : new Uint8Array() + )); + message.pk !== undefined && + (obj.pk = base64FromBytes( + message.pk !== undefined ? message.pk : new Uint8Array() + )); + message.oldId !== undefined && (obj.oldId = message.oldId); + return obj; + }, + + fromPartial, I>>( + object: I + ): RegisterPk { + const message = createBaseRegisterPk(); + message.id = object.id ?? ""; + message.uuid = object.uuid ?? new Uint8Array(); + message.pk = object.pk ?? new Uint8Array(); + message.oldId = object.oldId ?? ""; + return message; + }, +}; + +function createBaseRegisterPkResponse(): RegisterPkResponse { + return { result: 0 }; +} + +export const RegisterPkResponse = { + encode( + message: RegisterPkResponse, + writer: Writer = Writer.create() + ): Writer { + if (message.result !== 0) { + writer.uint32(8).int32(message.result); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): RegisterPkResponse { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRegisterPkResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.result = reader.int32() as any; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): RegisterPkResponse { + return { + result: isSet(object.result) + ? registerPkResponse_ResultFromJSON(object.result) + : 0, + }; + }, + + toJSON(message: RegisterPkResponse): unknown { + const obj: any = {}; + message.result !== undefined && + (obj.result = registerPkResponse_ResultToJSON(message.result)); + return obj; + }, + + fromPartial, I>>( + object: I + ): RegisterPkResponse { + const message = createBaseRegisterPkResponse(); + message.result = object.result ?? 0; + return message; + }, +}; + +function createBasePunchHoleResponse(): PunchHoleResponse { + return { + socketAddr: new Uint8Array(), + pk: new Uint8Array(), + failure: 0, + relayServer: "", + natType: undefined, + isLocal: undefined, + otherFailure: "", + }; +} + +export const PunchHoleResponse = { + encode(message: PunchHoleResponse, writer: Writer = Writer.create()): Writer { + if (message.socketAddr.length !== 0) { + writer.uint32(10).bytes(message.socketAddr); + } + if (message.pk.length !== 0) { + writer.uint32(18).bytes(message.pk); + } + if (message.failure !== 0) { + writer.uint32(24).int32(message.failure); + } + if (message.relayServer !== "") { + writer.uint32(34).string(message.relayServer); + } + if (message.natType !== undefined) { + writer.uint32(40).int32(message.natType); + } + if (message.isLocal !== undefined) { + writer.uint32(48).bool(message.isLocal); + } + if (message.otherFailure !== "") { + writer.uint32(58).string(message.otherFailure); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): PunchHoleResponse { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePunchHoleResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.socketAddr = reader.bytes(); + break; + case 2: + message.pk = reader.bytes(); + break; + case 3: + message.failure = reader.int32() as any; + break; + case 4: + message.relayServer = reader.string(); + break; + case 5: + message.natType = reader.int32() as any; + break; + case 6: + message.isLocal = reader.bool(); + break; + case 7: + message.otherFailure = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): PunchHoleResponse { + return { + socketAddr: isSet(object.socketAddr) + ? bytesFromBase64(object.socketAddr) + : new Uint8Array(), + pk: isSet(object.pk) ? bytesFromBase64(object.pk) : new Uint8Array(), + failure: isSet(object.failure) + ? punchHoleResponse_FailureFromJSON(object.failure) + : 0, + relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + natType: isSet(object.natType) + ? natTypeFromJSON(object.natType) + : undefined, + isLocal: isSet(object.isLocal) ? Boolean(object.isLocal) : undefined, + otherFailure: isSet(object.otherFailure) + ? String(object.otherFailure) + : "", + }; + }, + + toJSON(message: PunchHoleResponse): unknown { + const obj: any = {}; + message.socketAddr !== undefined && + (obj.socketAddr = base64FromBytes( + message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + )); + message.pk !== undefined && + (obj.pk = base64FromBytes( + message.pk !== undefined ? message.pk : new Uint8Array() + )); + message.failure !== undefined && + (obj.failure = punchHoleResponse_FailureToJSON(message.failure)); + message.relayServer !== undefined && + (obj.relayServer = message.relayServer); + message.natType !== undefined && + (obj.natType = + message.natType !== undefined + ? natTypeToJSON(message.natType) + : undefined); + message.isLocal !== undefined && (obj.isLocal = message.isLocal); + message.otherFailure !== undefined && + (obj.otherFailure = message.otherFailure); + return obj; + }, + + fromPartial, I>>( + object: I + ): PunchHoleResponse { + const message = createBasePunchHoleResponse(); + message.socketAddr = object.socketAddr ?? new Uint8Array(); + message.pk = object.pk ?? new Uint8Array(); + message.failure = object.failure ?? 0; + message.relayServer = object.relayServer ?? ""; + message.natType = object.natType ?? undefined; + message.isLocal = object.isLocal ?? undefined; + message.otherFailure = object.otherFailure ?? ""; + return message; + }, +}; + +function createBaseConfigUpdate(): ConfigUpdate { + return { serial: 0, rendezvousServers: [] }; +} + +export const ConfigUpdate = { + encode(message: ConfigUpdate, writer: Writer = Writer.create()): Writer { + if (message.serial !== 0) { + writer.uint32(8).int32(message.serial); + } + for (const v of message.rendezvousServers) { + writer.uint32(18).string(v!); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): ConfigUpdate { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseConfigUpdate(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.serial = reader.int32(); + break; + case 2: + message.rendezvousServers.push(reader.string()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): ConfigUpdate { + return { + serial: isSet(object.serial) ? Number(object.serial) : 0, + rendezvousServers: Array.isArray(object?.rendezvousServers) + ? object.rendezvousServers.map((e: any) => String(e)) + : [], + }; + }, + + toJSON(message: ConfigUpdate): unknown { + const obj: any = {}; + message.serial !== undefined && (obj.serial = Math.round(message.serial)); + if (message.rendezvousServers) { + obj.rendezvousServers = message.rendezvousServers.map((e) => e); + } else { + obj.rendezvousServers = []; + } + return obj; + }, + + fromPartial, I>>( + object: I + ): ConfigUpdate { + const message = createBaseConfigUpdate(); + message.serial = object.serial ?? 0; + message.rendezvousServers = object.rendezvousServers?.map((e) => e) || []; + return message; + }, +}; + +function createBaseRequestRelay(): RequestRelay { + return { + id: "", + uuid: "", + socketAddr: new Uint8Array(), + relayServer: "", + secure: false, + licenceKey: "", + connType: 0, + }; +} + +export const RequestRelay = { + encode(message: RequestRelay, writer: Writer = Writer.create()): Writer { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.uuid !== "") { + writer.uint32(18).string(message.uuid); + } + if (message.socketAddr.length !== 0) { + writer.uint32(26).bytes(message.socketAddr); + } + if (message.relayServer !== "") { + writer.uint32(34).string(message.relayServer); + } + if (message.secure === true) { + writer.uint32(40).bool(message.secure); + } + if (message.licenceKey !== "") { + writer.uint32(50).string(message.licenceKey); + } + if (message.connType !== 0) { + writer.uint32(56).int32(message.connType); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): RequestRelay { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRequestRelay(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.uuid = reader.string(); + break; + case 3: + message.socketAddr = reader.bytes(); + break; + case 4: + message.relayServer = reader.string(); + break; + case 5: + message.secure = reader.bool(); + break; + case 6: + message.licenceKey = reader.string(); + break; + case 7: + message.connType = reader.int32() as any; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): RequestRelay { + return { + id: isSet(object.id) ? String(object.id) : "", + uuid: isSet(object.uuid) ? String(object.uuid) : "", + socketAddr: isSet(object.socketAddr) + ? bytesFromBase64(object.socketAddr) + : new Uint8Array(), + relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + secure: isSet(object.secure) ? Boolean(object.secure) : false, + licenceKey: isSet(object.licenceKey) ? String(object.licenceKey) : "", + connType: isSet(object.connType) ? connTypeFromJSON(object.connType) : 0, + }; + }, + + toJSON(message: RequestRelay): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = message.id); + message.uuid !== undefined && (obj.uuid = message.uuid); + message.socketAddr !== undefined && + (obj.socketAddr = base64FromBytes( + message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + )); + message.relayServer !== undefined && + (obj.relayServer = message.relayServer); + message.secure !== undefined && (obj.secure = message.secure); + message.licenceKey !== undefined && (obj.licenceKey = message.licenceKey); + message.connType !== undefined && + (obj.connType = connTypeToJSON(message.connType)); + return obj; + }, + + fromPartial, I>>( + object: I + ): RequestRelay { + const message = createBaseRequestRelay(); + message.id = object.id ?? ""; + message.uuid = object.uuid ?? ""; + message.socketAddr = object.socketAddr ?? new Uint8Array(); + message.relayServer = object.relayServer ?? ""; + message.secure = object.secure ?? false; + message.licenceKey = object.licenceKey ?? ""; + message.connType = object.connType ?? 0; + return message; + }, +}; + +function createBaseRelayResponse(): RelayResponse { + return { + socketAddr: new Uint8Array(), + uuid: "", + relayServer: "", + id: undefined, + pk: undefined, + refuseReason: "", + version: "", + }; +} + +export const RelayResponse = { + encode(message: RelayResponse, writer: Writer = Writer.create()): Writer { + if (message.socketAddr.length !== 0) { + writer.uint32(10).bytes(message.socketAddr); + } + if (message.uuid !== "") { + writer.uint32(18).string(message.uuid); + } + if (message.relayServer !== "") { + writer.uint32(26).string(message.relayServer); + } + if (message.id !== undefined) { + writer.uint32(34).string(message.id); + } + if (message.pk !== undefined) { + writer.uint32(42).bytes(message.pk); + } + if (message.refuseReason !== "") { + writer.uint32(50).string(message.refuseReason); + } + if (message.version !== "") { + writer.uint32(58).string(message.version); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): RelayResponse { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRelayResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.socketAddr = reader.bytes(); + break; + case 2: + message.uuid = reader.string(); + break; + case 3: + message.relayServer = reader.string(); + break; + case 4: + message.id = reader.string(); + break; + case 5: + message.pk = reader.bytes(); + break; + case 6: + message.refuseReason = reader.string(); + break; + case 7: + message.version = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): RelayResponse { + return { + socketAddr: isSet(object.socketAddr) + ? bytesFromBase64(object.socketAddr) + : new Uint8Array(), + uuid: isSet(object.uuid) ? String(object.uuid) : "", + relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + id: isSet(object.id) ? String(object.id) : undefined, + pk: isSet(object.pk) ? bytesFromBase64(object.pk) : undefined, + refuseReason: isSet(object.refuseReason) + ? String(object.refuseReason) + : "", + version: isSet(object.version) ? String(object.version) : "", + }; + }, + + toJSON(message: RelayResponse): unknown { + const obj: any = {}; + message.socketAddr !== undefined && + (obj.socketAddr = base64FromBytes( + message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + )); + message.uuid !== undefined && (obj.uuid = message.uuid); + message.relayServer !== undefined && + (obj.relayServer = message.relayServer); + message.id !== undefined && (obj.id = message.id); + message.pk !== undefined && + (obj.pk = + message.pk !== undefined ? base64FromBytes(message.pk) : undefined); + message.refuseReason !== undefined && + (obj.refuseReason = message.refuseReason); + message.version !== undefined && (obj.version = message.version); + return obj; + }, + + fromPartial, I>>( + object: I + ): RelayResponse { + const message = createBaseRelayResponse(); + message.socketAddr = object.socketAddr ?? new Uint8Array(); + message.uuid = object.uuid ?? ""; + message.relayServer = object.relayServer ?? ""; + message.id = object.id ?? undefined; + message.pk = object.pk ?? undefined; + message.refuseReason = object.refuseReason ?? ""; + message.version = object.version ?? ""; + return message; + }, +}; + +function createBaseSoftwareUpdate(): SoftwareUpdate { + return { url: "" }; +} + +export const SoftwareUpdate = { + encode(message: SoftwareUpdate, writer: Writer = Writer.create()): Writer { + if (message.url !== "") { + writer.uint32(10).string(message.url); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): SoftwareUpdate { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSoftwareUpdate(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.url = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): SoftwareUpdate { + return { + url: isSet(object.url) ? String(object.url) : "", + }; + }, + + toJSON(message: SoftwareUpdate): unknown { + const obj: any = {}; + message.url !== undefined && (obj.url = message.url); + return obj; + }, + + fromPartial, I>>( + object: I + ): SoftwareUpdate { + const message = createBaseSoftwareUpdate(); + message.url = object.url ?? ""; + return message; + }, +}; + +function createBaseFetchLocalAddr(): FetchLocalAddr { + return { socketAddr: new Uint8Array(), relayServer: "" }; +} + +export const FetchLocalAddr = { + encode(message: FetchLocalAddr, writer: Writer = Writer.create()): Writer { + if (message.socketAddr.length !== 0) { + writer.uint32(10).bytes(message.socketAddr); + } + if (message.relayServer !== "") { + writer.uint32(18).string(message.relayServer); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): FetchLocalAddr { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFetchLocalAddr(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.socketAddr = reader.bytes(); + break; + case 2: + message.relayServer = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FetchLocalAddr { + return { + socketAddr: isSet(object.socketAddr) + ? bytesFromBase64(object.socketAddr) + : new Uint8Array(), + relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + }; + }, + + toJSON(message: FetchLocalAddr): unknown { + const obj: any = {}; + message.socketAddr !== undefined && + (obj.socketAddr = base64FromBytes( + message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + )); + message.relayServer !== undefined && + (obj.relayServer = message.relayServer); + return obj; + }, + + fromPartial, I>>( + object: I + ): FetchLocalAddr { + const message = createBaseFetchLocalAddr(); + message.socketAddr = object.socketAddr ?? new Uint8Array(); + message.relayServer = object.relayServer ?? ""; + return message; + }, +}; + +function createBaseLocalAddr(): LocalAddr { + return { + socketAddr: new Uint8Array(), + localAddr: new Uint8Array(), + relayServer: "", + id: "", + version: "", + }; +} + +export const LocalAddr = { + encode(message: LocalAddr, writer: Writer = Writer.create()): Writer { + if (message.socketAddr.length !== 0) { + writer.uint32(10).bytes(message.socketAddr); + } + if (message.localAddr.length !== 0) { + writer.uint32(18).bytes(message.localAddr); + } + if (message.relayServer !== "") { + writer.uint32(26).string(message.relayServer); + } + if (message.id !== "") { + writer.uint32(34).string(message.id); + } + if (message.version !== "") { + writer.uint32(42).string(message.version); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): LocalAddr { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLocalAddr(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.socketAddr = reader.bytes(); + break; + case 2: + message.localAddr = reader.bytes(); + break; + case 3: + message.relayServer = reader.string(); + break; + case 4: + message.id = reader.string(); + break; + case 5: + message.version = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): LocalAddr { + return { + socketAddr: isSet(object.socketAddr) + ? bytesFromBase64(object.socketAddr) + : new Uint8Array(), + localAddr: isSet(object.localAddr) + ? bytesFromBase64(object.localAddr) + : new Uint8Array(), + relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + id: isSet(object.id) ? String(object.id) : "", + version: isSet(object.version) ? String(object.version) : "", + }; + }, + + toJSON(message: LocalAddr): unknown { + const obj: any = {}; + message.socketAddr !== undefined && + (obj.socketAddr = base64FromBytes( + message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + )); + message.localAddr !== undefined && + (obj.localAddr = base64FromBytes( + message.localAddr !== undefined ? message.localAddr : new Uint8Array() + )); + message.relayServer !== undefined && + (obj.relayServer = message.relayServer); + message.id !== undefined && (obj.id = message.id); + message.version !== undefined && (obj.version = message.version); + return obj; + }, + + fromPartial, I>>( + object: I + ): LocalAddr { + const message = createBaseLocalAddr(); + message.socketAddr = object.socketAddr ?? new Uint8Array(); + message.localAddr = object.localAddr ?? new Uint8Array(); + message.relayServer = object.relayServer ?? ""; + message.id = object.id ?? ""; + message.version = object.version ?? ""; + return message; + }, +}; + +function createBasePeerDiscovery(): PeerDiscovery { + return { + cmd: "", + mac: "", + id: "", + username: "", + hostname: "", + platform: "", + misc: "", + }; +} + +export const PeerDiscovery = { + encode(message: PeerDiscovery, writer: Writer = Writer.create()): Writer { + if (message.cmd !== "") { + writer.uint32(10).string(message.cmd); + } + if (message.mac !== "") { + writer.uint32(18).string(message.mac); + } + if (message.id !== "") { + writer.uint32(26).string(message.id); + } + if (message.username !== "") { + writer.uint32(34).string(message.username); + } + if (message.hostname !== "") { + writer.uint32(42).string(message.hostname); + } + if (message.platform !== "") { + writer.uint32(50).string(message.platform); + } + if (message.misc !== "") { + writer.uint32(58).string(message.misc); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): PeerDiscovery { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePeerDiscovery(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.cmd = reader.string(); + break; + case 2: + message.mac = reader.string(); + break; + case 3: + message.id = reader.string(); + break; + case 4: + message.username = reader.string(); + break; + case 5: + message.hostname = reader.string(); + break; + case 6: + message.platform = reader.string(); + break; + case 7: + message.misc = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): PeerDiscovery { + return { + cmd: isSet(object.cmd) ? String(object.cmd) : "", + mac: isSet(object.mac) ? String(object.mac) : "", + id: isSet(object.id) ? String(object.id) : "", + username: isSet(object.username) ? String(object.username) : "", + hostname: isSet(object.hostname) ? String(object.hostname) : "", + platform: isSet(object.platform) ? String(object.platform) : "", + misc: isSet(object.misc) ? String(object.misc) : "", + }; + }, + + toJSON(message: PeerDiscovery): unknown { + const obj: any = {}; + message.cmd !== undefined && (obj.cmd = message.cmd); + message.mac !== undefined && (obj.mac = message.mac); + message.id !== undefined && (obj.id = message.id); + message.username !== undefined && (obj.username = message.username); + message.hostname !== undefined && (obj.hostname = message.hostname); + message.platform !== undefined && (obj.platform = message.platform); + message.misc !== undefined && (obj.misc = message.misc); + return obj; + }, + + fromPartial, I>>( + object: I + ): PeerDiscovery { + const message = createBasePeerDiscovery(); + message.cmd = object.cmd ?? ""; + message.mac = object.mac ?? ""; + message.id = object.id ?? ""; + message.username = object.username ?? ""; + message.hostname = object.hostname ?? ""; + message.platform = object.platform ?? ""; + message.misc = object.misc ?? ""; + return message; + }, +}; + +function createBaseRendezvousMessage(): RendezvousMessage { + return { + registerPeer: undefined, + registerPeerResponse: undefined, + punchHoleRequest: undefined, + punchHole: undefined, + punchHoleSent: undefined, + punchHoleResponse: undefined, + fetchLocalAddr: undefined, + localAddr: undefined, + configureUpdate: undefined, + registerPk: undefined, + registerPkResponse: undefined, + softwareUpdate: undefined, + requestRelay: undefined, + relayResponse: undefined, + testNatRequest: undefined, + testNatResponse: undefined, + peerDiscovery: undefined, + }; +} + +export const RendezvousMessage = { + encode(message: RendezvousMessage, writer: Writer = Writer.create()): Writer { + if (message.registerPeer !== undefined) { + RegisterPeer.encode( + message.registerPeer, + writer.uint32(50).fork() + ).ldelim(); + } + if (message.registerPeerResponse !== undefined) { + RegisterPeerResponse.encode( + message.registerPeerResponse, + writer.uint32(58).fork() + ).ldelim(); + } + if (message.punchHoleRequest !== undefined) { + PunchHoleRequest.encode( + message.punchHoleRequest, + writer.uint32(66).fork() + ).ldelim(); + } + if (message.punchHole !== undefined) { + PunchHole.encode(message.punchHole, writer.uint32(74).fork()).ldelim(); + } + if (message.punchHoleSent !== undefined) { + PunchHoleSent.encode( + message.punchHoleSent, + writer.uint32(82).fork() + ).ldelim(); + } + if (message.punchHoleResponse !== undefined) { + PunchHoleResponse.encode( + message.punchHoleResponse, + writer.uint32(90).fork() + ).ldelim(); + } + if (message.fetchLocalAddr !== undefined) { + FetchLocalAddr.encode( + message.fetchLocalAddr, + writer.uint32(98).fork() + ).ldelim(); + } + if (message.localAddr !== undefined) { + LocalAddr.encode(message.localAddr, writer.uint32(106).fork()).ldelim(); + } + if (message.configureUpdate !== undefined) { + ConfigUpdate.encode( + message.configureUpdate, + writer.uint32(114).fork() + ).ldelim(); + } + if (message.registerPk !== undefined) { + RegisterPk.encode(message.registerPk, writer.uint32(122).fork()).ldelim(); + } + if (message.registerPkResponse !== undefined) { + RegisterPkResponse.encode( + message.registerPkResponse, + writer.uint32(130).fork() + ).ldelim(); + } + if (message.softwareUpdate !== undefined) { + SoftwareUpdate.encode( + message.softwareUpdate, + writer.uint32(138).fork() + ).ldelim(); + } + if (message.requestRelay !== undefined) { + RequestRelay.encode( + message.requestRelay, + writer.uint32(146).fork() + ).ldelim(); + } + if (message.relayResponse !== undefined) { + RelayResponse.encode( + message.relayResponse, + writer.uint32(154).fork() + ).ldelim(); + } + if (message.testNatRequest !== undefined) { + TestNatRequest.encode( + message.testNatRequest, + writer.uint32(162).fork() + ).ldelim(); + } + if (message.testNatResponse !== undefined) { + TestNatResponse.encode( + message.testNatResponse, + writer.uint32(170).fork() + ).ldelim(); + } + if (message.peerDiscovery !== undefined) { + PeerDiscovery.encode( + message.peerDiscovery, + writer.uint32(178).fork() + ).ldelim(); + } + return writer; + }, + + decode(input: Reader | Uint8Array, length?: number): RendezvousMessage { + const reader = input instanceof Reader ? input : new Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRendezvousMessage(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 6: + message.registerPeer = RegisterPeer.decode(reader, reader.uint32()); + break; + case 7: + message.registerPeerResponse = RegisterPeerResponse.decode( + reader, + reader.uint32() + ); + break; + case 8: + message.punchHoleRequest = PunchHoleRequest.decode( + reader, + reader.uint32() + ); + break; + case 9: + message.punchHole = PunchHole.decode(reader, reader.uint32()); + break; + case 10: + message.punchHoleSent = PunchHoleSent.decode(reader, reader.uint32()); + break; + case 11: + message.punchHoleResponse = PunchHoleResponse.decode( + reader, + reader.uint32() + ); + break; + case 12: + message.fetchLocalAddr = FetchLocalAddr.decode( + reader, + reader.uint32() + ); + break; + case 13: + message.localAddr = LocalAddr.decode(reader, reader.uint32()); + break; + case 14: + message.configureUpdate = ConfigUpdate.decode( + reader, + reader.uint32() + ); + break; + case 15: + message.registerPk = RegisterPk.decode(reader, reader.uint32()); + break; + case 16: + message.registerPkResponse = RegisterPkResponse.decode( + reader, + reader.uint32() + ); + break; + case 17: + message.softwareUpdate = SoftwareUpdate.decode( + reader, + reader.uint32() + ); + break; + case 18: + message.requestRelay = RequestRelay.decode(reader, reader.uint32()); + break; + case 19: + message.relayResponse = RelayResponse.decode(reader, reader.uint32()); + break; + case 20: + message.testNatRequest = TestNatRequest.decode( + reader, + reader.uint32() + ); + break; + case 21: + message.testNatResponse = TestNatResponse.decode( + reader, + reader.uint32() + ); + break; + case 22: + message.peerDiscovery = PeerDiscovery.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): RendezvousMessage { + return { + registerPeer: isSet(object.registerPeer) + ? RegisterPeer.fromJSON(object.registerPeer) + : undefined, + registerPeerResponse: isSet(object.registerPeerResponse) + ? RegisterPeerResponse.fromJSON(object.registerPeerResponse) + : undefined, + punchHoleRequest: isSet(object.punchHoleRequest) + ? PunchHoleRequest.fromJSON(object.punchHoleRequest) + : undefined, + punchHole: isSet(object.punchHole) + ? PunchHole.fromJSON(object.punchHole) + : undefined, + punchHoleSent: isSet(object.punchHoleSent) + ? PunchHoleSent.fromJSON(object.punchHoleSent) + : undefined, + punchHoleResponse: isSet(object.punchHoleResponse) + ? PunchHoleResponse.fromJSON(object.punchHoleResponse) + : undefined, + fetchLocalAddr: isSet(object.fetchLocalAddr) + ? FetchLocalAddr.fromJSON(object.fetchLocalAddr) + : undefined, + localAddr: isSet(object.localAddr) + ? LocalAddr.fromJSON(object.localAddr) + : undefined, + configureUpdate: isSet(object.configureUpdate) + ? ConfigUpdate.fromJSON(object.configureUpdate) + : undefined, + registerPk: isSet(object.registerPk) + ? RegisterPk.fromJSON(object.registerPk) + : undefined, + registerPkResponse: isSet(object.registerPkResponse) + ? RegisterPkResponse.fromJSON(object.registerPkResponse) + : undefined, + softwareUpdate: isSet(object.softwareUpdate) + ? SoftwareUpdate.fromJSON(object.softwareUpdate) + : undefined, + requestRelay: isSet(object.requestRelay) + ? RequestRelay.fromJSON(object.requestRelay) + : undefined, + relayResponse: isSet(object.relayResponse) + ? RelayResponse.fromJSON(object.relayResponse) + : undefined, + testNatRequest: isSet(object.testNatRequest) + ? TestNatRequest.fromJSON(object.testNatRequest) + : undefined, + testNatResponse: isSet(object.testNatResponse) + ? TestNatResponse.fromJSON(object.testNatResponse) + : undefined, + peerDiscovery: isSet(object.peerDiscovery) + ? PeerDiscovery.fromJSON(object.peerDiscovery) + : undefined, + }; + }, + + toJSON(message: RendezvousMessage): unknown { + const obj: any = {}; + message.registerPeer !== undefined && + (obj.registerPeer = message.registerPeer + ? RegisterPeer.toJSON(message.registerPeer) + : undefined); + message.registerPeerResponse !== undefined && + (obj.registerPeerResponse = message.registerPeerResponse + ? RegisterPeerResponse.toJSON(message.registerPeerResponse) + : undefined); + message.punchHoleRequest !== undefined && + (obj.punchHoleRequest = message.punchHoleRequest + ? PunchHoleRequest.toJSON(message.punchHoleRequest) + : undefined); + message.punchHole !== undefined && + (obj.punchHole = message.punchHole + ? PunchHole.toJSON(message.punchHole) + : undefined); + message.punchHoleSent !== undefined && + (obj.punchHoleSent = message.punchHoleSent + ? PunchHoleSent.toJSON(message.punchHoleSent) + : undefined); + message.punchHoleResponse !== undefined && + (obj.punchHoleResponse = message.punchHoleResponse + ? PunchHoleResponse.toJSON(message.punchHoleResponse) + : undefined); + message.fetchLocalAddr !== undefined && + (obj.fetchLocalAddr = message.fetchLocalAddr + ? FetchLocalAddr.toJSON(message.fetchLocalAddr) + : undefined); + message.localAddr !== undefined && + (obj.localAddr = message.localAddr + ? LocalAddr.toJSON(message.localAddr) + : undefined); + message.configureUpdate !== undefined && + (obj.configureUpdate = message.configureUpdate + ? ConfigUpdate.toJSON(message.configureUpdate) + : undefined); + message.registerPk !== undefined && + (obj.registerPk = message.registerPk + ? RegisterPk.toJSON(message.registerPk) + : undefined); + message.registerPkResponse !== undefined && + (obj.registerPkResponse = message.registerPkResponse + ? RegisterPkResponse.toJSON(message.registerPkResponse) + : undefined); + message.softwareUpdate !== undefined && + (obj.softwareUpdate = message.softwareUpdate + ? SoftwareUpdate.toJSON(message.softwareUpdate) + : undefined); + message.requestRelay !== undefined && + (obj.requestRelay = message.requestRelay + ? RequestRelay.toJSON(message.requestRelay) + : undefined); + message.relayResponse !== undefined && + (obj.relayResponse = message.relayResponse + ? RelayResponse.toJSON(message.relayResponse) + : undefined); + message.testNatRequest !== undefined && + (obj.testNatRequest = message.testNatRequest + ? TestNatRequest.toJSON(message.testNatRequest) + : undefined); + message.testNatResponse !== undefined && + (obj.testNatResponse = message.testNatResponse + ? TestNatResponse.toJSON(message.testNatResponse) + : undefined); + message.peerDiscovery !== undefined && + (obj.peerDiscovery = message.peerDiscovery + ? PeerDiscovery.toJSON(message.peerDiscovery) + : undefined); + return obj; + }, + + fromPartial, I>>( + object: I + ): RendezvousMessage { + const message = createBaseRendezvousMessage(); + message.registerPeer = + object.registerPeer !== undefined && object.registerPeer !== null + ? RegisterPeer.fromPartial(object.registerPeer) + : undefined; + message.registerPeerResponse = + object.registerPeerResponse !== undefined && + object.registerPeerResponse !== null + ? RegisterPeerResponse.fromPartial(object.registerPeerResponse) + : undefined; + message.punchHoleRequest = + object.punchHoleRequest !== undefined && object.punchHoleRequest !== null + ? PunchHoleRequest.fromPartial(object.punchHoleRequest) + : undefined; + message.punchHole = + object.punchHole !== undefined && object.punchHole !== null + ? PunchHole.fromPartial(object.punchHole) + : undefined; + message.punchHoleSent = + object.punchHoleSent !== undefined && object.punchHoleSent !== null + ? PunchHoleSent.fromPartial(object.punchHoleSent) + : undefined; + message.punchHoleResponse = + object.punchHoleResponse !== undefined && + object.punchHoleResponse !== null + ? PunchHoleResponse.fromPartial(object.punchHoleResponse) + : undefined; + message.fetchLocalAddr = + object.fetchLocalAddr !== undefined && object.fetchLocalAddr !== null + ? FetchLocalAddr.fromPartial(object.fetchLocalAddr) + : undefined; + message.localAddr = + object.localAddr !== undefined && object.localAddr !== null + ? LocalAddr.fromPartial(object.localAddr) + : undefined; + message.configureUpdate = + object.configureUpdate !== undefined && object.configureUpdate !== null + ? ConfigUpdate.fromPartial(object.configureUpdate) + : undefined; + message.registerPk = + object.registerPk !== undefined && object.registerPk !== null + ? RegisterPk.fromPartial(object.registerPk) + : undefined; + message.registerPkResponse = + object.registerPkResponse !== undefined && + object.registerPkResponse !== null + ? RegisterPkResponse.fromPartial(object.registerPkResponse) + : undefined; + message.softwareUpdate = + object.softwareUpdate !== undefined && object.softwareUpdate !== null + ? SoftwareUpdate.fromPartial(object.softwareUpdate) + : undefined; + message.requestRelay = + object.requestRelay !== undefined && object.requestRelay !== null + ? RequestRelay.fromPartial(object.requestRelay) + : undefined; + message.relayResponse = + object.relayResponse !== undefined && object.relayResponse !== null + ? RelayResponse.fromPartial(object.relayResponse) + : undefined; + message.testNatRequest = + object.testNatRequest !== undefined && object.testNatRequest !== null + ? TestNatRequest.fromPartial(object.testNatRequest) + : undefined; + message.testNatResponse = + object.testNatResponse !== undefined && object.testNatResponse !== null + ? TestNatResponse.fromPartial(object.testNatResponse) + : undefined; + message.peerDiscovery = + object.peerDiscovery !== undefined && object.peerDiscovery !== null + ? PeerDiscovery.fromPartial(object.peerDiscovery) + : undefined; + return message; + }, +}; + +declare var self: any | undefined; +declare var window: any | undefined; +declare var global: any | undefined; +var globalThis: any = (() => { + if (typeof globalThis !== "undefined") return globalThis; + if (typeof self !== "undefined") return self; + if (typeof window !== "undefined") return window; + if (typeof global !== "undefined") return global; + throw "Unable to locate global object"; +})(); + +const atob: (b64: string) => string = + globalThis.atob || + ((b64) => globalThis.Buffer.from(b64, "base64").toString("binary")); +function bytesFromBase64(b64: string): Uint8Array { + const bin = atob(b64); + const arr = new Uint8Array(bin.length); + for (let i = 0; i < bin.length; ++i) { + arr[i] = bin.charCodeAt(i); + } + return arr; +} + +const btoa: (bin: string) => string = + globalThis.btoa || + ((bin) => globalThis.Buffer.from(bin, "binary").toString("base64")); +function base64FromBytes(arr: Uint8Array): string { + const bin: string[] = []; + for (const byte of arr) { + bin.push(String.fromCharCode(byte)); + } + return btoa(bin.join("")); +} + +type Builtin = + | Date + | Function + | Uint8Array + | string + | number + | boolean + | undefined; + +export type DeepPartial = T extends Builtin + ? T + : T extends Array + ? Array> + : T extends ReadonlyArray + ? ReadonlyArray> + : T extends {} + ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin + ? P + : P & { [K in keyof P]: Exact } & Record< + Exclude>, + never + >; + +// If you get a compile-error about 'Constructor and ... have no overlap', +// add '--ts_proto_opt=esModuleInterop=true' as a flag when calling 'protoc'. +if (util.Long !== Long) { + util.Long = Long as any; + configure(); +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} diff --git a/ts_proto.py b/ts_proto.py new file mode 100644 index 000000000..d1627f51f --- /dev/null +++ b/ts_proto.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python + +import os + +path = os.path.abspath(os.path.join(os.getcwd(), '..', 'hbb', 'libs', 'hbb_common', 'protos')) + +if os.name == 'nt': + cmd = r'protoc --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd -I "%s" --ts_proto_out=./src/ rendezvous.proto'%path + print(cmd) + os.system(cmd) + cmd = r'protoc --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd -I "%s" --ts_proto_out=./src/ message.proto'%path + print(cmd) + os.system(cmd) +else: + cmd = r'protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto -I "%s" --ts_proto_out=./src/ rendezvous.proto'%path + print(cmd) + os.system(cmd) + cmd = r'protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto -I "%s" --ts_proto_out=./src/ message.proto'%path + print(cmd) + os.system(cmd) \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 2cfb703a5..8672df468 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,79 @@ # yarn lockfile v1 +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= + +"@types/long@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" + integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== + +"@types/node@>=13.7.0": + version "17.0.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b" + integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg== + +"@types/object-hash@^1.3.0": + version "1.3.4" + resolved "https://registry.yarnpkg.com/@types/object-hash/-/object-hash-1.3.4.tgz#079ba142be65833293673254831b5e3e847fe58b" + integrity sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA== + +dataloader@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-1.4.0.tgz#bca11d867f5d3f1b9ed9f737bd15970c65dff5c8" + integrity sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw== + esbuild-android-arm64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz#3fc3ff0bab76fe35dd237476b5d2b32bb20a3d44" @@ -134,11 +207,26 @@ is-core-module@^2.8.0: dependencies: has "^1.0.3" +lodash@^4.17.15: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + nanoid@^3.1.30: version "3.2.0" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== +object-hash@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -158,6 +246,30 @@ postcss@^8.4.5: picocolors "^1.0.0" source-map-js "^1.0.1" +prettier@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== + +protobufjs@^6.8.8: + version "6.11.2" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b" + integrity sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + resolve@^1.20.0: version "1.21.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f" @@ -184,6 +296,34 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +ts-poet@^4.5.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/ts-poet/-/ts-poet-4.10.0.tgz#8732374655e87f8f833e5d110938e346713e8c66" + integrity sha512-V5xzt+LDMVtxWvK12WVwHhGHTA//CeoPdWOqka0mMjlRqq7RPKYSfWEnzJdMmhNbd34BwZuZpip4mm+nqEcbQA== + dependencies: + lodash "^4.17.15" + prettier "^2.5.1" + +ts-proto-descriptors@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/ts-proto-descriptors/-/ts-proto-descriptors-1.3.1.tgz#760ebaaa19475b03662f7b358ffea45b9c5348f5" + integrity sha512-Cybb3fqceMwA6JzHdC32dIo8eVGVmXrM6TWhdk1XQVVHT/6OQqk0ioyX1dIdu3rCIBhRmWUhUE4HsyK+olmgMw== + dependencies: + long "^4.0.0" + protobufjs "^6.8.8" + +ts-proto@^1.101.0: + version "1.101.0" + resolved "https://registry.yarnpkg.com/ts-proto/-/ts-proto-1.101.0.tgz#f8ce4523a0cb32ff224ff8a5759c2c046bf96244" + integrity sha512-XUV0WKQ3icHMToOOpUjf0RCKF9md+Lu9TV00LQlZ6ailJhbBqLh0BXQJ1PFUGxEW8YV65Wc/N8vAir152OE2Sg== + dependencies: + "@types/object-hash" "^1.3.0" + dataloader "^1.4.0" + object-hash "^1.3.1" + protobufjs "^6.8.8" + ts-poet "^4.5.0" + ts-proto-descriptors "^1.2.1" + typescript@^4.4.4: version "4.5.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" From fa31257cdc4b210445064de8af6346e1bdb1385e Mon Sep 17 00:00:00 2001 From: open-trade Date: Mon, 17 Jan 2022 18:11:14 +0800 Subject: [PATCH 03/66] initialize websock.ts --- src/websock.ts | 116 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/websock.ts diff --git a/src/websock.ts b/src/websock.ts new file mode 100644 index 000000000..abc5c6bc8 --- /dev/null +++ b/src/websock.ts @@ -0,0 +1,116 @@ +import * as proto from '../message.js'; + +export default class Websock { + constructor() { + this._websocket = null; // WebSocket object + this._eventHandlers = { + message: (msg) => { }, + open: () => { }, + close: () => { }, + error: () => { } + }; + this._next_yuv = null; + this._next_rgb = null; + } + + send(msg) { + if (msg instanceof Object) msg = proto.encodeMessage(msg); + this._websocket.send(msg); + } + + // Event Handlers + off(evt) { + this._eventHandlers[evt] = () => { }; + } + + on(evt, handler) { + this._eventHandlers[evt] = handler; + } + + init() { + this._websocket = null; + } + + open(uri, protocols) { + this.init(); + + this._websocket = new WebSocket(uri, protocols); + + this._websocket.onmessage = this._recv_message.bind(this); + this._websocket.binaryType = 'arraybuffer'; + this._websocket.onopen = () => { + console.debug('>> WebSock.onopen'); + if (this._websocket.protocol) { + console.info("Server choose sub-protocol: " + this._websocket.protocol); + } + + this._eventHandlers.open(); + console.debug("<< WebSock.onopen"); + }; + this._websocket.onclose = (e) => { + console.debug(">> WebSock.onclose"); + this._eventHandlers.close(e); + console.debug("<< WebSock.onclose"); + }; + this._websocket.onerror = (e) => { + console.debug(">> WebSock.onerror: " + e); + this._eventHandlers.error(e); + console.debug("<< WebSock.onerror: " + e); + }; + } + + close() { + if (this._websocket) { + if ((this._websocket.readyState === WebSocket.OPEN) || + (this._websocket.readyState === WebSocket.CONNECTING)) { + console.info("Closing WebSocket connection"); + this._websocket.close(); + } + + this._websocket.onmessage = () => { }; + } + } + + _recv_message(e) { + if (e.data instanceof window.ArrayBuffer) { + let bytes = new Uint8Array(e.data); + if (this._next_yuv) { + const yuv = this._next_yuv; + const { compress, stride } = yuv.format; + if (compress) { + bytes = window.simple_zstd.decompress(bytes); + } + if (!yuv.y) { + yuv.y = { bytes, stride: stride }; + } else if (!yuv.u) { + yuv.u = { bytes, stride: stride >> 1 }; + } else { + yuv.v = { bytes, stride: stride >> 1 }; + delete yuv.format.stride; + this._eventHandlers.message({ video_frame: { yuv } }); + this._next_yuv = null; + } + } else if (this._next_rgb) { + if (this._next_rgb.format.compress) { + bytes = window.simple_zstd.decompress(bytes); + } + this._eventHandlers.message({ video_frame: { rgb: bytes } }); + this._next_rgb = null; + } else { + const msg = proto.decodeMessage(bytes); + let vf = msg.video_frame; + if (vf) { + const { yuv, rgb } = vf; + if (yuv) { + this._next_yuv = { format: yuv }; + } else if (rgb) { + this._next_rgb = { format: rgb }; + } + return; + } else { + this._eventHandlers.message(msg); + } + } + } + } +} \ No newline at end of file From d4e8a66cf6439239a2f93e72d75294fd30cf7cd3 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Tue, 18 Jan 2022 02:02:39 +0800 Subject: [PATCH 04/66] websock init --- src/websock.ts | 185 ++++++++++++++++++++----------------------------- 1 file changed, 74 insertions(+), 111 deletions(-) diff --git a/src/websock.ts b/src/websock.ts index abc5c6bc8..2c6483584 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -1,116 +1,79 @@ -import * as proto from '../message.js'; +import * as message from "./message.js"; +import * as rendezvous from "./rendezvous.js"; + +type Keys = "message" | "open" | "close" | "error"; export default class Websock { - constructor() { - this._websocket = null; // WebSocket object - this._eventHandlers = { - message: (msg) => { }, - open: () => { }, - close: () => { }, - error: () => { } - }; - this._next_yuv = null; - this._next_rgb = null; + _websocket: WebSocket; + _eventHandlers: { [key in Keys]: Function }; + + send_message(msg: message.Message) { + this._websocket.send(message.Message.encode(msg).finish()); + } + + send_rendezvous(msg: rendezvous.RendezvousMessage) { + this._websocket.send(rendezvous.RendezvousMessage.encode(msg).finish()); + } + + // Event Handlers + off(evt: Keys) { + this._eventHandlers[evt] = () => {}; + } + + on(evt: Keys, handler: Function) { + this._eventHandlers[evt] = handler; + } + + constructor(uri: string, protocols: string) { + this._eventHandlers = { + message: (_: string) => {}, + open: () => {}, + close: () => {}, + error: () => {}, + }; + + this._websocket = new WebSocket(uri, protocols); + + this._websocket.onmessage = this._recv_message.bind(this); + this._websocket.binaryType = "arraybuffer"; + this._websocket.onopen = () => { + console.debug(">> WebSock.onopen"); + if (this._websocket.protocol) { + console.info("Server choose sub-protocol: " + this._websocket.protocol); + } + + this._eventHandlers.open(); + console.debug("<< WebSock.onopen"); + }; + this._websocket.onclose = (e) => { + console.debug(">> WebSock.onclose"); + this._eventHandlers.close(e); + console.debug("<< WebSock.onclose"); + }; + this._websocket.onerror = (e) => { + console.debug(">> WebSock.onerror: " + e); + this._eventHandlers.error(e); + console.debug("<< WebSock.onerror: " + e); + }; + } + + close() { + if (this._websocket) { + if ( + this._websocket.readyState === WebSocket.OPEN || + this._websocket.readyState === WebSocket.CONNECTING + ) { + console.info("Closing WebSocket connection"); + this._websocket.close(); + } + + this._websocket.onmessage = () => {}; } + } - send(msg) { - if (msg instanceof Object) msg = proto.encodeMessage(msg); - this._websocket.send(msg); + _recv_message(e: any) { + if (e.data instanceof window.ArrayBuffer) { + let bytes = new Uint8Array(e.data); } - - // Event Handlers - off(evt) { - this._eventHandlers[evt] = () => { }; - } - - on(evt, handler) { - this._eventHandlers[evt] = handler; - } - - init() { - this._websocket = null; - } - - open(uri, protocols) { - this.init(); - - this._websocket = new WebSocket(uri, protocols); - - this._websocket.onmessage = this._recv_message.bind(this); - this._websocket.binaryType = 'arraybuffer'; - this._websocket.onopen = () => { - console.debug('>> WebSock.onopen'); - if (this._websocket.protocol) { - console.info("Server choose sub-protocol: " + this._websocket.protocol); - } - - this._eventHandlers.open(); - console.debug("<< WebSock.onopen"); - }; - this._websocket.onclose = (e) => { - console.debug(">> WebSock.onclose"); - this._eventHandlers.close(e); - console.debug("<< WebSock.onclose"); - }; - this._websocket.onerror = (e) => { - console.debug(">> WebSock.onerror: " + e); - this._eventHandlers.error(e); - console.debug("<< WebSock.onerror: " + e); - }; - } - - close() { - if (this._websocket) { - if ((this._websocket.readyState === WebSocket.OPEN) || - (this._websocket.readyState === WebSocket.CONNECTING)) { - console.info("Closing WebSocket connection"); - this._websocket.close(); - } - - this._websocket.onmessage = () => { }; - } - } - - _recv_message(e) { - if (e.data instanceof window.ArrayBuffer) { - let bytes = new Uint8Array(e.data); - if (this._next_yuv) { - const yuv = this._next_yuv; - const { compress, stride } = yuv.format; - if (compress) { - bytes = window.simple_zstd.decompress(bytes); - } - if (!yuv.y) { - yuv.y = { bytes, stride: stride }; - } else if (!yuv.u) { - yuv.u = { bytes, stride: stride >> 1 }; - } else { - yuv.v = { bytes, stride: stride >> 1 }; - delete yuv.format.stride; - this._eventHandlers.message({ video_frame: { yuv } }); - this._next_yuv = null; - } - } else if (this._next_rgb) { - if (this._next_rgb.format.compress) { - bytes = window.simple_zstd.decompress(bytes); - } - this._eventHandlers.message({ video_frame: { rgb: bytes } }); - this._next_rgb = null; - } else { - const msg = proto.decodeMessage(bytes); - let vf = msg.video_frame; - if (vf) { - const { yuv, rgb } = vf; - if (yuv) { - this._next_yuv = { format: yuv }; - } else if (rgb) { - this._next_rgb = { format: rgb }; - } - return; - } else { - this._eventHandlers.message(msg); - } - } - } - } -} \ No newline at end of file + } +} From c09f65b6cc25c970daa0989e9fa38ed671b0004f Mon Sep 17 00:00:00 2001 From: open-trade Date: Tue, 18 Jan 2022 17:05:34 +0800 Subject: [PATCH 05/66] try out ogv codec loader --- package.json | 4 +++- src/codec.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.ts | 6 +++++- src/vite-env.d.ts | 2 +- tsconfig.json | 12 +++++++++--- yarn.lock | 24 ++++++++++++++++++++++++ 6 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 src/codec.js diff --git a/package.json b/package.json index abe5dd151..17f883055 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "web_hbb", "version": "1.0.0", "scripts": { - "dev": "vite", + "dev": "cp node_modules/ogv/dist/* dist/ && vite", "build": "tsc && vite build", "preview": "vite preview" }, @@ -11,6 +11,8 @@ "vite": "^2.7.2" }, "dependencies": { + "libsodium": "^0.7.9", + "ogv": "^1.8.6", "ts-proto": "^1.101.0" } } diff --git a/src/codec.js b/src/codec.js new file mode 100644 index 000000000..384a5165e --- /dev/null +++ b/src/codec.js @@ -0,0 +1,47 @@ +import { OGVLoader } from "ogv"; + +// example: https://github.com/rgov/js-theora-decoder/blob/main/index.html +// dev: copy decoder files from node/ogv/dist/* to project dir +// dist: .... to dist + +export function loadVp9() { + OGVLoader.loadClass( + "OGVDecoderVideoVP9W", + (videoCodecClass) => { + videoCodecClass().then((decoder) => { + decoder.init(() => { + onVp9Ready(decoder) + }) + }) + }, + { worker: true } + ); +} + +export function loadOpus() { + OGVLoader.loadClass( + "OGVDecoderAudioOpusW", + (audioCodecClass) => { + audioCodecClass().then((decoder) => { + decoder.init(() => { + onOpusReady(decoder) + }) + }) + }, + { worker: true } + ); +} + +async function onVp9Ready(decoder) { + console.log("Vp9 decoder ready"); + + /* + decoder.processFrame(buffer, () => { + player.drawFrame(decoder.frameBuffer) + }) + */ +} + +async function onOpusReady(decoder) { + console.log("Opus decoder ready"); +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index f77db7a8f..00470a0a5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,8 @@ -import './style.css' +import './style.css'; +import { loadVp9, loadOpus } from "./codec"; + +loadVp9(); +loadOpus(); const app = document.querySelector('#app')! diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 11f02fe2a..151aa6856 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1 +1 @@ -/// +/// \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 8cdbb2ac9..ca949de6a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,11 @@ "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", - "lib": ["ESNext", "DOM"], + "allowJs": true, + "lib": [ + "ESNext", + "DOM" + ], "moduleResolution": "Node", "strict": true, "sourceMap": true, @@ -14,5 +18,7 @@ "noUnusedParameters": true, "noImplicitReturns": true }, - "include": ["./src"] -} + "include": [ + "./src" + ] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 8672df468..f1a562057 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,13 @@ # yarn lockfile v1 +"@babel/runtime@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" + integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== + dependencies: + regenerator-runtime "^0.13.4" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -207,6 +214,11 @@ is-core-module@^2.8.0: dependencies: has "^1.0.3" +libsodium@^0.7.9: + version "0.7.9" + resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.9.tgz#4bb7bcbf662ddd920d8795c227ae25bbbfa3821b" + integrity sha512-gfeADtR4D/CM0oRUviKBViMGXZDgnFdMKMzHsvBdqLBHd9ySi6EtYnmuhHVDDYgYpAO8eU8hEY+F8vIUAPh08A== + lodash@^4.17.15: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -227,6 +239,13 @@ object-hash@^1.3.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== +ogv@^1.8.6: + version "1.8.6" + resolved "https://registry.yarnpkg.com/ogv/-/ogv-1.8.6.tgz#0e6fa1c166802e3a405b1b318d8eb27d2544cce9" + integrity sha512-YuvO37U7Hc0mIm/TyAbyn3qVDKgg+4b+ViU73qEGzEKVX8bdxEVH08SoYrGLTJ2b8Z1/IEx8Vdy0hO4CWhRMOA== + dependencies: + "@babel/runtime" "^7.16.7" + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -270,6 +289,11 @@ protobufjs@^6.8.8: "@types/node" ">=13.7.0" long "^4.0.0" +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + resolve@^1.20.0: version "1.21.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f" From 9f42fd534ccd2608324c51398200e5f7ce51b2ec Mon Sep 17 00:00:00 2001 From: open-trade Date: Tue, 18 Jan 2022 17:24:36 +0800 Subject: [PATCH 06/66] put ogv.js to html --- .gitignore | 4 +++- index.html | 1 + package.json | 4 ++-- src/codec.js | 23 +++++++++++++++++++---- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 53f7466ac..f2ed50767 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ node_modules .DS_Store dist dist-ssr -*.local \ No newline at end of file +*.local +*log +ogvjs diff --git a/index.html b/index.html index 867581c51..c88142fa2 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,7 @@ + Vite App diff --git a/package.json b/package.json index 17f883055..f68287840 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,8 @@ "name": "web_hbb", "version": "1.0.0", "scripts": { - "dev": "cp node_modules/ogv/dist/* dist/ && vite", - "build": "tsc && vite build", + "dev": "cp -rf node_modules/ogv/dist/* ogvjs/ && vite", + "build": "cp node_modules/ogv/dist/* dist/ogvjs/ && tsc && vite build", "preview": "vite preview" }, "devDependencies": { diff --git a/src/codec.js b/src/codec.js index 384a5165e..6b44321b6 100644 --- a/src/codec.js +++ b/src/codec.js @@ -1,11 +1,26 @@ -import { OGVLoader } from "ogv"; - // example: https://github.com/rgov/js-theora-decoder/blob/main/index.html // dev: copy decoder files from node/ogv/dist/* to project dir // dist: .... to dist +/* + OGVDemuxerOggW: 'ogv-demuxer-ogg-wasm.js', + OGVDemuxerWebMW: 'ogv-demuxer-webm-wasm.js', + OGVDecoderAudioOpusW: 'ogv-decoder-audio-opus-wasm.js', + OGVDecoderAudioVorbisW: 'ogv-decoder-audio-vorbis-wasm.js', + OGVDecoderVideoTheoraW: 'ogv-decoder-video-theora-wasm.js', + OGVDecoderVideoVP8W: 'ogv-decoder-video-vp8-wasm.js', + OGVDecoderVideoVP8MTW: 'ogv-decoder-video-vp8-mt-wasm.js', + OGVDecoderVideoVP9W: 'ogv-decoder-video-vp9-wasm.js', + OGVDecoderVideoVP9SIMDW: 'ogv-decoder-video-vp9-simd-wasm.js', + OGVDecoderVideoVP9MTW: 'ogv-decoder-video-vp9-mt-wasm.js', + OGVDecoderVideoVP9SIMDMTW: 'ogv-decoder-video-vp9-simd-mt-wasm.js', + OGVDecoderVideoAV1W: 'ogv-decoder-video-av1-wasm.js', + OGVDecoderVideoAV1SIMDW: 'ogv-decoder-video-av1-simd-wasm.js', + OGVDecoderVideoAV1MTW: 'ogv-decoder-video-av1-mt-wasm.js', + OGVDecoderVideoAV1SIMDMTW: 'ogv-decoder-video-av1-simd-mt-wasm.js', +*/ export function loadVp9() { - OGVLoader.loadClass( + window.OGVLoader.loadClass( "OGVDecoderVideoVP9W", (videoCodecClass) => { videoCodecClass().then((decoder) => { @@ -19,7 +34,7 @@ export function loadVp9() { } export function loadOpus() { - OGVLoader.loadClass( + window.OGVLoader.loadClass( "OGVDecoderAudioOpusW", (audioCodecClass) => { audioCodecClass().then((decoder) => { From d7d4b46c46e8847c63f7925d5b9bb4f4ae162db4 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Wed, 19 Jan 2022 00:57:57 +0800 Subject: [PATCH 07/66] sha256 --- package.json | 1 + src/websock.ts | 7 +++++++ yarn.lock | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/package.json b/package.json index f68287840..ae337fb4b 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "vite": "^2.7.2" }, "dependencies": { + "fast-sha256": "^1.3.0", "libsodium": "^0.7.9", "ogv": "^1.8.6", "ts-proto": "^1.101.0" diff --git a/src/websock.ts b/src/websock.ts index 2c6483584..67af1c139 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -1,5 +1,6 @@ import * as message from "./message.js"; import * as rendezvous from "./rendezvous.js"; +import * as sha256 from "fast-sha256"; type Keys = "message" | "open" | "close" | "error"; @@ -76,4 +77,10 @@ export default class Websock { let bytes = new Uint8Array(e.data); } } + + hash(datas: [Uint8Array]): Uint8Array { + const hasher = new sha256.Hash(); + datas.forEach((data) => hasher.update(data)); + return hasher.digest(); + } } diff --git a/yarn.lock b/yarn.lock index f1a562057..c71b7d1c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -190,6 +190,11 @@ esbuild@^0.13.12: esbuild-windows-64 "0.13.15" esbuild-windows-arm64 "0.13.15" +fast-sha256@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-sha256/-/fast-sha256-1.3.0.tgz#7916ba2054eeb255982608cccd0f6660c79b7ae6" + integrity sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ== + fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" From a90cacaeb88b1c48189b271cf44e1047e6148ae8 Mon Sep 17 00:00:00 2001 From: open-trade Date: Wed, 19 Jan 2022 19:13:49 +0800 Subject: [PATCH 08/66] will implement async web sock myself --- src/main.ts | 1 + src/websock.ts | 12 +++ yarn.lock | 266 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 279 insertions(+) diff --git a/src/main.ts b/src/main.ts index 00470a0a5..872e81375 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,6 @@ import './style.css'; import { loadVp9, loadOpus } from "./codec"; +import './websock'; loadVp9(); loadOpus(); diff --git a/src/websock.ts b/src/websock.ts index 67af1c139..04b7fca7c 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -84,3 +84,15 @@ export default class Websock { return hasher.digest(); } } + +/* +let ws = new Websock('ws://207.148.17.15:21118'); +await ws.open(); +console.log("ws connected"); +// let punchHole = rendezvous.PunchHoleRequest.fromJSON({ id: '' }); +// ws.send_rendezvous(rendezvous.RendezvousMessage.fromJSON({ punchHole })); +let testNatRequest = rendezvous.TestNatRequest.fromJSON({ serial: 0 }); +ws.send_rendezvous(rendezvous.RendezvousMessage.fromJSON({ testNatRequest })); +let msg = await ws.next(); +console.log(msg); +*/ \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index c71b7d1c5..22a489545 100644 --- a/yarn.lock +++ b/yarn.lock @@ -77,11 +77,66 @@ resolved "https://registry.yarnpkg.com/@types/object-hash/-/object-hash-1.3.4.tgz#079ba142be65833293673254831b5e3e847fe58b" integrity sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA== +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +chnl@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/chnl/-/chnl-1.2.0.tgz#d818c95367767a0880508e7cc0b5b3503f58fd4c" + integrity sha512-g5gJb59edwCliFbX2j7G6sBfY4sX9YLy211yctONI2GRaiX0f2zIbKWmBm+sPqFNEpM7Ljzm7IJX/xrjiEbPrw== + dataloader@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-1.4.0.tgz#bca11d867f5d3f1b9ed9f737bd15970c65dff5c8" integrity sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw== +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + esbuild-android-arm64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz#3fc3ff0bab76fe35dd237476b5d2b32bb20a3d44" @@ -205,6 +260,40 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -212,6 +301,35 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + is-core-module@^2.8.0: version "2.8.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" @@ -219,6 +337,59 @@ is-core-module@^2.8.0: dependencies: has "^1.0.3" +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-negative-zero@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-weakref@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + libsodium@^0.7.9: version "0.7.9" resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.9.tgz#4bb7bcbf662ddd920d8795c227ae25bbbfa3821b" @@ -244,6 +415,26 @@ object-hash@^1.3.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + ogv@^1.8.6: version "1.8.6" resolved "https://registry.yarnpkg.com/ogv/-/ogv-1.8.6.tgz#0e6fa1c166802e3a405b1b318d8eb27d2544cce9" @@ -275,6 +466,25 @@ prettier@^2.5.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== +promise-controller@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/promise-controller/-/promise-controller-1.0.0.tgz#81ebea71271aa40ac8f3bebccab3d4158dc4cc02" + integrity sha512-goA0zA9L91tuQbUmiMinSYqlyUtEgg4fxJcjYnLYOQnrktb4o4UqciXDNXiRUPiDBPACmsr1k8jDW4r7UDq9Qw== + +promise.prototype.finally@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.3.tgz#d3186e58fcf4df1682a150f934ccc27b7893389c" + integrity sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +promised-map@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/promised-map/-/promised-map-1.0.0.tgz#aa3ec59e13724d37b946415f6850273af8e213b5" + integrity sha512-fP9VSMgcml+U2uJ9PBc4/LDQ3ZkJCH4blLNCS6gbH7RHyRZCYs91zxWHqiUy+heFiEMiB2op/qllYoFqmIqdWA== + protobufjs@^6.8.8: version "6.11.2" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b" @@ -315,11 +525,36 @@ rollup@^2.59.0: optionalDependencies: fsevents "~2.3.2" +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + source-map-js@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -358,6 +593,16 @@ typescript@^4.4.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + vite@^2.7.2: version "2.7.12" resolved "https://registry.yarnpkg.com/vite/-/vite-2.7.12.tgz#7784ab19e7ff98f6a192d2d7d877480a8c2b7e7d" @@ -369,3 +614,24 @@ vite@^2.7.2: rollup "^2.59.0" optionalDependencies: fsevents "~2.3.2" + +websocket-as-promised@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/websocket-as-promised/-/websocket-as-promised-2.0.1.tgz#d18b7c160bba294585aaf6fa9572f31e05cfb175" + integrity sha512-ePV26D/D37ughXU9j+DjGmwUbelWJrC/vi+6GK++fRlBJmS7aU9T8ABu47KFF0O7r6XN2NAuqJRpegbUwXZxQg== + dependencies: + chnl "^1.2.0" + promise-controller "^1.0.0" + promise.prototype.finally "^3.1.2" + promised-map "^1.0.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" From b18da1fb39d67dae1c3830689735c2cecac75e58 Mon Sep 17 00:00:00 2001 From: open-trade Date: Wed, 19 Jan 2022 19:19:29 +0800 Subject: [PATCH 09/66] nothing --- src/websock.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/websock.ts b/src/websock.ts index 04b7fca7c..052adf9b2 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -18,7 +18,7 @@ export default class Websock { // Event Handlers off(evt: Keys) { - this._eventHandlers[evt] = () => {}; + this._eventHandlers[evt] = () => { }; } on(evt: Keys, handler: Function) { @@ -27,10 +27,10 @@ export default class Websock { constructor(uri: string, protocols: string) { this._eventHandlers = { - message: (_: string) => {}, - open: () => {}, - close: () => {}, - error: () => {}, + message: (_: any) => { }, + open: () => { }, + close: () => { }, + error: () => { }, }; this._websocket = new WebSocket(uri, protocols); @@ -68,7 +68,7 @@ export default class Websock { this._websocket.close(); } - this._websocket.onmessage = () => {}; + this._websocket.onmessage = () => { }; } } @@ -76,6 +76,7 @@ export default class Websock { if (e.data instanceof window.ArrayBuffer) { let bytes = new Uint8Array(e.data); } + this._eventHandlers.message(e.data); } hash(datas: [Uint8Array]): Uint8Array { From 85ec94e36cf5fbab9318fe006f91788cd7d8e9a6 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Wed, 19 Jan 2022 22:26:23 +0800 Subject: [PATCH 10/66] ws async works --- src/websock.ts | 135 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 97 insertions(+), 38 deletions(-) diff --git a/src/websock.ts b/src/websock.ts index 052adf9b2..acd9c3b58 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -7,55 +7,115 @@ type Keys = "message" | "open" | "close" | "error"; export default class Websock { _websocket: WebSocket; _eventHandlers: { [key in Keys]: Function }; + _buf: Uint8Array[]; + _status: any; - send_message(msg: message.Message) { - this._websocket.send(message.Message.encode(msg).finish()); + constructor(uri: string) { + this._eventHandlers = { + message: (_: any) => {}, + open: () => {}, + close: () => {}, + error: () => {}, + }; + this._status = ""; + this._buf = []; + this._websocket = new WebSocket(uri); + this._websocket.onmessage = this._recv_message.bind(this); + this._websocket.binaryType = "arraybuffer"; } - send_rendezvous(msg: rendezvous.RendezvousMessage) { - this._websocket.send(rendezvous.RendezvousMessage.encode(msg).finish()); + sendMessage(data: any) { + this._websocket.send( + message.Message.encode(message.Message.fromJSON(data)).finish() + ); + } + + sendRendezvous(data: any) { + this._websocket.send( + rendezvous.RendezvousMessage.encode( + rendezvous.RendezvousMessage.fromJSON(data) + ).finish() + ); + } + + parseMessage(data: Uint8Array) { + return message.Message.decode(data); + } + + parseRendezvous(data: Uint8Array) { + return rendezvous.RendezvousMessage.decode(data); } // Event Handlers off(evt: Keys) { - this._eventHandlers[evt] = () => { }; + this._eventHandlers[evt] = () => {}; } on(evt: Keys, handler: Function) { this._eventHandlers[evt] = handler; } - constructor(uri: string, protocols: string) { - this._eventHandlers = { - message: (_: any) => { }, - open: () => { }, - close: () => { }, - error: () => { }, - }; + async open(timeout: number = 12000): Promise { + return new Promise((resolve, reject) => { + setTimeout(() => { + if (this._status != "open") { + reject(this._status || "timeout"); + } + }, timeout); + this._websocket.onopen = () => { + this._status = "open"; + console.debug(">> WebSock.onopen"); + if (this._websocket?.protocol) { + console.info( + "Server choose sub-protocol: " + this._websocket.protocol + ); + } - this._websocket = new WebSocket(uri, protocols); + this._eventHandlers.open(); + console.debug("<< WebSock.onopen"); + resolve(this); + }; + this._websocket.onclose = (e) => { + this._status = e; + console.debug(">> WebSock.onclose"); + this._eventHandlers.close(e); + console.debug("<< WebSock.onclose"); + reject(e); + }; + this._websocket.onerror = (e) => { + this._status = e; + console.debug(">> WebSock.onerror: " + e); + this._eventHandlers.error(e); + console.debug("<< WebSock.onerror: " + e); + reject(e); + }; + }); + } - this._websocket.onmessage = this._recv_message.bind(this); - this._websocket.binaryType = "arraybuffer"; - this._websocket.onopen = () => { - console.debug(">> WebSock.onopen"); - if (this._websocket.protocol) { - console.info("Server choose sub-protocol: " + this._websocket.protocol); + async next(timeout = 12000): Promise { + let func = ( + resolve: (value: Uint8Array) => void, + reject: (reason: any) => void, + tm0: number + ) => { + if (this._buf.length) { + resolve(this._buf[0]); + this._buf.splice(0, 1); + } else { + if (this._status != 'open') { + reject(this._status); + return; + } + if (new Date().getTime() > tm0 + timeout) { + reject("timeout"); + } else { + setTimeout(() => func(resolve, reject, tm0), 1); + } } - - this._eventHandlers.open(); - console.debug("<< WebSock.onopen"); - }; - this._websocket.onclose = (e) => { - console.debug(">> WebSock.onclose"); - this._eventHandlers.close(e); - console.debug("<< WebSock.onclose"); - }; - this._websocket.onerror = (e) => { - console.debug(">> WebSock.onerror: " + e); - this._eventHandlers.error(e); - console.debug("<< WebSock.onerror: " + e); }; + return new Promise((resolve, reject) => { + func(resolve, reject, new Date().getTime()); + }); } close() { @@ -68,13 +128,14 @@ export default class Websock { this._websocket.close(); } - this._websocket.onmessage = () => { }; + this._websocket.onmessage = () => {}; } } _recv_message(e: any) { if (e.data instanceof window.ArrayBuffer) { let bytes = new Uint8Array(e.data); + this._buf.push(bytes); } this._eventHandlers.message(e.data); } @@ -86,14 +147,12 @@ export default class Websock { } } -/* -let ws = new Websock('ws://207.148.17.15:21118'); +let ws = new Websock("ws://207.148.17.15:21118"); await ws.open(); console.log("ws connected"); // let punchHole = rendezvous.PunchHoleRequest.fromJSON({ id: '' }); // ws.send_rendezvous(rendezvous.RendezvousMessage.fromJSON({ punchHole })); let testNatRequest = rendezvous.TestNatRequest.fromJSON({ serial: 0 }); -ws.send_rendezvous(rendezvous.RendezvousMessage.fromJSON({ testNatRequest })); -let msg = await ws.next(); +ws.sendRendezvous({ testNatRequest }); +let msg = ws.parseRendezvous(await ws.next()); console.log(msg); -*/ \ No newline at end of file From 28c096769061ffc9c2c6ac3e64903c35d168f10d Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 20 Jan 2022 01:00:35 +0800 Subject: [PATCH 11/66] can make relay connection now --- src/client.ts | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ src/codec.js | 88 +++++++++++++++++++++---------------------- src/main.ts | 6 +-- src/websock.ts | 31 +++++++-------- 4 files changed, 158 insertions(+), 67 deletions(-) create mode 100644 src/client.ts diff --git a/src/client.ts b/src/client.ts new file mode 100644 index 000000000..bc8170783 --- /dev/null +++ b/src/client.ts @@ -0,0 +1,100 @@ +import Websock from "./websock"; +import * as message from "./message.js"; +import * as rendezvous from "./rendezvous.js"; +import { loadVp9, loadOpus } from "./codec"; + +const URI = "ws://207.148.17.15"; +const PORT = 21118; +const licenceKey = ""; + +loadVp9(); +loadOpus(); + +export default class Client { + _msgs: any[]; + _ws: Websock | undefined; + _interval: any; + _id: string; + + constructor() { + this._msgs = []; + this._id = ''; + this._interval = setInterval(() => { + while (this._msgs.length) { + this._ws?.sendMessage(this._msgs[0]); + this._msgs.splice(0, 1); + } + }, 1); + } + + close() { + clearInterval(this._interval); + this._ws?.close(); + } + + async connect(id: string) { + const ws = new Websock(URI + ":" + PORT); + this._ws = ws; + this._id = id; + await ws.open(); + const connType = rendezvous.ConnType.DEFAULT_CONN; + const natType = rendezvous.NatType.SYMMETRIC; + const punchHoleRequest = rendezvous.PunchHoleRequest.fromJSON({ + id, + licenceKey, + connType, + natType, + }); + ws.sendRendezvous({ punchHoleRequest }); + const msg = ws.parseRendezvous(await ws.next()); + const phr = msg.punchHoleResponse; + const rr = msg.relayResponse; + if (phr) { + if (phr.failure != rendezvous.PunchHoleResponse_Failure.UNKNOWN) { + switch (phr?.failure) { + case rendezvous.PunchHoleResponse_Failure.ID_NOT_EXIST: + break; + } + ws.close(); + } + } else if (rr) { + await this.connectRelay(rr); + } + } + + async connectRelay(rr: rendezvous.RelayResponse) { + const pk = rr.pk; + let uri = rr.relayServer; + if (uri.indexOf(':') > 0) { + const tmp = uri.split(':'); + const port = parseInt(tmp[1]); + uri = tmp[0] + ':' + (port + 2); + } else { + uri += ':' + (PORT + 1); + } + const uuid = rr.uuid; + const ws = new Websock('ws://' + uri); + await ws.open(); + console.log('Connected to relay server') + this._ws = ws; + const requestRelay = rendezvous.RequestRelay.fromJSON({ + licenceKey, + uuid, + }); + ws.sendRendezvous({ requestRelay }); + await this.secure(pk); + } + + async secure(pk: Uint8Array | undefined) { + // + } +} + +async function testDelay() { + const ws = new Websock(URI + ":" + PORT); + await ws.open(); + console.log(ws.latency()); +} + +await testDelay(); +await new Client().connect("124931507"); diff --git a/src/codec.js b/src/codec.js index 6b44321b6..6f1381d96 100644 --- a/src/codec.js +++ b/src/codec.js @@ -2,61 +2,61 @@ // dev: copy decoder files from node/ogv/dist/* to project dir // dist: .... to dist /* - OGVDemuxerOggW: 'ogv-demuxer-ogg-wasm.js', - OGVDemuxerWebMW: 'ogv-demuxer-webm-wasm.js', - OGVDecoderAudioOpusW: 'ogv-decoder-audio-opus-wasm.js', - OGVDecoderAudioVorbisW: 'ogv-decoder-audio-vorbis-wasm.js', - OGVDecoderVideoTheoraW: 'ogv-decoder-video-theora-wasm.js', - OGVDecoderVideoVP8W: 'ogv-decoder-video-vp8-wasm.js', - OGVDecoderVideoVP8MTW: 'ogv-decoder-video-vp8-mt-wasm.js', - OGVDecoderVideoVP9W: 'ogv-decoder-video-vp9-wasm.js', - OGVDecoderVideoVP9SIMDW: 'ogv-decoder-video-vp9-simd-wasm.js', - OGVDecoderVideoVP9MTW: 'ogv-decoder-video-vp9-mt-wasm.js', - OGVDecoderVideoVP9SIMDMTW: 'ogv-decoder-video-vp9-simd-mt-wasm.js', - OGVDecoderVideoAV1W: 'ogv-decoder-video-av1-wasm.js', - OGVDecoderVideoAV1SIMDW: 'ogv-decoder-video-av1-simd-wasm.js', - OGVDecoderVideoAV1MTW: 'ogv-decoder-video-av1-mt-wasm.js', - OGVDecoderVideoAV1SIMDMTW: 'ogv-decoder-video-av1-simd-mt-wasm.js', + OGVDemuxerOggW: 'ogv-demuxer-ogg-wasm.js', + OGVDemuxerWebMW: 'ogv-demuxer-webm-wasm.js', + OGVDecoderAudioOpusW: 'ogv-decoder-audio-opus-wasm.js', + OGVDecoderAudioVorbisW: 'ogv-decoder-audio-vorbis-wasm.js', + OGVDecoderVideoTheoraW: 'ogv-decoder-video-theora-wasm.js', + OGVDecoderVideoVP8W: 'ogv-decoder-video-vp8-wasm.js', + OGVDecoderVideoVP8MTW: 'ogv-decoder-video-vp8-mt-wasm.js', + OGVDecoderVideoVP9W: 'ogv-decoder-video-vp9-wasm.js', + OGVDecoderVideoVP9SIMDW: 'ogv-decoder-video-vp9-simd-wasm.js', + OGVDecoderVideoVP9MTW: 'ogv-decoder-video-vp9-mt-wasm.js', + OGVDecoderVideoVP9SIMDMTW: 'ogv-decoder-video-vp9-simd-mt-wasm.js', + OGVDecoderVideoAV1W: 'ogv-decoder-video-av1-wasm.js', + OGVDecoderVideoAV1SIMDW: 'ogv-decoder-video-av1-simd-wasm.js', + OGVDecoderVideoAV1MTW: 'ogv-decoder-video-av1-mt-wasm.js', + OGVDecoderVideoAV1SIMDMTW: 'ogv-decoder-video-av1-simd-mt-wasm.js', */ export function loadVp9() { - window.OGVLoader.loadClass( - "OGVDecoderVideoVP9W", - (videoCodecClass) => { - videoCodecClass().then((decoder) => { - decoder.init(() => { - onVp9Ready(decoder) - }) - }) - }, - { worker: true } - ); + window.OGVLoader.loadClass( + "OGVDecoderVideoVP9W", + (videoCodecClass) => { + videoCodecClass().then((decoder) => { + decoder.init(() => { + onVp9Ready(decoder) + }) + }) + }, + { worker: true } + ); } export function loadOpus() { - window.OGVLoader.loadClass( - "OGVDecoderAudioOpusW", - (audioCodecClass) => { - audioCodecClass().then((decoder) => { - decoder.init(() => { - onOpusReady(decoder) - }) - }) - }, - { worker: true } - ); + window.OGVLoader.loadClass( + "OGVDecoderAudioOpusW", + (audioCodecClass) => { + audioCodecClass().then((decoder) => { + decoder.init(() => { + onOpusReady(decoder) + }) + }) + }, + { worker: true } + ); } async function onVp9Ready(decoder) { - console.log("Vp9 decoder ready"); + console.log("Vp9 decoder ready"); - /* - decoder.processFrame(buffer, () => { - player.drawFrame(decoder.frameBuffer) - }) - */ + /* + decoder.processFrame(buffer, () => { + player.drawFrame(decoder.frameBuffer) + }) + */ } async function onOpusReady(decoder) { - console.log("Opus decoder ready"); + console.log("Opus decoder ready"); } \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 872e81375..f1c79723d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,5 @@ import './style.css'; -import { loadVp9, loadOpus } from "./codec"; -import './websock'; - -loadVp9(); -loadOpus(); +import "./client"; const app = document.querySelector('#app')! diff --git a/src/websock.ts b/src/websock.ts index acd9c3b58..231bfafa8 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -9,6 +9,7 @@ export default class Websock { _eventHandlers: { [key in Keys]: Function }; _buf: Uint8Array[]; _status: any; + _latency: number; constructor(uri: string) { this._eventHandlers = { @@ -22,6 +23,11 @@ export default class Websock { this._websocket = new WebSocket(uri); this._websocket.onmessage = this._recv_message.bind(this); this._websocket.binaryType = "arraybuffer"; + this._latency = new Date().getTime(); + } + + latency(): number { + return this._latency; } sendMessage(data: any) { @@ -63,6 +69,7 @@ export default class Websock { } }, timeout); this._websocket.onopen = () => { + this._latency = new Date().getTime() - this._latency; this._status = "open"; console.debug(">> WebSock.onopen"); if (this._websocket?.protocol) { @@ -72,28 +79,26 @@ export default class Websock { } this._eventHandlers.open(); - console.debug("<< WebSock.onopen"); + console.info("WebSock.onopen"); resolve(this); }; this._websocket.onclose = (e) => { this._status = e; - console.debug(">> WebSock.onclose"); + console.error("WebSock.onclose: " + e); this._eventHandlers.close(e); - console.debug("<< WebSock.onclose"); reject(e); }; this._websocket.onerror = (e) => { this._status = e; - console.debug(">> WebSock.onerror: " + e); + console.error("WebSock.onerror: " + e); this._eventHandlers.error(e); - console.debug("<< WebSock.onerror: " + e); reject(e); }; }); } async next(timeout = 12000): Promise { - let func = ( + const func = ( resolve: (value: Uint8Array) => void, reject: (reason: any) => void, tm0: number @@ -102,7 +107,7 @@ export default class Websock { resolve(this._buf[0]); this._buf.splice(0, 1); } else { - if (this._status != 'open') { + if (this._status != "open") { reject(this._status); return; } @@ -134,7 +139,7 @@ export default class Websock { _recv_message(e: any) { if (e.data instanceof window.ArrayBuffer) { - let bytes = new Uint8Array(e.data); + const bytes = new Uint8Array(e.data); this._buf.push(bytes); } this._eventHandlers.message(e.data); @@ -146,13 +151,3 @@ export default class Websock { return hasher.digest(); } } - -let ws = new Websock("ws://207.148.17.15:21118"); -await ws.open(); -console.log("ws connected"); -// let punchHole = rendezvous.PunchHoleRequest.fromJSON({ id: '' }); -// ws.send_rendezvous(rendezvous.RendezvousMessage.fromJSON({ punchHole })); -let testNatRequest = rendezvous.TestNatRequest.fromJSON({ serial: 0 }); -ws.sendRendezvous({ testNatRequest }); -let msg = ws.parseRendezvous(await ws.next()); -console.log(msg); From 50c8650c63c574e7a703b8f076fbb3ead7e0f165 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 20 Jan 2022 01:55:57 +0800 Subject: [PATCH 12/66] test ui --- src/client.ts | 4 ++-- src/main.ts | 10 ++-------- src/ui.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 src/ui.js diff --git a/src/client.ts b/src/client.ts index bc8170783..0154242cb 100644 --- a/src/client.ts +++ b/src/client.ts @@ -96,5 +96,5 @@ async function testDelay() { console.log(ws.latency()); } -await testDelay(); -await new Client().connect("124931507"); +testDelay(); +new Client().connect("124931507"); diff --git a/src/main.ts b/src/main.ts index f1c79723d..2f573e805 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,3 @@ -import './style.css'; +import "./style.css"; import "./client"; - -const app = document.querySelector('#app')! - -app.innerHTML = ` -

Hello Vite!

- Documentation -` +import "./ui"; \ No newline at end of file diff --git a/src/ui.js b/src/ui.js new file mode 100644 index 000000000..e718e7488 --- /dev/null +++ b/src/ui.js @@ -0,0 +1,42 @@ +const app = document.querySelector("#app"); + +if (app) { + app.innerHTML = ` +
+ + + +
Host:
Id:
+ +`; + + document.body.onload = () => { + const host = document.querySelector('#host'); + host.value = localStorage.getItem('host'); + const id = document.querySelector('#id'); + id.value = localStorage.getItem('id'); + }; + + window.connect = () => { + const host = document.querySelector('#host'); + localStorage.setItem('host', host.value); + const id = document.querySelector('#id'); + localStorage.setItem('id', id.value); + document.querySelector('div#connect').style.display = 'none'; + document.querySelector('div#password').style.display = 'block'; + } + + window.cancel = () => { + document.querySelector('div#connect').style.display = 'block'; + document.querySelector('div#password').style.display = 'none'; + } + + window.confirm = () => { + // + } + +} \ No newline at end of file From 63242a4f3ab8d7e62381d5d9d35dbd99b6235cf3 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 20 Jan 2022 02:27:49 +0800 Subject: [PATCH 13/66] refactor --- src/{client.ts => connection.ts} | 47 +++++++++++++++++++------------- src/globals.js | 9 ++++++ src/main.ts | 3 +- src/ui.js | 8 ++++++ 4 files changed, 46 insertions(+), 21 deletions(-) rename src/{client.ts => connection.ts} (69%) create mode 100644 src/globals.js diff --git a/src/client.ts b/src/connection.ts similarity index 69% rename from src/client.ts rename to src/connection.ts index 0154242cb..22746a8ed 100644 --- a/src/client.ts +++ b/src/connection.ts @@ -3,14 +3,12 @@ import * as message from "./message.js"; import * as rendezvous from "./rendezvous.js"; import { loadVp9, loadOpus } from "./codec"; -const URI = "ws://207.148.17.15"; -const PORT = 21118; +const PORT = 21116; +const HOST = "rs-sg.rustdesk.com"; const licenceKey = ""; +const SCHEMA = "ws://"; -loadVp9(); -loadOpus(); - -export default class Client { +export default class Connection { _msgs: any[]; _ws: Websock | undefined; _interval: any; @@ -18,7 +16,7 @@ export default class Client { constructor() { this._msgs = []; - this._id = ''; + this._id = ""; this._interval = setInterval(() => { while (this._msgs.length) { this._ws?.sendMessage(this._msgs[0]); @@ -32,8 +30,8 @@ export default class Client { this._ws?.close(); } - async connect(id: string) { - const ws = new Websock(URI + ":" + PORT); + async start(id: string) { + const ws = new Websock(getDefaultUri()); this._ws = ws; this._id = id; await ws.open(); @@ -65,17 +63,15 @@ export default class Client { async connectRelay(rr: rendezvous.RelayResponse) { const pk = rr.pk; let uri = rr.relayServer; - if (uri.indexOf(':') > 0) { - const tmp = uri.split(':'); - const port = parseInt(tmp[1]); - uri = tmp[0] + ':' + (port + 2); + if (uri) { + uri = getrUriFromRs(uri); } else { - uri += ':' + (PORT + 1); + uri = getDefaultUri(true); } const uuid = rr.uuid; - const ws = new Websock('ws://' + uri); + const ws = new Websock(uri); await ws.open(); - console.log('Connected to relay server') + console.log("Connected to relay server"); this._ws = ws; const requestRelay = rendezvous.RequestRelay.fromJSON({ licenceKey, @@ -91,10 +87,23 @@ export default class Client { } async function testDelay() { - const ws = new Websock(URI + ":" + PORT); + const ws = new Websock(getDefaultUri(false)); await ws.open(); console.log(ws.latency()); } -testDelay(); -new Client().connect("124931507"); +function getDefaultUri(isRelay: Boolean = false): string { + const host = localStorage.getItem("host"); + return SCHEMA + (host || HOST) + ":" + (PORT + (isRelay ? 3 : 2)); +} + +function getrUriFromRs(uri: string): string { + if (uri.indexOf(":") > 0) { + const tmp = uri.split(":"); + const port = parseInt(tmp[1]); + uri = tmp[0] + ":" + (port + 2); + } else { + uri += ":" + (PORT + 3); + } + return uri; +} diff --git a/src/globals.js b/src/globals.js new file mode 100644 index 000000000..56d4defe2 --- /dev/null +++ b/src/globals.js @@ -0,0 +1,9 @@ +window.currentConnection = undefined; + +export function setConn(conn) { + window.currentConnection = conn; +} + +export function getConn() { + return windows.currentConnection; +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 2f573e805..2be877f58 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,3 +1,2 @@ -import "./style.css"; -import "./client"; +import "./globals"; import "./ui"; \ No newline at end of file diff --git a/src/ui.js b/src/ui.js index e718e7488..570265c57 100644 --- a/src/ui.js +++ b/src/ui.js @@ -1,9 +1,13 @@ +import "./style.css"; +import "./connection"; + const app = document.querySelector("#app"); if (app) { app.innerHTML = `
+
Host:
Key:
Id:
@@ -19,6 +23,8 @@ if (app) { host.value = localStorage.getItem('host'); const id = document.querySelector('#id'); id.value = localStorage.getItem('id'); + const key = document.querySelector('#key'); + key.value = localStorage.getItem('key'); }; window.connect = () => { @@ -26,6 +32,8 @@ if (app) { localStorage.setItem('host', host.value); const id = document.querySelector('#id'); localStorage.setItem('id', id.value); + const key = document.querySelector('#key'); + localStorage.setItem('key', key.value); document.querySelector('div#connect').style.display = 'none'; document.querySelector('div#password').style.display = 'block'; } From ce0f1f75de9bd7d7947879b8d03153de131e5021 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 20 Jan 2022 12:49:57 +0800 Subject: [PATCH 14/66] sodium verify works --- package.json | 1 + src/connection.ts | 12 +- src/globals.js | 23 +++- src/ui.js | 4 +- yarn.lock | 271 +--------------------------------------------- 5 files changed, 40 insertions(+), 271 deletions(-) diff --git a/package.json b/package.json index ae337fb4b..eeba1248b 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dependencies": { "fast-sha256": "^1.3.0", "libsodium": "^0.7.9", + "libsodium-wrappers": "^0.7.9", "ogv": "^1.8.6", "ts-proto": "^1.101.0" } diff --git a/src/connection.ts b/src/connection.ts index 22746a8ed..172f4f673 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -2,6 +2,7 @@ import Websock from "./websock"; import * as message from "./message.js"; import * as rendezvous from "./rendezvous.js"; import { loadVp9, loadOpus } from "./codec"; +import * as globals from "./globals"; const PORT = 21116; const HOST = "rs-sg.rustdesk.com"; @@ -16,7 +17,7 @@ export default class Connection { constructor() { this._msgs = []; - this._id = ""; + this._id = ''; this._interval = setInterval(() => { while (this._msgs.length) { this._ws?.sendMessage(this._msgs[0]); @@ -82,7 +83,10 @@ export default class Connection { } async secure(pk: Uint8Array | undefined) { - // + if (pk) { + const RS_PK = 'OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw='; + let pk_id = await globals.verify(pk, RS_PK); + } } } @@ -105,5 +109,5 @@ function getrUriFromRs(uri: string): string { } else { uri += ":" + (PORT + 3); } - return uri; -} + return SCHEMA + uri; +} \ No newline at end of file diff --git a/src/globals.js b/src/globals.js index 56d4defe2..38989f85a 100644 --- a/src/globals.js +++ b/src/globals.js @@ -1,3 +1,6 @@ +import Connection from "./connection"; +import _sodium from "libsodium-wrappers"; + window.currentConnection = undefined; export function setConn(conn) { @@ -6,4 +9,22 @@ export function setConn(conn) { export function getConn() { return windows.currentConnection; -} \ No newline at end of file +} + +export async function startConn(id) { + const conn = new Connection(); + setConn(conn); + await conn.start('124931507'); +} + +let sodium; +export async function verify(signed, pk) { + if (!sodium) { + await _sodium.ready; + sodium = _sodium; + } + pk = sodium.from_base64(pk, sodium.base64_variants.ORIGINAL); + return sodium.crypto_sign_open(signed, pk); +} + +window.startConn = startConn; \ No newline at end of file diff --git a/src/ui.js b/src/ui.js index 570265c57..9bae1326c 100644 --- a/src/ui.js +++ b/src/ui.js @@ -1,7 +1,8 @@ import "./style.css"; import "./connection"; +import { startConn } from "./globals"; -const app = document.querySelector("#app"); +const app = document.querySelector('#app'); if (app) { app.innerHTML = ` @@ -36,6 +37,7 @@ if (app) { localStorage.setItem('key', key.value); document.querySelector('div#connect').style.display = 'none'; document.querySelector('div#password').style.display = 'block'; + startConn(id); } window.cancel = () => { diff --git a/yarn.lock b/yarn.lock index 22a489545..2e61c8dbf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -77,66 +77,11 @@ resolved "https://registry.yarnpkg.com/@types/object-hash/-/object-hash-1.3.4.tgz#079ba142be65833293673254831b5e3e847fe58b" integrity sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA== -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -chnl@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/chnl/-/chnl-1.2.0.tgz#d818c95367767a0880508e7cc0b5b3503f58fd4c" - integrity sha512-g5gJb59edwCliFbX2j7G6sBfY4sX9YLy211yctONI2GRaiX0f2zIbKWmBm+sPqFNEpM7Ljzm7IJX/xrjiEbPrw== - dataloader@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-1.4.0.tgz#bca11d867f5d3f1b9ed9f737bd15970c65dff5c8" integrity sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw== -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -es-abstract@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" - integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.1" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.1" - is-string "^1.0.7" - is-weakref "^1.0.1" - object-inspect "^1.11.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - esbuild-android-arm64@0.13.15: version "0.13.15" resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz#3fc3ff0bab76fe35dd237476b5d2b32bb20a3d44" @@ -260,40 +205,6 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-symbols@^1.0.1, has-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" - integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -301,35 +212,6 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - is-core-module@^2.8.0: version "2.8.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" @@ -337,60 +219,14 @@ is-core-module@^2.8.0: dependencies: has "^1.0.3" -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== +libsodium-wrappers@^0.7.9: + version "0.7.9" + resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz#4ffc2b69b8f7c7c7c5594a93a4803f80f6d0f346" + integrity sha512-9HaAeBGk1nKTRFRHkt7nzxqCvnkWTjn1pdjKgcUnZxj0FyOP4CnhgFhMdrFfgNsukijBGyBLpP2m2uKT1vuWhQ== dependencies: - has-tostringtag "^1.0.0" + libsodium "^0.7.0" -is-negative-zero@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" - integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== - dependencies: - has-tostringtag "^1.0.0" - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" - integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-weakref@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -libsodium@^0.7.9: +libsodium@^0.7.0, libsodium@^0.7.9: version "0.7.9" resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.9.tgz#4bb7bcbf662ddd920d8795c227ae25bbbfa3821b" integrity sha512-gfeADtR4D/CM0oRUviKBViMGXZDgnFdMKMzHsvBdqLBHd9ySi6EtYnmuhHVDDYgYpAO8eU8hEY+F8vIUAPh08A== @@ -415,26 +251,6 @@ object-hash@^1.3.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== -object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" - integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - ogv@^1.8.6: version "1.8.6" resolved "https://registry.yarnpkg.com/ogv/-/ogv-1.8.6.tgz#0e6fa1c166802e3a405b1b318d8eb27d2544cce9" @@ -466,25 +282,6 @@ prettier@^2.5.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== -promise-controller@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/promise-controller/-/promise-controller-1.0.0.tgz#81ebea71271aa40ac8f3bebccab3d4158dc4cc02" - integrity sha512-goA0zA9L91tuQbUmiMinSYqlyUtEgg4fxJcjYnLYOQnrktb4o4UqciXDNXiRUPiDBPACmsr1k8jDW4r7UDq9Qw== - -promise.prototype.finally@^3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.3.tgz#d3186e58fcf4df1682a150f934ccc27b7893389c" - integrity sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -promised-map@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/promised-map/-/promised-map-1.0.0.tgz#aa3ec59e13724d37b946415f6850273af8e213b5" - integrity sha512-fP9VSMgcml+U2uJ9PBc4/LDQ3ZkJCH4blLNCS6gbH7RHyRZCYs91zxWHqiUy+heFiEMiB2op/qllYoFqmIqdWA== - protobufjs@^6.8.8: version "6.11.2" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.2.tgz#de39fabd4ed32beaa08e9bb1e30d08544c1edf8b" @@ -525,36 +322,11 @@ rollup@^2.59.0: optionalDependencies: fsevents "~2.3.2" -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - source-map-js@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf" integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA== -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -593,16 +365,6 @@ typescript@^4.4.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - vite@^2.7.2: version "2.7.12" resolved "https://registry.yarnpkg.com/vite/-/vite-2.7.12.tgz#7784ab19e7ff98f6a192d2d7d877480a8c2b7e7d" @@ -614,24 +376,3 @@ vite@^2.7.2: rollup "^2.59.0" optionalDependencies: fsevents "~2.3.2" - -websocket-as-promised@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/websocket-as-promised/-/websocket-as-promised-2.0.1.tgz#d18b7c160bba294585aaf6fa9572f31e05cfb175" - integrity sha512-ePV26D/D37ughXU9j+DjGmwUbelWJrC/vi+6GK++fRlBJmS7aU9T8ABu47KFF0O7r6XN2NAuqJRpegbUwXZxQg== - dependencies: - chnl "^1.2.0" - promise-controller "^1.0.0" - promise.prototype.finally "^3.1.2" - promised-map "^1.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" From 70c213a60acb523428de463d63c2d5a55ab9d5a2 Mon Sep 17 00:00:00 2001 From: open-trade Date: Thu, 20 Jan 2022 15:41:11 +0800 Subject: [PATCH 15/66] secure connection works --- src/connection.ts | 88 +++++++++++++++++++++++++++++++++++++---------- src/globals.js | 32 ++++++++++++++++- src/websock.ts | 9 +++-- 3 files changed, 108 insertions(+), 21 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index 172f4f673..f0cd100d1 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -1,13 +1,13 @@ -import Websock from "./websock"; -import * as message from "./message.js"; -import * as rendezvous from "./rendezvous.js"; -import { loadVp9, loadOpus } from "./codec"; -import * as globals from "./globals"; +import Websock from './websock'; +import * as message from './message.js'; +import * as rendezvous from './rendezvous.js'; +import { loadVp9, loadOpus } from './codec'; +import * as globals from './globals'; const PORT = 21116; -const HOST = "rs-sg.rustdesk.com"; -const licenceKey = ""; -const SCHEMA = "ws://"; +const HOST = 'rs-sg.rustdesk.com'; +const licenceKey = ''; +const SCHEMA = 'ws://'; export default class Connection { _msgs: any[]; @@ -38,7 +38,7 @@ export default class Connection { await ws.open(); const connType = rendezvous.ConnType.DEFAULT_CONN; const natType = rendezvous.NatType.SYMMETRIC; - const punchHoleRequest = rendezvous.PunchHoleRequest.fromJSON({ + const punchHoleRequest = rendezvous.PunchHoleRequest.fromPartial({ id, licenceKey, connType, @@ -72,9 +72,9 @@ export default class Connection { const uuid = rr.uuid; const ws = new Websock(uri); await ws.open(); - console.log("Connected to relay server"); + console.log('Connected to relay server'); this._ws = ws; - const requestRelay = rendezvous.RequestRelay.fromJSON({ + const requestRelay = rendezvous.RequestRelay.fromPartial({ licenceKey, uuid, }); @@ -85,8 +85,60 @@ export default class Connection { async secure(pk: Uint8Array | undefined) { if (pk) { const RS_PK = 'OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw='; - let pk_id = await globals.verify(pk, RS_PK); + try { + pk = await globals.verify(pk, RS_PK).catch(); + if (pk?.length != 32) { + pk = undefined; + } + } catch (e) { + console.error(e); + pk = undefined; + } + if (!pk) console.error('Handshake failed: invalid public key from rendezvous server'); } + if (!pk) { + // send an empty message out in case server is setting up secure and waiting for first message + await this._ws?.sendMessage({}); + return; + } + const msg = this._ws?.parseMessage(await this._ws?.next()); + let signedId: any = msg?.signedId; + if (!signedId) { + console.error("Handshake failed: invalid message type"); + await this._ws?.sendMessage({}); + return; + } + try { + signedId = await globals.verify(signedId.id, Uint8Array.from(pk!)); + } catch (e) { + console.error(e); + // fall back to non-secure connection in case pk mismatch + console.error("pk mismatch, fall back to non-secure"); + const publicKey = message.PublicKey.fromPartial({}); + await this._ws?.sendMessage({ publicKey }); + return; + } + signedId = new TextDecoder().decode(signedId!); + const tmp = signedId.split('\0'); + const id = tmp[0]; + let theirPk = tmp[1]; + if (id != this._id!) { + console.error("Handshake failed: sign failure"); + await this._ws?.sendMessage({}); + return; + } + theirPk = globals.decodeBase64(theirPk); + if (theirPk.length != 32) { + console.error("Handshake failed: invalid public box key length from peer"); + await this._ws?.sendMessage({}); + return; + } + const [mySk, asymmetricValue] = globals.genBoxKeyPair(); + const secretKey = globals.genSecretKey(); + const symmetricValue = globals.seal(secretKey, theirPk, mySk); + const publicKey = message.PublicKey.fromPartial({ asymmetricValue, symmetricValue }); + await this._ws?.sendMessage({ publicKey }); + this._ws?.setSecretKey(secretKey) } } @@ -97,17 +149,17 @@ async function testDelay() { } function getDefaultUri(isRelay: Boolean = false): string { - const host = localStorage.getItem("host"); - return SCHEMA + (host || HOST) + ":" + (PORT + (isRelay ? 3 : 2)); + const host = localStorage.getItem('host'); + return SCHEMA + (host || HOST) + ':' + (PORT + (isRelay ? 3 : 2)); } function getrUriFromRs(uri: string): string { - if (uri.indexOf(":") > 0) { - const tmp = uri.split(":"); + if (uri.indexOf(':') > 0) { + const tmp = uri.split(':'); const port = parseInt(tmp[1]); - uri = tmp[0] + ":" + (port + 2); + uri = tmp[0] + ':' + (port + 2); } else { - uri += ":" + (PORT + 3); + uri += ':' + (PORT + 3); } return SCHEMA + uri; } \ No newline at end of file diff --git a/src/globals.js b/src/globals.js index 38989f85a..f804f5278 100644 --- a/src/globals.js +++ b/src/globals.js @@ -23,8 +23,38 @@ export async function verify(signed, pk) { await _sodium.ready; sodium = _sodium; } - pk = sodium.from_base64(pk, sodium.base64_variants.ORIGINAL); + if (typeof pk == 'string') { + pk = decodeBase64(pk); + } return sodium.crypto_sign_open(signed, pk); } +export function decodeBase64(pk) { + return sodium.from_base64(pk, sodium.base64_variants.ORIGINAL); +} + +export function genBoxKeyPair() { + const pair = sodium.crypto_box_keypair(); + const sk = pair.privateKey; + const pk = pair.publicKey; + return [sk, pk]; +} + +export function genSecretKey() { + return sodium.crypto_secretbox_keygen(); +} + +export function seal(unsigned, theirPk, ourSk) { + const nonce = Uint8Array.from(Array(24).fill(0)); + return sodium.crypto_box_easy(unsigned, nonce, theirPk, ourSk); +} + +export function encrypt(unsigned, nonce, key) { + return sodium.crypto_secretbox_easy(unsigned, nonce, key); +} + +export function decrypt(signed, nonce, key) { + return sodium.crypto_secretbox_open_easy(signed, nonce, key); +} + window.startConn = startConn; \ No newline at end of file diff --git a/src/websock.ts b/src/websock.ts index 231bfafa8..f09cc181e 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -10,6 +10,7 @@ export default class Websock { _buf: Uint8Array[]; _status: any; _latency: number; + _secretKey: any; constructor(uri: string) { this._eventHandlers = { @@ -30,16 +31,20 @@ export default class Websock { return this._latency; } + setSecretKey(key: any) { + this._secretKey = key; + } + sendMessage(data: any) { this._websocket.send( - message.Message.encode(message.Message.fromJSON(data)).finish() + message.Message.encode(message.Message.fromPartial(data)).finish() ); } sendRendezvous(data: any) { this._websocket.send( rendezvous.RendezvousMessage.encode( - rendezvous.RendezvousMessage.fromJSON(data) + rendezvous.RendezvousMessage.fromPartial(data) ).finish() ); } From b8ff266d76895a23dde358ee030c275d037ba89f Mon Sep 17 00:00:00 2001 From: open-trade Date: Thu, 20 Jan 2022 18:02:20 +0800 Subject: [PATCH 16/66] msgLoop works --- src/connection.ts | 57 ++++++++++++++++++++++++++++++++++++++++++++--- src/globals.js | 32 +++++++++++++++++++------- src/ui.js | 37 ++++++++++++++++++++++++++---- src/websock.ts | 33 ++++++++++++++------------- 4 files changed, 129 insertions(+), 30 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index f0cd100d1..a2311e123 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -2,6 +2,7 @@ import Websock from './websock'; import * as message from './message.js'; import * as rendezvous from './rendezvous.js'; import { loadVp9, loadOpus } from './codec'; +import * as sha256 from "fast-sha256"; import * as globals from './globals'; const PORT = 21116; @@ -9,11 +10,15 @@ const HOST = 'rs-sg.rustdesk.com'; const licenceKey = ''; const SCHEMA = 'ws://'; +type MsgboxCallback = (type: string, title: string, text: string) => void; + export default class Connection { _msgs: any[]; _ws: Websock | undefined; _interval: any; _id: string; + _hash: message.Hash | undefined; + _msgbox: MsgboxCallback | undefined; constructor() { this._msgs = []; @@ -31,11 +36,18 @@ export default class Connection { this._ws?.close(); } + setMsgbox(callback: MsgboxCallback) { + this._msgbox = callback; + } + async start(id: string) { - const ws = new Websock(getDefaultUri()); + const uri = getDefaultUri(); + const ws = new Websock(uri); this._ws = ws; this._id = id; + console.log(new Date() + ': Conntecting to rendezvoous server: ' + uri); await ws.open(); + console.log(new Date() + ': Connected to rendezvoous server'); const connType = rendezvous.ConnType.DEFAULT_CONN; const natType = rendezvous.NatType.SYMMETRIC; const punchHoleRequest = rendezvous.PunchHoleRequest.fromPartial({ @@ -46,15 +58,27 @@ export default class Connection { }); ws.sendRendezvous({ punchHoleRequest }); const msg = ws.parseRendezvous(await ws.next()); + ws.close(); + console.log(new Date() + ': Got relay response'); const phr = msg.punchHoleResponse; const rr = msg.relayResponse; if (phr) { if (phr.failure != rendezvous.PunchHoleResponse_Failure.UNKNOWN) { switch (phr?.failure) { case rendezvous.PunchHoleResponse_Failure.ID_NOT_EXIST: + this.msgbox('error', 'Error', 'ID does not exist'); break; + case rendezvous.PunchHoleResponse_Failure.OFFLINE: + this.msgbox('error', 'Error', 'Remote desktop is offline'); + break; + case rendezvous.PunchHoleResponse_Failure.LICENSE_MISMATCH: + this.msgbox('error', 'Error', 'Key mismatch'); + break; + default: + if (phr?.otherFailure) { + this.msgbox('error', 'Error', phr?.otherFailure); + } } - ws.close(); } } else if (rr) { await this.connectRelay(rr); @@ -70,9 +94,10 @@ export default class Connection { uri = getDefaultUri(true); } const uuid = rr.uuid; + console.log(new Date() + ': Connecting to relay server: ' + uri); const ws = new Websock(uri); await ws.open(); - console.log('Connected to relay server'); + console.log(new Date() + ': Connected to relay server'); this._ws = ws; const requestRelay = rendezvous.RequestRelay.fromPartial({ licenceKey, @@ -80,6 +105,7 @@ export default class Connection { }); ws.sendRendezvous({ requestRelay }); await this.secure(pk); + await this.msgLoop(); } async secure(pk: Uint8Array | undefined) { @@ -140,6 +166,25 @@ export default class Connection { await this._ws?.sendMessage({ publicKey }); this._ws?.setSecretKey(secretKey) } + + async msgLoop() { + while (true) { + const msg = this._ws?.parseMessage(await this._ws?.next()); + if (msg?.hash) { + this._hash = msg?.hash; + this.msgbox("input-password", "Password Required", ""); + } else if (msg?.testDelay) { + const testDelay = msg?.testDelay; + if (!testDelay.fromClient) { + await this._ws?.sendMessage({ testDelay }); + } + } + } + } + + msgbox(type_: string, title: string, text: string) { + this._msgbox?.(type_, title, text); + } } async function testDelay() { @@ -162,4 +207,10 @@ function getrUriFromRs(uri: string): string { uri += ':' + (PORT + 3); } return SCHEMA + uri; +} + +function hash(datas: [string]): Uint8Array { + const hasher = new sha256.Hash(); + datas.forEach((data) => hasher.update(new TextEncoder().encode(data))); + return hasher.digest(); } \ No newline at end of file diff --git a/src/globals.js b/src/globals.js index f804f5278..cd3828dec 100644 --- a/src/globals.js +++ b/src/globals.js @@ -8,13 +8,19 @@ export function setConn(conn) { } export function getConn() { - return windows.currentConnection; + return window.currentConnection; } -export async function startConn(id) { +export function close() { + getConn()?.close(); + setConn(undefined); +} + +export function newConn() { + window.currentConnection?.close(); const conn = new Connection(); setConn(conn); - await conn.start('124931507'); + return conn; } let sodium; @@ -49,12 +55,22 @@ export function seal(unsigned, theirPk, ourSk) { return sodium.crypto_box_easy(unsigned, nonce, theirPk, ourSk); } +function makeOnce(value) { + var byteArray = Array(24).fill(0); + + for (var index = 0; index < byteArray.length && value > 0; index++) { + var byte = value & 0xff; + byteArray[index] = byte; + value = (value - byte) / 256; + } + + return Uint8Array.from(byteArray); +}; + export function encrypt(unsigned, nonce, key) { - return sodium.crypto_secretbox_easy(unsigned, nonce, key); + return sodium.crypto_secretbox_easy(unsigned, makeOnce(nonce), key); } export function decrypt(signed, nonce, key) { - return sodium.crypto_secretbox_open_easy(signed, nonce, key); -} - -window.startConn = startConn; \ No newline at end of file + return sodium.crypto_secretbox_open_easy(signed, makeOnce(nonce), key); +} \ No newline at end of file diff --git a/src/ui.js b/src/ui.js index 9bae1326c..e2495d1b3 100644 --- a/src/ui.js +++ b/src/ui.js @@ -1,6 +1,6 @@ import "./style.css"; import "./connection"; -import { startConn } from "./globals"; +import * as globals from "./globals"; const app = document.querySelector('#app'); @@ -17,6 +17,10 @@ if (app) { + `; document.body.onload = () => { @@ -35,14 +39,39 @@ if (app) { localStorage.setItem('id', id.value); const key = document.querySelector('#key'); localStorage.setItem('key', key.value); - document.querySelector('div#connect').style.display = 'none'; - document.querySelector('div#password').style.display = 'block'; - startConn(id); + const func = async () => { + const conn = globals.newConn(); + conn.setMsgbox(msgbox); + document.querySelector('div#status').style.display = 'block'; + document.querySelector('div#connect').style.display = 'none'; + document.querySelector('div#text').innerHTML = 'Connecting ...'; + try { + await conn.start(id.value); + } catch (e) { + msgbox('error', 'Error', e); + } + }; + func(); + } + + function msgbox(type, title, text) { + if (!globals.getConn()) return; + if (type == 'input-password') { + document.querySelector('div#status').style.display = 'none'; + document.querySelector('div#password').style.display = 'block'; + } else if (!type) { + document.querySelector('div#status').style.display = 'none'; + } else { + document.querySelector('div#status').style.display = 'block'; + document.querySelector('div#text').innerHTML = '
' + text + '
'; + } } window.cancel = () => { + globals.close(); document.querySelector('div#connect').style.display = 'block'; document.querySelector('div#password').style.display = 'none'; + document.querySelector('div#status').style.display = 'none'; } window.confirm = () => { diff --git a/src/websock.ts b/src/websock.ts index f09cc181e..1ce2c45e7 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -1,6 +1,6 @@ import * as message from "./message.js"; import * as rendezvous from "./rendezvous.js"; -import * as sha256 from "fast-sha256"; +import * as globals from "./globals"; type Keys = "message" | "open" | "close" | "error"; @@ -10,7 +10,7 @@ export default class Websock { _buf: Uint8Array[]; _status: any; _latency: number; - _secretKey: any; + _secretKey: [Uint8Array, number, number] | undefined; constructor(uri: string) { this._eventHandlers = { @@ -31,14 +31,18 @@ export default class Websock { return this._latency; } - setSecretKey(key: any) { - this._secretKey = key; + setSecretKey(key: Uint8Array) { + this._secretKey = [key, 0, 0]; } - sendMessage(data: any) { - this._websocket.send( - message.Message.encode(message.Message.fromPartial(data)).finish() - ); + sendMessage(json: any) { + let data = message.Message.encode(message.Message.fromPartial(json)).finish(); + let k = this._secretKey; + if (k) { + k[1] += 1; + data = globals.encrypt(data, k[1], k[0]); + } + this._websocket.send(data); } sendRendezvous(data: any) { @@ -144,15 +148,14 @@ export default class Websock { _recv_message(e: any) { if (e.data instanceof window.ArrayBuffer) { - const bytes = new Uint8Array(e.data); + let bytes = new Uint8Array(e.data); + const k = this._secretKey; + if (k) { + k[2] += 1; + bytes = globals.decrypt(bytes, k[2], k[0]); + } this._buf.push(bytes); } this._eventHandlers.message(e.data); } - - hash(datas: [Uint8Array]): Uint8Array { - const hasher = new sha256.Hash(); - datas.forEach((data) => hasher.update(data)); - return hasher.digest(); - } } From 72083647857cf4786688bd4f8383bc771fc36ec3 Mon Sep 17 00:00:00 2001 From: open-trade Date: Thu, 20 Jan 2022 18:41:35 +0800 Subject: [PATCH 17/66] login ok --- src/connection.ts | 64 +++++++++++++++++++++++++++++++++++++++-------- src/ui.js | 16 ++++++++---- 2 files changed, 64 insertions(+), 16 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index a2311e123..1e207f6bf 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -19,6 +19,7 @@ export default class Connection { _id: string; _hash: message.Hash | undefined; _msgbox: MsgboxCallback | undefined; + _peerInfo: message.PeerInfo | undefined; constructor() { this._msgs = []; @@ -31,15 +32,6 @@ export default class Connection { }, 1); } - close() { - clearInterval(this._interval); - this._ws?.close(); - } - - setMsgbox(callback: MsgboxCallback) { - this._msgbox = callback; - } - async start(id: string) { const uri = getDefaultUri(); const ws = new Websock(uri); @@ -172,19 +164,64 @@ export default class Connection { const msg = this._ws?.parseMessage(await this._ws?.next()); if (msg?.hash) { this._hash = msg?.hash; + await this.handleHash(); this.msgbox("input-password", "Password Required", ""); } else if (msg?.testDelay) { const testDelay = msg?.testDelay; if (!testDelay.fromClient) { await this._ws?.sendMessage({ testDelay }); } + } else if (msg?.loginResponse) { + const r = msg?.loginResponse; + if (r.error) { + this.msgbox('error', 'Error', r.error); + } else if (r.peerInfo) { + this._peerInfo = r.peerInfo; + this.msgbox('success', 'Successful', 'Connected, waiting for image...'); + } } } } + async handleHash() { + await this._sendLoginMessage(); + } + msgbox(type_: string, title: string, text: string) { this._msgbox?.(type_, title, text); } + + close() { + clearInterval(this._interval); + this._ws?.close(); + } + + setMsgbox(callback: MsgboxCallback) { + this._msgbox = callback; + } + + async login(password: string) { + this.msgbox('connecting', 'Connecting...', 'Logging in...'); + let salt = this._hash?.salt; + if (salt) { + let p = hash([password, salt]); + let challenge = this._hash?.challenge; + if (challenge) { + p = hash([p, challenge]); + await this._sendLoginMessage(p); + } + } + } + + async _sendLoginMessage(password: Uint8Array | undefined = undefined) { + const loginRequest = message.LoginRequest.fromPartial({ + username: this._id!, + myId: 'web', // to-do + myName: 'web', // to-do + password, + }); + await this._ws?.sendMessage({ loginRequest }); + } } async function testDelay() { @@ -209,8 +246,13 @@ function getrUriFromRs(uri: string): string { return SCHEMA + uri; } -function hash(datas: [string]): Uint8Array { +function hash(datas: (string | Uint8Array)[]): Uint8Array { const hasher = new sha256.Hash(); - datas.forEach((data) => hasher.update(new TextEncoder().encode(data))); + datas.forEach((data) => { + if (typeof data == 'string') { + data = new TextEncoder().encode(data); + } + return hasher.update(data); + }); return hasher.digest(); } \ No newline at end of file diff --git a/src/ui.js b/src/ui.js index e2495d1b3..f3839cb4b 100644 --- a/src/ui.js +++ b/src/ui.js @@ -14,7 +14,7 @@ if (app) { + `; + let player; + document.body.onload = () => { const host = document.querySelector('#host'); host.value = localStorage.getItem('host'); @@ -30,6 +33,7 @@ if (app) { id.value = localStorage.getItem('id'); const key = document.querySelector('#key'); key.value = localStorage.getItem('key'); + player = YUVCanvas.attach(document.getElementById("player")) }; window.connect = () => { @@ -42,6 +46,9 @@ if (app) { const func = async () => { const conn = globals.newConn(); conn.setMsgbox(msgbox); + conn.setDraw((f) => { + player.drawFrame(f); + }); document.querySelector('div#status').style.display = 'block'; document.querySelector('div#connect').style.display = 'none'; document.querySelector('div#text').innerHTML = 'Connecting ...'; diff --git a/ts_proto.py b/ts_proto.py index d1627f51f..5f8932731 100644 --- a/ts_proto.py +++ b/ts_proto.py @@ -5,16 +5,16 @@ import os path = os.path.abspath(os.path.join(os.getcwd(), '..', 'hbb', 'libs', 'hbb_common', 'protos')) if os.name == 'nt': - cmd = r'protoc --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd -I "%s" --ts_proto_out=./src/ rendezvous.proto'%path + cmd = r'protoc --ts_proto_opt=esModuleInterop=true --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd -I "%s" --ts_proto_out=./src/ rendezvous.proto'%path print(cmd) os.system(cmd) - cmd = r'protoc --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd -I "%s" --ts_proto_out=./src/ message.proto'%path + cmd = r'protoc --ts_proto_opt=esModuleInterop=true --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd -I "%s" --ts_proto_out=./src/ message.proto'%path print(cmd) os.system(cmd) else: - cmd = r'protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto -I "%s" --ts_proto_out=./src/ rendezvous.proto'%path + cmd = r'protoc --ts_proto_opt=esModuleInterop=true --plugin=./node_modules/.bin/protoc-gen-ts_proto -I "%s" --ts_proto_out=./src/ rendezvous.proto'%path print(cmd) os.system(cmd) - cmd = r'protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto -I "%s" --ts_proto_out=./src/ message.proto'%path + cmd = r'protoc --ts_proto_opt=esModuleInterop=true --plugin=./node_modules/.bin/protoc-gen-ts_proto -I "%s" --ts_proto_out=./src/ message.proto'%path print(cmd) - os.system(cmd) \ No newline at end of file + os.system(cmd) From e291e4d1c935a273ea972b898b4a38702cf7539f Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 21 Jan 2022 00:41:02 +0800 Subject: [PATCH 20/66] video works --- src/codec.js | 4 ++-- src/connection.ts | 9 +++++---- src/ui.js | 12 ++++++++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/codec.js b/src/codec.js index 213f2e8fc..da4f0cbdb 100644 --- a/src/codec.js +++ b/src/codec.js @@ -24,7 +24,7 @@ export function loadVp9(callback) { "OGVDecoderVideoVP9W", (videoCodecClass) => { window.videoCodecClass = videoCodecClass; - videoCodecClass().then((decoder) => { + videoCodecClass({ videoFormat: {} }).then((decoder) => { decoder.init(() => { callback(decoder); }) @@ -38,7 +38,7 @@ export function loadOpus(callback) { window.OGVLoader.loadClass( "OGVDecoderAudioOpusW", (audioCodecClass) => { - audioCodecClass().then((decoder) => { + audioCodecClass({ audioFormat: {} }).then((decoder) => { decoder.init(() => { callback(decoder); }) diff --git a/src/connection.ts b/src/connection.ts index a67fbd71a..85f919d40 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -226,6 +226,8 @@ export default class Connection { close() { clearInterval(this._interval); this._ws?.close(); + this._videoDecoder?.close(); + this._audioDecoder?.close(); } setMsgbox(callback: MsgboxCallback) { @@ -266,11 +268,10 @@ export default class Connection { } if (vf.vp9s) { let dec = this._videoDecoder; + // dec.sync(); vf.vp9s.frames.forEach((f) => { - dec.processFrame(f.data.buffer, (ok: any) => { - console.log(ok); - if (dec.frameBuffer) { - console.log(dec.frameBuffer); + dec.processFrame(f.data.slice(0).buffer, (ok: any) => { + if (ok && dec.frameBuffer) { this.draw(dec.frameBuffer); } }); diff --git a/src/ui.js b/src/ui.js index de602904b..c5c55bf5c 100644 --- a/src/ui.js +++ b/src/ui.js @@ -21,7 +21,10 @@ if (app) {
- + `; let player; @@ -33,7 +36,7 @@ if (app) { id.value = localStorage.getItem('id'); const key = document.querySelector('#key'); key.value = localStorage.getItem('key'); - player = YUVCanvas.attach(document.getElementById("player")) + player = YUVCanvas.attach(document.getElementById('player')) }; window.connect = () => { @@ -67,11 +70,15 @@ if (app) { document.querySelector('div#status').style.display = 'none'; document.querySelector('div#password').style.display = 'block'; } else if (!type) { + document.querySelector('div#canvas').style.display = 'block'; + document.querySelector('div#password').style.display = 'none'; document.querySelector('div#status').style.display = 'none'; } else if (type == 'error') { document.querySelector('div#status').style.display = 'block'; + document.querySelector('div#canvas').style.display = 'none'; document.querySelector('div#text').innerHTML = '
' + text + '
'; } else { + document.querySelector('div#password').style.display = 'none'; document.querySelector('div#status').style.display = 'block'; document.querySelector('div#text').innerHTML = '
' + text + '
'; } @@ -82,6 +89,7 @@ if (app) { document.querySelector('div#connect').style.display = 'block'; document.querySelector('div#password').style.display = 'none'; document.querySelector('div#status').style.display = 'none'; + document.querySelector('div#canvas').style.display = 'none'; } window.confirm = () => { From c1ff8242d9c2c4f4f177f8f779ad5c8d1d08cc94 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 21 Jan 2022 00:42:33 +0800 Subject: [PATCH 21/66] fix grammer --- src/connection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/connection.ts b/src/connection.ts index 85f919d40..05df1edda 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -11,7 +11,7 @@ const licenceKey = ""; const SCHEMA = "ws://"; type MsgboxCallback = (type: string, title: string, text: string) => void; -type DrawCallback = (Uint8Array) => void; +type DrawCallback = (data: Uint8Array) => void; export default class Connection { _msgs: any[]; From 28468042347efb6ec8910c1ce9b47907cf1579a1 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 21 Jan 2022 02:12:38 +0800 Subject: [PATCH 22/66] update protobuf --- src/message.ts | 16 ++-------------- src/rendezvous.ts | 16 ++-------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/src/message.ts b/src/message.ts index b85556fea..44405e14b 100644 --- a/src/message.ts +++ b/src/message.ts @@ -496,8 +496,7 @@ export function controlKeyToJSON(object: ControlKey): string { } export enum FileType { - UnknownFileType = 0, - Dir = 1, + Dir = 0, DirLink = 2, DirDrive = 3, File = 4, @@ -508,9 +507,6 @@ export enum FileType { export function fileTypeFromJSON(object: any): FileType { switch (object) { case 0: - case "UnknownFileType": - return FileType.UnknownFileType; - case 1: case "Dir": return FileType.Dir; case 2: @@ -534,8 +530,6 @@ export function fileTypeFromJSON(object: any): FileType { export function fileTypeToJSON(object: FileType): string { switch (object) { - case FileType.UnknownFileType: - return "UnknownFileType"; case FileType.Dir: return "Dir"; case FileType.DirLink: @@ -819,8 +813,7 @@ export interface PermissionInfo { } export enum PermissionInfo_Permission { - Unknown = 0, - Keyboard = 1, + Keyboard = 0, Clipboard = 2, Audio = 3, UNRECOGNIZED = -1, @@ -831,9 +824,6 @@ export function permissionInfo_PermissionFromJSON( ): PermissionInfo_Permission { switch (object) { case 0: - case "Unknown": - return PermissionInfo_Permission.Unknown; - case 1: case "Keyboard": return PermissionInfo_Permission.Keyboard; case 2: @@ -853,8 +843,6 @@ export function permissionInfo_PermissionToJSON( object: PermissionInfo_Permission ): string { switch (object) { - case PermissionInfo_Permission.Unknown: - return "Unknown"; case PermissionInfo_Permission.Keyboard: return "Keyboard"; case PermissionInfo_Permission.Clipboard: diff --git a/src/rendezvous.ts b/src/rendezvous.ts index 0ac3b1542..33fab950b 100644 --- a/src/rendezvous.ts +++ b/src/rendezvous.ts @@ -139,8 +139,7 @@ export interface RegisterPkResponse { } export enum RegisterPkResponse_Result { - UNKNOWN = 0, - OK = 1, + OK = 0, UUID_MISMATCH = 2, ID_EXISTS = 3, TOO_FREQUENT = 4, @@ -155,9 +154,6 @@ export function registerPkResponse_ResultFromJSON( ): RegisterPkResponse_Result { switch (object) { case 0: - case "UNKNOWN": - return RegisterPkResponse_Result.UNKNOWN; - case 1: case "OK": return RegisterPkResponse_Result.OK; case 2: @@ -189,8 +185,6 @@ export function registerPkResponse_ResultToJSON( object: RegisterPkResponse_Result ): string { switch (object) { - case RegisterPkResponse_Result.UNKNOWN: - return "UNKNOWN"; case RegisterPkResponse_Result.OK: return "OK"; case RegisterPkResponse_Result.UUID_MISMATCH: @@ -221,8 +215,7 @@ export interface PunchHoleResponse { } export enum PunchHoleResponse_Failure { - UNKNOWN = 0, - ID_NOT_EXIST = 1, + ID_NOT_EXIST = 0, OFFLINE = 2, LICENSE_MISMATCH = 3, LICENSE_OVERUSE = 4, @@ -234,9 +227,6 @@ export function punchHoleResponse_FailureFromJSON( ): PunchHoleResponse_Failure { switch (object) { case 0: - case "UNKNOWN": - return PunchHoleResponse_Failure.UNKNOWN; - case 1: case "ID_NOT_EXIST": return PunchHoleResponse_Failure.ID_NOT_EXIST; case 2: @@ -259,8 +249,6 @@ export function punchHoleResponse_FailureToJSON( object: PunchHoleResponse_Failure ): string { switch (object) { - case PunchHoleResponse_Failure.UNKNOWN: - return "UNKNOWN"; case PunchHoleResponse_Failure.ID_NOT_EXIST: return "ID_NOT_EXIST"; case PunchHoleResponse_Failure.OFFLINE: From 1df3df97b6a258a69f2a61a89b9c677c47729d60 Mon Sep 17 00:00:00 2001 From: open-trade Date: Fri, 21 Jan 2022 14:28:16 +0800 Subject: [PATCH 23/66] fix on grammert --- src/connection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/connection.ts b/src/connection.ts index 05df1edda..95d992a71 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -69,7 +69,7 @@ export default class Connection { const phr = msg.punchHoleResponse; const rr = msg.relayResponse; if (phr) { - if (phr.failure != rendezvous.PunchHoleResponse_Failure.UNKNOWN) { + if (phr.failure != rendezvous.PunchHoleResponse_Failure.UNRECOGNIZED) { switch (phr?.failure) { case rendezvous.PunchHoleResponse_Failure.ID_NOT_EXIST: this.msgbox("error", "Error", "ID does not exist"); From f4c3198037815eec9ed19708471410b83d038579 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Wed, 26 Jan 2022 12:39:44 +0800 Subject: [PATCH 24/66] more api --- package.json | 3 +- src/connection.ts | 112 ++++++++++++++++++++++++++++++++++++---------- src/globals.js | 87 +++++++++++++++++++++++++++++++++++ yarn.lock | 5 +++ 4 files changed, 183 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index a6d708e94..611351fff 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "libsodium": "^0.7.9", "libsodium-wrappers": "^0.7.9", "ogv": "^1.8.6", - "ts-proto": "^1.101.0" + "ts-proto": "^1.101.0", + "zstddec": "^0.0.2" } } diff --git a/src/connection.ts b/src/connection.ts index 05df1edda..6cbba8c12 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -19,16 +19,22 @@ export default class Connection { _interval: any; _id: string; _hash: message.Hash | undefined; - _msgbox: MsgboxCallback | undefined; - _draw: DrawCallback | undefined; + _msgbox: MsgboxCallback; + _draw: DrawCallback; _peerInfo: message.PeerInfo | undefined; _firstFrame: Boolean | undefined; _videoDecoder: any; _audioDecoder: any; + _password: string | undefined; constructor() { + this._msgbox = globals.msgbox; + this._draw = globals.draw; this._msgs = []; this._id = ""; + } + + async start(id: string) { this._interval = setInterval(() => { while (this._msgs.length) { this._ws?.sendMessage(this._msgs[0]); @@ -44,9 +50,6 @@ export default class Connection { this._audioDecoder = decoder; console.log("opus loaded"); }); - } - - async start(id: string) { const uri = getDefaultUri(); const ws = new Websock(uri); this._ws = ws; @@ -69,7 +72,7 @@ export default class Connection { const phr = msg.punchHoleResponse; const rr = msg.relayResponse; if (phr) { - if (phr.failure != rendezvous.PunchHoleResponse_Failure.UNKNOWN) { + if (phr.failure != rendezvous.PunchHoleResponse_Failure.UNRECOGNIZED) { switch (phr?.failure) { case rendezvous.PunchHoleResponse_Failure.ID_NOT_EXIST: this.msgbox("error", "Error", "ID does not exist"); @@ -110,7 +113,8 @@ export default class Connection { uuid, }); ws.sendRendezvous({ requestRelay }); - await this.secure(pk); + const secure = (await this.secure(pk)) || false; + globals.pushEvent("connection_ready", { secure, direct: false }); await this.msgLoop(); } @@ -179,6 +183,7 @@ export default class Connection { }); await this._ws?.sendMessage({ publicKey }); this._ws?.setSecretKey(secretKey); + return true; } async msgLoop() { @@ -186,7 +191,7 @@ export default class Connection { const msg = this._ws?.parseMessage(await this._ws?.next()); if (msg?.hash) { this._hash = msg?.hash; - await this.handleHash(); + await this.login(this._password); this.msgbox("input-password", "Password Required", ""); } else if (msg?.testDelay) { const testDelay = msg?.testDelay; @@ -198,23 +203,30 @@ export default class Connection { if (r.error) { this.msgbox("error", "Error", r.error); } else if (r.peerInfo) { - this._peerInfo = r.peerInfo; - this.msgbox( - "success", - "Successful", - "Connected, waiting for image..." - ); + this.handlePeerInfo(r.peerInfo); } } else if (msg?.videoFrame) { this.handleVideoFrame(msg?.videoFrame!); + } else if (msg?.clipboard) { + const cb = msg?.clipboard; + if (cb.compress) cb.content = globals.decompress(cb.content); + globals.pushEvent("clipboard", cb); + } else if (msg?.cursorData) { + const cd = msg?.cursorData; + cd.colors = globals.decompress(cd.colors); + globals.pushEvent("cursor_data", cd); + } else if (msg?.cursorId) { + globals.pushEvent("cursor_id", { id: msg?.cursorId }); + } else if (msg?.cursorPosition) { + globals.pushEvent("cursor_position", msg?.cursorPosition); + } else if (msg?.misc) { + this.handleMisc(msg?.misc); + } else if (msg?.audioFrame) { + // } } } - async handleHash() { - await this._sendLoginMessage(); - } - msgbox(type_: string, title: string, text: string) { this._msgbox?.(type_, title, text); } @@ -224,12 +236,20 @@ export default class Connection { } close() { + this._msgs = []; clearInterval(this._interval); this._ws?.close(); this._videoDecoder?.close(); this._audioDecoder?.close(); } + async refresh() { + const misc = message.Misc.fromPartial({ + refreshVideo: true, + }); + await this._ws?.sendMessage({ misc }); + } + setMsgbox(callback: MsgboxCallback) { this._msgbox = callback; } @@ -238,19 +258,27 @@ export default class Connection { this._draw = callback; } - async login(password: string) { + async login(password: string | undefined, _remember: Boolean = false) { + this._password = password; this.msgbox("connecting", "Connecting...", "Logging in..."); - let salt = this._hash?.salt; - if (salt) { + const salt = this._hash?.salt; + if (salt && password) { let p = hash([password, salt]); - let challenge = this._hash?.challenge; + const challenge = this._hash?.challenge; if (challenge) { p = hash([p, challenge]); await this._sendLoginMessage(p); } + } else { + await this._sendLoginMessage(); } } + async reconnect() { + this.close(); + await this.start(this._id); + } + async _sendLoginMessage(password: Uint8Array | undefined = undefined) { const loginRequest = message.LoginRequest.fromPartial({ username: this._id!, @@ -267,7 +295,7 @@ export default class Connection { this._firstFrame = true; } if (vf.vp9s) { - let dec = this._videoDecoder; + const dec = this._videoDecoder; // dec.sync(); vf.vp9s.frames.forEach((f) => { dec.processFrame(f.data.slice(0).buffer, (ok: any) => { @@ -278,6 +306,44 @@ export default class Connection { }); } } + + handlePeerInfo(pi: message.PeerInfo) { + this._peerInfo = pi; + if (pi.displays.length == 0) { + this.msgbox("error", "Remote Error", "No Display"); + return; + } + this.msgbox("success", "Successful", "Connected, waiting for image..."); + globals.pushEvent("peer_info", pi); + } + + handleMisc(misc: message.Misc) { + if (misc.audioFormat) { + // + } else if (misc.permissionInfo) { + const p = misc.permissionInfo; + console.info("Change permission " + p.permission + " -> " + p.enabled); + let name; + switch (p.permission) { + case message.PermissionInfo_Permission.Keyboard: + name = "keyboard"; + break; + case message.PermissionInfo_Permission.Clipboard: + name = "clipboard"; + break; + case message.PermissionInfo_Permission.Audio: + name = "audio"; + break; + default: + return; + } + globals.pushEvent("permission", { [name]: p.enabled }); + } else if (misc.switchDisplay) { + globals.pushEvent("switch_display", misc.switchDisplay); + } else if (misc.closeReason) { + this.msgbox("error", "Connection Error", misc.closeReason); + } + } } // @ts-ignore diff --git a/src/globals.js b/src/globals.js index cd3828dec..43d5a8022 100644 --- a/src/globals.js +++ b/src/globals.js @@ -1,7 +1,39 @@ import Connection from "./connection"; import _sodium from "libsodium-wrappers"; +import { ZSTDecoder } from 'zstddec'; + +const decompressor = new ZSTDDecoder(); +await decompressor.init(); + +var currentFrame = undefined; +var events = []; window.currentConnection = undefined; +window.getRgba = () => currentFrame; +window.getLanguage = () => navigator.language; + +export function msgbox(type, title, text) { + text = text.toLowerCase(); + var hasRetry = msgtype == "error" + && title == "Connection Error" + && !text.indexOf("offline") >= 0 + && !text.indexOf("exist") >= 0 + && !text.indexOf("handshake") >= 0 + && !text.indexOf("failed") >= 0 + && !text.indexOf("resolve") >= 0 + && !text.indexOf("mismatch") >= 0 + && !text.indexOf("manually") >= 0; + events.push({ name: 'msgbox', type, title, text, hasRetry }); +} + +export function pushEvent(name, payload) { + payload.name = name; + events.push(payload); +} + +export function draw(frame) { + currentFrame = frame; +} export function setConn(conn) { window.currentConnection = conn; @@ -14,6 +46,7 @@ export function getConn() { export function close() { getConn()?.close(); setConn(undefined); + currentFrame = undefined; } export function newConn() { @@ -73,4 +106,58 @@ export function encrypt(unsigned, nonce, key) { export function decrypt(signed, nonce, key) { return sodium.crypto_secretbox_open_easy(signed, makeOnce(nonce), key); +} + +export function decompress(compressedArray) { + const MAX = 1024 * 1024 * 64; + const MIN = 1024 * 1024; + let n = 30 * data.length; + if (n > MAX) { + n = MAX; + } + if (n < MIN) { + n = MIN; + } + try { + return decompressor.decode(compressedArray, n); + } catch (e) { + console.error('decompress failed: ' + e); + } +} + +window.setByName = (name, value) => { + switch (name) { + case 'connect': + newConn(); + break; + case 'login': + currentConnection.login(value.password, value.remember); + break; + case 'close': + close(); + break; + case 'refresh': + currentConnection.refresh(); + break; + case 'reconnect': + currentConnection.reconnect(); + break; + default: + break; + } +} + +window.getByName = (name, value) => { + switch (name) { + case 'peers': + return localStorage.getItem('peers'); + break; + case 'event': + if (events.length) { + const e = events[0]; + events.splice(0, 1); + return e; + } + break; + } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 2e61c8dbf..c8e30b076 100644 --- a/yarn.lock +++ b/yarn.lock @@ -376,3 +376,8 @@ vite@^2.7.2: rollup "^2.59.0" optionalDependencies: fsevents "~2.3.2" + +zstddec@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/zstddec/-/zstddec-0.0.2.tgz#57e2f28dd1ff56b750e07d158a43f0611ad9eeb4" + integrity sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA== From fad130b29af8e0fe19896f0893d2d2aaa95a3bff Mon Sep 17 00:00:00 2001 From: open-trade Date: Wed, 26 Jan 2022 18:58:55 +0800 Subject: [PATCH 25/66] more api --- package.json | 2 +- src/connection.ts | 29 ++++++++---- src/globals.js | 118 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 127 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 611351fff..9ee7ee122 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "web_hbb", "version": "1.0.0", "scripts": { - "dev": "curl -O https://raw.githubusercontent.com/rgov/js-theora-decoder/main/yuv-canvas-1.2.6.js; vite", + "dev": "curl -O https://raw.githubusercontent.com/rgov/js-theora-decoder/main/yuv-canvas-1.2.6.js && vite", "build": "tsc && vite build", "preview": "vite preview" }, diff --git a/src/connection.ts b/src/connection.ts index 6cbba8c12..cfbb72f11 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -6,9 +6,8 @@ import * as sha256 from "fast-sha256"; import * as globals from "./globals"; const PORT = 21116; -const HOST = "rs-sg.rustdesk.com"; -const licenceKey = ""; -const SCHEMA = "ws://"; +const HOST = 'rs-sg.rustdesk.com'; +const SCHEMA = 'ws://'; type MsgboxCallback = (type: string, title: string, text: string) => void; type DrawCallback = (data: Uint8Array) => void; @@ -26,6 +25,7 @@ export default class Connection { _videoDecoder: any; _audioDecoder: any; _password: string | undefined; + _options: any; constructor() { this._msgbox = globals.msgbox; @@ -35,6 +35,11 @@ export default class Connection { } async start(id: string) { + try { + this._options = JSON.parse((localStorage.getItem('peers') || '{}'))[id] || {}; + } catch (e) { + this._options = {}; + } this._interval = setInterval(() => { while (this._msgs.length) { this._ws?.sendMessage(this._msgs[0]); @@ -61,7 +66,7 @@ export default class Connection { const natType = rendezvous.NatType.SYMMETRIC; const punchHoleRequest = rendezvous.PunchHoleRequest.fromPartial({ id, - licenceKey, + licenceKey: localStorage.getItem('key') || undefined, connType, natType, }); @@ -109,7 +114,7 @@ export default class Connection { console.log(new Date() + ": Connected to relay server"); this._ws = ws; const requestRelay = rendezvous.RequestRelay.fromPartial({ - licenceKey, + licenceKey: localStorage.getItem('key') || undefined, uuid, }); ws.sendRendezvous({ requestRelay }); @@ -209,11 +214,11 @@ export default class Connection { this.handleVideoFrame(msg?.videoFrame!); } else if (msg?.clipboard) { const cb = msg?.clipboard; - if (cb.compress) cb.content = globals.decompress(cb.content); + if (cb.compress) cb.content = globals.decompress(cb.content)!; globals.pushEvent("clipboard", cb); } else if (msg?.cursorData) { const cd = msg?.cursorData; - cd.colors = globals.decompress(cd.colors); + cd.colors = globals.decompress(cd.colors)!; globals.pushEvent("cursor_data", cd); } else if (msg?.cursorId) { globals.pushEvent("cursor_id", { id: msg?.cursorId }); @@ -344,6 +349,14 @@ export default class Connection { this.msgbox("error", "Connection Error", misc.closeReason); } } + + getRemember(): any { + return this._options['remember']; + } + + getOption(name: string): any { + return this._options[name]; + } } // @ts-ignore @@ -354,7 +367,7 @@ async function testDelay() { } function getDefaultUri(isRelay: Boolean = false): string { - const host = localStorage.getItem("host"); + const host = localStorage.getItem("custom-rendezvous-server"); return SCHEMA + (host || HOST) + ":" + (PORT + (isRelay ? 3 : 2)); } diff --git a/src/globals.js b/src/globals.js index 43d5a8022..713d8baed 100644 --- a/src/globals.js +++ b/src/globals.js @@ -1,14 +1,14 @@ import Connection from "./connection"; import _sodium from "libsodium-wrappers"; -import { ZSTDecoder } from 'zstddec'; +import * as zstd from 'zstddec'; +import { CursorData } from "./message"; -const decompressor = new ZSTDDecoder(); -await decompressor.init(); +const decompressor = new zstd.ZSTDDecoder(); var currentFrame = undefined; var events = []; -window.currentConnection = undefined; +window.curConn = undefined; window.getRgba = () => currentFrame; window.getLanguage = () => navigator.language; @@ -36,11 +36,11 @@ export function draw(frame) { } export function setConn(conn) { - window.currentConnection = conn; + window.curConn = conn; } export function getConn() { - return window.currentConnection; + return window.curConn; } export function close() { @@ -50,7 +50,7 @@ export function close() { } export function newConn() { - window.currentConnection?.close(); + window.curConn?.close(); const conn = new Connection(); setConn(conn); return conn; @@ -126,38 +126,130 @@ export function decompress(compressedArray) { } window.setByName = (name, value) => { + try { + value = JSON.parse(value); + } catch (e) {} switch (name) { - case 'connect': + case 'connect': newConn(); + curConn.start(value); break; case 'login': - currentConnection.login(value.password, value.remember); + curConn.login(value.password, value.remember || false); break; case 'close': close(); break; case 'refresh': - currentConnection.refresh(); + curConn.refresh(); break; case 'reconnect': - currentConnection.reconnect(); + curConn.reconnect(); + break; + case 'toggle_option': + curConn.toggleOption(value); + break; + case 'image_quality': + curConn.setImageQuality(value); + break; + case 'lock_screen': + curConn.lockScreen(); + break; + case 'ctrl_alt_del': + curConn.ctrlAltDe(); + break; + case 'switch_display': + curConn.switchDisplay(value); + break; + case 'remove': + const peers = JSON.parse(localStorage.getItem('peers') || '{}'); + delete peers[value]; + localStorage.setItem('peers', JSON.stringify(peers)); + break; + case 'input_key': + curConn.inputKey(value.name, value.alt || false, value.ctrl || false, value.shift || false, value.command || false); + break; + case 'input_string': + curConn.inputString(value); + break; + case 'send_mouse': + let mask = 0; + switch (value.type) { + case 'down': + mask = 1; + break; + case 'up': + mask = 2; + break; + case 'wheel': + mask = 3; + break; + } + switch (value.buttons) { + case 'left': + mask |= 1 << 3; + break; + case 'right': + mask |= 2 << 3; + break; + case 'wheel': + mask |= 4 << 3; + } + curConn.inputMouse(mask, value.x || 0, value.y || 0, value.alt || false, value.ctrl || false, value.shift || false, value.command || false); + break; + case 'option': + localStorage.setItem(value.name, value.value); + break; + case 'peer_option': + curConn.setPeerOption(value.name, value.value); + break; + case 'input_os_password': + curConn.inputOsPassword(value, true); break; default: break; } } -window.getByName = (name, value) => { +window.getByName = (name, arg) => { + try { + arg = JSON.parse(arg); + } catch (e) {} switch (name) { case 'peers': return localStorage.getItem('peers'); break; + case 'remote_id': + return localStorage.getItem('remote-id') || ''; + break; + case 'remember': + return curConn.getRemember(); + break; case 'event': if (events.length) { const e = events[0]; events.splice(0, 1); - return e; + return JSON.stringify(e); } break; + case 'toggle_option': + return curConn.getOption(arg); + break; + case 'option': + return localStorage.getItem(arg); + break; + case 'image_quality': + return curConn.getImageQuality(); + break; + case 'translate': + return arg.text; + break; + case 'peer_option': + return curConn.getOption(arg); + break; } +} + +window.init = () => { + decompressor.init(); } \ No newline at end of file From 6c0030bbe292db2fefa5ffc14c03e5a771b12b04 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 27 Jan 2022 01:30:29 +0800 Subject: [PATCH 26/66] will do more on socket error --- src/connection.ts | 13 +++++++------ src/globals.js | 38 +++++++++++++++++++++++++------------- src/ui.js | 4 ++-- src/websock.ts | 10 +++++++++- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index cfbb72f11..2c3153112 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -6,8 +6,8 @@ import * as sha256 from "fast-sha256"; import * as globals from "./globals"; const PORT = 21116; -const HOST = 'rs-sg.rustdesk.com'; -const SCHEMA = 'ws://'; +const HOST = "rs-sg.rustdesk.com"; +const SCHEMA = "ws://"; type MsgboxCallback = (type: string, title: string, text: string) => void; type DrawCallback = (data: Uint8Array) => void; @@ -36,7 +36,8 @@ export default class Connection { async start(id: string) { try { - this._options = JSON.parse((localStorage.getItem('peers') || '{}'))[id] || {}; + this._options = + JSON.parse(localStorage.getItem("peers") || "{}")[id] || {}; } catch (e) { this._options = {}; } @@ -66,7 +67,7 @@ export default class Connection { const natType = rendezvous.NatType.SYMMETRIC; const punchHoleRequest = rendezvous.PunchHoleRequest.fromPartial({ id, - licenceKey: localStorage.getItem('key') || undefined, + licenceKey: localStorage.getItem("key") || undefined, connType, natType, }); @@ -114,7 +115,7 @@ export default class Connection { console.log(new Date() + ": Connected to relay server"); this._ws = ws; const requestRelay = rendezvous.RequestRelay.fromPartial({ - licenceKey: localStorage.getItem('key') || undefined, + licenceKey: localStorage.getItem("key") || undefined, uuid, }); ws.sendRendezvous({ requestRelay }); @@ -351,7 +352,7 @@ export default class Connection { } getRemember(): any { - return this._options['remember']; + return this._options["remember"]; } getOption(name: string): any { diff --git a/src/globals.js b/src/globals.js index 713d8baed..3562bbdef 100644 --- a/src/globals.js +++ b/src/globals.js @@ -13,16 +13,16 @@ window.getRgba = () => currentFrame; window.getLanguage = () => navigator.language; export function msgbox(type, title, text) { - text = text.toLowerCase(); - var hasRetry = msgtype == "error" + const text2 = text.toLowerCase(); + var hasRetry = type == "error" && title == "Connection Error" - && !text.indexOf("offline") >= 0 - && !text.indexOf("exist") >= 0 - && !text.indexOf("handshake") >= 0 - && !text.indexOf("failed") >= 0 - && !text.indexOf("resolve") >= 0 - && !text.indexOf("mismatch") >= 0 - && !text.indexOf("manually") >= 0; + && text2.indexOf("offline") < 0 + && text2.indexOf("exist") < 0 + && text2.indexOf("handshake") < 0 + && text2.indexOf("failed") < 0 + && text2.indexOf("resolve") < 0 + && text2.indexOf("mismatch") < 0 + && text2.indexOf("manually") < 0; events.push({ name: 'msgbox', type, title, text, hasRetry }); } @@ -43,6 +43,15 @@ export function getConn() { return window.curConn; } +export async function startConn(id) { + try { + await curConn.start(id); + } catch (e) { + console.log(e); + msgbox('error', 'Error', String(e)); + } +} + export function close() { getConn()?.close(); setConn(undefined); @@ -128,11 +137,11 @@ export function decompress(compressedArray) { window.setByName = (name, value) => { try { value = JSON.parse(value); - } catch (e) {} + } catch (e) { } switch (name) { case 'connect': newConn(); - curConn.start(value); + startConn(value); break; case 'login': curConn.login(value.password, value.remember || false); @@ -214,10 +223,10 @@ window.setByName = (name, value) => { window.getByName = (name, arg) => { try { arg = JSON.parse(arg); - } catch (e) {} + } catch (e) { } switch (name) { case 'peers': - return localStorage.getItem('peers'); + return localStorage.getItem('peers') || '[]'; break; case 'remote_id': return localStorage.getItem('remote-id') || ''; @@ -247,7 +256,10 @@ window.getByName = (name, arg) => { case 'peer_option': return curConn.getOption(arg); break; + case 'test_if_valid_server': + break; } + return ''; } window.init = () => { diff --git a/src/ui.js b/src/ui.js index c5c55bf5c..f506d0120 100644 --- a/src/ui.js +++ b/src/ui.js @@ -31,7 +31,7 @@ if (app) { document.body.onload = () => { const host = document.querySelector('#host'); - host.value = localStorage.getItem('host'); + host.value = localStorage.getItem('custom-rendezvous-server'); const id = document.querySelector('#id'); id.value = localStorage.getItem('id'); const key = document.querySelector('#key'); @@ -41,7 +41,7 @@ if (app) { window.connect = () => { const host = document.querySelector('#host'); - localStorage.setItem('host', host.value); + localStorage.setItem('custom-rendezvous-server', host.value); const id = document.querySelector('#id'); localStorage.setItem('id', id.value); const key = document.querySelector('#key'); diff --git a/src/websock.ts b/src/websock.ts index 1ce2c45e7..1087495a3 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -11,6 +11,7 @@ export default class Websock { _status: any; _latency: number; _secretKey: [Uint8Array, number, number] | undefined; + _uri: string; constructor(uri: string) { this._eventHandlers = { @@ -19,6 +20,7 @@ export default class Websock { close: () => {}, error: () => {}, }; + this._uri = uri; this._status = ""; this._buf = []; this._websocket = new WebSocket(uri); @@ -36,7 +38,9 @@ export default class Websock { } sendMessage(json: any) { - let data = message.Message.encode(message.Message.fromPartial(json)).finish(); + let data = message.Message.encode( + message.Message.fromPartial(json) + ).finish(); let k = this._secretKey; if (k) { k[1] += 1; @@ -98,6 +102,10 @@ export default class Websock { reject(e); }; this._websocket.onerror = (e) => { + if (!this._status) { + reject('Failed to connect to ' + this._uri); + return; + } this._status = e; console.error("WebSock.onerror: " + e); this._eventHandlers.error(e); From 74c53f17ae107a729023715498ea83e5ba9f7367 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 27 Jan 2022 13:24:40 +0800 Subject: [PATCH 27/66] bug fix --- src/connection.ts | 18 ++++++++---------- src/globals.js | 11 ++++++++--- src/ui.js | 7 ++----- src/websock.ts | 5 ++++- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index 2c3153112..2a6dad977 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -60,7 +60,7 @@ export default class Connection { const ws = new Websock(uri); this._ws = ws; this._id = id; - console.log(new Date() + ": Conntecting to rendezvoous server: " + uri); + console.log(new Date() + ": Conntecting to rendezvoous server: " + uri + ", for " + id); await ws.open(); console.log(new Date() + ": Connected to rendezvoous server"); const connType = rendezvous.ConnType.DEFAULT_CONN; @@ -197,8 +197,8 @@ export default class Connection { const msg = this._ws?.parseMessage(await this._ws?.next()); if (msg?.hash) { this._hash = msg?.hash; + if (!this._password) this.msgbox("input-password", "Password Required", ""); await this.login(this._password); - this.msgbox("input-password", "Password Required", ""); } else if (msg?.testDelay) { const testDelay = msg?.testDelay; if (!testDelay.fromClient) { @@ -266,15 +266,13 @@ export default class Connection { async login(password: string | undefined, _remember: Boolean = false) { this._password = password; - this.msgbox("connecting", "Connecting...", "Logging in..."); - const salt = this._hash?.salt; - if (salt && password) { - let p = hash([password, salt]); + if (password) { + const salt = this._hash?.salt; + let p = hash([password, salt!]); const challenge = this._hash?.challenge; - if (challenge) { - p = hash([p, challenge]); - await this._sendLoginMessage(p); - } + p = hash([p, challenge!]); + this.msgbox("connecting", "Connecting...", "Logging in..."); + await this._sendLoginMessage(p); } else { await this._sendLoginMessage(); } diff --git a/src/globals.js b/src/globals.js index 3562bbdef..d7a229560 100644 --- a/src/globals.js +++ b/src/globals.js @@ -13,6 +13,8 @@ window.getRgba = () => currentFrame; window.getLanguage = () => navigator.language; export function msgbox(type, title, text) { + if (!events) return; + if (!type) return; const text2 = text.toLowerCase(); var hasRetry = type == "error" && title == "Connection Error" @@ -27,6 +29,7 @@ export function msgbox(type, title, text) { } export function pushEvent(name, payload) { + if (!events) return; payload.name = name; events.push(payload); } @@ -56,10 +59,12 @@ export function close() { getConn()?.close(); setConn(undefined); currentFrame = undefined; + events = undefined; } export function newConn() { window.curConn?.close(); + events = []; const conn = new Connection(); setConn(conn); return conn; @@ -120,7 +125,7 @@ export function decrypt(signed, nonce, key) { export function decompress(compressedArray) { const MAX = 1024 * 1024 * 64; const MIN = 1024 * 1024; - let n = 30 * data.length; + let n = 30 * compressedArray.length; if (n > MAX) { n = MAX; } @@ -141,7 +146,7 @@ window.setByName = (name, value) => { switch (name) { case 'connect': newConn(); - startConn(value); + startConn(String(value)); break; case 'login': curConn.login(value.password, value.remember || false); @@ -235,7 +240,7 @@ window.getByName = (name, arg) => { return curConn.getRemember(); break; case 'event': - if (events.length) { + if (events && events.length) { const e = events[0]; events.splice(0, 1); return JSON.stringify(e); diff --git a/src/ui.js b/src/ui.js index f506d0120..4402d7400 100644 --- a/src/ui.js +++ b/src/ui.js @@ -28,6 +28,7 @@ if (app) { `; let player; + window.init(); document.body.onload = () => { const host = document.querySelector('#host'); @@ -55,11 +56,7 @@ if (app) { document.querySelector('div#status').style.display = 'block'; document.querySelector('div#connect').style.display = 'none'; document.querySelector('div#text').innerHTML = 'Connecting ...'; - try { - await conn.start(id.value); - } catch (e) { - msgbox('error', 'Error', e); - } + await conn.start(id.value); }; func(); } diff --git a/src/websock.ts b/src/websock.ts index 1087495a3..6fc66ee17 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -96,10 +96,12 @@ export default class Websock { resolve(this); }; this._websocket.onclose = (e) => { + if (this._status == 'open') { + reject(e); + } this._status = e; console.error("WebSock.onclose: " + e); this._eventHandlers.close(e); - reject(e); }; this._websocket.onerror = (e) => { if (!this._status) { @@ -141,6 +143,7 @@ export default class Websock { } close() { + this._status = ''; if (this._websocket) { if ( this._websocket.readyState === WebSocket.OPEN || From c8b681b84cb85e5c891a85844892e97cb71240f0 Mon Sep 17 00:00:00 2001 From: open-trade Date: Thu, 27 Jan 2022 18:58:29 +0800 Subject: [PATCH 28/66] working on yuv --- LibYUV.js | 2479 +++++++++++++++++++++++++++++++++++++++++++ LibYUV.wasm | Bin 0 -> 18588 bytes index.html | 1 + package.json | 2 +- src/connection.ts | 4 +- src/globals.js | 31 +- yuv-canvas-1.2.6.js | 1234 +++++++++++++++++++++ 7 files changed, 3744 insertions(+), 7 deletions(-) create mode 100644 LibYUV.js create mode 100644 LibYUV.wasm create mode 100644 yuv-canvas-1.2.6.js diff --git a/LibYUV.js b/LibYUV.js new file mode 100644 index 000000000..010d17bbc --- /dev/null +++ b/LibYUV.js @@ -0,0 +1,2479 @@ + +var LibYUV = (function() { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; + return ( +function(LibYUV) { + LibYUV = LibYUV || {}; + + +// The Module object: Our interface to the outside world. We import +// and export values on it. There are various ways Module can be used: +// 1. Not defined. We create it here +// 2. A function parameter, function(Module) { ..generated code.. } +// 3. pre-run appended it, var Module = {}; ..generated code.. +// 4. External script tag defines var Module. +// We need to check if Module already exists (e.g. case 3 above). +// Substitution will be replaced with actual code on later stage of the build, +// this way Closure Compiler will not mangle it (e.g. case 4. above). +// Note that if you want to run closure, and also to use Module +// after the generated code, you will need to define var Module = {}; +// before the code. Then that object will be used in the code, and you +// can continue to use Module afterwards as well. +var Module = typeof LibYUV !== 'undefined' ? LibYUV : {}; + +// Set up the promise that indicates the Module is initialized +var readyPromiseResolve, readyPromiseReject; +Module['ready'] = new Promise(function(resolve, reject) { + readyPromiseResolve = resolve; + readyPromiseReject = reject; +}); + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_malloc')) { + Object.defineProperty(Module['ready'], '_malloc', { configurable: true, get: function() { abort('You are getting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_malloc', { configurable: true, set: function() { abort('You are setting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_free')) { + Object.defineProperty(Module['ready'], '_free', { configurable: true, get: function() { abort('You are getting _free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_free', { configurable: true, set: function() { abort('You are setting _free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_ConvertRGBA88882YUV420P')) { + Object.defineProperty(Module['ready'], '_ConvertRGBA88882YUV420P', { configurable: true, get: function() { abort('You are getting _ConvertRGBA88882YUV420P on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_ConvertRGBA88882YUV420P', { configurable: true, set: function() { abort('You are setting _ConvertRGBA88882YUV420P on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_ConvertYUV420P2RGBA8888')) { + Object.defineProperty(Module['ready'], '_ConvertYUV420P2RGBA8888', { configurable: true, get: function() { abort('You are getting _ConvertYUV420P2RGBA8888 on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_ConvertYUV420P2RGBA8888', { configurable: true, set: function() { abort('You are setting _ConvertYUV420P2RGBA8888 on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_I420ToABGR')) { + Object.defineProperty(Module['ready'], '_I420ToABGR', { configurable: true, get: function() { abort('You are getting _I420ToABGR on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_I420ToABGR', { configurable: true, set: function() { abort('You are setting _I420ToABGR on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_ABGRToI420')) { + Object.defineProperty(Module['ready'], '_ABGRToI420', { configurable: true, get: function() { abort('You are getting _ABGRToI420 on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_ABGRToI420', { configurable: true, set: function() { abort('You are setting _ABGRToI420 on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_get_end')) { + Object.defineProperty(Module['ready'], '_emscripten_stack_get_end', { configurable: true, get: function() { abort('You are getting _emscripten_stack_get_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_emscripten_stack_get_end', { configurable: true, set: function() { abort('You are setting _emscripten_stack_get_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_get_free')) { + Object.defineProperty(Module['ready'], '_emscripten_stack_get_free', { configurable: true, get: function() { abort('You are getting _emscripten_stack_get_free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_emscripten_stack_get_free', { configurable: true, set: function() { abort('You are setting _emscripten_stack_get_free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_init')) { + Object.defineProperty(Module['ready'], '_emscripten_stack_init', { configurable: true, get: function() { abort('You are getting _emscripten_stack_init on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_emscripten_stack_init', { configurable: true, set: function() { abort('You are setting _emscripten_stack_init on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_get_base')) { + Object.defineProperty(Module['ready'], '_emscripten_stack_get_base', { configurable: true, get: function() { abort('You are getting _emscripten_stack_get_base on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_emscripten_stack_get_base', { configurable: true, set: function() { abort('You are setting _emscripten_stack_get_base on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackSave')) { + Object.defineProperty(Module['ready'], '_stackSave', { configurable: true, get: function() { abort('You are getting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_stackSave', { configurable: true, set: function() { abort('You are setting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackRestore')) { + Object.defineProperty(Module['ready'], '_stackRestore', { configurable: true, get: function() { abort('You are getting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_stackRestore', { configurable: true, set: function() { abort('You are setting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackAlloc')) { + Object.defineProperty(Module['ready'], '_stackAlloc', { configurable: true, get: function() { abort('You are getting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_stackAlloc', { configurable: true, set: function() { abort('You are setting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '___wasm_call_ctors')) { + Object.defineProperty(Module['ready'], '___wasm_call_ctors', { configurable: true, get: function() { abort('You are getting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '___wasm_call_ctors', { configurable: true, set: function() { abort('You are setting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '_fflush')) { + Object.defineProperty(Module['ready'], '_fflush', { configurable: true, get: function() { abort('You are getting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '_fflush', { configurable: true, set: function() { abort('You are setting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], '___errno_location')) { + Object.defineProperty(Module['ready'], '___errno_location', { configurable: true, get: function() { abort('You are getting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], '___errno_location', { configurable: true, set: function() { abort('You are setting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + + if (!Object.getOwnPropertyDescriptor(Module['ready'], 'onRuntimeInitialized')) { + Object.defineProperty(Module['ready'], 'onRuntimeInitialized', { configurable: true, get: function() { abort('You are getting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + Object.defineProperty(Module['ready'], 'onRuntimeInitialized', { configurable: true, set: function() { abort('You are setting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); + } + + +// --pre-jses are emitted after the Module integration code, so that they can +// refer to Module (if they choose; they can also define Module) +// {{PRE_JSES}} + +// Sometimes an existing Module object exists with properties +// meant to overwrite the default module functionality. Here +// we collect those properties and reapply _after_ we configure +// the current environment's defaults to avoid having to be so +// defensive during initialization. +var moduleOverrides = {}; +var key; +for (key in Module) { + if (Module.hasOwnProperty(key)) { + moduleOverrides[key] = Module[key]; + } +} + +var arguments_ = []; +var thisProgram = './this.program'; +var quit_ = function(status, toThrow) { + throw toThrow; +}; + +// Determine the runtime environment we are in. You can customize this by +// setting the ENVIRONMENT setting at compile time (see settings.js). + +var ENVIRONMENT_IS_WEB = false; +var ENVIRONMENT_IS_WORKER = false; +var ENVIRONMENT_IS_NODE = false; +var ENVIRONMENT_IS_SHELL = false; +ENVIRONMENT_IS_WEB = typeof window === 'object'; +ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; +// N.b. Electron.js environment is simultaneously a NODE-environment, but +// also a web environment. +ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string'; +ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; + +if (Module['ENVIRONMENT']) { + throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)'); +} + +// `/` should be present at the end if `scriptDirectory` is not empty +var scriptDirectory = ''; +function locateFile(path) { + if (Module['locateFile']) { + return Module['locateFile'](path, scriptDirectory); + } + return scriptDirectory + path; +} + +// Hooks that are implemented differently in different runtime environments. +var read_, + readAsync, + readBinary, + setWindowTitle; + +var nodeFS; +var nodePath; + +if (ENVIRONMENT_IS_NODE) { + if (ENVIRONMENT_IS_WORKER) { + scriptDirectory = require('path').dirname(scriptDirectory) + '/'; + } else { + scriptDirectory = __dirname + '/'; + } + +// include: node_shell_read.js + + +read_ = function shell_read(filename, binary) { + if (!nodeFS) nodeFS = require('fs'); + if (!nodePath) nodePath = require('path'); + filename = nodePath['normalize'](filename); + return nodeFS['readFileSync'](filename, binary ? null : 'utf8'); +}; + +readBinary = function readBinary(filename) { + var ret = read_(filename, true); + if (!ret.buffer) { + ret = new Uint8Array(ret); + } + assert(ret.buffer); + return ret; +}; + +// end include: node_shell_read.js + if (process['argv'].length > 1) { + thisProgram = process['argv'][1].replace(/\\/g, '/'); + } + + arguments_ = process['argv'].slice(2); + + // MODULARIZE will export the module in the proper place outside, we don't need to export here + + process['on']('uncaughtException', function(ex) { + // suppress ExitStatus exceptions from showing an error + if (!(ex instanceof ExitStatus)) { + throw ex; + } + }); + + process['on']('unhandledRejection', abort); + + quit_ = function(status) { + process['exit'](status); + }; + + Module['inspect'] = function () { return '[Emscripten Module object]'; }; + +} else +if (ENVIRONMENT_IS_SHELL) { + + if (typeof read != 'undefined') { + read_ = function shell_read(f) { + return read(f); + }; + } + + readBinary = function readBinary(f) { + var data; + if (typeof readbuffer === 'function') { + return new Uint8Array(readbuffer(f)); + } + data = read(f, 'binary'); + assert(typeof data === 'object'); + return data; + }; + + if (typeof scriptArgs != 'undefined') { + arguments_ = scriptArgs; + } else if (typeof arguments != 'undefined') { + arguments_ = arguments; + } + + if (typeof quit === 'function') { + quit_ = function(status) { + quit(status); + }; + } + + if (typeof print !== 'undefined') { + // Prefer to use print/printErr where they exist, as they usually work better. + if (typeof console === 'undefined') console = /** @type{!Console} */({}); + console.log = /** @type{!function(this:Console, ...*): undefined} */ (print); + console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr !== 'undefined' ? printErr : print); + } + +} else + +// Note that this includes Node.js workers when relevant (pthreads is enabled). +// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and +// ENVIRONMENT_IS_NODE. +if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { + if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled + scriptDirectory = self.location.href; + } else if (typeof document !== 'undefined' && document.currentScript) { // web + scriptDirectory = document.currentScript.src; + } + // When MODULARIZE, this JS may be executed later, after document.currentScript + // is gone, so we saved it, and we use it here instead of any other info. + if (_scriptDir) { + scriptDirectory = _scriptDir; + } + // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them. + // otherwise, slice off the final part of the url to find the script directory. + // if scriptDirectory does not contain a slash, lastIndexOf will return -1, + // and scriptDirectory will correctly be replaced with an empty string. + if (scriptDirectory.indexOf('blob:') !== 0) { + scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/')+1); + } else { + scriptDirectory = ''; + } + + // Differentiate the Web Worker from the Node Worker case, as reading must + // be done differently. + { + +// include: web_or_worker_shell_read.js + + + read_ = function(url) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.send(null); + return xhr.responseText; + }; + + if (ENVIRONMENT_IS_WORKER) { + readBinary = function(url) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.responseType = 'arraybuffer'; + xhr.send(null); + return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response)); + }; + } + + readAsync = function(url, onload, onerror) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.responseType = 'arraybuffer'; + xhr.onload = function() { + if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0 + onload(xhr.response); + return; + } + onerror(); + }; + xhr.onerror = onerror; + xhr.send(null); + }; + +// end include: web_or_worker_shell_read.js + } + + setWindowTitle = function(title) { document.title = title }; +} else +{ + throw new Error('environment detection error'); +} + +// Set up the out() and err() hooks, which are how we can print to stdout or +// stderr, respectively. +var out = Module['print'] || console.log.bind(console); +var err = Module['printErr'] || console.warn.bind(console); + +// Merge back in the overrides +for (key in moduleOverrides) { + if (moduleOverrides.hasOwnProperty(key)) { + Module[key] = moduleOverrides[key]; + } +} +// Free the object hierarchy contained in the overrides, this lets the GC +// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array. +moduleOverrides = null; + +// Emit code to handle expected values on the Module object. This applies Module.x +// to the proper local x. This has two benefits: first, we only emit it if it is +// expected to arrive, and second, by using a local everywhere else that can be +// minified. + +if (Module['arguments']) arguments_ = Module['arguments']; +if (!Object.getOwnPropertyDescriptor(Module, 'arguments')) { + Object.defineProperty(Module, 'arguments', { + configurable: true, + get: function() { + abort('Module.arguments has been replaced with plain arguments_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') + } + }); +} + +if (Module['thisProgram']) thisProgram = Module['thisProgram']; +if (!Object.getOwnPropertyDescriptor(Module, 'thisProgram')) { + Object.defineProperty(Module, 'thisProgram', { + configurable: true, + get: function() { + abort('Module.thisProgram has been replaced with plain thisProgram (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') + } + }); +} + +if (Module['quit']) quit_ = Module['quit']; +if (!Object.getOwnPropertyDescriptor(Module, 'quit')) { + Object.defineProperty(Module, 'quit', { + configurable: true, + get: function() { + abort('Module.quit has been replaced with plain quit_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') + } + }); +} + +// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message +// Assertions on removed incoming Module JS APIs. +assert(typeof Module['memoryInitializerPrefixURL'] === 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead'); +assert(typeof Module['pthreadMainPrefixURL'] === 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead'); +assert(typeof Module['cdInitializerPrefixURL'] === 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead'); +assert(typeof Module['filePackagePrefixURL'] === 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead'); +assert(typeof Module['read'] === 'undefined', 'Module.read option was removed (modify read_ in JS)'); +assert(typeof Module['readAsync'] === 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)'); +assert(typeof Module['readBinary'] === 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)'); +assert(typeof Module['setWindowTitle'] === 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)'); +assert(typeof Module['TOTAL_MEMORY'] === 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY'); + +if (!Object.getOwnPropertyDescriptor(Module, 'read')) { + Object.defineProperty(Module, 'read', { + configurable: true, + get: function() { + abort('Module.read has been replaced with plain read_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') + } + }); +} + +if (!Object.getOwnPropertyDescriptor(Module, 'readAsync')) { + Object.defineProperty(Module, 'readAsync', { + configurable: true, + get: function() { + abort('Module.readAsync has been replaced with plain readAsync (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') + } + }); +} + +if (!Object.getOwnPropertyDescriptor(Module, 'readBinary')) { + Object.defineProperty(Module, 'readBinary', { + configurable: true, + get: function() { + abort('Module.readBinary has been replaced with plain readBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') + } + }); +} + +if (!Object.getOwnPropertyDescriptor(Module, 'setWindowTitle')) { + Object.defineProperty(Module, 'setWindowTitle', { + configurable: true, + get: function() { + abort('Module.setWindowTitle has been replaced with plain setWindowTitle (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') + } + }); +} +var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js'; +var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js'; +var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js'; +var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js'; + + + + +var STACK_ALIGN = 16; + +function alignMemory(size, factor) { + if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default + return Math.ceil(size / factor) * factor; +} + +function getNativeTypeSize(type) { + switch (type) { + case 'i1': case 'i8': return 1; + case 'i16': return 2; + case 'i32': return 4; + case 'i64': return 8; + case 'float': return 4; + case 'double': return 8; + default: { + if (type[type.length-1] === '*') { + return 4; // A pointer + } else if (type[0] === 'i') { + var bits = Number(type.substr(1)); + assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type); + return bits / 8; + } else { + return 0; + } + } + } +} + +function warnOnce(text) { + if (!warnOnce.shown) warnOnce.shown = {}; + if (!warnOnce.shown[text]) { + warnOnce.shown[text] = 1; + err(text); + } +} + +// include: runtime_functions.js + + +// Wraps a JS function as a wasm function with a given signature. +function convertJsFunctionToWasm(func, sig) { + + // If the type reflection proposal is available, use the new + // "WebAssembly.Function" constructor. + // Otherwise, construct a minimal wasm module importing the JS function and + // re-exporting it. + if (typeof WebAssembly.Function === "function") { + var typeNames = { + 'i': 'i32', + 'j': 'i64', + 'f': 'f32', + 'd': 'f64' + }; + var type = { + parameters: [], + results: sig[0] == 'v' ? [] : [typeNames[sig[0]]] + }; + for (var i = 1; i < sig.length; ++i) { + type.parameters.push(typeNames[sig[i]]); + } + return new WebAssembly.Function(type, func); + } + + // The module is static, with the exception of the type section, which is + // generated based on the signature passed in. + var typeSection = [ + 0x01, // id: section, + 0x00, // length: 0 (placeholder) + 0x01, // count: 1 + 0x60, // form: func + ]; + var sigRet = sig.slice(0, 1); + var sigParam = sig.slice(1); + var typeCodes = { + 'i': 0x7f, // i32 + 'j': 0x7e, // i64 + 'f': 0x7d, // f32 + 'd': 0x7c, // f64 + }; + + // Parameters, length + signatures + typeSection.push(sigParam.length); + for (var i = 0; i < sigParam.length; ++i) { + typeSection.push(typeCodes[sigParam[i]]); + } + + // Return values, length + signatures + // With no multi-return in MVP, either 0 (void) or 1 (anything else) + if (sigRet == 'v') { + typeSection.push(0x00); + } else { + typeSection = typeSection.concat([0x01, typeCodes[sigRet]]); + } + + // Write the overall length of the type section back into the section header + // (excepting the 2 bytes for the section id and length) + typeSection[1] = typeSection.length - 2; + + // Rest of the module is static + var bytes = new Uint8Array([ + 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm") + 0x01, 0x00, 0x00, 0x00, // version: 1 + ].concat(typeSection, [ + 0x02, 0x07, // import section + // (import "e" "f" (func 0 (type 0))) + 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00, + 0x07, 0x05, // export section + // (export "f" (func 0 (type 0))) + 0x01, 0x01, 0x66, 0x00, 0x00, + ])); + + // We can compile this wasm module synchronously because it is very small. + // This accepts an import (at "e.f"), that it reroutes to an export (at "f") + var module = new WebAssembly.Module(bytes); + var instance = new WebAssembly.Instance(module, { + 'e': { + 'f': func + } + }); + var wrappedFunc = instance.exports['f']; + return wrappedFunc; +} + +var freeTableIndexes = []; + +// Weak map of functions in the table to their indexes, created on first use. +var functionsInTableMap; + +function getEmptyTableSlot() { + // Reuse a free index if there is one, otherwise grow. + if (freeTableIndexes.length) { + return freeTableIndexes.pop(); + } + // Grow the table + try { + wasmTable.grow(1); + } catch (err) { + if (!(err instanceof RangeError)) { + throw err; + } + throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.'; + } + return wasmTable.length - 1; +} + +// Add a wasm function to the table. +function addFunctionWasm(func, sig) { + // Check if the function is already in the table, to ensure each function + // gets a unique index. First, create the map if this is the first use. + if (!functionsInTableMap) { + functionsInTableMap = new WeakMap(); + for (var i = 0; i < wasmTable.length; i++) { + var item = wasmTable.get(i); + // Ignore null values. + if (item) { + functionsInTableMap.set(item, i); + } + } + } + if (functionsInTableMap.has(func)) { + return functionsInTableMap.get(func); + } + + // It's not in the table, add it now. + + // Make sure functionsInTableMap is actually up to date, that is, that this + // function is not actually in the wasm Table despite not being tracked in + // functionsInTableMap. + for (var i = 0; i < wasmTable.length; i++) { + assert(wasmTable.get(i) != func, 'function in Table but not functionsInTableMap'); + } + + var ret = getEmptyTableSlot(); + + // Set the new value. + try { + // Attempting to call this with JS function will cause of table.set() to fail + wasmTable.set(ret, func); + } catch (err) { + if (!(err instanceof TypeError)) { + throw err; + } + assert(typeof sig !== 'undefined', 'Missing signature argument to addFunction: ' + func); + var wrapped = convertJsFunctionToWasm(func, sig); + wasmTable.set(ret, wrapped); + } + + functionsInTableMap.set(func, ret); + + return ret; +} + +function removeFunction(index) { + functionsInTableMap.delete(wasmTable.get(index)); + freeTableIndexes.push(index); +} + +// 'sig' parameter is required for the llvm backend but only when func is not +// already a WebAssembly function. +function addFunction(func, sig) { + assert(typeof func !== 'undefined'); + if (typeof sig === 'undefined') { + err('warning: addFunction(): You should provide a wasm function signature string as a second argument. This is not necessary for asm.js and asm2wasm, but can be required for the LLVM wasm backend, so it is recommended for full portability.'); + } + + return addFunctionWasm(func, sig); +} + +// end include: runtime_functions.js +// include: runtime_debug.js + + +// end include: runtime_debug.js +function makeBigInt(low, high, unsigned) { + return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0)); +} + +var tempRet0 = 0; + +var setTempRet0 = function(value) { + tempRet0 = value; +}; + +var getTempRet0 = function() { + return tempRet0; +}; + +function getCompilerSetting(name) { + throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for getCompilerSetting or emscripten_get_compiler_setting to work'; +} + + + +// === Preamble library stuff === + +// Documentation for the public APIs defined in this file must be updated in: +// site/source/docs/api_reference/preamble.js.rst +// A prebuilt local version of the documentation is available at: +// site/build/text/docs/api_reference/preamble.js.txt +// You can also build docs locally as HTML or other formats in site/ +// An online HTML version (which may be of a different version of Emscripten) +// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html + +var wasmBinary; +if (Module['wasmBinary']) wasmBinary = Module['wasmBinary']; +if (!Object.getOwnPropertyDescriptor(Module, 'wasmBinary')) { + Object.defineProperty(Module, 'wasmBinary', { + configurable: true, + get: function() { + abort('Module.wasmBinary has been replaced with plain wasmBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') + } + }); +} +var noExitRuntime = Module['noExitRuntime'] || true; +if (!Object.getOwnPropertyDescriptor(Module, 'noExitRuntime')) { + Object.defineProperty(Module, 'noExitRuntime', { + configurable: true, + get: function() { + abort('Module.noExitRuntime has been replaced with plain noExitRuntime (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') + } + }); +} + +if (typeof WebAssembly !== 'object') { + abort('no native wasm support detected'); +} + +// include: runtime_safe_heap.js + + +// In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking. +// In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties) + +/** @param {number} ptr + @param {number} value + @param {string} type + @param {number|boolean=} noSafe */ +function setValue(ptr, value, type, noSafe) { + type = type || 'i8'; + if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit + switch(type) { + case 'i1': HEAP8[((ptr)>>0)] = value; break; + case 'i8': HEAP8[((ptr)>>0)] = value; break; + case 'i16': HEAP16[((ptr)>>1)] = value; break; + case 'i32': HEAP32[((ptr)>>2)] = value; break; + case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break; + case 'float': HEAPF32[((ptr)>>2)] = value; break; + case 'double': HEAPF64[((ptr)>>3)] = value; break; + default: abort('invalid type for setValue: ' + type); + } +} + +/** @param {number} ptr + @param {string} type + @param {number|boolean=} noSafe */ +function getValue(ptr, type, noSafe) { + type = type || 'i8'; + if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit + switch(type) { + case 'i1': return HEAP8[((ptr)>>0)]; + case 'i8': return HEAP8[((ptr)>>0)]; + case 'i16': return HEAP16[((ptr)>>1)]; + case 'i32': return HEAP32[((ptr)>>2)]; + case 'i64': return HEAP32[((ptr)>>2)]; + case 'float': return HEAPF32[((ptr)>>2)]; + case 'double': return HEAPF64[((ptr)>>3)]; + default: abort('invalid type for getValue: ' + type); + } + return null; +} + +// end include: runtime_safe_heap.js +// Wasm globals + +var wasmMemory; + +//======================================== +// Runtime essentials +//======================================== + +// whether we are quitting the application. no code should run after this. +// set in exit() and abort() +var ABORT = false; + +// set by exit() and abort(). Passed to 'onExit' handler. +// NOTE: This is also used as the process return code code in shell environments +// but only when noExitRuntime is false. +var EXITSTATUS; + +/** @type {function(*, string=)} */ +function assert(condition, text) { + if (!condition) { + abort('Assertion failed: ' + text); + } +} + +// Returns the C function with a specified identifier (for C++, you need to do manual name mangling) +function getCFunc(ident) { + var func = Module['_' + ident]; // closure exported function + assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported'); + return func; +} + +// C calling interface. +/** @param {string|null=} returnType + @param {Array=} argTypes + @param {Arguments|Array=} args + @param {Object=} opts */ +function ccall(ident, returnType, argTypes, args, opts) { + // For fast lookup of conversion functions + var toC = { + 'string': function(str) { + var ret = 0; + if (str !== null && str !== undefined && str !== 0) { // null string + // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0' + var len = (str.length << 2) + 1; + ret = stackAlloc(len); + stringToUTF8(str, ret, len); + } + return ret; + }, + 'array': function(arr) { + var ret = stackAlloc(arr.length); + writeArrayToMemory(arr, ret); + return ret; + } + }; + + function convertReturnValue(ret) { + if (returnType === 'string') return UTF8ToString(ret); + if (returnType === 'boolean') return Boolean(ret); + return ret; + } + + var func = getCFunc(ident); + var cArgs = []; + var stack = 0; + assert(returnType !== 'array', 'Return type should not be "array".'); + if (args) { + for (var i = 0; i < args.length; i++) { + var converter = toC[argTypes[i]]; + if (converter) { + if (stack === 0) stack = stackSave(); + cArgs[i] = converter(args[i]); + } else { + cArgs[i] = args[i]; + } + } + } + var ret = func.apply(null, cArgs); + + ret = convertReturnValue(ret); + if (stack !== 0) stackRestore(stack); + return ret; +} + +/** @param {string=} returnType + @param {Array=} argTypes + @param {Object=} opts */ +function cwrap(ident, returnType, argTypes, opts) { + return function() { + return ccall(ident, returnType, argTypes, arguments, opts); + } +} + +// We used to include malloc/free by default in the past. Show a helpful error in +// builds with assertions. + +var ALLOC_NORMAL = 0; // Tries to use _malloc() +var ALLOC_STACK = 1; // Lives for the duration of the current function call + +// allocate(): This is for internal use. You can use it yourself as well, but the interface +// is a little tricky (see docs right below). The reason is that it is optimized +// for multiple syntaxes to save space in generated code. So you should +// normally not use allocate(), and instead allocate memory using _malloc(), +// initialize it with setValue(), and so forth. +// @slab: An array of data. +// @allocator: How to allocate memory, see ALLOC_* +/** @type {function((Uint8Array|Array), number)} */ +function allocate(slab, allocator) { + var ret; + assert(typeof allocator === 'number', 'allocate no longer takes a type argument') + assert(typeof slab !== 'number', 'allocate no longer takes a number as arg0') + + if (allocator == ALLOC_STACK) { + ret = stackAlloc(slab.length); + } else { + ret = _malloc(slab.length); + } + + if (slab.subarray || slab.slice) { + HEAPU8.set(/** @type {!Uint8Array} */(slab), ret); + } else { + HEAPU8.set(new Uint8Array(slab), ret); + } + return ret; +} + +// include: runtime_strings.js + + +// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime. + +// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns +// a copy of that string as a Javascript String object. + +var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined; + +/** + * @param {number} idx + * @param {number=} maxBytesToRead + * @return {string} + */ +function UTF8ArrayToString(heap, idx, maxBytesToRead) { + var endIdx = idx + maxBytesToRead; + var endPtr = idx; + // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself. + // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage. + // (As a tiny code save trick, compare endPtr against endIdx using a negation, so that undefined means Infinity) + while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; + + if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { + return UTF8Decoder.decode(heap.subarray(idx, endPtr)); + } else { + var str = ''; + // If building with TextDecoder, we have already computed the string length above, so test loop end condition against that + while (idx < endPtr) { + // For UTF8 byte structure, see: + // http://en.wikipedia.org/wiki/UTF-8#Description + // https://www.ietf.org/rfc/rfc2279.txt + // https://tools.ietf.org/html/rfc3629 + var u0 = heap[idx++]; + if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } + var u1 = heap[idx++] & 63; + if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } + var u2 = heap[idx++] & 63; + if ((u0 & 0xF0) == 0xE0) { + u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; + } else { + if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte 0x' + u0.toString(16) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!'); + u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[idx++] & 63); + } + + if (u0 < 0x10000) { + str += String.fromCharCode(u0); + } else { + var ch = u0 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); + } + } + } + return str; +} + +// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns a +// copy of that string as a Javascript String object. +// maxBytesToRead: an optional length that specifies the maximum number of bytes to read. You can omit +// this parameter to scan the string until the first \0 byte. If maxBytesToRead is +// passed, and the string at [ptr, ptr+maxBytesToReadr[ contains a null byte in the +// middle, then the string will cut short at that byte index (i.e. maxBytesToRead will +// not produce a string of exact length [ptr, ptr+maxBytesToRead[) +// N.B. mixing frequent uses of UTF8ToString() with and without maxBytesToRead may +// throw JS JIT optimizations off, so it is worth to consider consistently using one +// style or the other. +/** + * @param {number} ptr + * @param {number=} maxBytesToRead + * @return {string} + */ +function UTF8ToString(ptr, maxBytesToRead) { + return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; +} + +// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx', +// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP. +// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. +// Parameters: +// str: the Javascript string to copy. +// heap: the array to copy to. Each index in this array is assumed to be one 8-byte element. +// outIdx: The starting offset in the array to begin the copying. +// maxBytesToWrite: The maximum number of bytes this function can write to the array. +// This count should include the null terminator, +// i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else. +// maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator. +// Returns the number of bytes written, EXCLUDING the null terminator. + +function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { + if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes. + return 0; + + var startIdx = outIdx; + var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator. + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629 + var u = str.charCodeAt(i); // possibly a lead surrogate + if (u >= 0xD800 && u <= 0xDFFF) { + var u1 = str.charCodeAt(++i); + u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF); + } + if (u <= 0x7F) { + if (outIdx >= endIdx) break; + heap[outIdx++] = u; + } else if (u <= 0x7FF) { + if (outIdx + 1 >= endIdx) break; + heap[outIdx++] = 0xC0 | (u >> 6); + heap[outIdx++] = 0x80 | (u & 63); + } else if (u <= 0xFFFF) { + if (outIdx + 2 >= endIdx) break; + heap[outIdx++] = 0xE0 | (u >> 12); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } else { + if (outIdx + 3 >= endIdx) break; + if (u >= 0x200000) warnOnce('Invalid Unicode code point 0x' + u.toString(16) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x1FFFFF).'); + heap[outIdx++] = 0xF0 | (u >> 18); + heap[outIdx++] = 0x80 | ((u >> 12) & 63); + heap[outIdx++] = 0x80 | ((u >> 6) & 63); + heap[outIdx++] = 0x80 | (u & 63); + } + } + // Null-terminate the pointer to the buffer. + heap[outIdx] = 0; + return outIdx - startIdx; +} + +// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', +// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP. +// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. +// Returns the number of bytes written, EXCLUDING the null terminator. + +function stringToUTF8(str, outPtr, maxBytesToWrite) { + assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); + return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite); +} + +// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte. +function lengthBytesUTF8(str) { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var u = str.charCodeAt(i); // possibly a lead surrogate + if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); + if (u <= 0x7F) ++len; + else if (u <= 0x7FF) len += 2; + else if (u <= 0xFFFF) len += 3; + else len += 4; + } + return len; +} + +// end include: runtime_strings.js +// include: runtime_strings_extra.js + + +// runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime. + +// Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns +// a copy of that string as a Javascript String object. + +function AsciiToString(ptr) { + var str = ''; + while (1) { + var ch = HEAPU8[((ptr++)>>0)]; + if (!ch) return str; + str += String.fromCharCode(ch); + } +} + +// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', +// null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP. + +function stringToAscii(str, outPtr) { + return writeAsciiToMemory(str, outPtr, false); +} + +// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns +// a copy of that string as a Javascript String object. + +var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined; + +function UTF16ToString(ptr, maxBytesToRead) { + assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!'); + var endPtr = ptr; + // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself. + // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage. + var idx = endPtr >> 1; + var maxIdx = idx + maxBytesToRead / 2; + // If maxBytesToRead is not passed explicitly, it will be undefined, and this + // will always evaluate to true. This saves on code size. + while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx; + endPtr = idx << 1; + + if (endPtr - ptr > 32 && UTF16Decoder) { + return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); + } else { + var str = ''; + + // If maxBytesToRead is not passed explicitly, it will be undefined, and the for-loop's condition + // will always evaluate to true. The loop is then terminated on the first null char. + for (var i = 0; !(i >= maxBytesToRead / 2); ++i) { + var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; + if (codeUnit == 0) break; + // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through. + str += String.fromCharCode(codeUnit); + } + + return str; + } +} + +// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', +// null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP. +// Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write. +// Parameters: +// str: the Javascript string to copy. +// outPtr: Byte address in Emscripten HEAP where to write the string to. +// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null +// terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else. +// maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator. +// Returns the number of bytes written, EXCLUDING the null terminator. + +function stringToUTF16(str, outPtr, maxBytesToWrite) { + assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!'); + assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + if (maxBytesToWrite === undefined) { + maxBytesToWrite = 0x7FFFFFFF; + } + if (maxBytesToWrite < 2) return 0; + maxBytesToWrite -= 2; // Null terminator. + var startPtr = outPtr; + var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length; + for (var i = 0; i < numCharsToWrite; ++i) { + // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. + var codeUnit = str.charCodeAt(i); // possibly a lead surrogate + HEAP16[((outPtr)>>1)] = codeUnit; + outPtr += 2; + } + // Null-terminate the pointer to the HEAP. + HEAP16[((outPtr)>>1)] = 0; + return outPtr - startPtr; +} + +// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte. + +function lengthBytesUTF16(str) { + return str.length*2; +} + +function UTF32ToString(ptr, maxBytesToRead) { + assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!'); + var i = 0; + + var str = ''; + // If maxBytesToRead is not passed explicitly, it will be undefined, and this + // will always evaluate to true. This saves on code size. + while (!(i >= maxBytesToRead / 4)) { + var utf32 = HEAP32[(((ptr)+(i*4))>>2)]; + if (utf32 == 0) break; + ++i; + // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + if (utf32 >= 0x10000) { + var ch = utf32 - 0x10000; + str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); + } else { + str += String.fromCharCode(utf32); + } + } + return str; +} + +// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', +// null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP. +// Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write. +// Parameters: +// str: the Javascript string to copy. +// outPtr: Byte address in Emscripten HEAP where to write the string to. +// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null +// terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else. +// maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator. +// Returns the number of bytes written, EXCLUDING the null terminator. + +function stringToUTF32(str, outPtr, maxBytesToWrite) { + assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!'); + assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); + // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. + if (maxBytesToWrite === undefined) { + maxBytesToWrite = 0x7FFFFFFF; + } + if (maxBytesToWrite < 4) return 0; + var startPtr = outPtr; + var endPtr = startPtr + maxBytesToWrite - 4; + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var codeUnit = str.charCodeAt(i); // possibly a lead surrogate + if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) { + var trailSurrogate = str.charCodeAt(++i); + codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF); + } + HEAP32[((outPtr)>>2)] = codeUnit; + outPtr += 4; + if (outPtr + 4 > endPtr) break; + } + // Null-terminate the pointer to the HEAP. + HEAP32[((outPtr)>>2)] = 0; + return outPtr - startPtr; +} + +// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte. + +function lengthBytesUTF32(str) { + var len = 0; + for (var i = 0; i < str.length; ++i) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var codeUnit = str.charCodeAt(i); + if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate. + len += 4; + } + + return len; +} + +// Allocate heap space for a JS string, and write it there. +// It is the responsibility of the caller to free() that memory. +function allocateUTF8(str) { + var size = lengthBytesUTF8(str) + 1; + var ret = _malloc(size); + if (ret) stringToUTF8Array(str, HEAP8, ret, size); + return ret; +} + +// Allocate stack space for a JS string, and write it there. +function allocateUTF8OnStack(str) { + var size = lengthBytesUTF8(str) + 1; + var ret = stackAlloc(size); + stringToUTF8Array(str, HEAP8, ret, size); + return ret; +} + +// Deprecated: This function should not be called because it is unsafe and does not provide +// a maximum length limit of how many bytes it is allowed to write. Prefer calling the +// function stringToUTF8Array() instead, which takes in a maximum length that can be used +// to be secure from out of bounds writes. +/** @deprecated + @param {boolean=} dontAddNull */ +function writeStringToMemory(string, buffer, dontAddNull) { + warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!'); + + var /** @type {number} */ lastChar, /** @type {number} */ end; + if (dontAddNull) { + // stringToUTF8Array always appends null. If we don't want to do that, remember the + // character that existed at the location where the null will be placed, and restore + // that after the write (below). + end = buffer + lengthBytesUTF8(string); + lastChar = HEAP8[end]; + } + stringToUTF8(string, buffer, Infinity); + if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character. +} + +function writeArrayToMemory(array, buffer) { + assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)') + HEAP8.set(array, buffer); +} + +/** @param {boolean=} dontAddNull */ +function writeAsciiToMemory(str, buffer, dontAddNull) { + for (var i = 0; i < str.length; ++i) { + assert(str.charCodeAt(i) === str.charCodeAt(i)&0xff); + HEAP8[((buffer++)>>0)] = str.charCodeAt(i); + } + // Null-terminate the pointer to the HEAP. + if (!dontAddNull) HEAP8[((buffer)>>0)] = 0; +} + +// end include: runtime_strings_extra.js +// Memory management + +function alignUp(x, multiple) { + if (x % multiple > 0) { + x += multiple - (x % multiple); + } + return x; +} + +var HEAP, +/** @type {ArrayBuffer} */ + buffer, +/** @type {Int8Array} */ + HEAP8, +/** @type {Uint8Array} */ + HEAPU8, +/** @type {Int16Array} */ + HEAP16, +/** @type {Uint16Array} */ + HEAPU16, +/** @type {Int32Array} */ + HEAP32, +/** @type {Uint32Array} */ + HEAPU32, +/** @type {Float32Array} */ + HEAPF32, +/** @type {Float64Array} */ + HEAPF64; + +function updateGlobalBufferAndViews(buf) { + buffer = buf; + Module['HEAP8'] = HEAP8 = new Int8Array(buf); + Module['HEAP16'] = HEAP16 = new Int16Array(buf); + Module['HEAP32'] = HEAP32 = new Int32Array(buf); + Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf); + Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf); + Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf); + Module['HEAPF32'] = HEAPF32 = new Float32Array(buf); + Module['HEAPF64'] = HEAPF64 = new Float64Array(buf); +} + +var TOTAL_STACK = 5242880; +if (Module['TOTAL_STACK']) assert(TOTAL_STACK === Module['TOTAL_STACK'], 'the stack size can no longer be determined at runtime') + +var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216; +if (!Object.getOwnPropertyDescriptor(Module, 'INITIAL_MEMORY')) { + Object.defineProperty(Module, 'INITIAL_MEMORY', { + configurable: true, + get: function() { + abort('Module.INITIAL_MEMORY has been replaced with plain INITIAL_MEMORY (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') + } + }); +} + +assert(INITIAL_MEMORY >= TOTAL_STACK, 'INITIAL_MEMORY should be larger than TOTAL_STACK, was ' + INITIAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')'); + +// check for full engine support (use string 'subarray' to avoid closure compiler confusion) +assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray !== undefined && Int32Array.prototype.set !== undefined, + 'JS engine does not provide full typed array support'); + +// If memory is defined in wasm, the user can't provide it. +assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -s IMPORTED_MEMORY to define wasmMemory externally'); +assert(INITIAL_MEMORY == 16777216, 'Detected runtime INITIAL_MEMORY setting. Use -s IMPORTED_MEMORY to define wasmMemory dynamically'); + +// include: runtime_init_table.js +// In regular non-RELOCATABLE mode the table is exported +// from the wasm module and this will be assigned once +// the exports are available. +var wasmTable; + +// end include: runtime_init_table.js +// include: runtime_stack_check.js + + +// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode. +function writeStackCookie() { + var max = _emscripten_stack_get_end(); + assert((max & 3) == 0); + // The stack grows downwards + HEAPU32[(max >> 2)+1] = 0x2135467; + HEAPU32[(max >> 2)+2] = 0x89BACDFE; + // Also test the global address 0 for integrity. + HEAP32[0] = 0x63736d65; /* 'emsc' */ +} + +function checkStackCookie() { + if (ABORT) return; + var max = _emscripten_stack_get_end(); + var cookie1 = HEAPU32[(max >> 2)+1]; + var cookie2 = HEAPU32[(max >> 2)+2]; + if (cookie1 != 0x2135467 || cookie2 != 0x89BACDFE) { + abort('Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x' + cookie2.toString(16) + ' ' + cookie1.toString(16)); + } + // Also test the global address 0 for integrity. + if (HEAP32[0] !== 0x63736d65 /* 'emsc' */) abort('Runtime error: The application has corrupted its heap memory area (address zero)!'); +} + +// end include: runtime_stack_check.js +// include: runtime_assertions.js + + +// Endianness check (note: assumes compiler arch was little-endian) +(function() { + var h16 = new Int16Array(1); + var h8 = new Int8Array(h16.buffer); + h16[0] = 0x6373; + if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian!'; +})(); + +function abortFnPtrError(ptr, sig) { + var possibleSig = ''; + for(var x in debug_tables) { + var tbl = debug_tables[x]; + if (tbl[ptr]) { + possibleSig += 'as sig "' + x + '" pointing to function ' + tbl[ptr] + ', '; + } + } + abort("Invalid function pointer " + ptr + " called with signature '" + sig + "'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this). This pointer might make sense in another type signature: " + possibleSig); +} + +// end include: runtime_assertions.js +var __ATPRERUN__ = []; // functions called before the runtime is initialized +var __ATINIT__ = []; // functions called during startup +var __ATMAIN__ = []; // functions called when main() is to be run +var __ATEXIT__ = []; // functions called during shutdown +var __ATPOSTRUN__ = []; // functions called after the main() is called + +var runtimeInitialized = false; +var runtimeExited = false; + +__ATINIT__.push({ func: function() { ___wasm_call_ctors() } }); + +function preRun() { + + if (Module['preRun']) { + if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']]; + while (Module['preRun'].length) { + addOnPreRun(Module['preRun'].shift()); + } + } + + callRuntimeCallbacks(__ATPRERUN__); +} + +function initRuntime() { + checkStackCookie(); + assert(!runtimeInitialized); + runtimeInitialized = true; + + ___set_stack_limits(_emscripten_stack_get_base(), _emscripten_stack_get_end()); + + callRuntimeCallbacks(__ATINIT__); +} + +function preMain() { + checkStackCookie(); + + callRuntimeCallbacks(__ATMAIN__); +} + +function exitRuntime() { + checkStackCookie(); + runtimeExited = true; +} + +function postRun() { + checkStackCookie(); + + if (Module['postRun']) { + if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']]; + while (Module['postRun'].length) { + addOnPostRun(Module['postRun'].shift()); + } + } + + callRuntimeCallbacks(__ATPOSTRUN__); +} + +function addOnPreRun(cb) { + __ATPRERUN__.unshift(cb); +} + +function addOnInit(cb) { + __ATINIT__.unshift(cb); +} + +function addOnPreMain(cb) { + __ATMAIN__.unshift(cb); +} + +function addOnExit(cb) { +} + +function addOnPostRun(cb) { + __ATPOSTRUN__.unshift(cb); +} + +// include: runtime_math.js + + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc + +assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); +assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); +assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); +assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); + +// end include: runtime_math.js +// A counter of dependencies for calling run(). If we need to +// do asynchronous work before running, increment this and +// decrement it. Incrementing must happen in a place like +// Module.preRun (used by emcc to add file preloading). +// Note that you can add dependencies in preRun, even though +// it happens right before run - run will be postponed until +// the dependencies are met. +var runDependencies = 0; +var runDependencyWatcher = null; +var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled +var runDependencyTracking = {}; + +function getUniqueRunDependency(id) { + var orig = id; + while (1) { + if (!runDependencyTracking[id]) return id; + id = orig + Math.random(); + } +} + +function addRunDependency(id) { + runDependencies++; + + if (Module['monitorRunDependencies']) { + Module['monitorRunDependencies'](runDependencies); + } + + if (id) { + assert(!runDependencyTracking[id]); + runDependencyTracking[id] = 1; + if (runDependencyWatcher === null && typeof setInterval !== 'undefined') { + // Check for missing dependencies every few seconds + runDependencyWatcher = setInterval(function() { + if (ABORT) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + return; + } + var shown = false; + for (var dep in runDependencyTracking) { + if (!shown) { + shown = true; + err('still waiting on run dependencies:'); + } + err('dependency: ' + dep); + } + if (shown) { + err('(end of list)'); + } + }, 10000); + } + } else { + err('warning: run dependency added without ID'); + } +} + +function removeRunDependency(id) { + runDependencies--; + + if (Module['monitorRunDependencies']) { + Module['monitorRunDependencies'](runDependencies); + } + + if (id) { + assert(runDependencyTracking[id]); + delete runDependencyTracking[id]; + } else { + err('warning: run dependency removed without ID'); + } + if (runDependencies == 0) { + if (runDependencyWatcher !== null) { + clearInterval(runDependencyWatcher); + runDependencyWatcher = null; + } + if (dependenciesFulfilled) { + var callback = dependenciesFulfilled; + dependenciesFulfilled = null; + callback(); // can add another dependenciesFulfilled + } + } +} + +Module["preloadedImages"] = {}; // maps url to image data +Module["preloadedAudios"] = {}; // maps url to audio data + +/** @param {string|number=} what */ +function abort(what) { + if (Module['onAbort']) { + Module['onAbort'](what); + } + + what += ''; + err(what); + + ABORT = true; + EXITSTATUS = 1; + + var output = 'abort(' + what + ') at ' + stackTrace(); + what = output; + + // Use a wasm runtime error, because a JS error might be seen as a foreign + // exception, which means we'd run destructors on it. We need the error to + // simply make the program stop. + var e = new WebAssembly.RuntimeError(what); + + readyPromiseReject(e); + // Throw the error whether or not MODULARIZE is set because abort is used + // in code paths apart from instantiation where an exception is expected + // to be thrown when abort is called. + throw e; +} + +// {{MEM_INITIALIZER}} + +// include: memoryprofiler.js + + +// end include: memoryprofiler.js +// show errors on likely calls to FS when it was not included +var FS = { + error: function() { + abort('Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -s FORCE_FILESYSTEM=1'); + }, + init: function() { FS.error() }, + createDataFile: function() { FS.error() }, + createPreloadedFile: function() { FS.error() }, + createLazyFile: function() { FS.error() }, + open: function() { FS.error() }, + mkdev: function() { FS.error() }, + registerDevice: function() { FS.error() }, + analyzePath: function() { FS.error() }, + loadFilesFromDB: function() { FS.error() }, + + ErrnoError: function ErrnoError() { FS.error() }, +}; +Module['FS_createDataFile'] = FS.createDataFile; +Module['FS_createPreloadedFile'] = FS.createPreloadedFile; + +// include: URIUtils.js + + +function hasPrefix(str, prefix) { + return String.prototype.startsWith ? + str.startsWith(prefix) : + str.indexOf(prefix) === 0; +} + +// Prefix of data URIs emitted by SINGLE_FILE and related options. +var dataURIPrefix = 'data:application/octet-stream;base64,'; + +// Indicates whether filename is a base64 data URI. +function isDataURI(filename) { + return hasPrefix(filename, dataURIPrefix); +} + +var fileURIPrefix = "file://"; + +// Indicates whether filename is delivered via file protocol (as opposed to http/https) +function isFileURI(filename) { + return hasPrefix(filename, fileURIPrefix); +} + +// end include: URIUtils.js +function createExportWrapper(name, fixedasm) { + return function() { + var displayName = name; + var asm = fixedasm; + if (!fixedasm) { + asm = Module['asm']; + } + assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization'); + assert(!runtimeExited, 'native function `' + displayName + '` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); + if (!asm[name]) { + assert(asm[name], 'exported native function `' + displayName + '` not found'); + } + return asm[name].apply(null, arguments); + }; +} + +var wasmBinaryFile = 'LibYUV.wasm'; +if (!isDataURI(wasmBinaryFile)) { + wasmBinaryFile = locateFile(wasmBinaryFile); +} + +function getBinary(file) { + try { + if (file == wasmBinaryFile && wasmBinary) { + return new Uint8Array(wasmBinary); + } + if (readBinary) { + return readBinary(file); + } else { + throw "both async and sync fetching of the wasm failed"; + } + } + catch (err) { + abort(err); + } +} + +function getBinaryPromise() { + // If we don't have the binary yet, try to to load it asynchronously. + // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url. + // See https://github.com/github/fetch/pull/92#issuecomment-140665932 + // Cordova or Electron apps are typically loaded from a file:// url. + // So use fetch if it is available and the url is not a file, otherwise fall back to XHR. + if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { + if (typeof fetch === 'function' + && !isFileURI(wasmBinaryFile) + ) { + return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) { + if (!response['ok']) { + throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; + } + return response['arrayBuffer'](); + }).catch(function () { + return getBinary(wasmBinaryFile); + }); + } + else { + if (readAsync) { + // fetch is not available or url is file => try XHR (readAsync uses XHR internally) + return new Promise(function(resolve, reject) { + readAsync(wasmBinaryFile, function(response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject) + }); + } + } + } + + // Otherwise, getBinary should be able to get it synchronously + return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); }); +} + +// Create the wasm instance. +// Receives the wasm imports, returns the exports. +function createWasm() { + console.log('createWasm'); + // prepare imports + var info = { + 'env': asmLibraryArg, + 'wasi_snapshot_preview1': asmLibraryArg, + }; + // Load the wasm module and create an instance of using native support in the JS engine. + // handle a generated wasm instance, receiving its exports and + // performing other necessary setup + /** @param {WebAssembly.Module=} module*/ + function receiveInstance(instance, module) { + var exports = instance.exports; + + Module['asm'] = exports; + + wasmMemory = Module['asm']['memory']; + assert(wasmMemory, "memory not found in wasm exports"); + // This assertion doesn't hold when emscripten is run in --post-link + // mode. + // TODO(sbc): Read INITIAL_MEMORY out of the wasm file in post-link mode. + //assert(wasmMemory.buffer.byteLength === 16777216); + updateGlobalBufferAndViews(wasmMemory.buffer); + + wasmTable = Module['asm']['__indirect_function_table']; + assert(wasmTable, "table not found in wasm exports"); + + removeRunDependency('wasm-instantiate'); + } + // we can't run yet (except in a pthread, where we have a custom sync instantiator) + addRunDependency('wasm-instantiate'); + + // Async compilation can be confusing when an error on the page overwrites Module + // (for example, if the order of elements is wrong, and the one defining Module is + // later), so we save Module and check it later. + var trueModule = Module; + function receiveInstantiatedSource(output) { + // 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance. + // receiveInstance() will swap in the exports (to Module.asm) so they can be called + assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?'); + trueModule = null; + // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line. + // When the regression is fixed, can restore the above USE_PTHREADS-enabled path. + receiveInstance(output['instance']); + } + + function instantiateArrayBuffer(receiver) { + console.log('instantiateArrayBuffer'); + return getBinaryPromise().then(function(binary) { + return WebAssembly.instantiate(binary, info); + }).then(receiver, function(reason) { + err('failed to asynchronously prepare wasm: ' + reason); + + // Warn on some common problems. + if (isFileURI(wasmBinaryFile)) { + err('warning: Loading from a file URI (' + wasmBinaryFile + ') is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing'); + } + abort(reason); + }); + } + + // Prefer streaming instantiation if available. + function instantiateAsync() { + if (!wasmBinary && + typeof WebAssembly.instantiateStreaming === 'function' && + !isDataURI(wasmBinaryFile) && + // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously. + !isFileURI(wasmBinaryFile) && + typeof fetch === 'function') { + return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) { + var result = WebAssembly.instantiateStreaming(response, info); + return result.then(receiveInstantiatedSource, function(reason) { + // We expect the most common failure cause to be a bad MIME type for the binary, + // in which case falling back to ArrayBuffer instantiation should work. + err('wasm streaming compile failed: ' + reason); + err('falling back to ArrayBuffer instantiation'); + return instantiateArrayBuffer(receiveInstantiatedSource); + }); + }); + } else { + return instantiateArrayBuffer(receiveInstantiatedSource); + } + } + + // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback + // to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel + // to any other async startup actions they are performing. + if (Module['instantiateWasm']) { + try { + var exports = Module['instantiateWasm'](info, receiveInstance); + return exports; + } catch(e) { + err('Module.instantiateWasm callback failed with error: ' + e); + return false; + } + } + + // If instantiation fails, reject the module ready promise. + instantiateAsync().catch(readyPromiseReject); + return {}; // no exports yet; we'll fill them in later +} + +// Globals used by JS i64 conversions (see makeSetValue) +var tempDouble; +var tempI64; + +// === Body === + +var ASM_CONSTS = { + +}; + + + + + + + function callRuntimeCallbacks(callbacks) { + while(callbacks.length > 0) { + var callback = callbacks.shift(); + if (typeof callback == 'function') { + callback(Module); // Pass the module as the first argument. + continue; + } + var func = callback.func; + if (typeof func === 'number') { + if (callback.arg === undefined) { + wasmTable.get(func)(); + } else { + wasmTable.get(func)(callback.arg); + } + } else { + func(callback.arg === undefined ? null : callback.arg); + } + } + } + + function demangle(func) { + warnOnce('warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling'); + return func; + } + + function demangleAll(text) { + var regex = + /\b_Z[\w\d_]+/g; + return text.replace(regex, + function(x) { + var y = demangle(x); + return x === y ? x : (y + ' [' + x + ']'); + }); + } + + function jsStackTrace() { + var error = new Error(); + if (!error.stack) { + // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown, + // so try that as a special-case. + try { + throw new Error(); + } catch(e) { + error = e; + } + if (!error.stack) { + return '(no stack trace available)'; + } + } + return error.stack.toString(); + } + + function stackTrace() { + var js = jsStackTrace(); + if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace'](); + return demangleAll(js); + } + + function ___handle_stack_overflow() { + // TODO(sbc): Improve this error message. The old abortStackOverflow used + // by asm.js used to do a better job: + // abort('Stack overflow! Attempted to allocate ' + allocSize + ' bytes on the stack, but stack has only ' + (_emscripten_stack_get_free() + allocSize) + ' bytes available!'); + abort('stack overflow'); + } + + function _abort() { + abort(); + } + + function _emscripten_get_heap_size() { + return HEAPU8.length; + } + + var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) { + _emscripten_get_now = function() { + var t = process['hrtime'](); + return t[0] * 1e3 + t[1] / 1e6; + }; + } else if (typeof dateNow !== 'undefined') { + _emscripten_get_now = dateNow; + } else _emscripten_get_now = function() { return performance.now(); } + ; + + function emscripten_realloc_buffer(size) { + try { + // round size grow request up to wasm page size (fixed 64KB per spec) + wasmMemory.grow((size - buffer.byteLength + 65535) >>> 16); // .grow() takes a delta compared to the previous size + updateGlobalBufferAndViews(wasmMemory.buffer); + return 1 /*success*/; + } catch(e) { + console.error('emscripten_realloc_buffer: Attempted to grow heap from ' + buffer.byteLength + ' bytes to ' + size + ' bytes, but got error: ' + e); + } + // implicit 0 return to save code size (caller will cast "undefined" into 0 + // anyhow) + } + function _emscripten_resize_heap(requestedSize) { + var oldSize = _emscripten_get_heap_size(); + // With pthreads, races can happen (another thread might increase the size in between), so return a failure, and let the caller retry. + assert(requestedSize > oldSize); + + // Memory resize rules: + // 1. Always increase heap size to at least the requested size, rounded up to next page multiple. + // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap geometrically: increase the heap size according to + // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), + // At most overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB). + // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap linearly: increase the heap size by at least MEMORY_GROWTH_LINEAR_STEP bytes. + // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest + // 4. If we were unable to allocate as much memory, it may be due to over-eager decision to excessively reserve due to (3) above. + // Hence if an allocation fails, cut down on the amount of excess growth, in an attempt to succeed to perform a smaller allocation. + + // A limit was set for how much we can grow. We should not exceed that + // (the wasm binary specifies it, so if we tried, we'd fail anyhow). + // In CAN_ADDRESS_2GB mode, stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate full 4GB Wasm memories, the size will wrap + // back to 0 bytes in Wasm side for any code that deals with heap sizes, which would require special casing all heap size related code to treat + // 0 specially. + var maxHeapSize = 2147483648; + if (requestedSize > maxHeapSize) { + err('Cannot enlarge memory, asked to go up to ' + requestedSize + ' bytes, but the limit is ' + maxHeapSize + ' bytes!'); + return false; + } + + // Loop through potential heap size increases. If we attempt a too eager reservation that fails, cut down on the + // attempted size and reserve a smaller bump instead. (max 3 times, chosen somewhat arbitrarily) + for(var cutDown = 1; cutDown <= 4; cutDown *= 2) { + var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth + // but limit overreserving (default to capping at +96MB overgrowth at most) + overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 ); + + var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); + + var t0 = _emscripten_get_now(); + var replacement = emscripten_realloc_buffer(newSize); + var t1 = _emscripten_get_now(); + console.log('Heap resize call from ' + oldSize + ' to ' + newSize + ' took ' + (t1 - t0) + ' msecs. Success: ' + !!replacement); + if (replacement) { + + return true; + } + } + err('Failed to grow the heap from ' + oldSize + ' bytes to ' + newSize + ' bytes, not enough memory!'); + return false; + } +var ASSERTIONS = true; + + + +/** @type {function(string, boolean=, number=)} */ +function intArrayFromString(stringy, dontAddNull, length) { + var len = length > 0 ? length : lengthBytesUTF8(stringy)+1; + var u8array = new Array(len); + var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); + if (dontAddNull) u8array.length = numBytesWritten; + return u8array; +} + +function intArrayToString(array) { + var ret = []; + for (var i = 0; i < array.length; i++) { + var chr = array[i]; + if (chr > 0xFF) { + if (ASSERTIONS) { + assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.'); + } + chr &= 0xFF; + } + ret.push(String.fromCharCode(chr)); + } + return ret.join(''); +} + + +var asmLibraryArg = { + "__handle_stack_overflow": ___handle_stack_overflow, + "abort": _abort, + "emscripten_resize_heap": _emscripten_resize_heap +}; +var asm = createWasm(); +/** @type {function(...*):?} */ +var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors"); + +/** @type {function(...*):?} */ +var _ConvertRGBA88882YUV420P = Module["_ConvertRGBA88882YUV420P"] = createExportWrapper("ConvertRGBA88882YUV420P"); + +/** @type {function(...*):?} */ +var _ABGRToI420 = Module["_ABGRToI420"] = createExportWrapper("ABGRToI420"); + +/** @type {function(...*):?} */ +var _ConvertYUV420P2RGBA8888 = Module["_ConvertYUV420P2RGBA8888"] = createExportWrapper("ConvertYUV420P2RGBA8888"); + +/** @type {function(...*):?} */ +var _I420ToABGR = Module["_I420ToABGR"] = createExportWrapper("I420ToABGR"); + +/** @type {function(...*):?} */ +var _malloc = Module["_malloc"] = createExportWrapper("malloc"); + +/** @type {function(...*):?} */ +var _free = Module["_free"] = createExportWrapper("free"); + +/** @type {function(...*):?} */ +var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location"); + +/** @type {function(...*):?} */ +var _fflush = Module["_fflush"] = createExportWrapper("fflush"); + +/** @type {function(...*):?} */ +var stackSave = Module["stackSave"] = createExportWrapper("stackSave"); + +/** @type {function(...*):?} */ +var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore"); + +/** @type {function(...*):?} */ +var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc"); + +/** @type {function(...*):?} */ +var _emscripten_stack_init = Module["_emscripten_stack_init"] = function() { + return (_emscripten_stack_init = Module["_emscripten_stack_init"] = Module["asm"]["emscripten_stack_init"]).apply(null, arguments); +}; + +/** @type {function(...*):?} */ +var _emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = function() { + return (_emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = Module["asm"]["emscripten_stack_get_free"]).apply(null, arguments); +}; + +/** @type {function(...*):?} */ +var _emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = function() { + return (_emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = Module["asm"]["emscripten_stack_get_base"]).apply(null, arguments); +}; + +/** @type {function(...*):?} */ +var _emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = function() { + return (_emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = Module["asm"]["emscripten_stack_get_end"]).apply(null, arguments); +}; + +/** @type {function(...*):?} */ +var ___set_stack_limits = Module["___set_stack_limits"] = createExportWrapper("__set_stack_limits"); + + + + + +// === Auto-generated postamble setup entry stuff === + +if (!Object.getOwnPropertyDescriptor(Module, "intArrayFromString")) Module["intArrayFromString"] = function() { abort("'intArrayFromString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "intArrayToString")) Module["intArrayToString"] = function() { abort("'intArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +Module["ccall"] = ccall; +Module["cwrap"] = cwrap; +if (!Object.getOwnPropertyDescriptor(Module, "setValue")) Module["setValue"] = function() { abort("'setValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getValue")) Module["getValue"] = function() { abort("'getValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "allocate")) Module["allocate"] = function() { abort("'allocate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF8ArrayToString")) Module["UTF8ArrayToString"] = function() { abort("'UTF8ArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF8ToString")) Module["UTF8ToString"] = function() { abort("'UTF8ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8Array")) Module["stringToUTF8Array"] = function() { abort("'stringToUTF8Array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8")) Module["stringToUTF8"] = function() { abort("'stringToUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF8")) Module["lengthBytesUTF8"] = function() { abort("'lengthBytesUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnPreRun")) Module["addOnPreRun"] = function() { abort("'addOnPreRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnInit")) Module["addOnInit"] = function() { abort("'addOnInit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnPreMain")) Module["addOnPreMain"] = function() { abort("'addOnPreMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnExit")) Module["addOnExit"] = function() { abort("'addOnExit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addOnPostRun")) Module["addOnPostRun"] = function() { abort("'addOnPostRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeStringToMemory")) Module["writeStringToMemory"] = function() { abort("'writeStringToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeArrayToMemory")) Module["writeArrayToMemory"] = function() { abort("'writeArrayToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeAsciiToMemory")) Module["writeAsciiToMemory"] = function() { abort("'writeAsciiToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addRunDependency")) Module["addRunDependency"] = function() { abort("'addRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "removeRunDependency")) Module["removeRunDependency"] = function() { abort("'removeRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createFolder")) Module["FS_createFolder"] = function() { abort("'FS_createFolder' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createPath")) Module["FS_createPath"] = function() { abort("'FS_createPath' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createDataFile")) Module["FS_createDataFile"] = function() { abort("'FS_createDataFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createPreloadedFile")) Module["FS_createPreloadedFile"] = function() { abort("'FS_createPreloadedFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createLazyFile")) Module["FS_createLazyFile"] = function() { abort("'FS_createLazyFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createLink")) Module["FS_createLink"] = function() { abort("'FS_createLink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_createDevice")) Module["FS_createDevice"] = function() { abort("'FS_createDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS_unlink")) Module["FS_unlink"] = function() { abort("'FS_unlink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; +if (!Object.getOwnPropertyDescriptor(Module, "getLEB")) Module["getLEB"] = function() { abort("'getLEB' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getFunctionTables")) Module["getFunctionTables"] = function() { abort("'getFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "alignFunctionTables")) Module["alignFunctionTables"] = function() { abort("'alignFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerFunctions")) Module["registerFunctions"] = function() { abort("'registerFunctions' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "addFunction")) Module["addFunction"] = function() { abort("'addFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "removeFunction")) Module["removeFunction"] = function() { abort("'removeFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "prettyPrint")) Module["prettyPrint"] = function() { abort("'prettyPrint' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "makeBigInt")) Module["makeBigInt"] = function() { abort("'makeBigInt' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getCompilerSetting")) Module["getCompilerSetting"] = function() { abort("'getCompilerSetting' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "print")) Module["print"] = function() { abort("'print' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "printErr")) Module["printErr"] = function() { abort("'printErr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getTempRet0")) Module["getTempRet0"] = function() { abort("'getTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setTempRet0")) Module["setTempRet0"] = function() { abort("'setTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "callMain")) Module["callMain"] = function() { abort("'callMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "abort")) Module["abort"] = function() { abort("'abort' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToNewUTF8")) Module["stringToNewUTF8"] = function() { abort("'stringToNewUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setFileTime")) Module["setFileTime"] = function() { abort("'setFileTime' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscripten_realloc_buffer")) Module["emscripten_realloc_buffer"] = function() { abort("'emscripten_realloc_buffer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ENV")) Module["ENV"] = function() { abort("'ENV' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_CODES")) Module["ERRNO_CODES"] = function() { abort("'ERRNO_CODES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_MESSAGES")) Module["ERRNO_MESSAGES"] = function() { abort("'ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setErrNo")) Module["setErrNo"] = function() { abort("'setErrNo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "inetPton4")) Module["inetPton4"] = function() { abort("'inetPton4' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "inetNtop4")) Module["inetNtop4"] = function() { abort("'inetNtop4' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "inetPton6")) Module["inetPton6"] = function() { abort("'inetPton6' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "inetNtop6")) Module["inetNtop6"] = function() { abort("'inetNtop6' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readSockaddr")) Module["readSockaddr"] = function() { abort("'readSockaddr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeSockaddr")) Module["writeSockaddr"] = function() { abort("'writeSockaddr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "DNS")) Module["DNS"] = function() { abort("'DNS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getHostByName")) Module["getHostByName"] = function() { abort("'getHostByName' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GAI_ERRNO_MESSAGES")) Module["GAI_ERRNO_MESSAGES"] = function() { abort("'GAI_ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "Protocols")) Module["Protocols"] = function() { abort("'Protocols' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "Sockets")) Module["Sockets"] = function() { abort("'Sockets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getRandomDevice")) Module["getRandomDevice"] = function() { abort("'getRandomDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "traverseStack")) Module["traverseStack"] = function() { abort("'traverseStack' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UNWIND_CACHE")) Module["UNWIND_CACHE"] = function() { abort("'UNWIND_CACHE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "withBuiltinMalloc")) Module["withBuiltinMalloc"] = function() { abort("'withBuiltinMalloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgsArray")) Module["readAsmConstArgsArray"] = function() { abort("'readAsmConstArgsArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgs")) Module["readAsmConstArgs"] = function() { abort("'readAsmConstArgs' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "mainThreadEM_ASM")) Module["mainThreadEM_ASM"] = function() { abort("'mainThreadEM_ASM' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "jstoi_q")) Module["jstoi_q"] = function() { abort("'jstoi_q' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "jstoi_s")) Module["jstoi_s"] = function() { abort("'jstoi_s' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getExecutableName")) Module["getExecutableName"] = function() { abort("'getExecutableName' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "listenOnce")) Module["listenOnce"] = function() { abort("'listenOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "autoResumeAudioContext")) Module["autoResumeAudioContext"] = function() { abort("'autoResumeAudioContext' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "dynCallLegacy")) Module["dynCallLegacy"] = function() { abort("'dynCallLegacy' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getDynCaller")) Module["getDynCaller"] = function() { abort("'getDynCaller' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "callRuntimeCallbacks")) Module["callRuntimeCallbacks"] = function() { abort("'callRuntimeCallbacks' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "reallyNegative")) Module["reallyNegative"] = function() { abort("'reallyNegative' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "unSign")) Module["unSign"] = function() { abort("'unSign' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "reSign")) Module["reSign"] = function() { abort("'reSign' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "formatString")) Module["formatString"] = function() { abort("'formatString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "PATH")) Module["PATH"] = function() { abort("'PATH' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "PATH_FS")) Module["PATH_FS"] = function() { abort("'PATH_FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SYSCALLS")) Module["SYSCALLS"] = function() { abort("'SYSCALLS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "syscallMmap2")) Module["syscallMmap2"] = function() { abort("'syscallMmap2' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "syscallMunmap")) Module["syscallMunmap"] = function() { abort("'syscallMunmap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getSocketFromFD")) Module["getSocketFromFD"] = function() { abort("'getSocketFromFD' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getSocketAddress")) Module["getSocketAddress"] = function() { abort("'getSocketAddress' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "JSEvents")) Module["JSEvents"] = function() { abort("'JSEvents' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerKeyEventCallback")) Module["registerKeyEventCallback"] = function() { abort("'registerKeyEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "specialHTMLTargets")) Module["specialHTMLTargets"] = function() { abort("'specialHTMLTargets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "maybeCStringToJsString")) Module["maybeCStringToJsString"] = function() { abort("'maybeCStringToJsString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "findEventTarget")) Module["findEventTarget"] = function() { abort("'findEventTarget' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "findCanvasEventTarget")) Module["findCanvasEventTarget"] = function() { abort("'findCanvasEventTarget' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getBoundingClientRect")) Module["getBoundingClientRect"] = function() { abort("'getBoundingClientRect' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillMouseEventData")) Module["fillMouseEventData"] = function() { abort("'fillMouseEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerMouseEventCallback")) Module["registerMouseEventCallback"] = function() { abort("'registerMouseEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerWheelEventCallback")) Module["registerWheelEventCallback"] = function() { abort("'registerWheelEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerUiEventCallback")) Module["registerUiEventCallback"] = function() { abort("'registerUiEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerFocusEventCallback")) Module["registerFocusEventCallback"] = function() { abort("'registerFocusEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillDeviceOrientationEventData")) Module["fillDeviceOrientationEventData"] = function() { abort("'fillDeviceOrientationEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerDeviceOrientationEventCallback")) Module["registerDeviceOrientationEventCallback"] = function() { abort("'registerDeviceOrientationEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillDeviceMotionEventData")) Module["fillDeviceMotionEventData"] = function() { abort("'fillDeviceMotionEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerDeviceMotionEventCallback")) Module["registerDeviceMotionEventCallback"] = function() { abort("'registerDeviceMotionEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "screenOrientation")) Module["screenOrientation"] = function() { abort("'screenOrientation' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillOrientationChangeEventData")) Module["fillOrientationChangeEventData"] = function() { abort("'fillOrientationChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerOrientationChangeEventCallback")) Module["registerOrientationChangeEventCallback"] = function() { abort("'registerOrientationChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillFullscreenChangeEventData")) Module["fillFullscreenChangeEventData"] = function() { abort("'fillFullscreenChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerFullscreenChangeEventCallback")) Module["registerFullscreenChangeEventCallback"] = function() { abort("'registerFullscreenChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerRestoreOldStyle")) Module["registerRestoreOldStyle"] = function() { abort("'registerRestoreOldStyle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "hideEverythingExceptGivenElement")) Module["hideEverythingExceptGivenElement"] = function() { abort("'hideEverythingExceptGivenElement' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "restoreHiddenElements")) Module["restoreHiddenElements"] = function() { abort("'restoreHiddenElements' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setLetterbox")) Module["setLetterbox"] = function() { abort("'setLetterbox' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "currentFullscreenStrategy")) Module["currentFullscreenStrategy"] = function() { abort("'currentFullscreenStrategy' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "restoreOldWindowedStyle")) Module["restoreOldWindowedStyle"] = function() { abort("'restoreOldWindowedStyle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "softFullscreenResizeWebGLRenderTarget")) Module["softFullscreenResizeWebGLRenderTarget"] = function() { abort("'softFullscreenResizeWebGLRenderTarget' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "doRequestFullscreen")) Module["doRequestFullscreen"] = function() { abort("'doRequestFullscreen' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillPointerlockChangeEventData")) Module["fillPointerlockChangeEventData"] = function() { abort("'fillPointerlockChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerPointerlockChangeEventCallback")) Module["registerPointerlockChangeEventCallback"] = function() { abort("'registerPointerlockChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerPointerlockErrorEventCallback")) Module["registerPointerlockErrorEventCallback"] = function() { abort("'registerPointerlockErrorEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "requestPointerLock")) Module["requestPointerLock"] = function() { abort("'requestPointerLock' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillVisibilityChangeEventData")) Module["fillVisibilityChangeEventData"] = function() { abort("'fillVisibilityChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerVisibilityChangeEventCallback")) Module["registerVisibilityChangeEventCallback"] = function() { abort("'registerVisibilityChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerTouchEventCallback")) Module["registerTouchEventCallback"] = function() { abort("'registerTouchEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillGamepadEventData")) Module["fillGamepadEventData"] = function() { abort("'fillGamepadEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerGamepadEventCallback")) Module["registerGamepadEventCallback"] = function() { abort("'registerGamepadEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerBeforeUnloadEventCallback")) Module["registerBeforeUnloadEventCallback"] = function() { abort("'registerBeforeUnloadEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "fillBatteryEventData")) Module["fillBatteryEventData"] = function() { abort("'fillBatteryEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "battery")) Module["battery"] = function() { abort("'battery' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "registerBatteryEventCallback")) Module["registerBatteryEventCallback"] = function() { abort("'registerBatteryEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setCanvasElementSize")) Module["setCanvasElementSize"] = function() { abort("'setCanvasElementSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getCanvasElementSize")) Module["getCanvasElementSize"] = function() { abort("'getCanvasElementSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "polyfillSetImmediate")) Module["polyfillSetImmediate"] = function() { abort("'polyfillSetImmediate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "demangle")) Module["demangle"] = function() { abort("'demangle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "demangleAll")) Module["demangleAll"] = function() { abort("'demangleAll' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "jsStackTrace")) Module["jsStackTrace"] = function() { abort("'jsStackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getEnvStrings")) Module["getEnvStrings"] = function() { abort("'getEnvStrings' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "checkWasiClock")) Module["checkWasiClock"] = function() { abort("'checkWasiClock' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "flush_NO_FILESYSTEM")) Module["flush_NO_FILESYSTEM"] = function() { abort("'flush_NO_FILESYSTEM' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64")) Module["writeI53ToI64"] = function() { abort("'writeI53ToI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Clamped")) Module["writeI53ToI64Clamped"] = function() { abort("'writeI53ToI64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Signaling")) Module["writeI53ToI64Signaling"] = function() { abort("'writeI53ToI64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Clamped")) Module["writeI53ToU64Clamped"] = function() { abort("'writeI53ToU64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Signaling")) Module["writeI53ToU64Signaling"] = function() { abort("'writeI53ToU64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readI53FromI64")) Module["readI53FromI64"] = function() { abort("'readI53FromI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "readI53FromU64")) Module["readI53FromU64"] = function() { abort("'readI53FromU64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "convertI32PairToI53")) Module["convertI32PairToI53"] = function() { abort("'convertI32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "convertU32PairToI53")) Module["convertU32PairToI53"] = function() { abort("'convertU32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "uncaughtExceptionCount")) Module["uncaughtExceptionCount"] = function() { abort("'uncaughtExceptionCount' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "exceptionLast")) Module["exceptionLast"] = function() { abort("'exceptionLast' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "exceptionCaught")) Module["exceptionCaught"] = function() { abort("'exceptionCaught' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ExceptionInfoAttrs")) Module["ExceptionInfoAttrs"] = function() { abort("'ExceptionInfoAttrs' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "ExceptionInfo")) Module["ExceptionInfo"] = function() { abort("'ExceptionInfo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "CatchInfo")) Module["CatchInfo"] = function() { abort("'CatchInfo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "exception_addRef")) Module["exception_addRef"] = function() { abort("'exception_addRef' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "exception_decRef")) Module["exception_decRef"] = function() { abort("'exception_decRef' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "Browser")) Module["Browser"] = function() { abort("'Browser' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "funcWrappers")) Module["funcWrappers"] = function() { abort("'funcWrappers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "setMainLoop")) Module["setMainLoop"] = function() { abort("'setMainLoop' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "FS")) Module["FS"] = function() { abort("'FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "mmapAlloc")) Module["mmapAlloc"] = function() { abort("'mmapAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "MEMFS")) Module["MEMFS"] = function() { abort("'MEMFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "TTY")) Module["TTY"] = function() { abort("'TTY' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "PIPEFS")) Module["PIPEFS"] = function() { abort("'PIPEFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SOCKFS")) Module["SOCKFS"] = function() { abort("'SOCKFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "_setNetworkCallback")) Module["_setNetworkCallback"] = function() { abort("'_setNetworkCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "tempFixedLengthArray")) Module["tempFixedLengthArray"] = function() { abort("'tempFixedLengthArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "miniTempWebGLFloatBuffers")) Module["miniTempWebGLFloatBuffers"] = function() { abort("'miniTempWebGLFloatBuffers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "heapObjectForWebGLType")) Module["heapObjectForWebGLType"] = function() { abort("'heapObjectForWebGLType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "heapAccessShiftForWebGLHeap")) Module["heapAccessShiftForWebGLHeap"] = function() { abort("'heapAccessShiftForWebGLHeap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GL")) Module["GL"] = function() { abort("'GL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGet")) Module["emscriptenWebGLGet"] = function() { abort("'emscriptenWebGLGet' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "computeUnpackAlignedImageSize")) Module["computeUnpackAlignedImageSize"] = function() { abort("'computeUnpackAlignedImageSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetTexPixelData")) Module["emscriptenWebGLGetTexPixelData"] = function() { abort("'emscriptenWebGLGetTexPixelData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetUniform")) Module["emscriptenWebGLGetUniform"] = function() { abort("'emscriptenWebGLGetUniform' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetVertexAttrib")) Module["emscriptenWebGLGetVertexAttrib"] = function() { abort("'emscriptenWebGLGetVertexAttrib' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "writeGLArray")) Module["writeGLArray"] = function() { abort("'writeGLArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "AL")) Module["AL"] = function() { abort("'AL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_unicode")) Module["SDL_unicode"] = function() { abort("'SDL_unicode' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_ttfContext")) Module["SDL_ttfContext"] = function() { abort("'SDL_ttfContext' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_audio")) Module["SDL_audio"] = function() { abort("'SDL_audio' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL")) Module["SDL"] = function() { abort("'SDL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "SDL_gfx")) Module["SDL_gfx"] = function() { abort("'SDL_gfx' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLUT")) Module["GLUT"] = function() { abort("'GLUT' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "EGL")) Module["EGL"] = function() { abort("'EGL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLFW_Window")) Module["GLFW_Window"] = function() { abort("'GLFW_Window' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLFW")) Module["GLFW"] = function() { abort("'GLFW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "GLEW")) Module["GLEW"] = function() { abort("'GLEW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "IDBStore")) Module["IDBStore"] = function() { abort("'IDBStore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "runAndAbortIfError")) Module["runAndAbortIfError"] = function() { abort("'runAndAbortIfError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "warnOnce")) Module["warnOnce"] = function() { abort("'warnOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackSave")) Module["stackSave"] = function() { abort("'stackSave' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackRestore")) Module["stackRestore"] = function() { abort("'stackRestore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stackAlloc")) Module["stackAlloc"] = function() { abort("'stackAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "AsciiToString")) Module["AsciiToString"] = function() { abort("'AsciiToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToAscii")) Module["stringToAscii"] = function() { abort("'stringToAscii' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF16ToString")) Module["UTF16ToString"] = function() { abort("'UTF16ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF16")) Module["stringToUTF16"] = function() { abort("'stringToUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF16")) Module["lengthBytesUTF16"] = function() { abort("'lengthBytesUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "UTF32ToString")) Module["UTF32ToString"] = function() { abort("'UTF32ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF32")) Module["stringToUTF32"] = function() { abort("'stringToUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF32")) Module["lengthBytesUTF32"] = function() { abort("'lengthBytesUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8")) Module["allocateUTF8"] = function() { abort("'allocateUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8OnStack")) Module["allocateUTF8OnStack"] = function() { abort("'allocateUTF8OnStack' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; +Module["writeStackCookie"] = writeStackCookie; +Module["checkStackCookie"] = checkStackCookie; +if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NORMAL")) Object.defineProperty(Module, "ALLOC_NORMAL", { configurable: true, get: function() { abort("'ALLOC_NORMAL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); +if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_STACK")) Object.defineProperty(Module, "ALLOC_STACK", { configurable: true, get: function() { abort("'ALLOC_STACK' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); + +var calledRun; + +/** + * @constructor + * @this {ExitStatus} + */ +function ExitStatus(status) { + this.name = "ExitStatus"; + this.message = "Program terminated with exit(" + status + ")"; + this.status = status; +} + +var calledMain = false; + +dependenciesFulfilled = function runCaller() { + // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false) + if (!calledRun) run(); + if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled +}; + +function stackCheckInit() { + // This is normally called automatically during __wasm_call_ctors but need to + // get these values before even running any of the ctors so we call it redundantly + // here. + // TODO(sbc): Move writeStackCookie to native to to avoid this. + _emscripten_stack_init(); + writeStackCookie(); +} + +/** @type {function(Array=)} */ +function run(args) { + args = args || arguments_; + + if (runDependencies > 0) { + return; + } + + stackCheckInit(); + + preRun(); + + // a preRun added a dependency, run will be called later + if (runDependencies > 0) { + return; + } + + function doRun() { + // run may have just been called through dependencies being fulfilled just in this very frame, + // or while the async setStatus time below was happening + if (calledRun) return; + calledRun = true; + Module['calledRun'] = true; + + if (ABORT) return; + + initRuntime(); + + preMain(); + + readyPromiseResolve(Module); + if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized'](); + + assert(!Module['_main'], 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]'); + + postRun(); + } + + if (Module['setStatus']) { + Module['setStatus']('Running...'); + setTimeout(function() { + setTimeout(function() { + Module['setStatus'](''); + }, 1); + doRun(); + }, 1); + } else + { + doRun(); + } + checkStackCookie(); +} +Module['run'] = run; + +function checkUnflushedContent() { + // Compiler settings do not allow exiting the runtime, so flushing + // the streams is not possible. but in ASSERTIONS mode we check + // if there was something to flush, and if so tell the user they + // should request that the runtime be exitable. + // Normally we would not even include flush() at all, but in ASSERTIONS + // builds we do so just for this check, and here we see if there is any + // content to flush, that is, we check if there would have been + // something a non-ASSERTIONS build would have not seen. + // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0 + // mode (which has its own special function for this; otherwise, all + // the code is inside libc) + var oldOut = out; + var oldErr = err; + var has = false; + out = err = function(x) { + has = true; + } + try { // it doesn't matter if it fails + var flush = null; + if (flush) flush(); + } catch(e) {} + out = oldOut; + err = oldErr; + if (has) { + warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.'); + warnOnce('(this may also be due to not including full filesystem support - try building with -s FORCE_FILESYSTEM=1)'); + } +} + +/** @param {boolean|number=} implicit */ +function exit(status, implicit) { + checkUnflushedContent(); + + // if this is just main exit-ing implicitly, and the status is 0, then we + // don't need to do anything here and can just leave. if the status is + // non-zero, though, then we need to report it. + // (we may have warned about this earlier, if a situation justifies doing so) + if (implicit && noExitRuntime && status === 0) { + return; + } + + if (noExitRuntime) { + // if exit() was called, we may warn the user if the runtime isn't actually being shut down + if (!implicit) { + var msg = 'program exited (with status: ' + status + '), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)'; + readyPromiseReject(msg); + err(msg); + } + } else { + + EXITSTATUS = status; + + exitRuntime(); + + if (Module['onExit']) Module['onExit'](status); + + ABORT = true; + } + + quit_(status, new ExitStatus(status)); +} + +if (Module['preInit']) { + if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; + while (Module['preInit'].length > 0) { + Module['preInit'].pop()(); + } +} + +Module['onRuntimeInitialized'] = window.onRuntimeInitialized; + +run(); + + + + + + + + return LibYUV +} +); +})(); +if (typeof exports === 'object' && typeof module === 'object') + module.exports = LibYUV; +else if (typeof define === 'function' && define['amd']) + define([], function() { return LibYUV; }); +else if (typeof exports === 'object') + exports["LibYUV"] = LibYUV; diff --git a/LibYUV.wasm b/LibYUV.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d30220dd62b91999e2f1443f84f0737750bab9ee GIT binary patch literal 18588 zcmcJXS&&@Eb*AsVwRcsa3qS*G01e_~p+Ph#fPf$nga9tMAc=(_2nt-mMUAaN^zFt{ zjc$;XC^o2FvNV=$*&{Dw)0SjvWJ0E8+Mx$UjACLQ^e_*OiI@mRj2`^p2gSrZ_(2g9 zF%u!p_h;Vfs>Wt=!p72h@6D5$Cr_U9=YR56S9J37`8bNA_|+vRT5n$WCw}upJRi@W zi1a_=IyzC9pVyNjg~|by;SYDod@d24DEWuciE^lnPE>NS=tMogQW4K52MdLX3s*`f zPhFgujr{e>iSw6F&rDvLowzVQGjVzHGZW+ICQe?8VhP?cK7Q`xg)`F=Dh}jm!rZR z4_~~18ned^>`Qm?XZ!JIp53v1+mlgoAl-N1*wYseaTk@lVtMWMu6R@$kigRyB^*`D z=jr<5>1e2Uc4lHCTCr+;eDcDX$(f1Mv*TyyE}Wj7ym(=J_T;JQi8yMFk5A0ZT(~$+ zgOjR=mY2_-ou0dVE*h+5`SJ^~0=R(P!>p)5!~yv(egB zH#~o30u7|ooj0#Lb@K8=v~KvO?ItdqiEP>U_+|PCqfAeppPaoM-Bqi_Q5x3^8^<;c z{ORZ8jm4<7w*Ehoc*Feq$Q4s_B`aEK%9WG7R&H-xUpQQ=UB zXEH(&?@Wd%lAXyAMPX;svhr9m>?+(aO;fY&F)i)tGEGI{2?^+>u4bZMc6^<2DwID^palFU63% z15*vlCg+23i?=fF@D0YDy@_#Iv+Imo{qV;9-?jK^EY}@Ke-`0Y16H4M4c4R4{%WiR z;pc+)el^yTG~~X!C~)5$6u9p;3fy-yMR8{`Mp4?Cj8c?$CPslXk5E+Q?+vTr?`e#; zHmr%4V~r(TE|D8I#*$rbFpXTx2IaN5>{45Hz%569$d=ns$E`^A>aVSMv>8c$n_G$e z9kx<7#h`fF0k<0YH8|Xw4&FMFOOCmf~_uHN+_W=DoAnfo~doc9%5DoX*L$-IyrFyc%?X%SOO}mHfL3=oJkI?85 zzkaHFl-~B+etUGv9iZX>D_ZB#L9P!1N6Fp-o}ef`6ncM*-VfVjc6iD?Zin0vd)z%? zN9>7%?kF`++EIJ5<344ddbAmTTMMb$m8VwXFvVw-y*bn~Jezh*C7vlnmCfjYJ4d!4)#I(b>e z4)FgwCv%snyX@mm3pY!6&DpHYW$p?US6J0XR96_w^Im1}*X&h$t>a$D z&0f#ltl>VR`d#j`VbnLm0H0Ga?B2vf=IyiBZ2p?Pam_w=&EC9)N$fLSb5z|`?-9G) zTfW@pKJUw6_l4Nrim%z{`TvFZ7XA3OyBe!Ax#t&YYF`9??)THU-+d_-dVN`szZ_@o zD=~BVO5FaMM=*XaAlTPDf_*6-tbe%@pAqiW)v{r9H07E!Yqrk|_Rja(oEPXd1L!pa z=rsfAH3R511L!pa=&=dQ_{{)%%>a5$4|+Tt!2W3gz-tD;Ys$(W0q~IjkbsBehXgz% zKP2EGIrO0b55ZPH;58Qj&)0lN!1J<;0Iw;)YZ(>h9#qkCivW)&BR2qEQ-H^csBRJ9 zH3fJh0q~jvJT^W655We2=X-w)lmqZUyTkVQL3f0B@qpKHNA0Lk4yh`@N3jdwqu2)K zQH+6k6b9x|41;+TLtx&guGz6`{g8K4w0qJA4oybDN8iu$_Pjlp0eVe4o=;~7*hk$i z_oBUMFJ$f|>RuAC@UY=tMpqAO9XF0+k1MvR*z8WI*ao_RZ$h`Gof6FOa1@ZE7;|U9 zt zqUwU8DjTf-I*ykI{;|z1q91G2U`?;Vng#A5nnCc3X23l}GvFRZ0rwEifP08$5Qc1x z3d0sfReaiW56?0-i+*UPP!Ab-FhCoUvcggo2Kk^Ef-h6F;2#tXw?YM6F1=cXbr8lj zD0XejL{DIK(6Ls<4X4}SA`M%Wxz)^nb$dk98R<=DMAI1_te=Zpntq(NTw<{$Q?6hI zfeo|LaK-dDv2qGmwo>4(Pq-@UP$L1Tb)aoxZ5R&L78-b3HRG13olgNekg3*S{oObo z)<^|LDl$ZIif&65?T!X1;@!~_iez^LjBSYqU0LmYBGO^J{~Uz@r^!F4UIJ`V?P0Uy zn(13{K(uK_9I(NR5s_-TrIPX#t^92d>w*_EGfxAc^m~-W%}K(#Ru5wSp08L_sEJgANiEqDMYxQ=!%4S9F`?)0mf5l`QG(Op zKtn{Bh`+8^5@{I_?8?m(+)W2kR z`iV$v9a{N}HFJ&%=clGgw5eFHEH!hZRE#pi0CO$3f&1Ggtb_HR*W(}ijH(0#cneLr z3Z|{J|IX79elF0Fzl((e6|-FfIa0Rqs^ObrSGq?O@im<}%VNFF<;w9!4cVYGoTbWLIswD{~uB zX3RF)SmriydADt{yXV};nBd3u#LL3?n{Bh)V~bk*G^^vbhMH}*ZA(;gA6LzG`?ziI zkYR1LPh@UK82DbhS50?Hz^7Lox65|eu8a)JYqr~VtA{-jAhWXjJLFcMvI_E+S8eP26djbXYAR` zJ;x>7z@DFj9aQYNFtQ>*dqG7Dc0jSrz2xETWqZM1?zm6;n{jx91WFO=#UqtXrK5B-QczoFle8mfVH75Ds;H2Ze z78^2OBPIDdqV{#aZ}~odE4JUFN$kGin|w32Z^ZUZn*6)G&)<&ix4po(yuk0o_N~}{ z2Z7&>4VmAi&)-v@zek@yf%N=#Y~Q9ylh#KX9)N_D_A;aDPTi7WwVisCk>Fe;ywEMQn)t z1rNR(9(*shKa1^qJotWWe;(U+WBY!LQ~jmaWz@YB8~^?i-r*gq>VA-q^dIw)ei-`s ztJtXdEBbjiJh&DcBG-8EqwwIbWBXxjf6asUVtY5XAI0`wjH~^PAIaR0W8>f7Xrwxj z{I@)|zh$cLYnk7V+kfw2nV$=={P%+8!TM+8`t{U|7KQeJsN6tLd_W++h_hL-)q-6W zL`AEjWmR^9a;xSlkS`usHFGuks&IR^1hD^+Sz$+8?qL1@ zl;cTtUP=EU(xzh7sa%_zlJuH5;!%#BvEUOFaKs}NaPET?aPCJam?+Z`8@S(U$^Zsz zK(4rmCnCUs->x9wcYh=IC8XGxtkq%fuh~)^D*7Hg1#n#o5YGM(SfO0S3#_!2TcWhf z1vpO?7pU1P!G{-sNp6i#xHTBvpIOhcS3w2l*sE$H0%JjJovqu-DX25#oSC^ohyY4`h&q~wyv6u31}G9+$I%cVH2AsS#CK_2W|5ew?!4BVe`t^ zylS>p`3hY>!D(U5w(XAA=6Zce+nTjRE;!)$2V?Gv+XXgll^bMD?0Z8)6!nlXGlp$ofr92Zl9!!1pW6doXnW5Ka7n;Vj!*YJ0W4 zq3A9S4ENc?)9w+rzeh55wwgVvjEcGuHaM@^0ooq419oth{f!-Nj{S}L9pQ{{nyeYI z)$DJ>VSAfZ)@)DAvArR-jfDA0`_wcE^W%0bV}sjoPffAG)$C~{ZGNO@LKn}{#dG$o zJvYl%$7ZLkj{42)amVe2Y4*5h>_uh3HD$o$dBXgc({jjw=Q!9KZw-?9^8BDXX=J_v z9`0K16jG<{l%1Z_R)^Gtoja#h5u?J0>*^~9$H1XVG^5ek^$Fa^AO zh=R~-Q4o6MwH{+Y15XR#<(>pq#li=SqDlzn?3)8F8&E0%86;~x$g3goZIagxS*fJ*d3}v8JTWXC>BoJGvdrwtYx?5pxy4wIBVxggWw|0 z9T~FgxVEm>llZOgbc1TRO9w~oF5YI0=uJ{A3rK{eazL4|Is1-JHWe2;xCup&cFovg)88KG1 zqj*B#H)y~C75({O>$qdM+c9w)ui8`gl#KPX?sQ1?jP9P*-4OBiobI02U5j}0#S8Sr zVN(b;|Kw#xUN}DINke=xCdi)lbW+!+iQLm2PQt!Wq1!j*RMN;^sm9n6)tn!lXJ z9V=$-Qd*cr=7U;B%GfSqq(;o-%y9|)!OAFP4Sp$K}9Qa zEsukbUs7HC~aIxTRdcPY3WK@?X*i4&1ewKHMx=&JMH2On)$iMSJLFV z`*`6#w?d_B1vILnD7*qIR2EsG4RrO}p(r~rqlQJY1C3+{pY37?Su)I>E4m8y;M8gg zqj(cYzf91_!dO}ET-JJ3v71JB-aJ38Ip7e1Bn8@L+tp537^`B%A3$MTwYM^2Y3=Ia zrfe%{t>SndVHsAs6?KFt-TWG1TQvS@jS?l^tFa_nkauhCns8LlYg7LgCQp;u^n<#0 zI!J#}{#uygK(FFTLVhO88Az)gVUbcg<1icreS#Va{iig^zHMC?V#s#Mku9T-l zGCE1ck!BLyw#^~M;bx*VV_0v88HLM68}hiHfvENVzu?=fJ?7$>`75v{Y*q4dEFL;Q zyEeK;UROFmX@3rpwlY_$7nlh9Rm76^%T;}?ha$Dp(PvY`HdFeJ{A#)?16ZRQ5EUsm zg5LzgwXp*(M<7Tkel%mPRX0}Otu>NvtTxnfBW8pZmh?G{ z;b0g)6YL+N-EZQci<%B&s@|#)p8a?OT=m5S*gFr~oInt(+f5m+l9%RNMh z>3AV%1^|)}C0u3l;>A%yaD^x-NdcmS>V)$R6Qo%ZqJ)bOB_&trMTrjB+65maOixkb zv5PQP9H<~zs@O(nQ$9Qx{k@u|Eof^L^#YtG>3^Enyac(-ir0^YJbV<(={o-^u0X2! z8~jdURltej>aQQl(w0Z9XjYh*Uj4^){)tcv$i(TdULEvLz^&43I(P-0z_ZfK6a&Sx z(l=d^ae&a7Njbf0N>@dYOyC`}*%x9Z0fy86fD}&16s4>1xA+S0H_~7cZoF@P~OTw`lI+Ex`O&QB2Os?dt3)&SfvN{C4s#M{{Z%j?g9J!KI@sq5qFAJ z1!*6wFyll1sFP={Hp-%mMi25}AchN>Wl+8lx~fwq$}{ssKR&u>?U4ON0PP9|TpjOzZ?vP*lp@6oOC+%{&B^0|d26q5DCormkxq zgp{o?TRcUCB6PR2(cgb zgAllOBM7l>IY#kTJO?4J7C=a^vlP)q&#t;S~cH|95|k;gIjqW6=>R9RDu{O_8|`8~_6H4-kgSc)M+6o|WN5w;+!E2VVkx*_c<86MBTE-C||CRt$NeRfYDKpv#6xl4FwZ}FBH{XBKt6Bmz zIO-{__J^O;P{A>x&YS*MgOZ28q)g{`CO^-Ejs!fOzk9bACpP+1(j*$lk zgMSN6{)=e4q_vK@8#BEI>8%_9uS_!E0EJ#--NT4VxBZBqh7bDC;rpC%E9s12jM78y zm=En8`-Y*F(V%{?XBGM)&1FY?5m@AnE*VX#SnIA?0ei7RR+7VVAk8BQo<5*Y+M?==aS?O9%EBD&XYqN~g&K!g-yC34*whc9W& zn11+LP9CW8wv>zx9FV%wCja+IP1~oWFoMHP{6SO@1w0?a8@=|@>j%pC%K7O`qVZTV z5lL8$8fr~KLne(ED6`2qg+}dW!O{dzNkU7nPPcg&H&9S%paHIZG`QxXC*v&q1N21hqFADvc18eYvk+kDv@4 zhHm#9laRsn@VkmmH9gM+rL$K_d7(Eeu~gUxgvqb;czuw zBM(%fm`0nDe{S4|VXM0QC6`=qQw4qhS-a=;yC_ro6$xrOOb8cV`N_>a|Hjkx5b`c3@%^f z(8li)2n1B?rdPLjem@DV-*7+*CXB&u;{QI+3jW{Cvw-*O{a=7}Yya1AAU5k8jzpwu z#e5qH=4SK2)-e#-O|=N!An7%xA2jx;F4tUG2OY7E!A)>VxV4Tjx%mIfW|DdYZd%|L$O13!Q|aL)}f3L@K6L4 z3b31g(XzIG|NDC_pW!Pt3Y#d{BGkaDT?PBLf7D_aj1ZLJoykqNf8M)ccc363x!?YE zpu{{mdtw$e)GLMDgV94L3uS-49gKoj$||s_wDMDKg)!OJG1HLhbBB=(t+oBSMAf#gkZ543kd0Eh@apk{?NJ<@eqh z^k%(}$&v^#2u!xG>)?c>dSXh_Ae29?4YG!zvaho~jvG2dmqyu!ICek* zZLYX9I35^n8UG5#?qjv+?^!L|`C_+D`dKYr*K3TW@g=#oZ>;rM#AP&k*R`b)uFclp z9hxWp=-+q2hk?au^=pmc>L%{3)9to=&a+#Ne0q01_b!lM7lV5*hPEZK8$ zbn-6VHC+gU>s*{jV4d~88K=A6k3j>EeH?uV+vRrNwJW!FeW2MB0C^kUL*RJtSwsMU zV*ipS5CGP{O91*_@i4AmXHNhK4_KI@1RxF6mmYY?=i{Kha#=?0e@){LPJ6FubSS_c zw)i!T5|zH!G-XeHapV~*Lw(sAW{m~xCjclD2Lcd_00gAy5`dijhG^s!tj<~W{yfYQ zC+_lJrXie#0%&&@1z?4sz>LUIYatx9q6a?f%3yDKfdWU`!3v_lEVU>wQcNPJ0IYY^ zF83&~=#y}0(QsPt+>R7|ESRoD0sOe01!L$SSyaJBv_Jtk8edomQ2;p!Co-JB#p%4o zkkX&yC)&@SiIaKNzFlKe#UZlv4NlH-I!F}72Z<4efjnp{iXP%~6SMvlti>l^<@s9e zw*fEu%eldPoy~=R15x^&X6ugh?Pk5=FNf{|Zx(Arw>mK2Luh|;qv@+S-TBYR_ zvnlLFE|z)JZRAa+4!y;QaXlXiM%%#aQr}v`X!H>V=VNr?=(M#Owpssv&{og;nqEsI z{kz$(frV$1A6*(n@2vJM0pxjYJ-R7saTTwLUYbSMEar^z-SoDA7+#Q8)`iO7wB_GMHzTcy8;}>rfyI-i${UVL-_imKB71w{$M!E0%I4Z6DOE+kJ zbzn4UcK`rMV>yH8J_Jb!8Xz4wkyUYOl9u&4W&R!?6%J~nsZ^5iQQ zCivaHb0=pu+wE>Q)%W%_-u~Lt7oX`hzkH6bKj~|K)B8=0>w9?iqxR5jr2ZR8jvu@D z>iEM;n&Ix5XZ`KqvaW&;Ytnwkt>xWk-VodT!=+!3yHAhLU3qfywTbDTBLA`_`sOL& zyZ`0;zR~!u6}~^@!t7-`t*g5?EgNJZxAW~OEQz1S@*BPtWvF^)I()0jit?FheTB)& z;^k8_Q+Jfd_01_$!`1QexeK~lH84JY@$9sJy1EgrL(Lj$Byo0fdSZl{@KkqeZ~hG` zxA>A2jlS;I-=AW){Q4Bv`$CuYqVIEA-}iMcqxsjrY#?017s2F;PMo>xCf~lYapctN z7e>!sI(_o;?3Ri1bEAv=VQkG!YlH7>y7Riq>sFz%r4SABeJ}o7dM;fgdM0M#diMce e2a{mLP^<5asVz;S$~`j|&zzh+8JF%+@&5p^DG0Ry literal 0 HcmV?d00001 diff --git a/index.html b/index.html index aef6abe0f..7cbc71406 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,7 @@ + Vite App diff --git a/package.json b/package.json index 9ee7ee122..bc2aa5fff 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "web_hbb", "version": "1.0.0", "scripts": { - "dev": "curl -O https://raw.githubusercontent.com/rgov/js-theora-decoder/main/yuv-canvas-1.2.6.js && vite", + "dev": "vite", "build": "tsc && vite build", "preview": "vite preview" }, diff --git a/src/connection.ts b/src/connection.ts index 2a6dad977..c5bb5a067 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -215,11 +215,11 @@ export default class Connection { this.handleVideoFrame(msg?.videoFrame!); } else if (msg?.clipboard) { const cb = msg?.clipboard; - if (cb.compress) cb.content = globals.decompress(cb.content)!; + if (cb.compress) cb.content = await globals.decompress(cb.content)!; globals.pushEvent("clipboard", cb); } else if (msg?.cursorData) { const cd = msg?.cursorData; - cd.colors = globals.decompress(cd.colors)!; + cd.colors = await globals.decompress(cd.colors)!; globals.pushEvent("cursor_data", cd); } else if (msg?.cursorId) { globals.pushEvent("cursor_id", { id: msg?.cursorId }); diff --git a/src/globals.js b/src/globals.js index d7a229560..481a05415 100644 --- a/src/globals.js +++ b/src/globals.js @@ -2,8 +2,10 @@ import Connection from "./connection"; import _sodium from "libsodium-wrappers"; import * as zstd from 'zstddec'; import { CursorData } from "./message"; +import { loadOpus, loadVp9 } from "./codec"; -const decompressor = new zstd.ZSTDDecoder(); +var decompressor; +var wasmDsp; var currentFrame = undefined; var events = []; @@ -122,7 +124,7 @@ export function decrypt(signed, nonce, key) { return sodium.crypto_secretbox_open_easy(signed, makeOnce(nonce), key); } -export function decompress(compressedArray) { +export async function decompress(compressedArray) { const MAX = 1024 * 1024 * 64; const MIN = 1024 * 1024; let n = 30 * compressedArray.length; @@ -133,6 +135,9 @@ export function decompress(compressedArray) { n = MIN; } try { + if (!decompressor) { + await initZstd(); + } return decompressor.decode(compressedArray, n); } catch (e) { console.error('decompress failed: ' + e); @@ -267,6 +272,24 @@ window.getByName = (name, arg) => { return ''; } -window.init = () => { - decompressor.init(); +window.init = async () => { + await initZstd(); +} + +function I420ToARGB(yuvbuffer) { + // +} + +async function initZstd() { + loadOpus(() => { }); + loadVp9(() => { }); + fetch('./LibYUV.wasm').then(res => res.arrayBuffer()).then((buffer) => { + LibYUV['wasmBinary'] = buffer; + window.wasmDsp = wasmDsp = LibYUV({ wasmBinary: LibYUV.wasmBinary }); + console.log('libyuv ready'); + }); + const tmp = new zstd.ZSTDDecoder(); + await tmp.init(); + console.log('zstd ready'); + decompressor = tmp; } \ No newline at end of file diff --git a/yuv-canvas-1.2.6.js b/yuv-canvas-1.2.6.js new file mode 100644 index 000000000..36e36f493 --- /dev/null +++ b/yuv-canvas-1.2.6.js @@ -0,0 +1,1234 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +MPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +ONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/** + * Represents metadata about a YUV frame format. + * @typedef {Object} YUVFormat + * @property {number} width - width of encoded frame in luma pixels + * @property {number} height - height of encoded frame in luma pixels + * @property {number} chromaWidth - width of encoded frame in chroma pixels + * @property {number} chromaHeight - height of encoded frame in chroma pixels + * @property {number} cropLeft - upper-left X coordinate of visible crop region, in luma pixels + * @property {number} cropTop - upper-left Y coordinate of visible crop region, in luma pixels + * @property {number} cropWidth - width of visible crop region, in luma pixels + * @property {number} cropHeight - height of visible crop region, in luma pixels + * @property {number} displayWidth - final display width of visible region, in luma pixels + * @property {number} displayHeight - final display height of visible region, in luma pixels + */ + +/** + * Represents underlying image data for a single luma or chroma plane. + * Cannot be interpreted without the format data from a frame buffer. + * @typedef {Object} YUVPlane + * @property {Uint8Array} bytes - typed array containing image data bytes + * @property {number} stride - byte distance between rows in data + */ + +/** + * Represents a YUV image frame buffer, with enough format information + * to interpret the data usefully. Buffer objects use generic objects + * under the hood and can be transferred between worker threads using + * the structured clone algorithm. + * + * @typedef {Object} YUVFrame + * @property {YUVFormat} format + * @property {YUVPlane} y + * @property {YUVPlane} u + * @property {YUVPlane} v + */ + +/** + * Holder namespace for utility functions and constants related to + * YUV frame and plane buffers. + * + * @namespace + */ +var YUVBuffer = { + /** + * Validate a plane dimension + * @param {number} dim - vertical or horizontal dimension + * @throws exception on zero, negative, or non-integer value + */ + validateDimension: function(dim) { + if (dim <= 0 || dim !== (dim | 0)) { + throw 'YUV plane dimensions must be a positive integer'; + } + }, + + /** + * Validate a plane offset + * @param {number} dim - vertical or horizontal dimension + * @throws exception on negative or non-integer value + */ + validateOffset: function(dim) { + if (dim < 0 || dim !== (dim | 0)) { + throw 'YUV plane offsets must be a non-negative integer'; + } + }, + + /** + * Validate and fill out a YUVFormat object structure. + * + * At least width and height fields are required; other fields will be + * derived if left missing or empty: + * - chromaWidth and chromaHeight will be copied from width and height as for a 4:4:4 layout + * - cropLeft and cropTop will be 0 + * - cropWidth and cropHeight will be set to whatever of the frame is visible after cropTop and cropLeft are applied + * - displayWidth and displayHeight will be set to cropWidth and cropHeight. + * + * @param {YUVFormat} fields - input fields, must include width and height. + * @returns {YUVFormat} - validated structure, with all derivable fields filled out. + * @throws exception on invalid fields or missing width/height + */ + format: function(fields) { + var width = fields.width, + height = fields.height, + chromaWidth = fields.chromaWidth || width, + chromaHeight = fields.chromaHeight || height, + cropLeft = fields.cropLeft || 0, + cropTop = fields.cropTop || 0, + cropWidth = fields.cropWidth || width - cropLeft, + cropHeight = fields.cropHeight || height - cropTop, + displayWidth = fields.displayWidth || cropWidth, + displayHeight = fields.displayHeight || cropHeight; + this.validateDimension(width); + this.validateDimension(height); + this.validateDimension(chromaWidth); + this.validateDimension(chromaHeight); + this.validateOffset(cropLeft); + this.validateOffset(cropTop); + this.validateDimension(cropWidth); + this.validateDimension(cropHeight); + this.validateDimension(displayWidth); + this.validateDimension(displayHeight); + return { + width: width, + height: height, + chromaWidth: chromaWidth, + chromaHeight: chromaHeight, + cropLeft: cropLeft, + cropTop: cropTop, + cropWidth: cropWidth, + cropHeight: cropHeight, + displayWidth: displayWidth, + displayHeight: displayHeight + }; + }, + + /** + * Allocate a new YUVPlane object of the given size. + * @param {number} stride - byte distance between rows + * @param {number} rows - number of rows to allocate + * @returns {YUVPlane} - freshly allocated planar buffer + */ + allocPlane: function(stride, rows) { + YUVBuffer.validateDimension(stride); + YUVBuffer.validateDimension(rows); + return { + bytes: new Uint8Array(stride * rows), + stride: stride + } + }, + + /** + * Pick a suitable stride for a custom-allocated thingy + * @param {number} width - width in bytes + * @returns {number} - new width in bytes at least as large + * @throws exception on invalid input width + */ + suitableStride: function(width) { + YUVBuffer.validateDimension(width); + var alignment = 4, + remainder = width % alignment; + if (remainder == 0) { + return width; + } else { + return width + (alignment - remainder); + } + }, + + /** + * Allocate or extract a YUVPlane object from given dimensions/source. + * @param {number} width - width in pixels + * @param {number} height - height in pixels + * @param {Uint8Array} source - input byte array; optional (will create empty buffer if missing) + * @param {number} stride - row length in bytes; optional (will create a default if missing) + * @param {number} offset - offset into source array to extract; optional (will start at 0 if missing) + * @returns {YUVPlane} - freshly allocated planar buffer + */ + allocPlane: function(width, height, source, stride, offset) { + var size, bytes; + + this.validateDimension(width); + this.validateDimension(height); + + offset = offset || 0; + + stride = stride || this.suitableStride(width); + this.validateDimension(stride); + if (stride < width) { + throw "Invalid input stride for YUV plane; must be larger than width"; + } + + size = stride * height; + + if (source) { + if (source.length - offset < size) { + throw "Invalid input buffer for YUV plane; must be large enough for stride times height"; + } + bytes = source.slice(offset, offset + size); + } else { + bytes = new Uint8Array(size); + stride = stride || this.suitableStride(width); + } + + return { + bytes: bytes, + stride: stride + }; + }, + + /** + * Allocate a new YUVPlane object big enough for a luma plane in the given format + * @param {YUVFormat} format - target frame format + * @param {Uint8Array} source - input byte array; optional (will create empty buffer if missing) + * @param {number} stride - row length in bytes; optional (will create a default if missing) + * @param {number} offset - offset into source array to extract; optional (will start at 0 if missing) + * @returns {YUVPlane} - freshly allocated planar buffer + */ + lumaPlane: function(format, source, stride, offset) { + return this.allocPlane(format.width, format.height, source, stride, offset); + }, + + /** + * Allocate a new YUVPlane object big enough for a chroma plane in the given format, + * optionally copying data from an existing buffer. + * + * @param {YUVFormat} format - target frame format + * @param {Uint8Array} source - input byte array; optional (will create empty buffer if missing) + * @param {number} stride - row length in bytes; optional (will create a default if missing) + * @param {number} offset - offset into source array to extract; optional (will start at 0 if missing) + * @returns {YUVPlane} - freshly allocated planar buffer + */ + chromaPlane: function(format, source, stride, offset) { + return this.allocPlane(format.chromaWidth, format.chromaHeight, source, stride, offset); + }, + + /** + * Allocate a new YUVFrame object big enough for the given format + * @param {YUVFormat} format - target frame format + * @param {YUVPlane} y - optional Y plane; if missing, fresh one will be allocated + * @param {YUVPlane} u - optional U plane; if missing, fresh one will be allocated + * @param {YUVPlane} v - optional V plane; if missing, fresh one will be allocated + * @returns {YUVFrame} - freshly allocated frame buffer + */ + frame: function(format, y, u, v) { + y = y || this.lumaPlane(format); + u = u || this.chromaPlane(format); + v = v || this.chromaPlane(format); + return { + format: format, + y: y, + u: u, + v: v + } + }, + + /** + * Duplicate a plane using new buffer memory. + * @param {YUVPlane} plane - input plane to copy + * @returns {YUVPlane} - freshly allocated and filled planar buffer + */ + copyPlane: function(plane) { + return { + bytes: plane.bytes.slice(), + stride: plane.stride + }; + }, + + /** + * Duplicate a frame using new buffer memory. + * @param {YUVFrame} frame - input frame to copyFrame + * @returns {YUVFrame} - freshly allocated and filled frame buffer + */ + copyFrame: function(frame) { + return { + format: frame.format, + y: this.copyPlane(frame.y), + u: this.copyPlane(frame.u), + v: this.copyPlane(frame.v) + } + }, + + /** + * List the backing buffers for the frame's planes for transfer between + * threads via Worker.postMessage. + * @param {YUVFrame} frame - input frame + * @returns {Array} - list of transferable objects + */ + transferables: function(frame) { + return [frame.y.bytes.buffer, frame.u.bytes.buffer, frame.v.bytes.buffer]; + } +}; + +module.exports = YUVBuffer; + +},{}],4:[function(require,module,exports){ +(function() { + "use strict"; + + /** + * Create a YUVCanvas and attach it to an HTML5 canvas element. + * + * This will take over the drawing context of the canvas and may turn + * it into a WebGL 3d canvas if possible. Do not attempt to use the + * drawing context directly after this. + * + * @param {HTMLCanvasElement} canvas - HTML canvas element to attach to + * @param {YUVCanvasOptions} options - map of options + * @throws exception if WebGL requested but unavailable + * @constructor + * @abstract + */ + function FrameSink(canvas, options) { + throw new Error('abstract'); + } + + /** + * Draw a single YUV frame on the underlying canvas, converting to RGB. + * If necessary the canvas will be resized to the optimal pixel size + * for the given buffer's format. + * + * @param {YUVBuffer} buffer - the YUV buffer to draw + * @see {@link https://www.npmjs.com/package/yuv-buffer|yuv-buffer} for format + */ + FrameSink.prototype.drawFrame = function(buffer) { + throw new Error('abstract'); + }; + + /** + * Clear the canvas using appropriate underlying 2d or 3d context. + */ + FrameSink.prototype.clear = function() { + throw new Error('abstract'); + }; + + module.exports = FrameSink; + +})(); + +},{}],5:[function(require,module,exports){ +/* +Copyright (c) 2014-2016 Brion Vibber + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +MPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +(function() { + "use strict"; + + var FrameSink = require('./FrameSink.js'), + YCbCr = require('./YCbCr.js'); + + /** + * @param {HTMLCanvasElement} canvas - HTML canvas eledment to attach to + * @constructor + */ + function SoftwareFrameSink(canvas) { + var self = this, + ctx = canvas.getContext('2d'), + imageData = null, + resampleCanvas = null, + resampleContext = null; + + + + function initImageData(width, height) { + imageData = ctx.createImageData(width, height); + + // Prefill the alpha to opaque + var data = imageData.data, + pixelCount = width * height * 4; + for (var i = 0; i < pixelCount; i += 4) { + data[i + 3] = 255; + } + } + + function initResampleCanvas(cropWidth, cropHeight) { + resampleCanvas = document.createElement('canvas'); + resampleCanvas.width = cropWidth; + resampleCanvas.height = cropHeight; + resampleContext = resampleCanvas.getContext('2d'); + } + + /** + * Actually draw a frame into the canvas. + * @param {YUVFrame} buffer - YUV frame buffer object to draw + */ + self.drawFrame = function drawFrame(buffer) { + var format = buffer.format; + + if (canvas.width !== format.displayWidth || canvas.height !== format.displayHeight) { + // Keep the canvas at the right size... + canvas.width = format.displayWidth; + canvas.height = format.displayHeight; + } + + if (imageData === null || + imageData.width != format.width || + imageData.height != format.height) { + initImageData(format.width, format.height); + } + + // YUV -> RGB over the entire encoded frame + YCbCr.convertYCbCr(buffer, imageData.data); + + var resample = (format.cropWidth != format.displayWidth || format.cropHeight != format.displayHeight); + var drawContext; + if (resample) { + // hack for non-square aspect-ratio + // putImageData doesn't resample, so we have to draw in two steps. + if (!resampleCanvas) { + initResampleCanvas(format.cropWidth, format.cropHeight); + } + drawContext = resampleContext; + } else { + drawContext = ctx; + } + + // Draw cropped frame to either the final or temporary canvas + drawContext.putImageData(imageData, + -format.cropLeft, -format.cropTop, // must offset the offset + format.cropLeft, format.cropTop, + format.cropWidth, format.cropHeight); + + if (resample) { + ctx.drawImage(resampleCanvas, 0, 0, format.displayWidth, format.displayHeight); + } + }; + + self.clear = function() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + }; + + return self; + } + + SoftwareFrameSink.prototype = Object.create(FrameSink.prototype); + + module.exports = SoftwareFrameSink; +})(); + +},{"./FrameSink.js":4,"./YCbCr.js":7}],6:[function(require,module,exports){ +/* +Copyright (c) 2014-2016 Brion Vibber + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +MPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +(function() { + "use strict"; + + var FrameSink = require('./FrameSink.js'), + shaders = require('../build/shaders.js'); + + /** + * Warning: canvas must not have been used for 2d drawing prior! + * + * @param {HTMLCanvasElement} canvas - HTML canvas element to attach to + * @constructor + */ + function WebGLFrameSink(canvas) { + var self = this, + gl = WebGLFrameSink.contextForCanvas(canvas), + debug = false; // swap this to enable more error checks, which can slow down rendering + + if (gl === null) { + throw new Error('WebGL unavailable'); + } + + // GL! + function checkError() { + if (debug) { + err = gl.getError(); + if (err !== 0) { + throw new Error("GL error " + err); + } + } + } + + function compileShader(type, source) { + var shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + var err = gl.getShaderInfoLog(shader); + gl.deleteShader(shader); + throw new Error('GL shader compilation for ' + type + ' failed: ' + err); + } + + return shader; + } + + + var program, + unpackProgram, + err; + + // In the world of GL there are no rectangles. + // There are only triangles. + // THERE IS NO SPOON. + var rectangle = new Float32Array([ + // First triangle (top left, clockwise) + -1.0, -1.0, + +1.0, -1.0, + -1.0, +1.0, + + // Second triangle (bottom right, clockwise) + -1.0, +1.0, + +1.0, -1.0, + +1.0, +1.0 + ]); + + var textures = {}; + var framebuffers = {}; + var stripes = {}; + var buf, positionLocation, unpackPositionLocation; + var unpackTexturePositionBuffer, unpackTexturePositionLocation; + var stripeLocation, unpackTextureLocation; + var lumaPositionBuffer, lumaPositionLocation; + var chromaPositionBuffer, chromaPositionLocation; + + function createOrReuseTexture(name) { + if (!textures[name]) { + textures[name] = gl.createTexture(); + } + return textures[name]; + } + + function uploadTexture(name, width, height, data) { + var texture = createOrReuseTexture(name); + gl.activeTexture(gl.TEXTURE0); + + if (WebGLFrameSink.stripe) { + var uploadTemp = !textures[name + '_temp']; + var tempTexture = createOrReuseTexture(name + '_temp'); + gl.bindTexture(gl.TEXTURE_2D, tempTexture); + if (uploadTemp) { + // new texture + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D( + gl.TEXTURE_2D, + 0, // mip level + gl.RGBA, // internal format + width / 4, + height, + 0, // border + gl.RGBA, // format + gl.UNSIGNED_BYTE, // type + data // data! + ); + } else { + // update texture + gl.texSubImage2D( + gl.TEXTURE_2D, + 0, // mip level + 0, // x offset + 0, // y offset + width / 4, + height, + gl.RGBA, // format + gl.UNSIGNED_BYTE, // type + data // data! + ); + } + + var stripeTexture = textures[name + '_stripe']; + var uploadStripe = !stripeTexture; + if (uploadStripe) { + stripeTexture = createOrReuseTexture(name + '_stripe'); + } + gl.bindTexture(gl.TEXTURE_2D, stripeTexture); + if (uploadStripe) { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D( + gl.TEXTURE_2D, + 0, // mip level + gl.RGBA, // internal format + width, + 1, + 0, // border + gl.RGBA, // format + gl.UNSIGNED_BYTE, //type + buildStripe(width, 1) // data! + ); + } + + } else { + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texImage2D( + gl.TEXTURE_2D, + 0, // mip level + gl.LUMINANCE, // internal format + width, + height, + 0, // border + gl.LUMINANCE, // format + gl.UNSIGNED_BYTE, //type + data // data! + ); + } + } + + function unpackTexture(name, width, height) { + var texture = textures[name]; + + // Upload to a temporary RGBA texture, then unpack it. + // This is faster than CPU-side swizzling in ANGLE on Windows. + gl.useProgram(unpackProgram); + + var fb = framebuffers[name]; + if (!fb) { + // Create a framebuffer and an empty target size + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texImage2D( + gl.TEXTURE_2D, + 0, // mip level + gl.RGBA, // internal format + width, + height, + 0, // border + gl.RGBA, // format + gl.UNSIGNED_BYTE, //type + null // data! + ); + + fb = framebuffers[name] = gl.createFramebuffer(); + } + + gl.bindFramebuffer(gl.FRAMEBUFFER, fb); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + + var tempTexture = textures[name + '_temp']; + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, tempTexture); + gl.uniform1i(unpackTextureLocation, 1); + + var stripeTexture = textures[name + '_stripe']; + gl.activeTexture(gl.TEXTURE2); + gl.bindTexture(gl.TEXTURE_2D, stripeTexture); + gl.uniform1i(stripeLocation, 2); + + // Rectangle geometry + gl.bindBuffer(gl.ARRAY_BUFFER, buf); + gl.enableVertexAttribArray(positionLocation); + gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); + + // Set up the texture geometry... + gl.bindBuffer(gl.ARRAY_BUFFER, unpackTexturePositionBuffer); + gl.enableVertexAttribArray(unpackTexturePositionLocation); + gl.vertexAttribPointer(unpackTexturePositionLocation, 2, gl.FLOAT, false, 0, 0); + + // Draw into the target texture... + gl.viewport(0, 0, width, height); + + gl.drawArrays(gl.TRIANGLES, 0, rectangle.length / 2); + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + } + + function attachTexture(name, register, index) { + gl.activeTexture(register); + gl.bindTexture(gl.TEXTURE_2D, textures[name]); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + + gl.uniform1i(gl.getUniformLocation(program, name), index); + } + + function buildStripe(width) { + if (stripes[width]) { + return stripes[width]; + } + var len = width, + out = new Uint32Array(len); + for (var i = 0; i < len; i += 4) { + out[i ] = 0x000000ff; + out[i + 1] = 0x0000ff00; + out[i + 2] = 0x00ff0000; + out[i + 3] = 0xff000000; + } + return stripes[width] = new Uint8Array(out.buffer); + } + + function initProgram(vertexShaderSource, fragmentShaderSource) { + var vertexShader = compileShader(gl.VERTEX_SHADER, vertexShaderSource); + var fragmentShader = compileShader(gl.FRAGMENT_SHADER, fragmentShaderSource); + + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + + gl.linkProgram(program); + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + var err = gl.getProgramInfoLog(program); + gl.deleteProgram(program); + throw new Error('GL program linking failed: ' + err); + } + + return program; + } + + function init() { + if (WebGLFrameSink.stripe) { + unpackProgram = initProgram(shaders.vertexStripe, shaders.fragmentStripe); + unpackPositionLocation = gl.getAttribLocation(unpackProgram, 'aPosition'); + + unpackTexturePositionBuffer = gl.createBuffer(); + var textureRectangle = new Float32Array([ + 0, 0, + 1, 0, + 0, 1, + 0, 1, + 1, 0, + 1, 1 + ]); + gl.bindBuffer(gl.ARRAY_BUFFER, unpackTexturePositionBuffer); + gl.bufferData(gl.ARRAY_BUFFER, textureRectangle, gl.STATIC_DRAW); + + unpackTexturePositionLocation = gl.getAttribLocation(unpackProgram, 'aTexturePosition'); + stripeLocation = gl.getUniformLocation(unpackProgram, 'uStripe'); + unpackTextureLocation = gl.getUniformLocation(unpackProgram, 'uTexture'); + } + program = initProgram(shaders.vertex, shaders.fragment); + + buf = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buf); + gl.bufferData(gl.ARRAY_BUFFER, rectangle, gl.STATIC_DRAW); + + positionLocation = gl.getAttribLocation(program, 'aPosition'); + lumaPositionBuffer = gl.createBuffer(); + lumaPositionLocation = gl.getAttribLocation(program, 'aLumaPosition'); + chromaPositionBuffer = gl.createBuffer(); + chromaPositionLocation = gl.getAttribLocation(program, 'aChromaPosition'); + } + + /** + * Actually draw a frame. + * @param {YUVFrame} buffer - YUV frame buffer object + */ + self.drawFrame = function(buffer) { + var format = buffer.format; + + var formatUpdate = (!program || canvas.width !== format.displayWidth || canvas.height !== format.displayHeight); + if (formatUpdate) { + // Keep the canvas at the right size... + canvas.width = format.displayWidth; + canvas.height = format.displayHeight; + self.clear(); + } + + if (!program) { + init(); + } + + if (formatUpdate) { + var setupTexturePosition = function(buffer, location, texWidth) { + // Warning: assumes that the stride for Cb and Cr is the same size in output pixels + var textureX0 = format.cropLeft / texWidth; + var textureX1 = (format.cropLeft + format.cropWidth) / texWidth; + var textureY0 = (format.cropTop + format.cropHeight) / format.height; + var textureY1 = format.cropTop / format.height; + var textureRectangle = new Float32Array([ + textureX0, textureY0, + textureX1, textureY0, + textureX0, textureY1, + textureX0, textureY1, + textureX1, textureY0, + textureX1, textureY1 + ]); + + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, textureRectangle, gl.STATIC_DRAW); + }; + setupTexturePosition( + lumaPositionBuffer, + lumaPositionLocation, + buffer.y.stride); + setupTexturePosition( + chromaPositionBuffer, + chromaPositionLocation, + buffer.u.stride * format.width / format.chromaWidth); + } + + // Create or update the textures... + uploadTexture('uTextureY', buffer.y.stride, format.height, buffer.y.bytes); + uploadTexture('uTextureCb', buffer.u.stride, format.chromaHeight, buffer.u.bytes); + uploadTexture('uTextureCr', buffer.v.stride, format.chromaHeight, buffer.v.bytes); + + if (WebGLFrameSink.stripe) { + // Unpack the textures after upload to avoid blocking on GPU + unpackTexture('uTextureY', buffer.y.stride, format.height); + unpackTexture('uTextureCb', buffer.u.stride, format.chromaHeight); + unpackTexture('uTextureCr', buffer.v.stride, format.chromaHeight); + } + + // Set up the rectangle and draw it + gl.useProgram(program); + gl.viewport(0, 0, canvas.width, canvas.height); + + attachTexture('uTextureY', gl.TEXTURE0, 0); + attachTexture('uTextureCb', gl.TEXTURE1, 1); + attachTexture('uTextureCr', gl.TEXTURE2, 2); + + // Set up geometry + gl.bindBuffer(gl.ARRAY_BUFFER, buf); + gl.enableVertexAttribArray(positionLocation); + gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); + + // Set up the texture geometry... + gl.bindBuffer(gl.ARRAY_BUFFER, lumaPositionBuffer); + gl.enableVertexAttribArray(lumaPositionLocation); + gl.vertexAttribPointer(lumaPositionLocation, 2, gl.FLOAT, false, 0, 0); + + gl.bindBuffer(gl.ARRAY_BUFFER, chromaPositionBuffer); + gl.enableVertexAttribArray(chromaPositionLocation); + gl.vertexAttribPointer(chromaPositionLocation, 2, gl.FLOAT, false, 0, 0); + + // Aaaaand draw stuff. + gl.drawArrays(gl.TRIANGLES, 0, rectangle.length / 2); + }; + + self.clear = function() { + gl.viewport(0, 0, canvas.width, canvas.height); + gl.clearColor(0.0, 0.0, 0.0, 0.0); + gl.clear(gl.COLOR_BUFFER_BIT); + }; + + self.clear(); + + return self; + } + + // For Windows; luminance and alpha textures are ssllooww to upload, + // so we pack into RGBA and unpack in the shaders. + // + // This seems to affect all browsers on Windows, probably due to fun + // mismatches between GL and D3D. + WebGLFrameSink.stripe = (function() { + if (navigator.userAgent.indexOf('Windows') !== -1) { + return true; + } + return false; + })(); + + WebGLFrameSink.contextForCanvas = function(canvas) { + var options = { + // Don't trigger discrete GPU in multi-GPU systems + preferLowPowerToHighPerformance: true, + powerPreference: 'low-power', + // Don't try to use software GL rendering! + failIfMajorPerformanceCaveat: true, + // In case we need to capture the resulting output. + preserveDrawingBuffer: true + }; + return canvas.getContext('webgl', options) || canvas.getContext('experimental-webgl', options); + }; + + /** + * Static function to check if WebGL will be available with appropriate features. + * + * @returns {boolean} - true if available + */ + WebGLFrameSink.isAvailable = function() { + var canvas = document.createElement('canvas'), + gl; + canvas.width = 1; + canvas.height = 1; + try { + gl = WebGLFrameSink.contextForCanvas(canvas); + } catch (e) { + return false; + } + if (gl) { + var register = gl.TEXTURE0, + width = 4, + height = 4, + texture = gl.createTexture(), + data = new Uint8Array(width * height), + texWidth = WebGLFrameSink.stripe ? (width / 4) : width, + format = WebGLFrameSink.stripe ? gl.RGBA : gl.LUMINANCE, + filter = WebGLFrameSink.stripe ? gl.NEAREST : gl.LINEAR; + + gl.activeTexture(register); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter); + gl.texImage2D( + gl.TEXTURE_2D, + 0, // mip level + format, // internal format + texWidth, + height, + 0, // border + format, // format + gl.UNSIGNED_BYTE, //type + data // data! + ); + + var err = gl.getError(); + if (err) { + // Doesn't support luminance textures? + return false; + } else { + return true; + } + } else { + return false; + } + }; + + WebGLFrameSink.prototype = Object.create(FrameSink.prototype); + + module.exports = WebGLFrameSink; +})(); + +},{"../build/shaders.js":1,"./FrameSink.js":4}],7:[function(require,module,exports){ +/* +Copyright (c) 2014-2019 Brion Vibber + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +MPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +(function() { + "use strict"; + + var depower = require('./depower.js'); + + /** + * Basic YCbCr->RGB conversion + * + * @author Brion Vibber + * @copyright 2014-2019 + * @license MIT-style + * + * @param {YUVFrame} buffer - input frame buffer + * @param {Uint8ClampedArray} output - array to draw RGBA into + * Assumes that the output array already has alpha channel set to opaque. + */ + function convertYCbCr(buffer, output) { + var width = buffer.format.width | 0, + height = buffer.format.height | 0, + hdec = depower(buffer.format.width / buffer.format.chromaWidth) | 0, + vdec = depower(buffer.format.height / buffer.format.chromaHeight) | 0, + bytesY = buffer.y.bytes, + bytesCb = buffer.u.bytes, + bytesCr = buffer.v.bytes, + strideY = buffer.y.stride | 0, + strideCb = buffer.u.stride | 0, + strideCr = buffer.v.stride | 0, + outStride = width << 2, + YPtr = 0, Y0Ptr = 0, Y1Ptr = 0, + CbPtr = 0, CrPtr = 0, + outPtr = 0, outPtr0 = 0, outPtr1 = 0, + colorCb = 0, colorCr = 0, + multY = 0, multCrR = 0, multCbCrG = 0, multCbB = 0, + x = 0, y = 0, xdec = 0, ydec = 0; + + if (hdec == 1 && vdec == 1) { + // Optimize for 4:2:0, which is most common + outPtr0 = 0; + outPtr1 = outStride; + ydec = 0; + for (y = 0; y < height; y += 2) { + Y0Ptr = y * strideY | 0; + Y1Ptr = Y0Ptr + strideY | 0; + CbPtr = ydec * strideCb | 0; + CrPtr = ydec * strideCr | 0; + for (x = 0; x < width; x += 2) { + colorCb = bytesCb[CbPtr++] | 0; + colorCr = bytesCr[CrPtr++] | 0; + + // Quickie YUV conversion + // https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion + // multiplied by 256 for integer-friendliness + multCrR = (409 * colorCr | 0) - 57088 | 0; + multCbCrG = (100 * colorCb | 0) + (208 * colorCr | 0) - 34816 | 0; + multCbB = (516 * colorCb | 0) - 70912 | 0; + + multY = 298 * bytesY[Y0Ptr++] | 0; + output[outPtr0 ] = (multY + multCrR) >> 8; + output[outPtr0 + 1] = (multY - multCbCrG) >> 8; + output[outPtr0 + 2] = (multY + multCbB) >> 8; + outPtr0 += 4; + + multY = 298 * bytesY[Y0Ptr++] | 0; + output[outPtr0 ] = (multY + multCrR) >> 8; + output[outPtr0 + 1] = (multY - multCbCrG) >> 8; + output[outPtr0 + 2] = (multY + multCbB) >> 8; + outPtr0 += 4; + + multY = 298 * bytesY[Y1Ptr++] | 0; + output[outPtr1 ] = (multY + multCrR) >> 8; + output[outPtr1 + 1] = (multY - multCbCrG) >> 8; + output[outPtr1 + 2] = (multY + multCbB) >> 8; + outPtr1 += 4; + + multY = 298 * bytesY[Y1Ptr++] | 0; + output[outPtr1 ] = (multY + multCrR) >> 8; + output[outPtr1 + 1] = (multY - multCbCrG) >> 8; + output[outPtr1 + 2] = (multY + multCbB) >> 8; + outPtr1 += 4; + } + outPtr0 += outStride; + outPtr1 += outStride; + ydec++; + } + } else { + outPtr = 0; + for (y = 0; y < height; y++) { + xdec = 0; + ydec = y >> vdec; + YPtr = y * strideY | 0; + CbPtr = ydec * strideCb | 0; + CrPtr = ydec * strideCr | 0; + + for (x = 0; x < width; x++) { + xdec = x >> hdec; + colorCb = bytesCb[CbPtr + xdec] | 0; + colorCr = bytesCr[CrPtr + xdec] | 0; + + // Quickie YUV conversion + // https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion + // multiplied by 256 for integer-friendliness + multCrR = (409 * colorCr | 0) - 57088 | 0; + multCbCrG = (100 * colorCb | 0) + (208 * colorCr | 0) - 34816 | 0; + multCbB = (516 * colorCb | 0) - 70912 | 0; + + multY = 298 * bytesY[YPtr++] | 0; + output[outPtr ] = (multY + multCrR) >> 8; + output[outPtr + 1] = (multY - multCbCrG) >> 8; + output[outPtr + 2] = (multY + multCbB) >> 8; + outPtr += 4; + } + } + } + } + + module.exports = { + convertYCbCr: convertYCbCr + }; +})(); + +},{"./depower.js":8}],8:[function(require,module,exports){ +/* +Copyright (c) 2014-2016 Brion Vibber + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +MPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +(function() { + "use strict"; + + /** + * Convert a ratio into a bit-shift count; for instance a ratio of 2 + * becomes a bit-shift of 1, while a ratio of 1 is a bit-shift of 0. + * + * @author Brion Vibber + * @copyright 2016 + * @license MIT-style + * + * @param {number} ratio - the integer ratio to convert. + * @returns {number} - number of bits to shift to multiply/divide by the ratio. + * @throws exception if given a non-power-of-two + */ + function depower(ratio) { + var shiftCount = 0, + n = ratio >> 1; + while (n != 0) { + n = n >> 1; + shiftCount++ + } + if (ratio !== (1 << shiftCount)) { + throw 'chroma plane dimensions must be power of 2 ratio to luma plane dimensions; got ' + ratio; + } + return shiftCount; + } + + module.exports = depower; +})(); + +},{}],9:[function(require,module,exports){ +/* +Copyright (c) 2014-2016 Brion Vibber + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +MPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +(function() { + "use strict"; + + var FrameSink = require('./FrameSink.js'), + SoftwareFrameSink = require('./SoftwareFrameSink.js'), + WebGLFrameSink = require('./WebGLFrameSink.js'); + + /** + * @typedef {Object} YUVCanvasOptions + * @property {boolean} webGL - Whether to use WebGL to draw to the canvas and accelerate color space conversion. If left out, defaults to auto-detect. + */ + + var YUVCanvas = { + FrameSink: FrameSink, + + SoftwareFrameSink: SoftwareFrameSink, + + WebGLFrameSink: WebGLFrameSink, + + /** + * Attach a suitable FrameSink instance to an HTML5 canvas element. + * + * This will take over the drawing context of the canvas and may turn + * it into a WebGL 3d canvas if possible. Do not attempt to use the + * drawing context directly after this. + * + * @param {HTMLCanvasElement} canvas - HTML canvas element to attach to + * @param {YUVCanvasOptions} options - map of options + * @returns {FrameSink} - instance of suitable subclass. + */ + attach: function(canvas, options) { + options = options || {}; + var webGL = ('webGL' in options) ? options.webGL : WebGLFrameSink.isAvailable(); + if (webGL) { + return new WebGLFrameSink(canvas, options); + } else { + return new SoftwareFrameSink(canvas, options); + } + } + }; + + module.exports = YUVCanvas; +})(); + +},{"./FrameSink.js":4,"./SoftwareFrameSink.js":5,"./WebGLFrameSink.js":6}]},{},[2]); From 58f2419f2754d72e538bb2d133c6a6178c79c0ce Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 27 Jan 2022 23:32:51 +0800 Subject: [PATCH 29/66] yuv wasm seems slow --- src/connection.ts | 32 ++++++++++++++++---------------- src/globals.js | 28 ++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index c5bb5a067..56f132641 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -143,14 +143,14 @@ export default class Connection { } if (!pk) { // send an empty message out in case server is setting up secure and waiting for first message - await this._ws?.sendMessage({}); + this._ws?.sendMessage({}); return; } const msg = this._ws?.parseMessage(await this._ws?.next()); let signedId: any = msg?.signedId; if (!signedId) { console.error("Handshake failed: invalid message type"); - await this._ws?.sendMessage({}); + this._ws?.sendMessage({}); return; } try { @@ -160,7 +160,7 @@ export default class Connection { // fall back to non-secure connection in case pk mismatch console.error("pk mismatch, fall back to non-secure"); const publicKey = message.PublicKey.fromPartial({}); - await this._ws?.sendMessage({ publicKey }); + this._ws?.sendMessage({ publicKey }); return; } signedId = new TextDecoder().decode(signedId!); @@ -169,7 +169,7 @@ export default class Connection { let theirPk = tmp[1]; if (id != this._id!) { console.error("Handshake failed: sign failure"); - await this._ws?.sendMessage({}); + this._ws?.sendMessage({}); return; } theirPk = globals.decodeBase64(theirPk); @@ -177,7 +177,7 @@ export default class Connection { console.error( "Handshake failed: invalid public box key length from peer" ); - await this._ws?.sendMessage({}); + this._ws?.sendMessage({}); return; } const [mySk, asymmetricValue] = globals.genBoxKeyPair(); @@ -187,7 +187,7 @@ export default class Connection { asymmetricValue, symmetricValue, }); - await this._ws?.sendMessage({ publicKey }); + this._ws?.sendMessage({ publicKey }); this._ws?.setSecretKey(secretKey); return true; } @@ -198,11 +198,11 @@ export default class Connection { if (msg?.hash) { this._hash = msg?.hash; if (!this._password) this.msgbox("input-password", "Password Required", ""); - await this.login(this._password); + this.login(this._password); } else if (msg?.testDelay) { const testDelay = msg?.testDelay; if (!testDelay.fromClient) { - await this._ws?.sendMessage({ testDelay }); + this._ws?.sendMessage({ testDelay }); } } else if (msg?.loginResponse) { const r = msg?.loginResponse; @@ -237,7 +237,7 @@ export default class Connection { this._msgbox?.(type_, title, text); } - draw(frame: Uint8Array) { + draw(frame: any) { this._draw?.(frame); } @@ -249,11 +249,11 @@ export default class Connection { this._audioDecoder?.close(); } - async refresh() { + refresh() { const misc = message.Misc.fromPartial({ refreshVideo: true, }); - await this._ws?.sendMessage({ misc }); + this._ws?.sendMessage({ misc }); } setMsgbox(callback: MsgboxCallback) { @@ -264,7 +264,7 @@ export default class Connection { this._draw = callback; } - async login(password: string | undefined, _remember: Boolean = false) { + login(password: string | undefined, _remember: Boolean = false) { this._password = password; if (password) { const salt = this._hash?.salt; @@ -272,9 +272,9 @@ export default class Connection { const challenge = this._hash?.challenge; p = hash([p, challenge!]); this.msgbox("connecting", "Connecting...", "Logging in..."); - await this._sendLoginMessage(p); + this._sendLoginMessage(p); } else { - await this._sendLoginMessage(); + this._sendLoginMessage(); } } @@ -283,14 +283,14 @@ export default class Connection { await this.start(this._id); } - async _sendLoginMessage(password: Uint8Array | undefined = undefined) { + _sendLoginMessage(password: Uint8Array | undefined = undefined) { const loginRequest = message.LoginRequest.fromPartial({ username: this._id!, myId: "web", // to-do myName: "web", // to-do password, }); - await this._ws?.sendMessage({ loginRequest }); + this._ws?.sendMessage({ loginRequest }); } handleVideoFrame(vf: message.VideoFrame) { diff --git a/src/globals.js b/src/globals.js index 481a05415..2ed654aac 100644 --- a/src/globals.js +++ b/src/globals.js @@ -11,7 +11,11 @@ var currentFrame = undefined; var events = []; window.curConn = undefined; -window.getRgba = () => currentFrame; +window.getRgba = () => { + const tmp = currentFrame; + currentFrame = undefined; + return tmp || null; +} window.getLanguage = () => navigator.language; export function msgbox(type, title, text) { @@ -37,7 +41,7 @@ export function pushEvent(name, payload) { } export function draw(frame) { - currentFrame = frame; + currentFrame = I420ToABGR(frame); } export function setConn(conn) { @@ -276,8 +280,24 @@ window.init = async () => { await initZstd(); } -function I420ToARGB(yuvbuffer) { - // +function I420ToABGR(yb) { + if (!wasmDsp) return null; + const yPtr = wasmDsp._malloc(yb.y.bytes.length); + wasmDsp.HEAPU8.set(yb.y.bytes, yPtr); + const uPtr = wasmDsp._malloc(yb.u.bytes.length); + wasmDsp.HEAPU8.set(yb.u.bytes, uPtr); + const vPtr = wasmDsp._malloc(yb.v.bytes.length); + wasmDsp.HEAPU8.set(yb.v.bytes, vPtr); + const oSize = yb.format.width * yb.format.height * 4; + const outPtr = wasmDsp._malloc(oSize); + const res = wasmDsp._I420ToABGR(yPtr, yb.y.stride, uPtr, yb.u.stride, vPtr, yb.v.stride, outPtr, yb.format.width * 4, + yb.format.width, yb.format.height); + const out = wasmDsp.HEAPU8.slice(outPtr, outPtr + oSize); + wasmDsp._free(yPtr); + wasmDsp._free(uPtr); + wasmDsp._free(vPtr); + wasmDsp._free(outPtr); + return out; } async function initZstd() { From 58415897ae2124e49a7b60b22e2d869bd92a43d3 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 28 Jan 2022 03:53:23 +0800 Subject: [PATCH 30/66] new yuv --- LibYUV.js | 2479 --------------------------------------------- LibYUV.wasm | Bin 18588 -> 0 bytes index.html | 1 - src/connection.ts | 1 + src/globals.js | 79 +- yuv.wasm | Bin 0 -> 8238 bytes 6 files changed, 56 insertions(+), 2504 deletions(-) delete mode 100644 LibYUV.js delete mode 100644 LibYUV.wasm create mode 100755 yuv.wasm diff --git a/LibYUV.js b/LibYUV.js deleted file mode 100644 index 010d17bbc..000000000 --- a/LibYUV.js +++ /dev/null @@ -1,2479 +0,0 @@ - -var LibYUV = (function() { - var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; - if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; - return ( -function(LibYUV) { - LibYUV = LibYUV || {}; - - -// The Module object: Our interface to the outside world. We import -// and export values on it. There are various ways Module can be used: -// 1. Not defined. We create it here -// 2. A function parameter, function(Module) { ..generated code.. } -// 3. pre-run appended it, var Module = {}; ..generated code.. -// 4. External script tag defines var Module. -// We need to check if Module already exists (e.g. case 3 above). -// Substitution will be replaced with actual code on later stage of the build, -// this way Closure Compiler will not mangle it (e.g. case 4. above). -// Note that if you want to run closure, and also to use Module -// after the generated code, you will need to define var Module = {}; -// before the code. Then that object will be used in the code, and you -// can continue to use Module afterwards as well. -var Module = typeof LibYUV !== 'undefined' ? LibYUV : {}; - -// Set up the promise that indicates the Module is initialized -var readyPromiseResolve, readyPromiseReject; -Module['ready'] = new Promise(function(resolve, reject) { - readyPromiseResolve = resolve; - readyPromiseReject = reject; -}); - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_malloc')) { - Object.defineProperty(Module['ready'], '_malloc', { configurable: true, get: function() { abort('You are getting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_malloc', { configurable: true, set: function() { abort('You are setting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_free')) { - Object.defineProperty(Module['ready'], '_free', { configurable: true, get: function() { abort('You are getting _free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_free', { configurable: true, set: function() { abort('You are setting _free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_ConvertRGBA88882YUV420P')) { - Object.defineProperty(Module['ready'], '_ConvertRGBA88882YUV420P', { configurable: true, get: function() { abort('You are getting _ConvertRGBA88882YUV420P on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_ConvertRGBA88882YUV420P', { configurable: true, set: function() { abort('You are setting _ConvertRGBA88882YUV420P on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_ConvertYUV420P2RGBA8888')) { - Object.defineProperty(Module['ready'], '_ConvertYUV420P2RGBA8888', { configurable: true, get: function() { abort('You are getting _ConvertYUV420P2RGBA8888 on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_ConvertYUV420P2RGBA8888', { configurable: true, set: function() { abort('You are setting _ConvertYUV420P2RGBA8888 on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_I420ToABGR')) { - Object.defineProperty(Module['ready'], '_I420ToABGR', { configurable: true, get: function() { abort('You are getting _I420ToABGR on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_I420ToABGR', { configurable: true, set: function() { abort('You are setting _I420ToABGR on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_ABGRToI420')) { - Object.defineProperty(Module['ready'], '_ABGRToI420', { configurable: true, get: function() { abort('You are getting _ABGRToI420 on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_ABGRToI420', { configurable: true, set: function() { abort('You are setting _ABGRToI420 on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_get_end')) { - Object.defineProperty(Module['ready'], '_emscripten_stack_get_end', { configurable: true, get: function() { abort('You are getting _emscripten_stack_get_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_emscripten_stack_get_end', { configurable: true, set: function() { abort('You are setting _emscripten_stack_get_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_get_free')) { - Object.defineProperty(Module['ready'], '_emscripten_stack_get_free', { configurable: true, get: function() { abort('You are getting _emscripten_stack_get_free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_emscripten_stack_get_free', { configurable: true, set: function() { abort('You are setting _emscripten_stack_get_free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_init')) { - Object.defineProperty(Module['ready'], '_emscripten_stack_init', { configurable: true, get: function() { abort('You are getting _emscripten_stack_init on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_emscripten_stack_init', { configurable: true, set: function() { abort('You are setting _emscripten_stack_init on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_emscripten_stack_get_base')) { - Object.defineProperty(Module['ready'], '_emscripten_stack_get_base', { configurable: true, get: function() { abort('You are getting _emscripten_stack_get_base on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_emscripten_stack_get_base', { configurable: true, set: function() { abort('You are setting _emscripten_stack_get_base on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackSave')) { - Object.defineProperty(Module['ready'], '_stackSave', { configurable: true, get: function() { abort('You are getting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_stackSave', { configurable: true, set: function() { abort('You are setting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackRestore')) { - Object.defineProperty(Module['ready'], '_stackRestore', { configurable: true, get: function() { abort('You are getting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_stackRestore', { configurable: true, set: function() { abort('You are setting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_stackAlloc')) { - Object.defineProperty(Module['ready'], '_stackAlloc', { configurable: true, get: function() { abort('You are getting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_stackAlloc', { configurable: true, set: function() { abort('You are setting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '___wasm_call_ctors')) { - Object.defineProperty(Module['ready'], '___wasm_call_ctors', { configurable: true, get: function() { abort('You are getting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '___wasm_call_ctors', { configurable: true, set: function() { abort('You are setting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '_fflush')) { - Object.defineProperty(Module['ready'], '_fflush', { configurable: true, get: function() { abort('You are getting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '_fflush', { configurable: true, set: function() { abort('You are setting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], '___errno_location')) { - Object.defineProperty(Module['ready'], '___errno_location', { configurable: true, get: function() { abort('You are getting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], '___errno_location', { configurable: true, set: function() { abort('You are setting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - - if (!Object.getOwnPropertyDescriptor(Module['ready'], 'onRuntimeInitialized')) { - Object.defineProperty(Module['ready'], 'onRuntimeInitialized', { configurable: true, get: function() { abort('You are getting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - Object.defineProperty(Module['ready'], 'onRuntimeInitialized', { configurable: true, set: function() { abort('You are setting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js') } }); - } - - -// --pre-jses are emitted after the Module integration code, so that they can -// refer to Module (if they choose; they can also define Module) -// {{PRE_JSES}} - -// Sometimes an existing Module object exists with properties -// meant to overwrite the default module functionality. Here -// we collect those properties and reapply _after_ we configure -// the current environment's defaults to avoid having to be so -// defensive during initialization. -var moduleOverrides = {}; -var key; -for (key in Module) { - if (Module.hasOwnProperty(key)) { - moduleOverrides[key] = Module[key]; - } -} - -var arguments_ = []; -var thisProgram = './this.program'; -var quit_ = function(status, toThrow) { - throw toThrow; -}; - -// Determine the runtime environment we are in. You can customize this by -// setting the ENVIRONMENT setting at compile time (see settings.js). - -var ENVIRONMENT_IS_WEB = false; -var ENVIRONMENT_IS_WORKER = false; -var ENVIRONMENT_IS_NODE = false; -var ENVIRONMENT_IS_SHELL = false; -ENVIRONMENT_IS_WEB = typeof window === 'object'; -ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; -// N.b. Electron.js environment is simultaneously a NODE-environment, but -// also a web environment. -ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string'; -ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; - -if (Module['ENVIRONMENT']) { - throw new Error('Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)'); -} - -// `/` should be present at the end if `scriptDirectory` is not empty -var scriptDirectory = ''; -function locateFile(path) { - if (Module['locateFile']) { - return Module['locateFile'](path, scriptDirectory); - } - return scriptDirectory + path; -} - -// Hooks that are implemented differently in different runtime environments. -var read_, - readAsync, - readBinary, - setWindowTitle; - -var nodeFS; -var nodePath; - -if (ENVIRONMENT_IS_NODE) { - if (ENVIRONMENT_IS_WORKER) { - scriptDirectory = require('path').dirname(scriptDirectory) + '/'; - } else { - scriptDirectory = __dirname + '/'; - } - -// include: node_shell_read.js - - -read_ = function shell_read(filename, binary) { - if (!nodeFS) nodeFS = require('fs'); - if (!nodePath) nodePath = require('path'); - filename = nodePath['normalize'](filename); - return nodeFS['readFileSync'](filename, binary ? null : 'utf8'); -}; - -readBinary = function readBinary(filename) { - var ret = read_(filename, true); - if (!ret.buffer) { - ret = new Uint8Array(ret); - } - assert(ret.buffer); - return ret; -}; - -// end include: node_shell_read.js - if (process['argv'].length > 1) { - thisProgram = process['argv'][1].replace(/\\/g, '/'); - } - - arguments_ = process['argv'].slice(2); - - // MODULARIZE will export the module in the proper place outside, we don't need to export here - - process['on']('uncaughtException', function(ex) { - // suppress ExitStatus exceptions from showing an error - if (!(ex instanceof ExitStatus)) { - throw ex; - } - }); - - process['on']('unhandledRejection', abort); - - quit_ = function(status) { - process['exit'](status); - }; - - Module['inspect'] = function () { return '[Emscripten Module object]'; }; - -} else -if (ENVIRONMENT_IS_SHELL) { - - if (typeof read != 'undefined') { - read_ = function shell_read(f) { - return read(f); - }; - } - - readBinary = function readBinary(f) { - var data; - if (typeof readbuffer === 'function') { - return new Uint8Array(readbuffer(f)); - } - data = read(f, 'binary'); - assert(typeof data === 'object'); - return data; - }; - - if (typeof scriptArgs != 'undefined') { - arguments_ = scriptArgs; - } else if (typeof arguments != 'undefined') { - arguments_ = arguments; - } - - if (typeof quit === 'function') { - quit_ = function(status) { - quit(status); - }; - } - - if (typeof print !== 'undefined') { - // Prefer to use print/printErr where they exist, as they usually work better. - if (typeof console === 'undefined') console = /** @type{!Console} */({}); - console.log = /** @type{!function(this:Console, ...*): undefined} */ (print); - console.warn = console.error = /** @type{!function(this:Console, ...*): undefined} */ (typeof printErr !== 'undefined' ? printErr : print); - } - -} else - -// Note that this includes Node.js workers when relevant (pthreads is enabled). -// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and -// ENVIRONMENT_IS_NODE. -if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) { - if (ENVIRONMENT_IS_WORKER) { // Check worker, not web, since window could be polyfilled - scriptDirectory = self.location.href; - } else if (typeof document !== 'undefined' && document.currentScript) { // web - scriptDirectory = document.currentScript.src; - } - // When MODULARIZE, this JS may be executed later, after document.currentScript - // is gone, so we saved it, and we use it here instead of any other info. - if (_scriptDir) { - scriptDirectory = _scriptDir; - } - // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them. - // otherwise, slice off the final part of the url to find the script directory. - // if scriptDirectory does not contain a slash, lastIndexOf will return -1, - // and scriptDirectory will correctly be replaced with an empty string. - if (scriptDirectory.indexOf('blob:') !== 0) { - scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf('/')+1); - } else { - scriptDirectory = ''; - } - - // Differentiate the Web Worker from the Node Worker case, as reading must - // be done differently. - { - -// include: web_or_worker_shell_read.js - - - read_ = function(url) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - xhr.send(null); - return xhr.responseText; - }; - - if (ENVIRONMENT_IS_WORKER) { - readBinary = function(url) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, false); - xhr.responseType = 'arraybuffer'; - xhr.send(null); - return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response)); - }; - } - - readAsync = function(url, onload, onerror) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.responseType = 'arraybuffer'; - xhr.onload = function() { - if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0 - onload(xhr.response); - return; - } - onerror(); - }; - xhr.onerror = onerror; - xhr.send(null); - }; - -// end include: web_or_worker_shell_read.js - } - - setWindowTitle = function(title) { document.title = title }; -} else -{ - throw new Error('environment detection error'); -} - -// Set up the out() and err() hooks, which are how we can print to stdout or -// stderr, respectively. -var out = Module['print'] || console.log.bind(console); -var err = Module['printErr'] || console.warn.bind(console); - -// Merge back in the overrides -for (key in moduleOverrides) { - if (moduleOverrides.hasOwnProperty(key)) { - Module[key] = moduleOverrides[key]; - } -} -// Free the object hierarchy contained in the overrides, this lets the GC -// reclaim data used e.g. in memoryInitializerRequest, which is a large typed array. -moduleOverrides = null; - -// Emit code to handle expected values on the Module object. This applies Module.x -// to the proper local x. This has two benefits: first, we only emit it if it is -// expected to arrive, and second, by using a local everywhere else that can be -// minified. - -if (Module['arguments']) arguments_ = Module['arguments']; -if (!Object.getOwnPropertyDescriptor(Module, 'arguments')) { - Object.defineProperty(Module, 'arguments', { - configurable: true, - get: function() { - abort('Module.arguments has been replaced with plain arguments_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') - } - }); -} - -if (Module['thisProgram']) thisProgram = Module['thisProgram']; -if (!Object.getOwnPropertyDescriptor(Module, 'thisProgram')) { - Object.defineProperty(Module, 'thisProgram', { - configurable: true, - get: function() { - abort('Module.thisProgram has been replaced with plain thisProgram (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') - } - }); -} - -if (Module['quit']) quit_ = Module['quit']; -if (!Object.getOwnPropertyDescriptor(Module, 'quit')) { - Object.defineProperty(Module, 'quit', { - configurable: true, - get: function() { - abort('Module.quit has been replaced with plain quit_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') - } - }); -} - -// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message -// Assertions on removed incoming Module JS APIs. -assert(typeof Module['memoryInitializerPrefixURL'] === 'undefined', 'Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead'); -assert(typeof Module['pthreadMainPrefixURL'] === 'undefined', 'Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead'); -assert(typeof Module['cdInitializerPrefixURL'] === 'undefined', 'Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead'); -assert(typeof Module['filePackagePrefixURL'] === 'undefined', 'Module.filePackagePrefixURL option was removed, use Module.locateFile instead'); -assert(typeof Module['read'] === 'undefined', 'Module.read option was removed (modify read_ in JS)'); -assert(typeof Module['readAsync'] === 'undefined', 'Module.readAsync option was removed (modify readAsync in JS)'); -assert(typeof Module['readBinary'] === 'undefined', 'Module.readBinary option was removed (modify readBinary in JS)'); -assert(typeof Module['setWindowTitle'] === 'undefined', 'Module.setWindowTitle option was removed (modify setWindowTitle in JS)'); -assert(typeof Module['TOTAL_MEMORY'] === 'undefined', 'Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY'); - -if (!Object.getOwnPropertyDescriptor(Module, 'read')) { - Object.defineProperty(Module, 'read', { - configurable: true, - get: function() { - abort('Module.read has been replaced with plain read_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') - } - }); -} - -if (!Object.getOwnPropertyDescriptor(Module, 'readAsync')) { - Object.defineProperty(Module, 'readAsync', { - configurable: true, - get: function() { - abort('Module.readAsync has been replaced with plain readAsync (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') - } - }); -} - -if (!Object.getOwnPropertyDescriptor(Module, 'readBinary')) { - Object.defineProperty(Module, 'readBinary', { - configurable: true, - get: function() { - abort('Module.readBinary has been replaced with plain readBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') - } - }); -} - -if (!Object.getOwnPropertyDescriptor(Module, 'setWindowTitle')) { - Object.defineProperty(Module, 'setWindowTitle', { - configurable: true, - get: function() { - abort('Module.setWindowTitle has been replaced with plain setWindowTitle (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') - } - }); -} -var IDBFS = 'IDBFS is no longer included by default; build with -lidbfs.js'; -var PROXYFS = 'PROXYFS is no longer included by default; build with -lproxyfs.js'; -var WORKERFS = 'WORKERFS is no longer included by default; build with -lworkerfs.js'; -var NODEFS = 'NODEFS is no longer included by default; build with -lnodefs.js'; - - - - -var STACK_ALIGN = 16; - -function alignMemory(size, factor) { - if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default - return Math.ceil(size / factor) * factor; -} - -function getNativeTypeSize(type) { - switch (type) { - case 'i1': case 'i8': return 1; - case 'i16': return 2; - case 'i32': return 4; - case 'i64': return 8; - case 'float': return 4; - case 'double': return 8; - default: { - if (type[type.length-1] === '*') { - return 4; // A pointer - } else if (type[0] === 'i') { - var bits = Number(type.substr(1)); - assert(bits % 8 === 0, 'getNativeTypeSize invalid bits ' + bits + ', type ' + type); - return bits / 8; - } else { - return 0; - } - } - } -} - -function warnOnce(text) { - if (!warnOnce.shown) warnOnce.shown = {}; - if (!warnOnce.shown[text]) { - warnOnce.shown[text] = 1; - err(text); - } -} - -// include: runtime_functions.js - - -// Wraps a JS function as a wasm function with a given signature. -function convertJsFunctionToWasm(func, sig) { - - // If the type reflection proposal is available, use the new - // "WebAssembly.Function" constructor. - // Otherwise, construct a minimal wasm module importing the JS function and - // re-exporting it. - if (typeof WebAssembly.Function === "function") { - var typeNames = { - 'i': 'i32', - 'j': 'i64', - 'f': 'f32', - 'd': 'f64' - }; - var type = { - parameters: [], - results: sig[0] == 'v' ? [] : [typeNames[sig[0]]] - }; - for (var i = 1; i < sig.length; ++i) { - type.parameters.push(typeNames[sig[i]]); - } - return new WebAssembly.Function(type, func); - } - - // The module is static, with the exception of the type section, which is - // generated based on the signature passed in. - var typeSection = [ - 0x01, // id: section, - 0x00, // length: 0 (placeholder) - 0x01, // count: 1 - 0x60, // form: func - ]; - var sigRet = sig.slice(0, 1); - var sigParam = sig.slice(1); - var typeCodes = { - 'i': 0x7f, // i32 - 'j': 0x7e, // i64 - 'f': 0x7d, // f32 - 'd': 0x7c, // f64 - }; - - // Parameters, length + signatures - typeSection.push(sigParam.length); - for (var i = 0; i < sigParam.length; ++i) { - typeSection.push(typeCodes[sigParam[i]]); - } - - // Return values, length + signatures - // With no multi-return in MVP, either 0 (void) or 1 (anything else) - if (sigRet == 'v') { - typeSection.push(0x00); - } else { - typeSection = typeSection.concat([0x01, typeCodes[sigRet]]); - } - - // Write the overall length of the type section back into the section header - // (excepting the 2 bytes for the section id and length) - typeSection[1] = typeSection.length - 2; - - // Rest of the module is static - var bytes = new Uint8Array([ - 0x00, 0x61, 0x73, 0x6d, // magic ("\0asm") - 0x01, 0x00, 0x00, 0x00, // version: 1 - ].concat(typeSection, [ - 0x02, 0x07, // import section - // (import "e" "f" (func 0 (type 0))) - 0x01, 0x01, 0x65, 0x01, 0x66, 0x00, 0x00, - 0x07, 0x05, // export section - // (export "f" (func 0 (type 0))) - 0x01, 0x01, 0x66, 0x00, 0x00, - ])); - - // We can compile this wasm module synchronously because it is very small. - // This accepts an import (at "e.f"), that it reroutes to an export (at "f") - var module = new WebAssembly.Module(bytes); - var instance = new WebAssembly.Instance(module, { - 'e': { - 'f': func - } - }); - var wrappedFunc = instance.exports['f']; - return wrappedFunc; -} - -var freeTableIndexes = []; - -// Weak map of functions in the table to their indexes, created on first use. -var functionsInTableMap; - -function getEmptyTableSlot() { - // Reuse a free index if there is one, otherwise grow. - if (freeTableIndexes.length) { - return freeTableIndexes.pop(); - } - // Grow the table - try { - wasmTable.grow(1); - } catch (err) { - if (!(err instanceof RangeError)) { - throw err; - } - throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.'; - } - return wasmTable.length - 1; -} - -// Add a wasm function to the table. -function addFunctionWasm(func, sig) { - // Check if the function is already in the table, to ensure each function - // gets a unique index. First, create the map if this is the first use. - if (!functionsInTableMap) { - functionsInTableMap = new WeakMap(); - for (var i = 0; i < wasmTable.length; i++) { - var item = wasmTable.get(i); - // Ignore null values. - if (item) { - functionsInTableMap.set(item, i); - } - } - } - if (functionsInTableMap.has(func)) { - return functionsInTableMap.get(func); - } - - // It's not in the table, add it now. - - // Make sure functionsInTableMap is actually up to date, that is, that this - // function is not actually in the wasm Table despite not being tracked in - // functionsInTableMap. - for (var i = 0; i < wasmTable.length; i++) { - assert(wasmTable.get(i) != func, 'function in Table but not functionsInTableMap'); - } - - var ret = getEmptyTableSlot(); - - // Set the new value. - try { - // Attempting to call this with JS function will cause of table.set() to fail - wasmTable.set(ret, func); - } catch (err) { - if (!(err instanceof TypeError)) { - throw err; - } - assert(typeof sig !== 'undefined', 'Missing signature argument to addFunction: ' + func); - var wrapped = convertJsFunctionToWasm(func, sig); - wasmTable.set(ret, wrapped); - } - - functionsInTableMap.set(func, ret); - - return ret; -} - -function removeFunction(index) { - functionsInTableMap.delete(wasmTable.get(index)); - freeTableIndexes.push(index); -} - -// 'sig' parameter is required for the llvm backend but only when func is not -// already a WebAssembly function. -function addFunction(func, sig) { - assert(typeof func !== 'undefined'); - if (typeof sig === 'undefined') { - err('warning: addFunction(): You should provide a wasm function signature string as a second argument. This is not necessary for asm.js and asm2wasm, but can be required for the LLVM wasm backend, so it is recommended for full portability.'); - } - - return addFunctionWasm(func, sig); -} - -// end include: runtime_functions.js -// include: runtime_debug.js - - -// end include: runtime_debug.js -function makeBigInt(low, high, unsigned) { - return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0)); -} - -var tempRet0 = 0; - -var setTempRet0 = function(value) { - tempRet0 = value; -}; - -var getTempRet0 = function() { - return tempRet0; -}; - -function getCompilerSetting(name) { - throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for getCompilerSetting or emscripten_get_compiler_setting to work'; -} - - - -// === Preamble library stuff === - -// Documentation for the public APIs defined in this file must be updated in: -// site/source/docs/api_reference/preamble.js.rst -// A prebuilt local version of the documentation is available at: -// site/build/text/docs/api_reference/preamble.js.txt -// You can also build docs locally as HTML or other formats in site/ -// An online HTML version (which may be of a different version of Emscripten) -// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html - -var wasmBinary; -if (Module['wasmBinary']) wasmBinary = Module['wasmBinary']; -if (!Object.getOwnPropertyDescriptor(Module, 'wasmBinary')) { - Object.defineProperty(Module, 'wasmBinary', { - configurable: true, - get: function() { - abort('Module.wasmBinary has been replaced with plain wasmBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') - } - }); -} -var noExitRuntime = Module['noExitRuntime'] || true; -if (!Object.getOwnPropertyDescriptor(Module, 'noExitRuntime')) { - Object.defineProperty(Module, 'noExitRuntime', { - configurable: true, - get: function() { - abort('Module.noExitRuntime has been replaced with plain noExitRuntime (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') - } - }); -} - -if (typeof WebAssembly !== 'object') { - abort('no native wasm support detected'); -} - -// include: runtime_safe_heap.js - - -// In MINIMAL_RUNTIME, setValue() and getValue() are only available when building with safe heap enabled, for heap safety checking. -// In traditional runtime, setValue() and getValue() are always available (although their use is highly discouraged due to perf penalties) - -/** @param {number} ptr - @param {number} value - @param {string} type - @param {number|boolean=} noSafe */ -function setValue(ptr, value, type, noSafe) { - type = type || 'i8'; - if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit - switch(type) { - case 'i1': HEAP8[((ptr)>>0)] = value; break; - case 'i8': HEAP8[((ptr)>>0)] = value; break; - case 'i16': HEAP16[((ptr)>>1)] = value; break; - case 'i32': HEAP32[((ptr)>>2)] = value; break; - case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math.abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math.min((+(Math.floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math.ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)] = tempI64[0],HEAP32[(((ptr)+(4))>>2)] = tempI64[1]); break; - case 'float': HEAPF32[((ptr)>>2)] = value; break; - case 'double': HEAPF64[((ptr)>>3)] = value; break; - default: abort('invalid type for setValue: ' + type); - } -} - -/** @param {number} ptr - @param {string} type - @param {number|boolean=} noSafe */ -function getValue(ptr, type, noSafe) { - type = type || 'i8'; - if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit - switch(type) { - case 'i1': return HEAP8[((ptr)>>0)]; - case 'i8': return HEAP8[((ptr)>>0)]; - case 'i16': return HEAP16[((ptr)>>1)]; - case 'i32': return HEAP32[((ptr)>>2)]; - case 'i64': return HEAP32[((ptr)>>2)]; - case 'float': return HEAPF32[((ptr)>>2)]; - case 'double': return HEAPF64[((ptr)>>3)]; - default: abort('invalid type for getValue: ' + type); - } - return null; -} - -// end include: runtime_safe_heap.js -// Wasm globals - -var wasmMemory; - -//======================================== -// Runtime essentials -//======================================== - -// whether we are quitting the application. no code should run after this. -// set in exit() and abort() -var ABORT = false; - -// set by exit() and abort(). Passed to 'onExit' handler. -// NOTE: This is also used as the process return code code in shell environments -// but only when noExitRuntime is false. -var EXITSTATUS; - -/** @type {function(*, string=)} */ -function assert(condition, text) { - if (!condition) { - abort('Assertion failed: ' + text); - } -} - -// Returns the C function with a specified identifier (for C++, you need to do manual name mangling) -function getCFunc(ident) { - var func = Module['_' + ident]; // closure exported function - assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported'); - return func; -} - -// C calling interface. -/** @param {string|null=} returnType - @param {Array=} argTypes - @param {Arguments|Array=} args - @param {Object=} opts */ -function ccall(ident, returnType, argTypes, args, opts) { - // For fast lookup of conversion functions - var toC = { - 'string': function(str) { - var ret = 0; - if (str !== null && str !== undefined && str !== 0) { // null string - // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0' - var len = (str.length << 2) + 1; - ret = stackAlloc(len); - stringToUTF8(str, ret, len); - } - return ret; - }, - 'array': function(arr) { - var ret = stackAlloc(arr.length); - writeArrayToMemory(arr, ret); - return ret; - } - }; - - function convertReturnValue(ret) { - if (returnType === 'string') return UTF8ToString(ret); - if (returnType === 'boolean') return Boolean(ret); - return ret; - } - - var func = getCFunc(ident); - var cArgs = []; - var stack = 0; - assert(returnType !== 'array', 'Return type should not be "array".'); - if (args) { - for (var i = 0; i < args.length; i++) { - var converter = toC[argTypes[i]]; - if (converter) { - if (stack === 0) stack = stackSave(); - cArgs[i] = converter(args[i]); - } else { - cArgs[i] = args[i]; - } - } - } - var ret = func.apply(null, cArgs); - - ret = convertReturnValue(ret); - if (stack !== 0) stackRestore(stack); - return ret; -} - -/** @param {string=} returnType - @param {Array=} argTypes - @param {Object=} opts */ -function cwrap(ident, returnType, argTypes, opts) { - return function() { - return ccall(ident, returnType, argTypes, arguments, opts); - } -} - -// We used to include malloc/free by default in the past. Show a helpful error in -// builds with assertions. - -var ALLOC_NORMAL = 0; // Tries to use _malloc() -var ALLOC_STACK = 1; // Lives for the duration of the current function call - -// allocate(): This is for internal use. You can use it yourself as well, but the interface -// is a little tricky (see docs right below). The reason is that it is optimized -// for multiple syntaxes to save space in generated code. So you should -// normally not use allocate(), and instead allocate memory using _malloc(), -// initialize it with setValue(), and so forth. -// @slab: An array of data. -// @allocator: How to allocate memory, see ALLOC_* -/** @type {function((Uint8Array|Array), number)} */ -function allocate(slab, allocator) { - var ret; - assert(typeof allocator === 'number', 'allocate no longer takes a type argument') - assert(typeof slab !== 'number', 'allocate no longer takes a number as arg0') - - if (allocator == ALLOC_STACK) { - ret = stackAlloc(slab.length); - } else { - ret = _malloc(slab.length); - } - - if (slab.subarray || slab.slice) { - HEAPU8.set(/** @type {!Uint8Array} */(slab), ret); - } else { - HEAPU8.set(new Uint8Array(slab), ret); - } - return ret; -} - -// include: runtime_strings.js - - -// runtime_strings.js: Strings related runtime functions that are part of both MINIMAL_RUNTIME and regular runtime. - -// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns -// a copy of that string as a Javascript String object. - -var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined; - -/** - * @param {number} idx - * @param {number=} maxBytesToRead - * @return {string} - */ -function UTF8ArrayToString(heap, idx, maxBytesToRead) { - var endIdx = idx + maxBytesToRead; - var endPtr = idx; - // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself. - // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage. - // (As a tiny code save trick, compare endPtr against endIdx using a negation, so that undefined means Infinity) - while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr; - - if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) { - return UTF8Decoder.decode(heap.subarray(idx, endPtr)); - } else { - var str = ''; - // If building with TextDecoder, we have already computed the string length above, so test loop end condition against that - while (idx < endPtr) { - // For UTF8 byte structure, see: - // http://en.wikipedia.org/wiki/UTF-8#Description - // https://www.ietf.org/rfc/rfc2279.txt - // https://tools.ietf.org/html/rfc3629 - var u0 = heap[idx++]; - if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; } - var u1 = heap[idx++] & 63; - if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; } - var u2 = heap[idx++] & 63; - if ((u0 & 0xF0) == 0xE0) { - u0 = ((u0 & 15) << 12) | (u1 << 6) | u2; - } else { - if ((u0 & 0xF8) != 0xF0) warnOnce('Invalid UTF-8 leading byte 0x' + u0.toString(16) + ' encountered when deserializing a UTF-8 string in wasm memory to a JS string!'); - u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[idx++] & 63); - } - - if (u0 < 0x10000) { - str += String.fromCharCode(u0); - } else { - var ch = u0 - 0x10000; - str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); - } - } - } - return str; -} - -// Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns a -// copy of that string as a Javascript String object. -// maxBytesToRead: an optional length that specifies the maximum number of bytes to read. You can omit -// this parameter to scan the string until the first \0 byte. If maxBytesToRead is -// passed, and the string at [ptr, ptr+maxBytesToReadr[ contains a null byte in the -// middle, then the string will cut short at that byte index (i.e. maxBytesToRead will -// not produce a string of exact length [ptr, ptr+maxBytesToRead[) -// N.B. mixing frequent uses of UTF8ToString() with and without maxBytesToRead may -// throw JS JIT optimizations off, so it is worth to consider consistently using one -// style or the other. -/** - * @param {number} ptr - * @param {number=} maxBytesToRead - * @return {string} - */ -function UTF8ToString(ptr, maxBytesToRead) { - return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : ''; -} - -// Copies the given Javascript String object 'str' to the given byte array at address 'outIdx', -// encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP. -// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. -// Parameters: -// str: the Javascript string to copy. -// heap: the array to copy to. Each index in this array is assumed to be one 8-byte element. -// outIdx: The starting offset in the array to begin the copying. -// maxBytesToWrite: The maximum number of bytes this function can write to the array. -// This count should include the null terminator, -// i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else. -// maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) { - if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes. - return 0; - - var startIdx = outIdx; - var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator. - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629 - var u = str.charCodeAt(i); // possibly a lead surrogate - if (u >= 0xD800 && u <= 0xDFFF) { - var u1 = str.charCodeAt(++i); - u = 0x10000 + ((u & 0x3FF) << 10) | (u1 & 0x3FF); - } - if (u <= 0x7F) { - if (outIdx >= endIdx) break; - heap[outIdx++] = u; - } else if (u <= 0x7FF) { - if (outIdx + 1 >= endIdx) break; - heap[outIdx++] = 0xC0 | (u >> 6); - heap[outIdx++] = 0x80 | (u & 63); - } else if (u <= 0xFFFF) { - if (outIdx + 2 >= endIdx) break; - heap[outIdx++] = 0xE0 | (u >> 12); - heap[outIdx++] = 0x80 | ((u >> 6) & 63); - heap[outIdx++] = 0x80 | (u & 63); - } else { - if (outIdx + 3 >= endIdx) break; - if (u >= 0x200000) warnOnce('Invalid Unicode code point 0x' + u.toString(16) + ' encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x1FFFFF).'); - heap[outIdx++] = 0xF0 | (u >> 18); - heap[outIdx++] = 0x80 | ((u >> 12) & 63); - heap[outIdx++] = 0x80 | ((u >> 6) & 63); - heap[outIdx++] = 0x80 | (u & 63); - } - } - // Null-terminate the pointer to the buffer. - heap[outIdx] = 0; - return outIdx - startIdx; -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP. -// Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF8(str, outPtr, maxBytesToWrite) { - assert(typeof maxBytesToWrite == 'number', 'stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite); -} - -// Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte. -function lengthBytesUTF8(str) { - var len = 0; - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - var u = str.charCodeAt(i); // possibly a lead surrogate - if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); - if (u <= 0x7F) ++len; - else if (u <= 0x7FF) len += 2; - else if (u <= 0xFFFF) len += 3; - else len += 4; - } - return len; -} - -// end include: runtime_strings.js -// include: runtime_strings_extra.js - - -// runtime_strings_extra.js: Strings related runtime functions that are available only in regular runtime. - -// Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns -// a copy of that string as a Javascript String object. - -function AsciiToString(ptr) { - var str = ''; - while (1) { - var ch = HEAPU8[((ptr++)>>0)]; - if (!ch) return str; - str += String.fromCharCode(ch); - } -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP. - -function stringToAscii(str, outPtr) { - return writeAsciiToMemory(str, outPtr, false); -} - -// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns -// a copy of that string as a Javascript String object. - -var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined; - -function UTF16ToString(ptr, maxBytesToRead) { - assert(ptr % 2 == 0, 'Pointer passed to UTF16ToString must be aligned to two bytes!'); - var endPtr = ptr; - // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself. - // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage. - var idx = endPtr >> 1; - var maxIdx = idx + maxBytesToRead / 2; - // If maxBytesToRead is not passed explicitly, it will be undefined, and this - // will always evaluate to true. This saves on code size. - while (!(idx >= maxIdx) && HEAPU16[idx]) ++idx; - endPtr = idx << 1; - - if (endPtr - ptr > 32 && UTF16Decoder) { - return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr)); - } else { - var str = ''; - - // If maxBytesToRead is not passed explicitly, it will be undefined, and the for-loop's condition - // will always evaluate to true. The loop is then terminated on the first null char. - for (var i = 0; !(i >= maxBytesToRead / 2); ++i) { - var codeUnit = HEAP16[(((ptr)+(i*2))>>1)]; - if (codeUnit == 0) break; - // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through. - str += String.fromCharCode(codeUnit); - } - - return str; - } -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP. -// Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write. -// Parameters: -// str: the Javascript string to copy. -// outPtr: Byte address in Emscripten HEAP where to write the string to. -// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null -// terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else. -// maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF16(str, outPtr, maxBytesToWrite) { - assert(outPtr % 2 == 0, 'Pointer passed to stringToUTF16 must be aligned to two bytes!'); - assert(typeof maxBytesToWrite == 'number', 'stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. - if (maxBytesToWrite === undefined) { - maxBytesToWrite = 0x7FFFFFFF; - } - if (maxBytesToWrite < 2) return 0; - maxBytesToWrite -= 2; // Null terminator. - var startPtr = outPtr; - var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length; - for (var i = 0; i < numCharsToWrite; ++i) { - // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP. - var codeUnit = str.charCodeAt(i); // possibly a lead surrogate - HEAP16[((outPtr)>>1)] = codeUnit; - outPtr += 2; - } - // Null-terminate the pointer to the HEAP. - HEAP16[((outPtr)>>1)] = 0; - return outPtr - startPtr; -} - -// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte. - -function lengthBytesUTF16(str) { - return str.length*2; -} - -function UTF32ToString(ptr, maxBytesToRead) { - assert(ptr % 4 == 0, 'Pointer passed to UTF32ToString must be aligned to four bytes!'); - var i = 0; - - var str = ''; - // If maxBytesToRead is not passed explicitly, it will be undefined, and this - // will always evaluate to true. This saves on code size. - while (!(i >= maxBytesToRead / 4)) { - var utf32 = HEAP32[(((ptr)+(i*4))>>2)]; - if (utf32 == 0) break; - ++i; - // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - if (utf32 >= 0x10000) { - var ch = utf32 - 0x10000; - str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF)); - } else { - str += String.fromCharCode(utf32); - } - } - return str; -} - -// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr', -// null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP. -// Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write. -// Parameters: -// str: the Javascript string to copy. -// outPtr: Byte address in Emscripten HEAP where to write the string to. -// maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null -// terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else. -// maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator. -// Returns the number of bytes written, EXCLUDING the null terminator. - -function stringToUTF32(str, outPtr, maxBytesToWrite) { - assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!'); - assert(typeof maxBytesToWrite == 'number', 'stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!'); - // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed. - if (maxBytesToWrite === undefined) { - maxBytesToWrite = 0x7FFFFFFF; - } - if (maxBytesToWrite < 4) return 0; - var startPtr = outPtr; - var endPtr = startPtr + maxBytesToWrite - 4; - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - var codeUnit = str.charCodeAt(i); // possibly a lead surrogate - if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) { - var trailSurrogate = str.charCodeAt(++i); - codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF); - } - HEAP32[((outPtr)>>2)] = codeUnit; - outPtr += 4; - if (outPtr + 4 > endPtr) break; - } - // Null-terminate the pointer to the HEAP. - HEAP32[((outPtr)>>2)] = 0; - return outPtr - startPtr; -} - -// Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte. - -function lengthBytesUTF32(str) { - var len = 0; - for (var i = 0; i < str.length; ++i) { - // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap. - // See http://unicode.org/faq/utf_bom.html#utf16-3 - var codeUnit = str.charCodeAt(i); - if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate. - len += 4; - } - - return len; -} - -// Allocate heap space for a JS string, and write it there. -// It is the responsibility of the caller to free() that memory. -function allocateUTF8(str) { - var size = lengthBytesUTF8(str) + 1; - var ret = _malloc(size); - if (ret) stringToUTF8Array(str, HEAP8, ret, size); - return ret; -} - -// Allocate stack space for a JS string, and write it there. -function allocateUTF8OnStack(str) { - var size = lengthBytesUTF8(str) + 1; - var ret = stackAlloc(size); - stringToUTF8Array(str, HEAP8, ret, size); - return ret; -} - -// Deprecated: This function should not be called because it is unsafe and does not provide -// a maximum length limit of how many bytes it is allowed to write. Prefer calling the -// function stringToUTF8Array() instead, which takes in a maximum length that can be used -// to be secure from out of bounds writes. -/** @deprecated - @param {boolean=} dontAddNull */ -function writeStringToMemory(string, buffer, dontAddNull) { - warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!'); - - var /** @type {number} */ lastChar, /** @type {number} */ end; - if (dontAddNull) { - // stringToUTF8Array always appends null. If we don't want to do that, remember the - // character that existed at the location where the null will be placed, and restore - // that after the write (below). - end = buffer + lengthBytesUTF8(string); - lastChar = HEAP8[end]; - } - stringToUTF8(string, buffer, Infinity); - if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character. -} - -function writeArrayToMemory(array, buffer) { - assert(array.length >= 0, 'writeArrayToMemory array must have a length (should be an array or typed array)') - HEAP8.set(array, buffer); -} - -/** @param {boolean=} dontAddNull */ -function writeAsciiToMemory(str, buffer, dontAddNull) { - for (var i = 0; i < str.length; ++i) { - assert(str.charCodeAt(i) === str.charCodeAt(i)&0xff); - HEAP8[((buffer++)>>0)] = str.charCodeAt(i); - } - // Null-terminate the pointer to the HEAP. - if (!dontAddNull) HEAP8[((buffer)>>0)] = 0; -} - -// end include: runtime_strings_extra.js -// Memory management - -function alignUp(x, multiple) { - if (x % multiple > 0) { - x += multiple - (x % multiple); - } - return x; -} - -var HEAP, -/** @type {ArrayBuffer} */ - buffer, -/** @type {Int8Array} */ - HEAP8, -/** @type {Uint8Array} */ - HEAPU8, -/** @type {Int16Array} */ - HEAP16, -/** @type {Uint16Array} */ - HEAPU16, -/** @type {Int32Array} */ - HEAP32, -/** @type {Uint32Array} */ - HEAPU32, -/** @type {Float32Array} */ - HEAPF32, -/** @type {Float64Array} */ - HEAPF64; - -function updateGlobalBufferAndViews(buf) { - buffer = buf; - Module['HEAP8'] = HEAP8 = new Int8Array(buf); - Module['HEAP16'] = HEAP16 = new Int16Array(buf); - Module['HEAP32'] = HEAP32 = new Int32Array(buf); - Module['HEAPU8'] = HEAPU8 = new Uint8Array(buf); - Module['HEAPU16'] = HEAPU16 = new Uint16Array(buf); - Module['HEAPU32'] = HEAPU32 = new Uint32Array(buf); - Module['HEAPF32'] = HEAPF32 = new Float32Array(buf); - Module['HEAPF64'] = HEAPF64 = new Float64Array(buf); -} - -var TOTAL_STACK = 5242880; -if (Module['TOTAL_STACK']) assert(TOTAL_STACK === Module['TOTAL_STACK'], 'the stack size can no longer be determined at runtime') - -var INITIAL_MEMORY = Module['INITIAL_MEMORY'] || 16777216; -if (!Object.getOwnPropertyDescriptor(Module, 'INITIAL_MEMORY')) { - Object.defineProperty(Module, 'INITIAL_MEMORY', { - configurable: true, - get: function() { - abort('Module.INITIAL_MEMORY has been replaced with plain INITIAL_MEMORY (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)') - } - }); -} - -assert(INITIAL_MEMORY >= TOTAL_STACK, 'INITIAL_MEMORY should be larger than TOTAL_STACK, was ' + INITIAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')'); - -// check for full engine support (use string 'subarray' to avoid closure compiler confusion) -assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && Int32Array.prototype.subarray !== undefined && Int32Array.prototype.set !== undefined, - 'JS engine does not provide full typed array support'); - -// If memory is defined in wasm, the user can't provide it. -assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -s IMPORTED_MEMORY to define wasmMemory externally'); -assert(INITIAL_MEMORY == 16777216, 'Detected runtime INITIAL_MEMORY setting. Use -s IMPORTED_MEMORY to define wasmMemory dynamically'); - -// include: runtime_init_table.js -// In regular non-RELOCATABLE mode the table is exported -// from the wasm module and this will be assigned once -// the exports are available. -var wasmTable; - -// end include: runtime_init_table.js -// include: runtime_stack_check.js - - -// Initializes the stack cookie. Called at the startup of main and at the startup of each thread in pthreads mode. -function writeStackCookie() { - var max = _emscripten_stack_get_end(); - assert((max & 3) == 0); - // The stack grows downwards - HEAPU32[(max >> 2)+1] = 0x2135467; - HEAPU32[(max >> 2)+2] = 0x89BACDFE; - // Also test the global address 0 for integrity. - HEAP32[0] = 0x63736d65; /* 'emsc' */ -} - -function checkStackCookie() { - if (ABORT) return; - var max = _emscripten_stack_get_end(); - var cookie1 = HEAPU32[(max >> 2)+1]; - var cookie2 = HEAPU32[(max >> 2)+2]; - if (cookie1 != 0x2135467 || cookie2 != 0x89BACDFE) { - abort('Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x' + cookie2.toString(16) + ' ' + cookie1.toString(16)); - } - // Also test the global address 0 for integrity. - if (HEAP32[0] !== 0x63736d65 /* 'emsc' */) abort('Runtime error: The application has corrupted its heap memory area (address zero)!'); -} - -// end include: runtime_stack_check.js -// include: runtime_assertions.js - - -// Endianness check (note: assumes compiler arch was little-endian) -(function() { - var h16 = new Int16Array(1); - var h8 = new Int8Array(h16.buffer); - h16[0] = 0x6373; - if (h8[0] !== 0x73 || h8[1] !== 0x63) throw 'Runtime error: expected the system to be little-endian!'; -})(); - -function abortFnPtrError(ptr, sig) { - var possibleSig = ''; - for(var x in debug_tables) { - var tbl = debug_tables[x]; - if (tbl[ptr]) { - possibleSig += 'as sig "' + x + '" pointing to function ' + tbl[ptr] + ', '; - } - } - abort("Invalid function pointer " + ptr + " called with signature '" + sig + "'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this). This pointer might make sense in another type signature: " + possibleSig); -} - -// end include: runtime_assertions.js -var __ATPRERUN__ = []; // functions called before the runtime is initialized -var __ATINIT__ = []; // functions called during startup -var __ATMAIN__ = []; // functions called when main() is to be run -var __ATEXIT__ = []; // functions called during shutdown -var __ATPOSTRUN__ = []; // functions called after the main() is called - -var runtimeInitialized = false; -var runtimeExited = false; - -__ATINIT__.push({ func: function() { ___wasm_call_ctors() } }); - -function preRun() { - - if (Module['preRun']) { - if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']]; - while (Module['preRun'].length) { - addOnPreRun(Module['preRun'].shift()); - } - } - - callRuntimeCallbacks(__ATPRERUN__); -} - -function initRuntime() { - checkStackCookie(); - assert(!runtimeInitialized); - runtimeInitialized = true; - - ___set_stack_limits(_emscripten_stack_get_base(), _emscripten_stack_get_end()); - - callRuntimeCallbacks(__ATINIT__); -} - -function preMain() { - checkStackCookie(); - - callRuntimeCallbacks(__ATMAIN__); -} - -function exitRuntime() { - checkStackCookie(); - runtimeExited = true; -} - -function postRun() { - checkStackCookie(); - - if (Module['postRun']) { - if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']]; - while (Module['postRun'].length) { - addOnPostRun(Module['postRun'].shift()); - } - } - - callRuntimeCallbacks(__ATPOSTRUN__); -} - -function addOnPreRun(cb) { - __ATPRERUN__.unshift(cb); -} - -function addOnInit(cb) { - __ATINIT__.unshift(cb); -} - -function addOnPreMain(cb) { - __ATMAIN__.unshift(cb); -} - -function addOnExit(cb) { -} - -function addOnPostRun(cb) { - __ATPOSTRUN__.unshift(cb); -} - -// include: runtime_math.js - - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc - -assert(Math.imul, 'This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); -assert(Math.fround, 'This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); -assert(Math.clz32, 'This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); -assert(Math.trunc, 'This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill'); - -// end include: runtime_math.js -// A counter of dependencies for calling run(). If we need to -// do asynchronous work before running, increment this and -// decrement it. Incrementing must happen in a place like -// Module.preRun (used by emcc to add file preloading). -// Note that you can add dependencies in preRun, even though -// it happens right before run - run will be postponed until -// the dependencies are met. -var runDependencies = 0; -var runDependencyWatcher = null; -var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled -var runDependencyTracking = {}; - -function getUniqueRunDependency(id) { - var orig = id; - while (1) { - if (!runDependencyTracking[id]) return id; - id = orig + Math.random(); - } -} - -function addRunDependency(id) { - runDependencies++; - - if (Module['monitorRunDependencies']) { - Module['monitorRunDependencies'](runDependencies); - } - - if (id) { - assert(!runDependencyTracking[id]); - runDependencyTracking[id] = 1; - if (runDependencyWatcher === null && typeof setInterval !== 'undefined') { - // Check for missing dependencies every few seconds - runDependencyWatcher = setInterval(function() { - if (ABORT) { - clearInterval(runDependencyWatcher); - runDependencyWatcher = null; - return; - } - var shown = false; - for (var dep in runDependencyTracking) { - if (!shown) { - shown = true; - err('still waiting on run dependencies:'); - } - err('dependency: ' + dep); - } - if (shown) { - err('(end of list)'); - } - }, 10000); - } - } else { - err('warning: run dependency added without ID'); - } -} - -function removeRunDependency(id) { - runDependencies--; - - if (Module['monitorRunDependencies']) { - Module['monitorRunDependencies'](runDependencies); - } - - if (id) { - assert(runDependencyTracking[id]); - delete runDependencyTracking[id]; - } else { - err('warning: run dependency removed without ID'); - } - if (runDependencies == 0) { - if (runDependencyWatcher !== null) { - clearInterval(runDependencyWatcher); - runDependencyWatcher = null; - } - if (dependenciesFulfilled) { - var callback = dependenciesFulfilled; - dependenciesFulfilled = null; - callback(); // can add another dependenciesFulfilled - } - } -} - -Module["preloadedImages"] = {}; // maps url to image data -Module["preloadedAudios"] = {}; // maps url to audio data - -/** @param {string|number=} what */ -function abort(what) { - if (Module['onAbort']) { - Module['onAbort'](what); - } - - what += ''; - err(what); - - ABORT = true; - EXITSTATUS = 1; - - var output = 'abort(' + what + ') at ' + stackTrace(); - what = output; - - // Use a wasm runtime error, because a JS error might be seen as a foreign - // exception, which means we'd run destructors on it. We need the error to - // simply make the program stop. - var e = new WebAssembly.RuntimeError(what); - - readyPromiseReject(e); - // Throw the error whether or not MODULARIZE is set because abort is used - // in code paths apart from instantiation where an exception is expected - // to be thrown when abort is called. - throw e; -} - -// {{MEM_INITIALIZER}} - -// include: memoryprofiler.js - - -// end include: memoryprofiler.js -// show errors on likely calls to FS when it was not included -var FS = { - error: function() { - abort('Filesystem support (FS) was not included. The problem is that you are using files from JS, but files were not used from C/C++, so filesystem support was not auto-included. You can force-include filesystem support with -s FORCE_FILESYSTEM=1'); - }, - init: function() { FS.error() }, - createDataFile: function() { FS.error() }, - createPreloadedFile: function() { FS.error() }, - createLazyFile: function() { FS.error() }, - open: function() { FS.error() }, - mkdev: function() { FS.error() }, - registerDevice: function() { FS.error() }, - analyzePath: function() { FS.error() }, - loadFilesFromDB: function() { FS.error() }, - - ErrnoError: function ErrnoError() { FS.error() }, -}; -Module['FS_createDataFile'] = FS.createDataFile; -Module['FS_createPreloadedFile'] = FS.createPreloadedFile; - -// include: URIUtils.js - - -function hasPrefix(str, prefix) { - return String.prototype.startsWith ? - str.startsWith(prefix) : - str.indexOf(prefix) === 0; -} - -// Prefix of data URIs emitted by SINGLE_FILE and related options. -var dataURIPrefix = 'data:application/octet-stream;base64,'; - -// Indicates whether filename is a base64 data URI. -function isDataURI(filename) { - return hasPrefix(filename, dataURIPrefix); -} - -var fileURIPrefix = "file://"; - -// Indicates whether filename is delivered via file protocol (as opposed to http/https) -function isFileURI(filename) { - return hasPrefix(filename, fileURIPrefix); -} - -// end include: URIUtils.js -function createExportWrapper(name, fixedasm) { - return function() { - var displayName = name; - var asm = fixedasm; - if (!fixedasm) { - asm = Module['asm']; - } - assert(runtimeInitialized, 'native function `' + displayName + '` called before runtime initialization'); - assert(!runtimeExited, 'native function `' + displayName + '` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)'); - if (!asm[name]) { - assert(asm[name], 'exported native function `' + displayName + '` not found'); - } - return asm[name].apply(null, arguments); - }; -} - -var wasmBinaryFile = 'LibYUV.wasm'; -if (!isDataURI(wasmBinaryFile)) { - wasmBinaryFile = locateFile(wasmBinaryFile); -} - -function getBinary(file) { - try { - if (file == wasmBinaryFile && wasmBinary) { - return new Uint8Array(wasmBinary); - } - if (readBinary) { - return readBinary(file); - } else { - throw "both async and sync fetching of the wasm failed"; - } - } - catch (err) { - abort(err); - } -} - -function getBinaryPromise() { - // If we don't have the binary yet, try to to load it asynchronously. - // Fetch has some additional restrictions over XHR, like it can't be used on a file:// url. - // See https://github.com/github/fetch/pull/92#issuecomment-140665932 - // Cordova or Electron apps are typically loaded from a file:// url. - // So use fetch if it is available and the url is not a file, otherwise fall back to XHR. - if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) { - if (typeof fetch === 'function' - && !isFileURI(wasmBinaryFile) - ) { - return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) { - if (!response['ok']) { - throw "failed to load wasm binary file at '" + wasmBinaryFile + "'"; - } - return response['arrayBuffer'](); - }).catch(function () { - return getBinary(wasmBinaryFile); - }); - } - else { - if (readAsync) { - // fetch is not available or url is file => try XHR (readAsync uses XHR internally) - return new Promise(function(resolve, reject) { - readAsync(wasmBinaryFile, function(response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject) - }); - } - } - } - - // Otherwise, getBinary should be able to get it synchronously - return Promise.resolve().then(function() { return getBinary(wasmBinaryFile); }); -} - -// Create the wasm instance. -// Receives the wasm imports, returns the exports. -function createWasm() { - console.log('createWasm'); - // prepare imports - var info = { - 'env': asmLibraryArg, - 'wasi_snapshot_preview1': asmLibraryArg, - }; - // Load the wasm module and create an instance of using native support in the JS engine. - // handle a generated wasm instance, receiving its exports and - // performing other necessary setup - /** @param {WebAssembly.Module=} module*/ - function receiveInstance(instance, module) { - var exports = instance.exports; - - Module['asm'] = exports; - - wasmMemory = Module['asm']['memory']; - assert(wasmMemory, "memory not found in wasm exports"); - // This assertion doesn't hold when emscripten is run in --post-link - // mode. - // TODO(sbc): Read INITIAL_MEMORY out of the wasm file in post-link mode. - //assert(wasmMemory.buffer.byteLength === 16777216); - updateGlobalBufferAndViews(wasmMemory.buffer); - - wasmTable = Module['asm']['__indirect_function_table']; - assert(wasmTable, "table not found in wasm exports"); - - removeRunDependency('wasm-instantiate'); - } - // we can't run yet (except in a pthread, where we have a custom sync instantiator) - addRunDependency('wasm-instantiate'); - - // Async compilation can be confusing when an error on the page overwrites Module - // (for example, if the order of elements is wrong, and the one defining Module is - // later), so we save Module and check it later. - var trueModule = Module; - function receiveInstantiatedSource(output) { - // 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance. - // receiveInstance() will swap in the exports (to Module.asm) so they can be called - assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?'); - trueModule = null; - // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line. - // When the regression is fixed, can restore the above USE_PTHREADS-enabled path. - receiveInstance(output['instance']); - } - - function instantiateArrayBuffer(receiver) { - console.log('instantiateArrayBuffer'); - return getBinaryPromise().then(function(binary) { - return WebAssembly.instantiate(binary, info); - }).then(receiver, function(reason) { - err('failed to asynchronously prepare wasm: ' + reason); - - // Warn on some common problems. - if (isFileURI(wasmBinaryFile)) { - err('warning: Loading from a file URI (' + wasmBinaryFile + ') is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing'); - } - abort(reason); - }); - } - - // Prefer streaming instantiation if available. - function instantiateAsync() { - if (!wasmBinary && - typeof WebAssembly.instantiateStreaming === 'function' && - !isDataURI(wasmBinaryFile) && - // Don't use streaming for file:// delivered objects in a webview, fetch them synchronously. - !isFileURI(wasmBinaryFile) && - typeof fetch === 'function') { - return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function (response) { - var result = WebAssembly.instantiateStreaming(response, info); - return result.then(receiveInstantiatedSource, function(reason) { - // We expect the most common failure cause to be a bad MIME type for the binary, - // in which case falling back to ArrayBuffer instantiation should work. - err('wasm streaming compile failed: ' + reason); - err('falling back to ArrayBuffer instantiation'); - return instantiateArrayBuffer(receiveInstantiatedSource); - }); - }); - } else { - return instantiateArrayBuffer(receiveInstantiatedSource); - } - } - - // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback - // to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel - // to any other async startup actions they are performing. - if (Module['instantiateWasm']) { - try { - var exports = Module['instantiateWasm'](info, receiveInstance); - return exports; - } catch(e) { - err('Module.instantiateWasm callback failed with error: ' + e); - return false; - } - } - - // If instantiation fails, reject the module ready promise. - instantiateAsync().catch(readyPromiseReject); - return {}; // no exports yet; we'll fill them in later -} - -// Globals used by JS i64 conversions (see makeSetValue) -var tempDouble; -var tempI64; - -// === Body === - -var ASM_CONSTS = { - -}; - - - - - - - function callRuntimeCallbacks(callbacks) { - while(callbacks.length > 0) { - var callback = callbacks.shift(); - if (typeof callback == 'function') { - callback(Module); // Pass the module as the first argument. - continue; - } - var func = callback.func; - if (typeof func === 'number') { - if (callback.arg === undefined) { - wasmTable.get(func)(); - } else { - wasmTable.get(func)(callback.arg); - } - } else { - func(callback.arg === undefined ? null : callback.arg); - } - } - } - - function demangle(func) { - warnOnce('warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling'); - return func; - } - - function demangleAll(text) { - var regex = - /\b_Z[\w\d_]+/g; - return text.replace(regex, - function(x) { - var y = demangle(x); - return x === y ? x : (y + ' [' + x + ']'); - }); - } - - function jsStackTrace() { - var error = new Error(); - if (!error.stack) { - // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown, - // so try that as a special-case. - try { - throw new Error(); - } catch(e) { - error = e; - } - if (!error.stack) { - return '(no stack trace available)'; - } - } - return error.stack.toString(); - } - - function stackTrace() { - var js = jsStackTrace(); - if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace'](); - return demangleAll(js); - } - - function ___handle_stack_overflow() { - // TODO(sbc): Improve this error message. The old abortStackOverflow used - // by asm.js used to do a better job: - // abort('Stack overflow! Attempted to allocate ' + allocSize + ' bytes on the stack, but stack has only ' + (_emscripten_stack_get_free() + allocSize) + ' bytes available!'); - abort('stack overflow'); - } - - function _abort() { - abort(); - } - - function _emscripten_get_heap_size() { - return HEAPU8.length; - } - - var _emscripten_get_now;if (ENVIRONMENT_IS_NODE) { - _emscripten_get_now = function() { - var t = process['hrtime'](); - return t[0] * 1e3 + t[1] / 1e6; - }; - } else if (typeof dateNow !== 'undefined') { - _emscripten_get_now = dateNow; - } else _emscripten_get_now = function() { return performance.now(); } - ; - - function emscripten_realloc_buffer(size) { - try { - // round size grow request up to wasm page size (fixed 64KB per spec) - wasmMemory.grow((size - buffer.byteLength + 65535) >>> 16); // .grow() takes a delta compared to the previous size - updateGlobalBufferAndViews(wasmMemory.buffer); - return 1 /*success*/; - } catch(e) { - console.error('emscripten_realloc_buffer: Attempted to grow heap from ' + buffer.byteLength + ' bytes to ' + size + ' bytes, but got error: ' + e); - } - // implicit 0 return to save code size (caller will cast "undefined" into 0 - // anyhow) - } - function _emscripten_resize_heap(requestedSize) { - var oldSize = _emscripten_get_heap_size(); - // With pthreads, races can happen (another thread might increase the size in between), so return a failure, and let the caller retry. - assert(requestedSize > oldSize); - - // Memory resize rules: - // 1. Always increase heap size to at least the requested size, rounded up to next page multiple. - // 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap geometrically: increase the heap size according to - // MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), - // At most overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB). - // 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap linearly: increase the heap size by at least MEMORY_GROWTH_LINEAR_STEP bytes. - // 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest - // 4. If we were unable to allocate as much memory, it may be due to over-eager decision to excessively reserve due to (3) above. - // Hence if an allocation fails, cut down on the amount of excess growth, in an attempt to succeed to perform a smaller allocation. - - // A limit was set for how much we can grow. We should not exceed that - // (the wasm binary specifies it, so if we tried, we'd fail anyhow). - // In CAN_ADDRESS_2GB mode, stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate full 4GB Wasm memories, the size will wrap - // back to 0 bytes in Wasm side for any code that deals with heap sizes, which would require special casing all heap size related code to treat - // 0 specially. - var maxHeapSize = 2147483648; - if (requestedSize > maxHeapSize) { - err('Cannot enlarge memory, asked to go up to ' + requestedSize + ' bytes, but the limit is ' + maxHeapSize + ' bytes!'); - return false; - } - - // Loop through potential heap size increases. If we attempt a too eager reservation that fails, cut down on the - // attempted size and reserve a smaller bump instead. (max 3 times, chosen somewhat arbitrarily) - for(var cutDown = 1; cutDown <= 4; cutDown *= 2) { - var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown); // ensure geometric growth - // but limit overreserving (default to capping at +96MB overgrowth at most) - overGrownHeapSize = Math.min(overGrownHeapSize, requestedSize + 100663296 ); - - var newSize = Math.min(maxHeapSize, alignUp(Math.max(requestedSize, overGrownHeapSize), 65536)); - - var t0 = _emscripten_get_now(); - var replacement = emscripten_realloc_buffer(newSize); - var t1 = _emscripten_get_now(); - console.log('Heap resize call from ' + oldSize + ' to ' + newSize + ' took ' + (t1 - t0) + ' msecs. Success: ' + !!replacement); - if (replacement) { - - return true; - } - } - err('Failed to grow the heap from ' + oldSize + ' bytes to ' + newSize + ' bytes, not enough memory!'); - return false; - } -var ASSERTIONS = true; - - - -/** @type {function(string, boolean=, number=)} */ -function intArrayFromString(stringy, dontAddNull, length) { - var len = length > 0 ? length : lengthBytesUTF8(stringy)+1; - var u8array = new Array(len); - var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length); - if (dontAddNull) u8array.length = numBytesWritten; - return u8array; -} - -function intArrayToString(array) { - var ret = []; - for (var i = 0; i < array.length; i++) { - var chr = array[i]; - if (chr > 0xFF) { - if (ASSERTIONS) { - assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.'); - } - chr &= 0xFF; - } - ret.push(String.fromCharCode(chr)); - } - return ret.join(''); -} - - -var asmLibraryArg = { - "__handle_stack_overflow": ___handle_stack_overflow, - "abort": _abort, - "emscripten_resize_heap": _emscripten_resize_heap -}; -var asm = createWasm(); -/** @type {function(...*):?} */ -var ___wasm_call_ctors = Module["___wasm_call_ctors"] = createExportWrapper("__wasm_call_ctors"); - -/** @type {function(...*):?} */ -var _ConvertRGBA88882YUV420P = Module["_ConvertRGBA88882YUV420P"] = createExportWrapper("ConvertRGBA88882YUV420P"); - -/** @type {function(...*):?} */ -var _ABGRToI420 = Module["_ABGRToI420"] = createExportWrapper("ABGRToI420"); - -/** @type {function(...*):?} */ -var _ConvertYUV420P2RGBA8888 = Module["_ConvertYUV420P2RGBA8888"] = createExportWrapper("ConvertYUV420P2RGBA8888"); - -/** @type {function(...*):?} */ -var _I420ToABGR = Module["_I420ToABGR"] = createExportWrapper("I420ToABGR"); - -/** @type {function(...*):?} */ -var _malloc = Module["_malloc"] = createExportWrapper("malloc"); - -/** @type {function(...*):?} */ -var _free = Module["_free"] = createExportWrapper("free"); - -/** @type {function(...*):?} */ -var ___errno_location = Module["___errno_location"] = createExportWrapper("__errno_location"); - -/** @type {function(...*):?} */ -var _fflush = Module["_fflush"] = createExportWrapper("fflush"); - -/** @type {function(...*):?} */ -var stackSave = Module["stackSave"] = createExportWrapper("stackSave"); - -/** @type {function(...*):?} */ -var stackRestore = Module["stackRestore"] = createExportWrapper("stackRestore"); - -/** @type {function(...*):?} */ -var stackAlloc = Module["stackAlloc"] = createExportWrapper("stackAlloc"); - -/** @type {function(...*):?} */ -var _emscripten_stack_init = Module["_emscripten_stack_init"] = function() { - return (_emscripten_stack_init = Module["_emscripten_stack_init"] = Module["asm"]["emscripten_stack_init"]).apply(null, arguments); -}; - -/** @type {function(...*):?} */ -var _emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = function() { - return (_emscripten_stack_get_free = Module["_emscripten_stack_get_free"] = Module["asm"]["emscripten_stack_get_free"]).apply(null, arguments); -}; - -/** @type {function(...*):?} */ -var _emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = function() { - return (_emscripten_stack_get_base = Module["_emscripten_stack_get_base"] = Module["asm"]["emscripten_stack_get_base"]).apply(null, arguments); -}; - -/** @type {function(...*):?} */ -var _emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = function() { - return (_emscripten_stack_get_end = Module["_emscripten_stack_get_end"] = Module["asm"]["emscripten_stack_get_end"]).apply(null, arguments); -}; - -/** @type {function(...*):?} */ -var ___set_stack_limits = Module["___set_stack_limits"] = createExportWrapper("__set_stack_limits"); - - - - - -// === Auto-generated postamble setup entry stuff === - -if (!Object.getOwnPropertyDescriptor(Module, "intArrayFromString")) Module["intArrayFromString"] = function() { abort("'intArrayFromString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "intArrayToString")) Module["intArrayToString"] = function() { abort("'intArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -Module["ccall"] = ccall; -Module["cwrap"] = cwrap; -if (!Object.getOwnPropertyDescriptor(Module, "setValue")) Module["setValue"] = function() { abort("'setValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getValue")) Module["getValue"] = function() { abort("'getValue' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "allocate")) Module["allocate"] = function() { abort("'allocate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF8ArrayToString")) Module["UTF8ArrayToString"] = function() { abort("'UTF8ArrayToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF8ToString")) Module["UTF8ToString"] = function() { abort("'UTF8ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8Array")) Module["stringToUTF8Array"] = function() { abort("'stringToUTF8Array' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF8")) Module["stringToUTF8"] = function() { abort("'stringToUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF8")) Module["lengthBytesUTF8"] = function() { abort("'lengthBytesUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnPreRun")) Module["addOnPreRun"] = function() { abort("'addOnPreRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnInit")) Module["addOnInit"] = function() { abort("'addOnInit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnPreMain")) Module["addOnPreMain"] = function() { abort("'addOnPreMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnExit")) Module["addOnExit"] = function() { abort("'addOnExit' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addOnPostRun")) Module["addOnPostRun"] = function() { abort("'addOnPostRun' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeStringToMemory")) Module["writeStringToMemory"] = function() { abort("'writeStringToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeArrayToMemory")) Module["writeArrayToMemory"] = function() { abort("'writeArrayToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeAsciiToMemory")) Module["writeAsciiToMemory"] = function() { abort("'writeAsciiToMemory' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addRunDependency")) Module["addRunDependency"] = function() { abort("'addRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "removeRunDependency")) Module["removeRunDependency"] = function() { abort("'removeRunDependency' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createFolder")) Module["FS_createFolder"] = function() { abort("'FS_createFolder' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createPath")) Module["FS_createPath"] = function() { abort("'FS_createPath' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createDataFile")) Module["FS_createDataFile"] = function() { abort("'FS_createDataFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createPreloadedFile")) Module["FS_createPreloadedFile"] = function() { abort("'FS_createPreloadedFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createLazyFile")) Module["FS_createLazyFile"] = function() { abort("'FS_createLazyFile' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createLink")) Module["FS_createLink"] = function() { abort("'FS_createLink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_createDevice")) Module["FS_createDevice"] = function() { abort("'FS_createDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS_unlink")) Module["FS_unlink"] = function() { abort("'FS_unlink' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ). Alternatively, forcing filesystem support (-s FORCE_FILESYSTEM=1) can export this for you") }; -if (!Object.getOwnPropertyDescriptor(Module, "getLEB")) Module["getLEB"] = function() { abort("'getLEB' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getFunctionTables")) Module["getFunctionTables"] = function() { abort("'getFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "alignFunctionTables")) Module["alignFunctionTables"] = function() { abort("'alignFunctionTables' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerFunctions")) Module["registerFunctions"] = function() { abort("'registerFunctions' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "addFunction")) Module["addFunction"] = function() { abort("'addFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "removeFunction")) Module["removeFunction"] = function() { abort("'removeFunction' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "prettyPrint")) Module["prettyPrint"] = function() { abort("'prettyPrint' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "makeBigInt")) Module["makeBigInt"] = function() { abort("'makeBigInt' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getCompilerSetting")) Module["getCompilerSetting"] = function() { abort("'getCompilerSetting' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "print")) Module["print"] = function() { abort("'print' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "printErr")) Module["printErr"] = function() { abort("'printErr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getTempRet0")) Module["getTempRet0"] = function() { abort("'getTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setTempRet0")) Module["setTempRet0"] = function() { abort("'setTempRet0' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "callMain")) Module["callMain"] = function() { abort("'callMain' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "abort")) Module["abort"] = function() { abort("'abort' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToNewUTF8")) Module["stringToNewUTF8"] = function() { abort("'stringToNewUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setFileTime")) Module["setFileTime"] = function() { abort("'setFileTime' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscripten_realloc_buffer")) Module["emscripten_realloc_buffer"] = function() { abort("'emscripten_realloc_buffer' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ENV")) Module["ENV"] = function() { abort("'ENV' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_CODES")) Module["ERRNO_CODES"] = function() { abort("'ERRNO_CODES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ERRNO_MESSAGES")) Module["ERRNO_MESSAGES"] = function() { abort("'ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setErrNo")) Module["setErrNo"] = function() { abort("'setErrNo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "inetPton4")) Module["inetPton4"] = function() { abort("'inetPton4' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "inetNtop4")) Module["inetNtop4"] = function() { abort("'inetNtop4' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "inetPton6")) Module["inetPton6"] = function() { abort("'inetPton6' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "inetNtop6")) Module["inetNtop6"] = function() { abort("'inetNtop6' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readSockaddr")) Module["readSockaddr"] = function() { abort("'readSockaddr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeSockaddr")) Module["writeSockaddr"] = function() { abort("'writeSockaddr' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "DNS")) Module["DNS"] = function() { abort("'DNS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getHostByName")) Module["getHostByName"] = function() { abort("'getHostByName' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GAI_ERRNO_MESSAGES")) Module["GAI_ERRNO_MESSAGES"] = function() { abort("'GAI_ERRNO_MESSAGES' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "Protocols")) Module["Protocols"] = function() { abort("'Protocols' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "Sockets")) Module["Sockets"] = function() { abort("'Sockets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getRandomDevice")) Module["getRandomDevice"] = function() { abort("'getRandomDevice' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "traverseStack")) Module["traverseStack"] = function() { abort("'traverseStack' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UNWIND_CACHE")) Module["UNWIND_CACHE"] = function() { abort("'UNWIND_CACHE' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "withBuiltinMalloc")) Module["withBuiltinMalloc"] = function() { abort("'withBuiltinMalloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgsArray")) Module["readAsmConstArgsArray"] = function() { abort("'readAsmConstArgsArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readAsmConstArgs")) Module["readAsmConstArgs"] = function() { abort("'readAsmConstArgs' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "mainThreadEM_ASM")) Module["mainThreadEM_ASM"] = function() { abort("'mainThreadEM_ASM' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "jstoi_q")) Module["jstoi_q"] = function() { abort("'jstoi_q' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "jstoi_s")) Module["jstoi_s"] = function() { abort("'jstoi_s' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getExecutableName")) Module["getExecutableName"] = function() { abort("'getExecutableName' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "listenOnce")) Module["listenOnce"] = function() { abort("'listenOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "autoResumeAudioContext")) Module["autoResumeAudioContext"] = function() { abort("'autoResumeAudioContext' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "dynCallLegacy")) Module["dynCallLegacy"] = function() { abort("'dynCallLegacy' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getDynCaller")) Module["getDynCaller"] = function() { abort("'getDynCaller' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "dynCall")) Module["dynCall"] = function() { abort("'dynCall' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "callRuntimeCallbacks")) Module["callRuntimeCallbacks"] = function() { abort("'callRuntimeCallbacks' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "reallyNegative")) Module["reallyNegative"] = function() { abort("'reallyNegative' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "unSign")) Module["unSign"] = function() { abort("'unSign' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "reSign")) Module["reSign"] = function() { abort("'reSign' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "formatString")) Module["formatString"] = function() { abort("'formatString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "PATH")) Module["PATH"] = function() { abort("'PATH' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "PATH_FS")) Module["PATH_FS"] = function() { abort("'PATH_FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SYSCALLS")) Module["SYSCALLS"] = function() { abort("'SYSCALLS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "syscallMmap2")) Module["syscallMmap2"] = function() { abort("'syscallMmap2' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "syscallMunmap")) Module["syscallMunmap"] = function() { abort("'syscallMunmap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getSocketFromFD")) Module["getSocketFromFD"] = function() { abort("'getSocketFromFD' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getSocketAddress")) Module["getSocketAddress"] = function() { abort("'getSocketAddress' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "JSEvents")) Module["JSEvents"] = function() { abort("'JSEvents' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerKeyEventCallback")) Module["registerKeyEventCallback"] = function() { abort("'registerKeyEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "specialHTMLTargets")) Module["specialHTMLTargets"] = function() { abort("'specialHTMLTargets' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "maybeCStringToJsString")) Module["maybeCStringToJsString"] = function() { abort("'maybeCStringToJsString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "findEventTarget")) Module["findEventTarget"] = function() { abort("'findEventTarget' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "findCanvasEventTarget")) Module["findCanvasEventTarget"] = function() { abort("'findCanvasEventTarget' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getBoundingClientRect")) Module["getBoundingClientRect"] = function() { abort("'getBoundingClientRect' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillMouseEventData")) Module["fillMouseEventData"] = function() { abort("'fillMouseEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerMouseEventCallback")) Module["registerMouseEventCallback"] = function() { abort("'registerMouseEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerWheelEventCallback")) Module["registerWheelEventCallback"] = function() { abort("'registerWheelEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerUiEventCallback")) Module["registerUiEventCallback"] = function() { abort("'registerUiEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerFocusEventCallback")) Module["registerFocusEventCallback"] = function() { abort("'registerFocusEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillDeviceOrientationEventData")) Module["fillDeviceOrientationEventData"] = function() { abort("'fillDeviceOrientationEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerDeviceOrientationEventCallback")) Module["registerDeviceOrientationEventCallback"] = function() { abort("'registerDeviceOrientationEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillDeviceMotionEventData")) Module["fillDeviceMotionEventData"] = function() { abort("'fillDeviceMotionEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerDeviceMotionEventCallback")) Module["registerDeviceMotionEventCallback"] = function() { abort("'registerDeviceMotionEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "screenOrientation")) Module["screenOrientation"] = function() { abort("'screenOrientation' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillOrientationChangeEventData")) Module["fillOrientationChangeEventData"] = function() { abort("'fillOrientationChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerOrientationChangeEventCallback")) Module["registerOrientationChangeEventCallback"] = function() { abort("'registerOrientationChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillFullscreenChangeEventData")) Module["fillFullscreenChangeEventData"] = function() { abort("'fillFullscreenChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerFullscreenChangeEventCallback")) Module["registerFullscreenChangeEventCallback"] = function() { abort("'registerFullscreenChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerRestoreOldStyle")) Module["registerRestoreOldStyle"] = function() { abort("'registerRestoreOldStyle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "hideEverythingExceptGivenElement")) Module["hideEverythingExceptGivenElement"] = function() { abort("'hideEverythingExceptGivenElement' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "restoreHiddenElements")) Module["restoreHiddenElements"] = function() { abort("'restoreHiddenElements' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setLetterbox")) Module["setLetterbox"] = function() { abort("'setLetterbox' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "currentFullscreenStrategy")) Module["currentFullscreenStrategy"] = function() { abort("'currentFullscreenStrategy' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "restoreOldWindowedStyle")) Module["restoreOldWindowedStyle"] = function() { abort("'restoreOldWindowedStyle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "softFullscreenResizeWebGLRenderTarget")) Module["softFullscreenResizeWebGLRenderTarget"] = function() { abort("'softFullscreenResizeWebGLRenderTarget' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "doRequestFullscreen")) Module["doRequestFullscreen"] = function() { abort("'doRequestFullscreen' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillPointerlockChangeEventData")) Module["fillPointerlockChangeEventData"] = function() { abort("'fillPointerlockChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerPointerlockChangeEventCallback")) Module["registerPointerlockChangeEventCallback"] = function() { abort("'registerPointerlockChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerPointerlockErrorEventCallback")) Module["registerPointerlockErrorEventCallback"] = function() { abort("'registerPointerlockErrorEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "requestPointerLock")) Module["requestPointerLock"] = function() { abort("'requestPointerLock' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillVisibilityChangeEventData")) Module["fillVisibilityChangeEventData"] = function() { abort("'fillVisibilityChangeEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerVisibilityChangeEventCallback")) Module["registerVisibilityChangeEventCallback"] = function() { abort("'registerVisibilityChangeEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerTouchEventCallback")) Module["registerTouchEventCallback"] = function() { abort("'registerTouchEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillGamepadEventData")) Module["fillGamepadEventData"] = function() { abort("'fillGamepadEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerGamepadEventCallback")) Module["registerGamepadEventCallback"] = function() { abort("'registerGamepadEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerBeforeUnloadEventCallback")) Module["registerBeforeUnloadEventCallback"] = function() { abort("'registerBeforeUnloadEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "fillBatteryEventData")) Module["fillBatteryEventData"] = function() { abort("'fillBatteryEventData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "battery")) Module["battery"] = function() { abort("'battery' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "registerBatteryEventCallback")) Module["registerBatteryEventCallback"] = function() { abort("'registerBatteryEventCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setCanvasElementSize")) Module["setCanvasElementSize"] = function() { abort("'setCanvasElementSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getCanvasElementSize")) Module["getCanvasElementSize"] = function() { abort("'getCanvasElementSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "polyfillSetImmediate")) Module["polyfillSetImmediate"] = function() { abort("'polyfillSetImmediate' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "demangle")) Module["demangle"] = function() { abort("'demangle' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "demangleAll")) Module["demangleAll"] = function() { abort("'demangleAll' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "jsStackTrace")) Module["jsStackTrace"] = function() { abort("'jsStackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackTrace")) Module["stackTrace"] = function() { abort("'stackTrace' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getEnvStrings")) Module["getEnvStrings"] = function() { abort("'getEnvStrings' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "checkWasiClock")) Module["checkWasiClock"] = function() { abort("'checkWasiClock' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "flush_NO_FILESYSTEM")) Module["flush_NO_FILESYSTEM"] = function() { abort("'flush_NO_FILESYSTEM' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64")) Module["writeI53ToI64"] = function() { abort("'writeI53ToI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Clamped")) Module["writeI53ToI64Clamped"] = function() { abort("'writeI53ToI64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToI64Signaling")) Module["writeI53ToI64Signaling"] = function() { abort("'writeI53ToI64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Clamped")) Module["writeI53ToU64Clamped"] = function() { abort("'writeI53ToU64Clamped' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeI53ToU64Signaling")) Module["writeI53ToU64Signaling"] = function() { abort("'writeI53ToU64Signaling' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readI53FromI64")) Module["readI53FromI64"] = function() { abort("'readI53FromI64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "readI53FromU64")) Module["readI53FromU64"] = function() { abort("'readI53FromU64' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "convertI32PairToI53")) Module["convertI32PairToI53"] = function() { abort("'convertI32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "convertU32PairToI53")) Module["convertU32PairToI53"] = function() { abort("'convertU32PairToI53' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "uncaughtExceptionCount")) Module["uncaughtExceptionCount"] = function() { abort("'uncaughtExceptionCount' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "exceptionLast")) Module["exceptionLast"] = function() { abort("'exceptionLast' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "exceptionCaught")) Module["exceptionCaught"] = function() { abort("'exceptionCaught' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ExceptionInfoAttrs")) Module["ExceptionInfoAttrs"] = function() { abort("'ExceptionInfoAttrs' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "ExceptionInfo")) Module["ExceptionInfo"] = function() { abort("'ExceptionInfo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "CatchInfo")) Module["CatchInfo"] = function() { abort("'CatchInfo' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "exception_addRef")) Module["exception_addRef"] = function() { abort("'exception_addRef' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "exception_decRef")) Module["exception_decRef"] = function() { abort("'exception_decRef' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "Browser")) Module["Browser"] = function() { abort("'Browser' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "funcWrappers")) Module["funcWrappers"] = function() { abort("'funcWrappers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "getFuncWrapper")) Module["getFuncWrapper"] = function() { abort("'getFuncWrapper' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "setMainLoop")) Module["setMainLoop"] = function() { abort("'setMainLoop' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "FS")) Module["FS"] = function() { abort("'FS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "mmapAlloc")) Module["mmapAlloc"] = function() { abort("'mmapAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "MEMFS")) Module["MEMFS"] = function() { abort("'MEMFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "TTY")) Module["TTY"] = function() { abort("'TTY' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "PIPEFS")) Module["PIPEFS"] = function() { abort("'PIPEFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SOCKFS")) Module["SOCKFS"] = function() { abort("'SOCKFS' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "_setNetworkCallback")) Module["_setNetworkCallback"] = function() { abort("'_setNetworkCallback' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "tempFixedLengthArray")) Module["tempFixedLengthArray"] = function() { abort("'tempFixedLengthArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "miniTempWebGLFloatBuffers")) Module["miniTempWebGLFloatBuffers"] = function() { abort("'miniTempWebGLFloatBuffers' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "heapObjectForWebGLType")) Module["heapObjectForWebGLType"] = function() { abort("'heapObjectForWebGLType' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "heapAccessShiftForWebGLHeap")) Module["heapAccessShiftForWebGLHeap"] = function() { abort("'heapAccessShiftForWebGLHeap' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GL")) Module["GL"] = function() { abort("'GL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGet")) Module["emscriptenWebGLGet"] = function() { abort("'emscriptenWebGLGet' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "computeUnpackAlignedImageSize")) Module["computeUnpackAlignedImageSize"] = function() { abort("'computeUnpackAlignedImageSize' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetTexPixelData")) Module["emscriptenWebGLGetTexPixelData"] = function() { abort("'emscriptenWebGLGetTexPixelData' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetUniform")) Module["emscriptenWebGLGetUniform"] = function() { abort("'emscriptenWebGLGetUniform' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "emscriptenWebGLGetVertexAttrib")) Module["emscriptenWebGLGetVertexAttrib"] = function() { abort("'emscriptenWebGLGetVertexAttrib' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "writeGLArray")) Module["writeGLArray"] = function() { abort("'writeGLArray' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "AL")) Module["AL"] = function() { abort("'AL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_unicode")) Module["SDL_unicode"] = function() { abort("'SDL_unicode' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_ttfContext")) Module["SDL_ttfContext"] = function() { abort("'SDL_ttfContext' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_audio")) Module["SDL_audio"] = function() { abort("'SDL_audio' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL")) Module["SDL"] = function() { abort("'SDL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "SDL_gfx")) Module["SDL_gfx"] = function() { abort("'SDL_gfx' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLUT")) Module["GLUT"] = function() { abort("'GLUT' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "EGL")) Module["EGL"] = function() { abort("'EGL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLFW_Window")) Module["GLFW_Window"] = function() { abort("'GLFW_Window' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLFW")) Module["GLFW"] = function() { abort("'GLFW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "GLEW")) Module["GLEW"] = function() { abort("'GLEW' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "IDBStore")) Module["IDBStore"] = function() { abort("'IDBStore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "runAndAbortIfError")) Module["runAndAbortIfError"] = function() { abort("'runAndAbortIfError' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "warnOnce")) Module["warnOnce"] = function() { abort("'warnOnce' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackSave")) Module["stackSave"] = function() { abort("'stackSave' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackRestore")) Module["stackRestore"] = function() { abort("'stackRestore' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stackAlloc")) Module["stackAlloc"] = function() { abort("'stackAlloc' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "AsciiToString")) Module["AsciiToString"] = function() { abort("'AsciiToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToAscii")) Module["stringToAscii"] = function() { abort("'stringToAscii' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF16ToString")) Module["UTF16ToString"] = function() { abort("'UTF16ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF16")) Module["stringToUTF16"] = function() { abort("'stringToUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF16")) Module["lengthBytesUTF16"] = function() { abort("'lengthBytesUTF16' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "UTF32ToString")) Module["UTF32ToString"] = function() { abort("'UTF32ToString' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "stringToUTF32")) Module["stringToUTF32"] = function() { abort("'stringToUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "lengthBytesUTF32")) Module["lengthBytesUTF32"] = function() { abort("'lengthBytesUTF32' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8")) Module["allocateUTF8"] = function() { abort("'allocateUTF8' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -if (!Object.getOwnPropertyDescriptor(Module, "allocateUTF8OnStack")) Module["allocateUTF8OnStack"] = function() { abort("'allocateUTF8OnStack' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") }; -Module["writeStackCookie"] = writeStackCookie; -Module["checkStackCookie"] = checkStackCookie; -if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_NORMAL")) Object.defineProperty(Module, "ALLOC_NORMAL", { configurable: true, get: function() { abort("'ALLOC_NORMAL' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); -if (!Object.getOwnPropertyDescriptor(Module, "ALLOC_STACK")) Object.defineProperty(Module, "ALLOC_STACK", { configurable: true, get: function() { abort("'ALLOC_STACK' was not exported. add it to EXTRA_EXPORTED_RUNTIME_METHODS (see the FAQ)") } }); - -var calledRun; - -/** - * @constructor - * @this {ExitStatus} - */ -function ExitStatus(status) { - this.name = "ExitStatus"; - this.message = "Program terminated with exit(" + status + ")"; - this.status = status; -} - -var calledMain = false; - -dependenciesFulfilled = function runCaller() { - // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false) - if (!calledRun) run(); - if (!calledRun) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled -}; - -function stackCheckInit() { - // This is normally called automatically during __wasm_call_ctors but need to - // get these values before even running any of the ctors so we call it redundantly - // here. - // TODO(sbc): Move writeStackCookie to native to to avoid this. - _emscripten_stack_init(); - writeStackCookie(); -} - -/** @type {function(Array=)} */ -function run(args) { - args = args || arguments_; - - if (runDependencies > 0) { - return; - } - - stackCheckInit(); - - preRun(); - - // a preRun added a dependency, run will be called later - if (runDependencies > 0) { - return; - } - - function doRun() { - // run may have just been called through dependencies being fulfilled just in this very frame, - // or while the async setStatus time below was happening - if (calledRun) return; - calledRun = true; - Module['calledRun'] = true; - - if (ABORT) return; - - initRuntime(); - - preMain(); - - readyPromiseResolve(Module); - if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized'](); - - assert(!Module['_main'], 'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]'); - - postRun(); - } - - if (Module['setStatus']) { - Module['setStatus']('Running...'); - setTimeout(function() { - setTimeout(function() { - Module['setStatus'](''); - }, 1); - doRun(); - }, 1); - } else - { - doRun(); - } - checkStackCookie(); -} -Module['run'] = run; - -function checkUnflushedContent() { - // Compiler settings do not allow exiting the runtime, so flushing - // the streams is not possible. but in ASSERTIONS mode we check - // if there was something to flush, and if so tell the user they - // should request that the runtime be exitable. - // Normally we would not even include flush() at all, but in ASSERTIONS - // builds we do so just for this check, and here we see if there is any - // content to flush, that is, we check if there would have been - // something a non-ASSERTIONS build would have not seen. - // How we flush the streams depends on whether we are in SYSCALLS_REQUIRE_FILESYSTEM=0 - // mode (which has its own special function for this; otherwise, all - // the code is inside libc) - var oldOut = out; - var oldErr = err; - var has = false; - out = err = function(x) { - has = true; - } - try { // it doesn't matter if it fails - var flush = null; - if (flush) flush(); - } catch(e) {} - out = oldOut; - err = oldErr; - if (has) { - warnOnce('stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.'); - warnOnce('(this may also be due to not including full filesystem support - try building with -s FORCE_FILESYSTEM=1)'); - } -} - -/** @param {boolean|number=} implicit */ -function exit(status, implicit) { - checkUnflushedContent(); - - // if this is just main exit-ing implicitly, and the status is 0, then we - // don't need to do anything here and can just leave. if the status is - // non-zero, though, then we need to report it. - // (we may have warned about this earlier, if a situation justifies doing so) - if (implicit && noExitRuntime && status === 0) { - return; - } - - if (noExitRuntime) { - // if exit() was called, we may warn the user if the runtime isn't actually being shut down - if (!implicit) { - var msg = 'program exited (with status: ' + status + '), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)'; - readyPromiseReject(msg); - err(msg); - } - } else { - - EXITSTATUS = status; - - exitRuntime(); - - if (Module['onExit']) Module['onExit'](status); - - ABORT = true; - } - - quit_(status, new ExitStatus(status)); -} - -if (Module['preInit']) { - if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']]; - while (Module['preInit'].length > 0) { - Module['preInit'].pop()(); - } -} - -Module['onRuntimeInitialized'] = window.onRuntimeInitialized; - -run(); - - - - - - - - return LibYUV -} -); -})(); -if (typeof exports === 'object' && typeof module === 'object') - module.exports = LibYUV; -else if (typeof define === 'function' && define['amd']) - define([], function() { return LibYUV; }); -else if (typeof exports === 'object') - exports["LibYUV"] = LibYUV; diff --git a/LibYUV.wasm b/LibYUV.wasm deleted file mode 100644 index d30220dd62b91999e2f1443f84f0737750bab9ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18588 zcmcJXS&&@Eb*AsVwRcsa3qS*G01e_~p+Ph#fPf$nga9tMAc=(_2nt-mMUAaN^zFt{ zjc$;XC^o2FvNV=$*&{Dw)0SjvWJ0E8+Mx$UjACLQ^e_*OiI@mRj2`^p2gSrZ_(2g9 zF%u!p_h;Vfs>Wt=!p72h@6D5$Cr_U9=YR56S9J37`8bNA_|+vRT5n$WCw}upJRi@W zi1a_=IyzC9pVyNjg~|by;SYDod@d24DEWuciE^lnPE>NS=tMogQW4K52MdLX3s*`f zPhFgujr{e>iSw6F&rDvLowzVQGjVzHGZW+ICQe?8VhP?cK7Q`xg)`F=Dh}jm!rZR z4_~~18ned^>`Qm?XZ!JIp53v1+mlgoAl-N1*wYseaTk@lVtMWMu6R@$kigRyB^*`D z=jr<5>1e2Uc4lHCTCr+;eDcDX$(f1Mv*TyyE}Wj7ym(=J_T;JQi8yMFk5A0ZT(~$+ zgOjR=mY2_-ou0dVE*h+5`SJ^~0=R(P!>p)5!~yv(egB zH#~o30u7|ooj0#Lb@K8=v~KvO?ItdqiEP>U_+|PCqfAeppPaoM-Bqi_Q5x3^8^<;c z{ORZ8jm4<7w*Ehoc*Feq$Q4s_B`aEK%9WG7R&H-xUpQQ=UB zXEH(&?@Wd%lAXyAMPX;svhr9m>?+(aO;fY&F)i)tGEGI{2?^+>u4bZMc6^<2DwID^palFU63% z15*vlCg+23i?=fF@D0YDy@_#Iv+Imo{qV;9-?jK^EY}@Ke-`0Y16H4M4c4R4{%WiR z;pc+)el^yTG~~X!C~)5$6u9p;3fy-yMR8{`Mp4?Cj8c?$CPslXk5E+Q?+vTr?`e#; zHmr%4V~r(TE|D8I#*$rbFpXTx2IaN5>{45Hz%569$d=ns$E`^A>aVSMv>8c$n_G$e z9kx<7#h`fF0k<0YH8|Xw4&FMFOOCmf~_uHN+_W=DoAnfo~doc9%5DoX*L$-IyrFyc%?X%SOO}mHfL3=oJkI?85 zzkaHFl-~B+etUGv9iZX>D_ZB#L9P!1N6Fp-o}ef`6ncM*-VfVjc6iD?Zin0vd)z%? zN9>7%?kF`++EIJ5<344ddbAmTTMMb$m8VwXFvVw-y*bn~Jezh*C7vlnmCfjYJ4d!4)#I(b>e z4)FgwCv%snyX@mm3pY!6&DpHYW$p?US6J0XR96_w^Im1}*X&h$t>a$D z&0f#ltl>VR`d#j`VbnLm0H0Ga?B2vf=IyiBZ2p?Pam_w=&EC9)N$fLSb5z|`?-9G) zTfW@pKJUw6_l4Nrim%z{`TvFZ7XA3OyBe!Ax#t&YYF`9??)THU-+d_-dVN`szZ_@o zD=~BVO5FaMM=*XaAlTPDf_*6-tbe%@pAqiW)v{r9H07E!Yqrk|_Rja(oEPXd1L!pa z=rsfAH3R511L!pa=&=dQ_{{)%%>a5$4|+Tt!2W3gz-tD;Ys$(W0q~IjkbsBehXgz% zKP2EGIrO0b55ZPH;58Qj&)0lN!1J<;0Iw;)YZ(>h9#qkCivW)&BR2qEQ-H^csBRJ9 zH3fJh0q~jvJT^W655We2=X-w)lmqZUyTkVQL3f0B@qpKHNA0Lk4yh`@N3jdwqu2)K zQH+6k6b9x|41;+TLtx&guGz6`{g8K4w0qJA4oybDN8iu$_Pjlp0eVe4o=;~7*hk$i z_oBUMFJ$f|>RuAC@UY=tMpqAO9XF0+k1MvR*z8WI*ao_RZ$h`Gof6FOa1@ZE7;|U9 zt zqUwU8DjTf-I*ykI{;|z1q91G2U`?;Vng#A5nnCc3X23l}GvFRZ0rwEifP08$5Qc1x z3d0sfReaiW56?0-i+*UPP!Ab-FhCoUvcggo2Kk^Ef-h6F;2#tXw?YM6F1=cXbr8lj zD0XejL{DIK(6Ls<4X4}SA`M%Wxz)^nb$dk98R<=DMAI1_te=Zpntq(NTw<{$Q?6hI zfeo|LaK-dDv2qGmwo>4(Pq-@UP$L1Tb)aoxZ5R&L78-b3HRG13olgNekg3*S{oObo z)<^|LDl$ZIif&65?T!X1;@!~_iez^LjBSYqU0LmYBGO^J{~Uz@r^!F4UIJ`V?P0Uy zn(13{K(uK_9I(NR5s_-TrIPX#t^92d>w*_EGfxAc^m~-W%}K(#Ru5wSp08L_sEJgANiEqDMYxQ=!%4S9F`?)0mf5l`QG(Op zKtn{Bh`+8^5@{I_?8?m(+)W2kR z`iV$v9a{N}HFJ&%=clGgw5eFHEH!hZRE#pi0CO$3f&1Ggtb_HR*W(}ijH(0#cneLr z3Z|{J|IX79elF0Fzl((e6|-FfIa0Rqs^ObrSGq?O@im<}%VNFF<;w9!4cVYGoTbWLIswD{~uB zX3RF)SmriydADt{yXV};nBd3u#LL3?n{Bh)V~bk*G^^vbhMH}*ZA(;gA6LzG`?ziI zkYR1LPh@UK82DbhS50?Hz^7Lox65|eu8a)JYqr~VtA{-jAhWXjJLFcMvI_E+S8eP26djbXYAR` zJ;x>7z@DFj9aQYNFtQ>*dqG7Dc0jSrz2xETWqZM1?zm6;n{jx91WFO=#UqtXrK5B-QczoFle8mfVH75Ds;H2Ze z78^2OBPIDdqV{#aZ}~odE4JUFN$kGin|w32Z^ZUZn*6)G&)<&ix4po(yuk0o_N~}{ z2Z7&>4VmAi&)-v@zek@yf%N=#Y~Q9ylh#KX9)N_D_A;aDPTi7WwVisCk>Fe;ywEMQn)t z1rNR(9(*shKa1^qJotWWe;(U+WBY!LQ~jmaWz@YB8~^?i-r*gq>VA-q^dIw)ei-`s ztJtXdEBbjiJh&DcBG-8EqwwIbWBXxjf6asUVtY5XAI0`wjH~^PAIaR0W8>f7Xrwxj z{I@)|zh$cLYnk7V+kfw2nV$=={P%+8!TM+8`t{U|7KQeJsN6tLd_W++h_hL-)q-6W zL`AEjWmR^9a;xSlkS`usHFGuks&IR^1hD^+Sz$+8?qL1@ zl;cTtUP=EU(xzh7sa%_zlJuH5;!%#BvEUOFaKs}NaPET?aPCJam?+Z`8@S(U$^Zsz zK(4rmCnCUs->x9wcYh=IC8XGxtkq%fuh~)^D*7Hg1#n#o5YGM(SfO0S3#_!2TcWhf z1vpO?7pU1P!G{-sNp6i#xHTBvpIOhcS3w2l*sE$H0%JjJovqu-DX25#oSC^ohyY4`h&q~wyv6u31}G9+$I%cVH2AsS#CK_2W|5ew?!4BVe`t^ zylS>p`3hY>!D(U5w(XAA=6Zce+nTjRE;!)$2V?Gv+XXgll^bMD?0Z8)6!nlXGlp$ofr92Zl9!!1pW6doXnW5Ka7n;Vj!*YJ0W4 zq3A9S4ENc?)9w+rzeh55wwgVvjEcGuHaM@^0ooq419oth{f!-Nj{S}L9pQ{{nyeYI z)$DJ>VSAfZ)@)DAvArR-jfDA0`_wcE^W%0bV}sjoPffAG)$C~{ZGNO@LKn}{#dG$o zJvYl%$7ZLkj{42)amVe2Y4*5h>_uh3HD$o$dBXgc({jjw=Q!9KZw-?9^8BDXX=J_v z9`0K16jG<{l%1Z_R)^Gtoja#h5u?J0>*^~9$H1XVG^5ek^$Fa^AO zh=R~-Q4o6MwH{+Y15XR#<(>pq#li=SqDlzn?3)8F8&E0%86;~x$g3goZIagxS*fJ*d3}v8JTWXC>BoJGvdrwtYx?5pxy4wIBVxggWw|0 z9T~FgxVEm>llZOgbc1TRO9w~oF5YI0=uJ{A3rK{eazL4|Is1-JHWe2;xCup&cFovg)88KG1 zqj*B#H)y~C75({O>$qdM+c9w)ui8`gl#KPX?sQ1?jP9P*-4OBiobI02U5j}0#S8Sr zVN(b;|Kw#xUN}DINke=xCdi)lbW+!+iQLm2PQt!Wq1!j*RMN;^sm9n6)tn!lXJ z9V=$-Qd*cr=7U;B%GfSqq(;o-%y9|)!OAFP4Sp$K}9Qa zEsukbUs7HC~aIxTRdcPY3WK@?X*i4&1ewKHMx=&JMH2On)$iMSJLFV z`*`6#w?d_B1vILnD7*qIR2EsG4RrO}p(r~rqlQJY1C3+{pY37?Su)I>E4m8y;M8gg zqj(cYzf91_!dO}ET-JJ3v71JB-aJ38Ip7e1Bn8@L+tp537^`B%A3$MTwYM^2Y3=Ia zrfe%{t>SndVHsAs6?KFt-TWG1TQvS@jS?l^tFa_nkauhCns8LlYg7LgCQp;u^n<#0 zI!J#}{#uygK(FFTLVhO88Az)gVUbcg<1icreS#Va{iig^zHMC?V#s#Mku9T-l zGCE1ck!BLyw#^~M;bx*VV_0v88HLM68}hiHfvENVzu?=fJ?7$>`75v{Y*q4dEFL;Q zyEeK;UROFmX@3rpwlY_$7nlh9Rm76^%T;}?ha$Dp(PvY`HdFeJ{A#)?16ZRQ5EUsm zg5LzgwXp*(M<7Tkel%mPRX0}Otu>NvtTxnfBW8pZmh?G{ z;b0g)6YL+N-EZQci<%B&s@|#)p8a?OT=m5S*gFr~oInt(+f5m+l9%RNMh z>3AV%1^|)}C0u3l;>A%yaD^x-NdcmS>V)$R6Qo%ZqJ)bOB_&trMTrjB+65maOixkb zv5PQP9H<~zs@O(nQ$9Qx{k@u|Eof^L^#YtG>3^Enyac(-ir0^YJbV<(={o-^u0X2! z8~jdURltej>aQQl(w0Z9XjYh*Uj4^){)tcv$i(TdULEvLz^&43I(P-0z_ZfK6a&Sx z(l=d^ae&a7Njbf0N>@dYOyC`}*%x9Z0fy86fD}&16s4>1xA+S0H_~7cZoF@P~OTw`lI+Ex`O&QB2Os?dt3)&SfvN{C4s#M{{Z%j?g9J!KI@sq5qFAJ z1!*6wFyll1sFP={Hp-%mMi25}AchN>Wl+8lx~fwq$}{ssKR&u>?U4ON0PP9|TpjOzZ?vP*lp@6oOC+%{&B^0|d26q5DCormkxq zgp{o?TRcUCB6PR2(cgb zgAllOBM7l>IY#kTJO?4J7C=a^vlP)q&#t;S~cH|95|k;gIjqW6=>R9RDu{O_8|`8~_6H4-kgSc)M+6o|WN5w;+!E2VVkx*_c<86MBTE-C||CRt$NeRfYDKpv#6xl4FwZ}FBH{XBKt6Bmz zIO-{__J^O;P{A>x&YS*MgOZ28q)g{`CO^-Ejs!fOzk9bACpP+1(j*$lk zgMSN6{)=e4q_vK@8#BEI>8%_9uS_!E0EJ#--NT4VxBZBqh7bDC;rpC%E9s12jM78y zm=En8`-Y*F(V%{?XBGM)&1FY?5m@AnE*VX#SnIA?0ei7RR+7VVAk8BQo<5*Y+M?==aS?O9%EBD&XYqN~g&K!g-yC34*whc9W& zn11+LP9CW8wv>zx9FV%wCja+IP1~oWFoMHP{6SO@1w0?a8@=|@>j%pC%K7O`qVZTV z5lL8$8fr~KLne(ED6`2qg+}dW!O{dzNkU7nPPcg&H&9S%paHIZG`QxXC*v&q1N21hqFADvc18eYvk+kDv@4 zhHm#9laRsn@VkmmH9gM+rL$K_d7(Eeu~gUxgvqb;czuw zBM(%fm`0nDe{S4|VXM0QC6`=qQw4qhS-a=;yC_ro6$xrOOb8cV`N_>a|Hjkx5b`c3@%^f z(8li)2n1B?rdPLjem@DV-*7+*CXB&u;{QI+3jW{Cvw-*O{a=7}Yya1AAU5k8jzpwu z#e5qH=4SK2)-e#-O|=N!An7%xA2jx;F4tUG2OY7E!A)>VxV4Tjx%mIfW|DdYZd%|L$O13!Q|aL)}f3L@K6L4 z3b31g(XzIG|NDC_pW!Pt3Y#d{BGkaDT?PBLf7D_aj1ZLJoykqNf8M)ccc363x!?YE zpu{{mdtw$e)GLMDgV94L3uS-49gKoj$||s_wDMDKg)!OJG1HLhbBB=(t+oBSMAf#gkZ543kd0Eh@apk{?NJ<@eqh z^k%(}$&v^#2u!xG>)?c>dSXh_Ae29?4YG!zvaho~jvG2dmqyu!ICek* zZLYX9I35^n8UG5#?qjv+?^!L|`C_+D`dKYr*K3TW@g=#oZ>;rM#AP&k*R`b)uFclp z9hxWp=-+q2hk?au^=pmc>L%{3)9to=&a+#Ne0q01_b!lM7lV5*hPEZK8$ zbn-6VHC+gU>s*{jV4d~88K=A6k3j>EeH?uV+vRrNwJW!FeW2MB0C^kUL*RJtSwsMU zV*ipS5CGP{O91*_@i4AmXHNhK4_KI@1RxF6mmYY?=i{Kha#=?0e@){LPJ6FubSS_c zw)i!T5|zH!G-XeHapV~*Lw(sAW{m~xCjclD2Lcd_00gAy5`dijhG^s!tj<~W{yfYQ zC+_lJrXie#0%&&@1z?4sz>LUIYatx9q6a?f%3yDKfdWU`!3v_lEVU>wQcNPJ0IYY^ zF83&~=#y}0(QsPt+>R7|ESRoD0sOe01!L$SSyaJBv_Jtk8edomQ2;p!Co-JB#p%4o zkkX&yC)&@SiIaKNzFlKe#UZlv4NlH-I!F}72Z<4efjnp{iXP%~6SMvlti>l^<@s9e zw*fEu%eldPoy~=R15x^&X6ugh?Pk5=FNf{|Zx(Arw>mK2Luh|;qv@+S-TBYR_ zvnlLFE|z)JZRAa+4!y;QaXlXiM%%#aQr}v`X!H>V=VNr?=(M#Owpssv&{og;nqEsI z{kz$(frV$1A6*(n@2vJM0pxjYJ-R7saTTwLUYbSMEar^z-SoDA7+#Q8)`iO7wB_GMHzTcy8;}>rfyI-i${UVL-_imKB71w{$M!E0%I4Z6DOE+kJ zbzn4UcK`rMV>yH8J_Jb!8Xz4wkyUYOl9u&4W&R!?6%J~nsZ^5iQQ zCivaHb0=pu+wE>Q)%W%_-u~Lt7oX`hzkH6bKj~|K)B8=0>w9?iqxR5jr2ZR8jvu@D z>iEM;n&Ix5XZ`KqvaW&;Ytnwkt>xWk-VodT!=+!3yHAhLU3qfywTbDTBLA`_`sOL& zyZ`0;zR~!u6}~^@!t7-`t*g5?EgNJZxAW~OEQz1S@*BPtWvF^)I()0jit?FheTB)& z;^k8_Q+Jfd_01_$!`1QexeK~lH84JY@$9sJy1EgrL(Lj$Byo0fdSZl{@KkqeZ~hG` zxA>A2jlS;I-=AW){Q4Bv`$CuYqVIEA-}iMcqxsjrY#?017s2F;PMo>xCf~lYapctN z7e>!sI(_o;?3Ri1bEAv=VQkG!YlH7>y7Riq>sFz%r4SABeJ}o7dM;fgdM0M#diMce e2a{mLP^<5asVz;S$~`j|&zzh+8JF%+@&5p^DG0Ry diff --git a/index.html b/index.html index 7cbc71406..aef6abe0f 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,6 @@ - Vite App diff --git a/src/connection.ts b/src/connection.ts index 56f132641..feb27255c 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -239,6 +239,7 @@ export default class Connection { draw(frame: any) { this._draw?.(frame); + // globals.I420ToABGR(frame); } close() { diff --git a/src/globals.js b/src/globals.js index 2ed654aac..86e6100b8 100644 --- a/src/globals.js +++ b/src/globals.js @@ -5,7 +5,7 @@ import { CursorData } from "./message"; import { loadOpus, loadVp9 } from "./codec"; var decompressor; -var wasmDsp; +var wasmExports; var currentFrame = undefined; var events = []; @@ -280,36 +280,67 @@ window.init = async () => { await initZstd(); } -function I420ToABGR(yb) { - if (!wasmDsp) return null; - const yPtr = wasmDsp._malloc(yb.y.bytes.length); - wasmDsp.HEAPU8.set(yb.y.bytes, yPtr); - const uPtr = wasmDsp._malloc(yb.u.bytes.length); - wasmDsp.HEAPU8.set(yb.u.bytes, uPtr); - const vPtr = wasmDsp._malloc(yb.v.bytes.length); - wasmDsp.HEAPU8.set(yb.v.bytes, vPtr); - const oSize = yb.format.width * yb.format.height * 4; - const outPtr = wasmDsp._malloc(oSize); - const res = wasmDsp._I420ToABGR(yPtr, yb.y.stride, uPtr, yb.u.stride, vPtr, yb.v.stride, outPtr, yb.format.width * 4, - yb.format.width, yb.format.height); - const out = wasmDsp.HEAPU8.slice(outPtr, outPtr + oSize); - wasmDsp._free(yPtr); - wasmDsp._free(uPtr); - wasmDsp._free(vPtr); - wasmDsp._free(outPtr); +let yPtr, yPtrLen, uPtr, uPtrLen, vPtr, vPtrLen, outPtr, outPtrLen; +// let testSpeed = [0, 0]; +export function I420ToABGR(yb) { + if (!wasmExports) return; + // testSpeed[0] += 1; + const tm0 = new Date().getTime(); + const { malloc, free, memory } = wasmExports; + const HEAPU8 = new Uint8Array(memory.buffer); + let n = yb.y.bytes.length; + if (yPtrLen != n) { + if (yPtr) free(yPtr); + yPtrLen = n; + yPtr = malloc(n); + } + HEAPU8.set(yb.y.bytes, yPtr); + n = yb.u.bytes.length; + if (uPtrLen != n) { + if (uPtr) free(uPtr); + uPtrLen = n; + uPtr = malloc(n); + } + HEAPU8.set(yb.u.bytes, uPtr); + n = yb.v.bytes.length; + if (vPtrLen != n) { + if (vPtr) free(vPtr); + vPtrLen = n; + vPtr = malloc(n); + } + HEAPU8.set(yb.v.bytes, vPtr); + const w = yb.format.width; + const h = yb.format.height; + n = w * h * 4; + if (outPtrLen != n) { + if (outPtr) free(outPtr); + outPtrLen = n; + outPtr = malloc(n); + } + // const res = wasmExports.I420ToARGB(yPtr, yb.y.stride, uPtr, yb.u.stride, vPtr, yb.v.stride, outPtr, w * 4, w, h); + // const res = wasmExports.AVX_YUV_to_RGB(outPtr, yPtr, uPtr, vPtr, w, h); + const res = wasmExports.yuv420_rgb24_std(w, h, yPtr, uPtr, vPtr, yb.y.stride, yb.v.stride, outPtr, w * 4, 0); + const out = HEAPU8.slice(outPtr, outPtr + n); + /* + testSpeed[1] += new Date().getTime() - tm0; + if (testSpeed[0] > 30) { + console.log(testSpeed[1] / testSpeed[0]); + testSpeed = [0, 0]; + } + */ return out; } async function initZstd() { loadOpus(() => { }); loadVp9(() => { }); - fetch('./LibYUV.wasm').then(res => res.arrayBuffer()).then((buffer) => { - LibYUV['wasmBinary'] = buffer; - window.wasmDsp = wasmDsp = LibYUV({ wasmBinary: LibYUV.wasmBinary }); - console.log('libyuv ready'); - }); + const response = await fetch('yuv.wasm'); + const file = await response.arrayBuffer(); + const wasm = await WebAssembly.instantiate(file); + wasmExports = wasm.instance.exports; + console.log('yuv ready'); const tmp = new zstd.ZSTDDecoder(); await tmp.init(); console.log('zstd ready'); decompressor = tmp; -} \ No newline at end of file +} diff --git a/yuv.wasm b/yuv.wasm new file mode 100755 index 0000000000000000000000000000000000000000..37925d29b447a61ea8996750576711cbdc06437e GIT binary patch literal 8238 zcmcJUzmFuxb;ql!yXVLD3~zK?ip$%juBIixXMlzXLO1~qtSv&^^Z9U)VP{gXJW)%V zGe@3wZn>fWgR`<}*ntBD5}-f<0|6EU1qvj%I4V-}hdPyZ7*Q@0|0y<;#BQmoGd1_e=Nk)^hd76kk%R4{q}HH%~wF!t;lVzxnbDpE-PZ z@)hTwIXryrjjz16IC|ye@YOfpc;)1^2X7pn-23wVBkv}MhewOW8xIceKX~PyKDes) z`n~(SxqkWT;^@c?h7V8fy)ysnd#6V(jO_WZjvk&oSR8RYdrdaH-1^C%4fkAh>5;d8 z{(QG_N$>72cIi8=-zojm%jlDzHyr(nm?OfjV_k6>6054^eMKz`W!D$L?om)PUi7r_f!AP zW-DHgPx2|9Egv@Z{nUH28P6u}PZ{ImR;=T*_v0tx6Yb}jraUp%ci(=GHm9~Zfj*Y^ zo6G0b3LBkgmiC-yRB;%uTsTm-|B(H=z4YAeF^pr)+1RDqLtnZ*hMYb3SMkZ@rQfS+ zuEr}VNU2VZlNF^-ug1rx=xm;f+qcKAt}y~{qxf-qt4sGuSNFihr(8YZIl6iJ>T$zs zbamy@cLwz>AC~D`gB!s$o(+mw`n%&s+l2iX662!3yE~@+oJ*6FJ7dS-=xzr3uhcA% zp659&>;HYu*UL{bX5Q4FV)A8wS^qz1#FtaoU8_#;4*K z%=xr@nEY`>q#_k3biX&4>7-=>nL1&4BMcgBnEqohYy5#N9ee5RSbXi6bB%lrF#XLi ziav&$VNl01wo4U@n?ZIhnHc?zPy%0iMx#3R)A#IvTX)BNDv>3H7*4W_%@8;J3mJ3^m2b%csQ*NpO{?@HDPmfNC0a!n z*x>l3tYsg2EbL+>C087=o_g4zWP7ct!<4bgjh%_LWCMqCZ9g=f-ZecBUqa7A)H(cv zs56C=^xl>M$LtK;`tvFNJq^V^APP6aq;ZI)r){3bNaTbF8!4@UqT+TFcA15SBM&~h zX+ZQ^*x8v%W*$aOc}u{R#a#NKq`M8HcIv=HgOR4BZHyr#+qMkX0md9DO=i5zDOc8`5H}+O7%W?_0)rxiXXSC&eA0viVp*(q*@JkLy3F$*6uw-7#V}* z|3D7DR>Kr48sLikO~`rRHdSmwybQWh52eOT8ebCHfd^=<4G7TMOX#J@yoH^mC1A2M z?cszxj2bUo8eMMUvZY4D<&ag@aFaV^ph*=Od23v50GORJYK8jqxP)#yDh;CjOeR1O z3&B84`vSet0mpEnhe9MJNMkT;WyFQ&&1`_aW-=3Gel#%bGuv7zs%1J&XjoxI={1T` zyueRb;rm88gWK%<{Q+5u4x;UUJm5dMBxk$i5FL+(ZmAZupPn^CBIt)TQ(5v?YIVM| z(TmH^vh4rVFP^=7#-CDeAJ(x>qZvUseei?-`a$(jJOA@2i}C@Ep!c&_H-3h*poDo- z5maLT?s%B~Q)@RRyS!&lh^*LE+yy7)oy8a$_@E{;0r=xme%=aHFyrU-)B!O-tu;J) zXOdI|_um=IeT=f?7|Bg~*k*Y!#*?N!B+!&1$2qUK3^3=i(2Nrn^W)jHSH~V_#BYCX zJhB*9mz=gIvv69V$!Rr*jacT^*pK>JVK9$K+buFKZGas!n{##`iZqwuc-Zp!S?t|4 zCpNvKjA87}bu2%JquSGOVmGxd{G^wbM$nPmsn>Qhyf>fpu8m66AjxlyD;Na>mz;~n zk1BCC{Xr_`KQxj`g+KC(b{9feXccD~Bq=(83Q3<9eA0;;bd+w)NGfV9n2pFe4DjiF ztr?wQ`98Bj_MjX-NPUDbE+wY3xewdw1(zx^slr5nB z9I4d)bdZ*6e>TWC*7GkJN?V{irCx=S5&TGbmV!8s@6%zAP(4DVcnkE%r+Vpz(u=nc zIrWb@g~w-jqDGn9WN@jIt-LI(QW4V68zf=r-v;TO5ei`^1X6}RBBcVp)g9$f6*`r0 z(DqEjS+8Qhs@< z%FN(|uhyG9hhLpuX+`IUM&3}3{Lp5Rg%ZMWVF6@qWK`5ws6`KIk*a%Us@u_qnN8QHo*L7aY?r0v*eS?sdg20L$A zDCP6bup?23tjJ_?P&H}A9h2MgRo*4w_UZ!`7QbO?rIT4LWqO;Ms3hcd{uX2`bK%fh zgc!Ou#WWDua;Zizj*bkeOa9r=l7D5u%DYJZHrt>nL9~S(wm6;BPUN4Wa*D$+0p^edfJ_(Ps4#&ssjDg-68D?86o|5{l~#nCVsQW z0evzSJo|XyXoCdbcgU~MhfCmsfm5U+GyW;j+EA8beUBUEy+@E9t8*WyQNIFCx(e2?x-5Gux6 zIO37=uMIc`gChY?`k?M<;RxkWC0&3c80_F^ss)ba0qN6uII1cV92rdsA%ocJ6IMqx zz>(4^t4Mki^)r$(HoJ3SAdQx7?_>lExzc7$?QZ!sS(3PbDYg)nl>w|s-O0Oj1`yQ6 zz?6M=DdWJss?*;k5rBp|RpJpCC%RX}{Qy{f0-Q=)w|ZQM3YvQM8A;(EJ5f1*}`#PaKu?A(F=~5 zA1yhsShdrZ-6F3Jj*4A&(iV>PLCJxASi@1*3+Lddl>7o5$v|4P@`R#RaJ0Jo{Jmk9 z!)@LhX6un>ty71`?hQq798DxZvvF@|?4q<&Ns2BCw4X{bsaB=*WM)^{|2p#hC310- z!uivH@`I+Fi(*KZxzFJ)lkcQ4$97*)9HT*`7jrgLW<`5fmn$^|tsW z@j4oE?QzR8w6R#?NwVN5)p`EH-jBL*jHS83tJDHNB7fM$_EB63) z{pE20KpwdMD|5QqedL_FOU&?Ku<}gwN!vsAZu1R1Dyb1Yaw*QRmL6B>Dild?E(lfx zS!@y{f>9dDX%K~LHzP=Uoq9B9j z3n7${ON=Y57%N?MwX+GImWXrTF0>JO>_$g*1htN^v#xax z8lr6xCe!|Z7^4Jlz2B2tj@$5!-$iojW}!*<0JXx6AfwntGt$v=BSPR; zwCjv0x>BVJxzHHD#BjEa0*QUdo;UB|Nlv-oO=s(S_;P&@UvdwxD{r>RQmqom{dy{q5FTyl~&<_h^tR&12pIt#t1fa)mZ>c|+UOGn`p3%yREH{|Mw z(I*HD%~<1aq Date: Fri, 28 Jan 2022 04:14:35 +0800 Subject: [PATCH 31/66] yuv-to-rgb.c --- yuv-to-rgb.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 yuv-to-rgb.c diff --git a/yuv-to-rgb.c b/yuv-to-rgb.c new file mode 100644 index 000000000..5fb37a030 --- /dev/null +++ b/yuv-to-rgb.c @@ -0,0 +1,84 @@ +/* + * Copyright 2018 Google LLC. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +/* + * Brute force conversion from YUV->RGB for testing only. Replace with WebGL + * shader conversion ASAP. + * NOTE: This code explicitly knows that the input is 16-bit 4:2:0 YCbCr + * and assumes there's space for 8-bit/channel RGB to write into. + * NO ERROR CHECKING! + */ +#include +#include + +#define ZOF_TAB 65536 +#define ZOF_RGB 3 + +static int T1[ZOF_TAB], T2[ZOF_TAB], T3[ZOF_TAB], T4[ZOF_TAB]; +static int initialized; + +static void +build_tables() { + int i; + + for (i = 0;i < ZOF_TAB; i++) { + T1[i] = (int)(1.370705 * (float)(i - 128)); + T2[i] = (int)(-0.698001 * (float)(i - 128)); + T3[i] = (int)(-0.337633 * (float)(i - 128)); + T4[i] = (int)(1.732446 * (float)(i - 128)); + } +} + +#define clamp(val) ((val) < 0 ? 0 : (255 < (val) ? 255 : (val))) +static int foo; +static int frame; + +void +AVX_YUV_to_RGB(unsigned char *dst, unsigned short *src, int width, int height) { + int r, g, b; + unsigned short *y, *u, *v, *uline, *vline; + int w, h; + + if (initialized == 0) { + initialized = !0; + build_tables(); + } + // Setup pointers to the Y, U, V planes + y = src; + u = src + (width * height); + v = u + (width * height) / 4; // Each chroma does 4 pixels in 4:2:0 + // Loop the image, taking into account sub-sample for the chroma channels + for (h = 0; h < height; h++) { + uline = u; + vline = v; + for (w = 0; w < width; w++, y++) { + r = *y + T1[*vline]; + g = *y + T2[*vline] + T3[*uline]; + b = *y + T4[*uline]; + dst[0] = clamp(r); // 16-bit to 8-bit, chuck precision + dst[1] = clamp(g); + dst[2] = clamp(b); + dst += ZOF_RGB; + if (w & 0x01) { + uline++; + vline++; + } + } + if (h & 0x01) { + u += width / 2; + v += width / 2; + } + } +} From 604dcd6748084f9aa4f075f1f7dca45531cf3f94 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 28 Jan 2022 04:30:38 +0800 Subject: [PATCH 32/66] improve yuv --- src/connection.ts | 2 +- src/globals.js | 8 ++++---- yuv-to-rgb.c | 22 +++++++++------------- yuv.wasm | Bin 8238 -> 8573 bytes 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index feb27255c..0703668af 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -239,7 +239,7 @@ export default class Connection { draw(frame: any) { this._draw?.(frame); - // globals.I420ToABGR(frame); + // globals.I420ToARGB(frame); } close() { diff --git a/src/globals.js b/src/globals.js index 86e6100b8..ca7281dae 100644 --- a/src/globals.js +++ b/src/globals.js @@ -41,7 +41,7 @@ export function pushEvent(name, payload) { } export function draw(frame) { - currentFrame = I420ToABGR(frame); + currentFrame = I420ToARGB(frame); } export function setConn(conn) { @@ -282,7 +282,7 @@ window.init = async () => { let yPtr, yPtrLen, uPtr, uPtrLen, vPtr, vPtrLen, outPtr, outPtrLen; // let testSpeed = [0, 0]; -export function I420ToABGR(yb) { +export function I420ToARGB(yb) { if (!wasmExports) return; // testSpeed[0] += 1; const tm0 = new Date().getTime(); @@ -318,8 +318,8 @@ export function I420ToABGR(yb) { outPtr = malloc(n); } // const res = wasmExports.I420ToARGB(yPtr, yb.y.stride, uPtr, yb.u.stride, vPtr, yb.v.stride, outPtr, w * 4, w, h); - // const res = wasmExports.AVX_YUV_to_RGB(outPtr, yPtr, uPtr, vPtr, w, h); - const res = wasmExports.yuv420_rgb24_std(w, h, yPtr, uPtr, vPtr, yb.y.stride, yb.v.stride, outPtr, w * 4, 0); + const res = wasmExports.AVX_YUV_to_RGBA(outPtr, yPtr, uPtr, vPtr, w, h); + // const res = wasmExports.yuv420_rgb24_std(w, h, yPtr, uPtr, vPtr, yb.y.stride, yb.v.stride, outPtr, w * 4, 0); const out = HEAPU8.slice(outPtr, outPtr + n); /* testSpeed[1] += new Date().getTime() - tm0; diff --git a/yuv-to-rgb.c b/yuv-to-rgb.c index 5fb37a030..14eb60c78 100644 --- a/yuv-to-rgb.c +++ b/yuv-to-rgb.c @@ -24,7 +24,6 @@ #include #define ZOF_TAB 65536 -#define ZOF_RGB 3 static int T1[ZOF_TAB], T2[ZOF_TAB], T3[ZOF_TAB], T4[ZOF_TAB]; static int initialized; @@ -46,19 +45,16 @@ static int foo; static int frame; void -AVX_YUV_to_RGB(unsigned char *dst, unsigned short *src, int width, int height) { +AVX_YUV_to_RGBA(unsigned char *dst, unsigned char *y, unsigned char* u, unsigned char* v, int width, int height) { int r, g, b; - unsigned short *y, *u, *v, *uline, *vline; + unsigned char *uline, *vline; int w, h; if (initialized == 0) { initialized = !0; build_tables(); } - // Setup pointers to the Y, U, V planes - y = src; - u = src + (width * height); - v = u + (width * height) / 4; // Each chroma does 4 pixels in 4:2:0 + int half_width = width / 2; // Loop the image, taking into account sub-sample for the chroma channels for (h = 0; h < height; h++) { uline = u; @@ -67,18 +63,18 @@ AVX_YUV_to_RGB(unsigned char *dst, unsigned short *src, int width, int height) { r = *y + T1[*vline]; g = *y + T2[*vline] + T3[*uline]; b = *y + T4[*uline]; - dst[0] = clamp(r); // 16-bit to 8-bit, chuck precision - dst[1] = clamp(g); - dst[2] = clamp(b); - dst += ZOF_RGB; + *dst++ = clamp(r); // 16-bit to 8-bit, chuck precision + *dst++ = clamp(g); + *dst++ = clamp(b); + *dst++ = 255; if (w & 0x01) { uline++; vline++; } } if (h & 0x01) { - u += width / 2; - v += width / 2; + u += half_width; + v += half_width; } } } diff --git a/yuv.wasm b/yuv.wasm index 37925d29b447a61ea8996750576711cbdc06437e..f93a6eb2a012c870f33dc34b1f776175cbeafbbf 100755 GIT binary patch delta 2993 zcmb7GYitx%6ux)n?(FQ&zFLI7%iU?A4aY(L@sx#rmB)+it-^v`MGu-h1BX zJLmNM+_ko5)-%}08DqRkbaS8k-3-6nXWf>sf0!Aw56)?5KC-`PI??BO%mS%- zu(aCx(6)!SY~420zine@n_}!>{&rtjeLcH&^>1gE*fG%C%c8Ntp`PveO+8QbGM>=% z#@@l9{()X*#Pv~Wb~Aod*&hqT@r`HH0eb;s_lX<`#aA(A=44bEL$0lk3}-yU$EnEk zAARapw4d8Ku-MxA^Xa2*LZOY_d_&F2KVhhXoGS}e+~8YOanD6i zMbVjLjw6LK`m#wGQEVL|5sGcdrp%mTSx1`Ls5G*+Od&tW3uTH@V<9!tYxND5P0MKM zGN$v@io1*iZF@w9h3Y@(#dK zvtKdW#k(Z8RP4)^<%pev3)$HO`#JI0EPa=asFM(*QV77&Qpm`V%L{~et$1@}NgZ)W zgM1_t(gc-AIO=V(cR2F6IR6reh&3pV)6LV?UZJ0^SqJsg$bo2thfJ^An?g4)+sz?& zWh}ppv{INx7p#uEV=TWyJH3mzN=uGTDM8Z=~ z7SzRK7mh^+N#_Bug)UqIL-0<#am_cOVpl-*`4VkP12vOom*i5cA4tX>Mf?jG&{s$b zBWL8aXOs&QazElRh&b~rB1nSYk&K|%EbUW}bCzXpG!g7|YIr0#s&rmW}(^%<4Yr@JqRD%FzCzk){>#LP*i%puoQx+$btY6U_w4i_QkRcUO4 z4;{>uqz=}g37$wc35}GmDrd$<$;5uj=!xXqd3245xLZc@Dq4Ww5ws|%Iu~uJTZLd3 zs{dLhw%qh&3u=o$AmI{r6S5hx+&^B!fZ$dX^8ko}41Vcq} z)Ker(2aR0nBWiiwFj|nBC~T80>CFviaq>E9F~Y1?BT=3vVdsygM_lS`sD~Nokzv{; zPjcP+;Q)9w^H!5qlr=EmXl76;F;*oTa#?whJWz4GNvp%4$!SsIGef>`;OMF0R=y}G zzMEzL_sZp~FQdG347S3^0J@YPeXteXW$BxIZ-p5{K0qA<;-%DrI;ekLH&#~|HI$f zU~$!R4PmA^H68Y$u7#m%p>uq;>da)Tv_{~mfSXd3iW|IFJv!Bj2z8+q%az?TJSgccEvcGm5lh}kB zlR}Sz8!&ly-B3*L3u=s@p|LUex~{2_DiBKPI_N!CZlxeoUp?M5ok>%7NjTHVH%+A- zv^kwhT6EB~4MS$K2rV;$LjB@NaYUww{Jyq$0C>16?MyzCYh|+PKILA)3 J9Sn@_e*o_$63qYr delta 2665 zcmai0O>A7%6~6brpSd&ljc4M2d;D|e5pV#frA|l$lxS`Q4k3zY0U?!2I3YNY89TxD zB&t=RHvuCm)J4$?KZ`6PHK-N@6e&Ss!6J)_s;U=3P$?2wAORBHu|QQ(Dds!(d0bjHDc1|rcpAd3jYU7MAzo{tC|K%#ttr5|UOn;$FXo3)!f4Q{IL% zP<&q3t9>|2mayo@;yK6x$Y&u3Ax}eAAX|__UX8lp!lTH_Q^XGH)lL%R*Q;HmD4=Mj zUKLp3em>4qfNhC#q}_#dt31x~)VE!TYMJ_3Y@vbe3FI&h@^*wOEJkUF1zAz;LEO%9 zY&r;U#3_{dowQ&{!<*Bp@Q5!%W0NTNLomnVY6xn7&lwy5~F?sH) z9V8F*nX7=htmG7Tvgo9eRh(DBLU1KHqmqTB9vsF!)V;qbj6of+i>P;h>UnV#2>Y5g z`=m(p@4oe$7HL@86@&>-5+DQl+iWY7!V(O{}T?+kbo%`)Xh>YB;U>DxuJ#6wO%9 z-J7|3CfLz)QIldU=QVkdQDp2no&F2J9}^5s?i z5Ca*@Z)Kea@{R51IZ~_+!h06f!y^>s8nLwH2XKlYl7k_rm$nK$sbAo!PsjCoU{I1 z(N{H90|vJ6U~%1~$IW;t#N(35VnC`I0zvwwxjowGHvQ5J$S^HLgx|MDW9l1|J`&x8 z%`*{Syc&&-UE?tDYyEkEG^FgetE;QI14T)yoCUC=9H#$@Mt8563@e2wHb3bqTaw^} zT{VtmhLNsg4Kl0;iZ>+}9C*wt0uc{Zm2>tvP5~3$)p^bQ>n=asho+ev#M}+Hsi@s_+;`8HFAc2}@E!nw zC1;SID~l2h!#(rpme+^5;}m-StV=XL1SFcVX!qL(-TmpEoo9#P2K`ur5qu$oPAlt5 z`1!i?1%(IaI&S!Wu0HJA^^4EU%}VT6WiaG=w$%1B=8LZL12@<23zJTEKlPKSE;~eM z)-^HE0<{mOa_9-4sabESM&sr1UgmCb`O^B^c} z7wYxF9XD(mjOYkAmU*a@>stj0^OtmWaBsI`;eK=~xWL~C51dMWQ=v5?De^WE>6J=G zB&5U<3E#Ny6R9!O Date: Fri, 28 Jan 2022 18:20:52 +0800 Subject: [PATCH 33/66] make event compatible with native ffi --- src/globals.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/globals.js b/src/globals.js index ca7281dae..ba1be3f9d 100644 --- a/src/globals.js +++ b/src/globals.js @@ -20,7 +20,7 @@ window.getLanguage = () => navigator.language; export function msgbox(type, title, text) { if (!events) return; - if (!type) return; + if (!type || (type == 'error' && !text)) return; const text2 = text.toLowerCase(); var hasRetry = type == "error" && title == "Connection Error" @@ -34,10 +34,28 @@ export function msgbox(type, title, text) { events.push({ name: 'msgbox', type, title, text, hasRetry }); } +function jsonfyForDart(payload) { + var tmp = {}; + for (const [key, value] of Object.entries(payload)) { + if (!key) continue; + var newName = ''; + for (var i = 0; i < key.length; ++i) { + var ch = key[i]; + if (ch.toUpperCase() == ch) { + newName += '_' + ch.toLowerCase(); + } else { + newName += ch; + } + } + tmp[newName] = value instanceof Uint8Array ? '[' + value.toString() + ']' : JSON.stringify(value); + } + return tmp; +} + export function pushEvent(name, payload) { if (!events) return; payload.name = name; - events.push(payload); + events.push(jsonfyForDart(payload)); } export function draw(frame) { From bf9badb10e4c097f69041e605b8681b7b9aa2c6b Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 29 Jan 2022 11:31:05 +0800 Subject: [PATCH 34/66] more api --- src/connection.ts | 76 +++++++++++++++++++++++++++++++++++++++++++++++ src/globals.js | 5 ++-- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index 0703668af..fbb0f3221 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -357,6 +357,82 @@ export default class Connection { getOption(name: string): any { return this._options[name]; } + + setOption(name: string, value: any) { + this._options[name] = value; + } + + inputKey() { // name: string, x: number, y: number, alt: Boolean, ctrl: Boolean, shift: Boolean, command: Boolean) { + } + + inputString(seq: string) { + const keyEvent = message.KeyEvent.fromPartial({ seq }); + this._ws?.sendMessage({ keyEvent }); + } + + inputMouse(mask: number, x: number, y: number, alt: Boolean, ctrl: Boolean, shift: Boolean, command: Boolean) { + const mouseEvent = message.MouseEvent.fromPartial({ mask, x, y }); + if (alt) mouseEvent.modifiers.push(message.ControlKey.Alt); + if (ctrl) mouseEvent.modifiers.push(message.ControlKey.Control); + if (shift) mouseEvent.modifiers.push(message.ControlKey.Shift); + if (command) mouseEvent.modifiers.push(message.ControlKey.Meta); + this._ws?.sendMessage({ mouseEvent }); + } + + toggleOption(name: string) { + const v = !this._options[name]; + const option = message.OptionMessage.fromPartial({}); + const v2 = v ? message.OptionMessage_BoolOption.Yes : message.OptionMessage_BoolOption.No; + switch (name) { + case 'show-remote-cursor': + option.showRemoteCursor = v2; + break; + case 'disable-audio': + option.disableAudio = v2; + break; + case 'disable-clipboard': + option.disableClipboard = v2; + break; + case 'lock-after-session-end': + option.lockAfterSessionEnd = v2; + break; + case 'privacy-mode': + option.privacyMode = v2; + break; + case 'block-input': + option.blockInput = message.OptionMessage_BoolOption.Yes; + break; + case 'unblock-input': + option.blockInput = message.OptionMessage_BoolOption.No; + break; + default: + return; + } + if (name.indexOf('block-input') < 0) this.setOption(name, v); + const misc = message.Misc.fromPartial({ option }); + this._ws?.sendMessage({ misc }); + } + + getImageQualityEnum(value: string, ignoreDefault: Boolean): message.ImageQuality | undefined { + switch (value) { + case 'low': + return message.ImageQuality.Low; + case 'best': + return message.ImageQuality.Best; + case 'balanced': + return ignoreDefault ? undefined : message.ImageQuality.Balanced; + default: + return undefined; + } + } + + setImageQuality(value: string) { + const imageQuality = this.getImageQualityEnum(value, false); + if (imageQuality == undefined) return; + const option = message.OptionMessage.fromPartial({ imageQuality }); + const misc = message.Misc.fromPartial({ option }); + this._ws?.sendMessage({ misc }); + } } // @ts-ignore diff --git a/src/globals.js b/src/globals.js index ba1be3f9d..3aaf6685c 100644 --- a/src/globals.js +++ b/src/globals.js @@ -54,8 +54,9 @@ function jsonfyForDart(payload) { export function pushEvent(name, payload) { if (!events) return; + payload = jsonfyForDart(payload); payload.name = name; - events.push(jsonfyForDart(payload)); + events.push(payload); } export function draw(frame) { @@ -242,7 +243,7 @@ window.setByName = (name, value) => { localStorage.setItem(value.name, value.value); break; case 'peer_option': - curConn.setPeerOption(value.name, value.value); + curConn.setOption(value.name, value.value); break; case 'input_os_password': curConn.inputOsPassword(value, true); From 9de2944d6b280036b6876c0dcbe057aa9dacaa73 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 29 Jan 2022 20:45:53 +0800 Subject: [PATCH 35/66] yuv-to-rgb.c is not correct though it is faster --- src/connection.ts | 1 - src/globals.js | 9 +- yuv-to-rgb.c | 16 +- yuv.wasm | Bin 8573 -> 8238 bytes yuv_rgb.c | 1305 +++++++++++++++++++++++++++++++++++++++++++++ yuv_rgb.h | 155 ++++++ 6 files changed, 1473 insertions(+), 13 deletions(-) create mode 100644 yuv_rgb.c create mode 100644 yuv_rgb.h diff --git a/src/connection.ts b/src/connection.ts index fbb0f3221..80119511a 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -239,7 +239,6 @@ export default class Connection { draw(frame: any) { this._draw?.(frame); - // globals.I420ToARGB(frame); } close() { diff --git a/src/globals.js b/src/globals.js index 3aaf6685c..c9452b349 100644 --- a/src/globals.js +++ b/src/globals.js @@ -328,17 +328,18 @@ export function I420ToARGB(yb) { vPtr = malloc(n); } HEAPU8.set(yb.v.bytes, vPtr); - const w = yb.format.width; - const h = yb.format.height; + const w = yb.format.displayWidth; + const h = yb.format.displayHeight; n = w * h * 4; if (outPtrLen != n) { if (outPtr) free(outPtr); outPtrLen = n; outPtr = malloc(n); + HEAPU8.fill(255, outPtr, outPtr + n); } // const res = wasmExports.I420ToARGB(yPtr, yb.y.stride, uPtr, yb.u.stride, vPtr, yb.v.stride, outPtr, w * 4, w, h); - const res = wasmExports.AVX_YUV_to_RGBA(outPtr, yPtr, uPtr, vPtr, w, h); - // const res = wasmExports.yuv420_rgb24_std(w, h, yPtr, uPtr, vPtr, yb.y.stride, yb.v.stride, outPtr, w * 4, 0); + // const res = wasmExports.AVX_YUV_to_ARGB(outPtr, yPtr, yb.y.stride, uPtr, yb.u.stride, vPtr, yb.v.stride, w, h); + const res = wasmExports.yuv420_rgb24_std(w, h, yPtr, uPtr, vPtr, yb.y.stride, yb.v.stride, outPtr, w * 4, 1); const out = HEAPU8.slice(outPtr, outPtr + n); /* testSpeed[1] += new Date().getTime() - tm0; diff --git a/yuv-to-rgb.c b/yuv-to-rgb.c index 14eb60c78..ed99462e8 100644 --- a/yuv-to-rgb.c +++ b/yuv-to-rgb.c @@ -45,7 +45,7 @@ static int foo; static int frame; void -AVX_YUV_to_RGBA(unsigned char *dst, unsigned char *y, unsigned char* u, unsigned char* v, int width, int height) { +AVX_YUV_to_ARGB(unsigned char *dst, unsigned char *y, int ystride, unsigned char* u, int ustride, unsigned char* v, int vstride, int width, int height) { int r, g, b; unsigned char *uline, *vline; int w, h; @@ -54,27 +54,27 @@ AVX_YUV_to_RGBA(unsigned char *dst, unsigned char *y, unsigned char* u, unsigned initialized = !0; build_tables(); } - int half_width = width / 2; // Loop the image, taking into account sub-sample for the chroma channels for (h = 0; h < height; h++) { uline = u; vline = v; - for (w = 0; w < width; w++, y++) { + for (w = 0; w < width; w++) { r = *y + T1[*vline]; g = *y + T2[*vline] + T3[*uline]; b = *y + T4[*uline]; - *dst++ = clamp(r); // 16-bit to 8-bit, chuck precision + *dst++ = clamp(b); // 16-bit to 8-bit, chuck precision *dst++ = clamp(g); - *dst++ = clamp(b); - *dst++ = 255; + *dst++ = clamp(r); + ++dst; if (w & 0x01) { uline++; vline++; } } + y += ystride; if (h & 0x01) { - u += half_width; - v += half_width; + u += ustride; + v += vstride; } } } diff --git a/yuv.wasm b/yuv.wasm index f93a6eb2a012c870f33dc34b1f776175cbeafbbf..f203c685c932a7c62cccb523540555965bd1a695 100755 GIT binary patch delta 2665 zcmai0OKhCg6~6cWkGV7VAJ4>Zd;B=_6L2U_OP!DiXrs9iI1Nz*lnSXJ)d|6Y%-9LG zClMAx{{)PvsxFHD(6Y!P5<#^fts*5zU9iZa0-<^l1eGF@MI}I@yDm^w#KZm0{XMQb zRfT2GxsUVs?m6E%<8Su=v6hIVOY>3)AuIk7naJdbz@JRSkwUWhBfLUhcv1-{DnF3V zNGXF*%9d)WFb^yHn_pj3CbuH<;r#6Usl{a_%FCzE?4G)FX7Q;frgqOPHJ=o6XlCZb z$tO=N&K_&d96x>XSo6fGldmifCqX!WbZ+j{F_H6+FV4;ionLAmJ=S>S=$ToeBDenO z>{9d8;w*r;t##^t;q86-5kbPPOZV}UN-Qkz#RCNKru1 zT)ir=!u?{LrvTd$)qmzLbn2OD;MT@j_>`wo2ckBBJOH$V@j9~*uqd+4mMF#g3}Xu2 zRXa!?=rdP7^;pR%?q<Gg4cX^Y8=QN2u3a>61+}Jy@wu$*_GF|rWQ0H~J>h0aWrt3SDh<$c1RE_){ zO2^2q{j;vea@wz1DCYh9)J2^>?5|YX`m82_k=4Y8+CTj##<8yk_Ogc4s;?3XElSah z<-+}$tLKAVeU~*U#&S`U2N^}iUeM`Zf~VA4A>9)$sY^QjLwHuM*=#K|MS|QLYh7TYeCy2qHNcf_iDI(3kp!zQSc~IWxFS zCkj6pU3E_ML8z~4(3!3I`l`ln`ds1e=`Rez;QDKpkup}}ZKJUIT zWNcKo&n(y*Z~pboV2Qo_GRlJ8FsU|U`#xe9u@7f!Zsie*D9Jkv-uZ_Xiv?qE7;w(| z3q@bmR1Fx|!h^+4lb$q_r4Wxxri%foY6t}BTjs84tK0M+W=Mu;CPQTk}t z_inwaDX`B{(6G4$APc~LtT0;Zv18_{hHd&**R7MzCWFCccdsFNXv-^5wy<7RT$`}8 zTS4qA{i=uvnxSW&J}y=I9X+{Iz(jX-Q8WK~%Rd`H(@YOz?uI*5)NVTNyO+vWM%D^= z4*8HD3O#?`B^qA@B$}~k_uB`(gXulp=SSfN{aAw$d?ABQ zE9*-5`Lg?Eg$L)lZu#$Aeb}?-ho73;mDsDwV93pEsqLrC7hUHEcGmB6lTPFn{dFI(yA9r5{v!(qD|tI?DfFq@Rr~n++6_`)7XqZdX6C*#b7)^3wR delta 2993 zcmb7GYitx%6ux)n?(FQ&zFLI7%iU?A4aY(L@sx#rmB)+it-^v`MGu-h1BX zJLmNM+_ko5)-%}08DqRkbaS8k-3-6nXWf>sf0!Aw56)?5KC-`PI??BO%mS%- zu(aCx(6)!SY~420zine@n_}!>{&rtjeLcH&^>1gE*fG%C%c8Ntp`PveO+8QbGM>=% z#@@l9{()X*#Pv~Wb~Aod*&hqT@r`HH0eb;s_lX<`#aA(A=44bEL$0lk3}-yU$EnEk zAARapw4d8Ku-MxA^Xa2*LZOY_d_&F2KVhhXoGS}e+~8YOanD6i zMbVjLjw6LK`m#wGQEVL|5sGcdrp%mTSx1`Ls5G*+Od&tW3uTH@V<9!tYxND5P0MKM zGN$v@io1*iZF@w9h3Y@(#dK zvtKdW#k(Z8RP4)^<%pev3)$HO`#JI0EPa=asFM(*QV77&Qpm`V%L{~et$1@}NgZ)W zgM1_t(gc-AIO=V(cR2F6IR6reh&3pV)6LV?UZJ0^SqJsg$bo2thfJ^An?g4)+sz?& zWh}ppv{INx7p#uEV=TWyJH3mzN=uGTDM8Z=~ z7SzRK7mh^+N#_Bug)UqIL-0<#am_cOVpl-*`4VkP12vOom*i5cA4tX>Mf?jG&{s$b zBWL8aXOs&QazElRh&b~rB1nSYk&K|%EbUW}bCzXpG!g7|YIr0#s&rmW}(^%<4Yr@JqRD%FzCzk){>#LP*i%puoQx+$btY6U_w4i_QkRcUO4 z4;{>uqz=}g37$wc35}GmDrd$<$;5uj=!xXqd3245xLZc@Dq4Ww5ws|%Iu~uJTZLd3 zs{dLhw%qh&3u=o$AmI{r6S5hx+&^B!fZ$dX^8ko}41Vcq} z)Ker(2aR0nBWiiwFj|nBC~T80>CFviaq>E9F~Y1?BT=3vVdsygM_lS`sD~Nokzv{; zPjcP+;Q)9w^H!5qlr=EmXl76;F;*oTa#?whJWz4GNvp%4$!SsIGef>`;OMF0R=y}G zzMEzL_sZp~FQdG347S3^0J@YPeXteXW$BxIZ-p5{K0qA<;-%DrI;ekLH&#~|HI$f zU~$!R4PmA^H68Y$u7#m%p>uq;>da)Tv_{~mfSXd3iW|IFJv!Bj2z8+q%az?TJSgccEvcGm5lh}kB zlR}Sz8!&ly-B3*L3u=s@p|LUex~{2_DiBKPI_N!CZlxeoUp?M5ok>%7NjTHVH%+A- zv^kwhT6EB~4MS$K2rV;$LjB@NaYUww{Jyq$0C>16?MyzCYh|+PKILA)3 J9Sn@_e*o_$63qYr diff --git a/yuv_rgb.c b/yuv_rgb.c new file mode 100644 index 000000000..9ac3b4bae --- /dev/null +++ b/yuv_rgb.c @@ -0,0 +1,1305 @@ +// Copyright 2016 Adrien Descamps +// Distributed under BSD 3-Clause License + +#include "yuv_rgb.h" + +//#include +// +#include + +#include + + +uint8_t clamp(int16_t value) +{ + return value<0 ? 0 : (value>255 ? 255 : value); +} + +// Definitions +// +// E'R, E'G, E'B, E'Y, E'Cb and E'Cr refer to the analog signals +// E'R, E'G, E'B and E'Y range is [0:1], while E'Cb and E'Cr range is [-0.5:0.5] +// R, G, B, Y, Cb and Cr refer to the digitalized values +// The digitalized values can use their full range ([0:255] for 8bit values), +// or a subrange (typically [16:235] for Y and [16:240] for CbCr). +// We assume here that RGB range is always [0:255], since it is the case for +// most digitalized images. +// For 8bit values : +// * Y = round((YMax-YMin)*E'Y + YMin) +// * Cb = round((CbRange)*E'Cb + 128) +// * Cr = round((CrRange)*E'Cr + 128) +// Where *Min and *Max are the range of each channel +// +// In the analog domain , the RGB to YCbCr transformation is defined as: +// * E'Y = Rf*E'R + Gf*E'G + Bf*E'B +// Where Rf, Gf and Bf are constants defined in each standard, with +// Rf + Gf + Bf = 1 (necessary to ensure that E'Y range is [0:1]) +// * E'Cb = (E'B - E'Y) / CbNorm +// * E'Cr = (E'R - E'Y) / CrNorm +// Where CbNorm and CrNorm are constants, dependent of Rf, Gf, Bf, computed +// to normalize to a [-0.5:0.5] range : CbNorm=2*(1-Bf) and CrNorm=2*(1-Rf) +// +// Algorithms +// +// Most operations will be made in a fixed point format for speed, using +// N bits of precision. In next section the [x] convention is used for +// a fixed point rounded value, that is (int being the c type conversion) +// * [x] = int(x*(2^N)+0.5) +// N can be different for each factor, we simply use the highest value +// that will not overflow in 16 bits intermediate variables. +//. +// For RGB to YCbCr conversion, we start by generating a pseudo Y value +// (noted Y') in fixed point format, using the full range for now. +// * Y' = ([Rf]*R + [Gf]*G + [Bf]*B)>>N +// We can then compute Cb and Cr by +// * Cb = ((B - Y')*[CbRange/(255*CbNorm)])>>N + 128 +// * Cr = ((R - Y')*[CrRange/(255*CrNorm)])>>N + 128 +// And finally, we normalize Y to its digital range +// * Y = (Y'*[(YMax-YMin)/255])>>N + YMin +// +// For YCbCr to RGB conversion, we first compute the full range Y' value : +// * Y' = ((Y-YMin)*[255/(YMax-YMin)])>>N +// We can then compute B and R values by : +// * B = ((Cb-128)*[(255*CbNorm)/CbRange])>>N + Y' +// * R = ((Cr-128)*[(255*CrNorm)/CrRange])>>N + Y' +// And finally, for G we know that: +// * G = (Y' - (Rf*R + Bf*B)) / Gf +// From above: +// * G = (Y' - Rf * ((Cr-128)*(255*CrNorm)/CrRange + Y') - Bf * ((Cb-128)*(255*CbNorm)/CbRange + Y')) / Gf +// Since 1-Rf-Bf=Gf, we can take Y' out of the division by Gf, and we get: +// * G = Y' - (Cr-128)*Rf/Gf*(255*CrNorm)/CrRange - (Cb-128)*Bf/Gf*(255*CbNorm)/CbRange +// That we can compute, with fixed point arithmetic, by +// * G = Y' - ((Cr-128)*[Rf/Gf*(255*CrNorm)/CrRange] + (Cb-128)*[Bf/Gf*(255*CbNorm)/CbRange])>>N +// +// Note : in ITU-T T.871(JPEG), Y=Y', so that part could be optimized out + + +#define FIXED_POINT_VALUE(value, precision) ((int)(((value)*(1<r_factor*rgb_ptr1[0] + param->g_factor*rgb_ptr1[1] + param->b_factor*rgb_ptr1[2])>>8; + u_tmp = rgb_ptr1[2]-y_tmp; + v_tmp = rgb_ptr1[0]-y_tmp; + y_ptr1[0]=((y_tmp*param->y_factor)>>7) + param->y_offset; + + y_tmp = (param->r_factor*rgb_ptr1[3] + param->g_factor*rgb_ptr1[4] + param->b_factor*rgb_ptr1[5])>>8; + u_tmp += rgb_ptr1[5]-y_tmp; + v_tmp += rgb_ptr1[3]-y_tmp; + y_ptr1[1]=((y_tmp*param->y_factor)>>7) + param->y_offset; + + y_tmp = (param->r_factor*rgb_ptr2[0] + param->g_factor*rgb_ptr2[1] + param->b_factor*rgb_ptr2[2])>>8; + u_tmp += rgb_ptr2[2]-y_tmp; + v_tmp += rgb_ptr2[0]-y_tmp; + y_ptr2[0]=((y_tmp*param->y_factor)>>7) + param->y_offset; + + y_tmp = (param->r_factor*rgb_ptr2[3] + param->g_factor*rgb_ptr2[4] + param->b_factor*rgb_ptr2[5])>>8; + u_tmp += rgb_ptr2[5]-y_tmp; + v_tmp += rgb_ptr2[3]-y_tmp; + y_ptr2[1]=((y_tmp*param->y_factor)>>7) + param->y_offset; + + u_ptr[0] = (((u_tmp>>2)*param->cb_factor)>>8) + 128; + v_ptr[0] = (((v_tmp>>2)*param->cb_factor)>>8) + 128; + + rgb_ptr1 += 6; + rgb_ptr2 += 6; + y_ptr1 += 2; + y_ptr2 += 2; + u_ptr += 1; + v_ptr += 1; + } + } +} + +void rgb32_yuv420_std( + uint32_t width, uint32_t height, + const uint8_t *RGBA, uint32_t RGBA_stride, + uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + YCbCrType yuv_type) +{ + const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *rgb_ptr1=RGBA+y*RGBA_stride, + *rgb_ptr2=RGBA+(y+1)*RGBA_stride; + + uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *u_ptr=U+(y/2)*UV_stride, + *v_ptr=V+(y/2)*UV_stride; + + for(x=0; x<(width-1); x+=2) + { + // compute yuv for the four pixels, u and v values are summed + uint8_t y_tmp; + int16_t u_tmp, v_tmp; + + y_tmp = (param->r_factor*rgb_ptr1[0] + param->g_factor*rgb_ptr1[1] + param->b_factor*rgb_ptr1[2])>>8; + u_tmp = rgb_ptr1[2]-y_tmp; + v_tmp = rgb_ptr1[0]-y_tmp; + y_ptr1[0]=((y_tmp*param->y_factor)>>7) + param->y_offset; + + y_tmp = (param->r_factor*rgb_ptr1[4] + param->g_factor*rgb_ptr1[5] + param->b_factor*rgb_ptr1[6])>>8; + u_tmp += rgb_ptr1[6]-y_tmp; + v_tmp += rgb_ptr1[4]-y_tmp; + y_ptr1[1]=((y_tmp*param->y_factor)>>7) + param->y_offset; + + y_tmp = (param->r_factor*rgb_ptr2[0] + param->g_factor*rgb_ptr2[1] + param->b_factor*rgb_ptr2[2])>>8; + u_tmp += rgb_ptr2[2]-y_tmp; + v_tmp += rgb_ptr2[0]-y_tmp; + y_ptr2[0]=((y_tmp*param->y_factor)>>7) + param->y_offset; + + y_tmp = (param->r_factor*rgb_ptr2[4] + param->g_factor*rgb_ptr2[5] + param->b_factor*rgb_ptr2[6])>>8; + u_tmp += rgb_ptr2[6]-y_tmp; + v_tmp += rgb_ptr2[4]-y_tmp; + y_ptr2[1]=((y_tmp*param->y_factor)>>7) + param->y_offset; + + u_ptr[0] = (((u_tmp>>2)*param->cb_factor)>>8) + 128; + v_ptr[0] = (((v_tmp>>2)*param->cb_factor)>>8) + 128; + + rgb_ptr1 += 8; + rgb_ptr2 += 8; + y_ptr1 += 2; + y_ptr2 += 2; + u_ptr += 1; + v_ptr += 1; + } + } +} + + +void yuv420_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *U, const uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *u_ptr=U+(y/2)*UV_stride, + *v_ptr=V+(y/2)*UV_stride; + + uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + for(x=0; x<(width-1); x+=2) + { + int8_t u_tmp, v_tmp; + u_tmp = u_ptr[0]-128; + v_tmp = v_ptr[0]-128; + + //compute Cb Cr color offsets, common to four pixels + int16_t b_cb_offset, r_cr_offset, g_cbcr_offset; + b_cb_offset = (param->cb_factor*u_tmp)>>6; + r_cr_offset = (param->cr_factor*v_tmp)>>6; + g_cbcr_offset = (param->g_cb_factor*u_tmp + param->g_cr_factor*v_tmp)>>7; + + int16_t y_tmp; + y_tmp = (param->y_factor*(y_ptr1[0]-param->y_offset))>>7; + rgb_ptr1[2] = clamp(y_tmp + r_cr_offset); + rgb_ptr1[1] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr1[0] = clamp(y_tmp + b_cb_offset); + + y_tmp = (param->y_factor*(y_ptr1[1]-param->y_offset))>>7; + rgb_ptr1[6] = clamp(y_tmp + r_cr_offset); + rgb_ptr1[5] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr1[4] = clamp(y_tmp + b_cb_offset); + + y_tmp = (param->y_factor*(y_ptr2[0]-param->y_offset))>>7; + rgb_ptr2[2] = clamp(y_tmp + r_cr_offset); + rgb_ptr2[1] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr2[0] = clamp(y_tmp + b_cb_offset); + + y_tmp = (param->y_factor*(y_ptr2[1]-param->y_offset))>>7; + rgb_ptr2[6] = clamp(y_tmp + r_cr_offset); + rgb_ptr2[5] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr2[4] = clamp(y_tmp + b_cb_offset); + + rgb_ptr1 += 8; + rgb_ptr2 += 8; + y_ptr1 += 2; + y_ptr2 += 2; + u_ptr += 1; + v_ptr += 1; + } + } +} + +void nv12_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *UV, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *uv_ptr=UV+(y/2)*UV_stride; + + uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + for(x=0; x<(width-1); x+=2) + { + int8_t u_tmp, v_tmp; + u_tmp = uv_ptr[0]-128; + v_tmp = uv_ptr[1]-128; + + //compute Cb Cr color offsets, common to four pixels + int16_t b_cb_offset, r_cr_offset, g_cbcr_offset; + b_cb_offset = (param->cb_factor*u_tmp)>>6; + r_cr_offset = (param->cr_factor*v_tmp)>>6; + g_cbcr_offset = (param->g_cb_factor*u_tmp + param->g_cr_factor*v_tmp)>>7; + + int16_t y_tmp; + y_tmp = (param->y_factor*(y_ptr1[0]-param->y_offset))>>7; + rgb_ptr1[0] = clamp(y_tmp + r_cr_offset); + rgb_ptr1[1] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr1[2] = clamp(y_tmp + b_cb_offset); + + y_tmp = (param->y_factor*(y_ptr1[1]-param->y_offset))>>7; + rgb_ptr1[3] = clamp(y_tmp + r_cr_offset); + rgb_ptr1[4] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr1[5] = clamp(y_tmp + b_cb_offset); + + y_tmp = (param->y_factor*(y_ptr2[0]-param->y_offset))>>7; + rgb_ptr2[0] = clamp(y_tmp + r_cr_offset); + rgb_ptr2[1] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr2[2] = clamp(y_tmp + b_cb_offset); + + y_tmp = (param->y_factor*(y_ptr2[1]-param->y_offset))>>7; + rgb_ptr2[3] = clamp(y_tmp + r_cr_offset); + rgb_ptr2[4] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr2[5] = clamp(y_tmp + b_cb_offset); + + rgb_ptr1 += 6; + rgb_ptr2 += 6; + y_ptr1 += 2; + y_ptr2 += 2; + uv_ptr += 2; + } + } +} + +void nv21_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *UV, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *uv_ptr=UV+(y/2)*UV_stride; + + uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + for(x=0; x<(width-1); x+=2) + { + int8_t u_tmp, v_tmp; + u_tmp = uv_ptr[1]-128; + v_tmp = uv_ptr[0]-128; + + //compute Cb Cr color offsets, common to four pixels + int16_t b_cb_offset, r_cr_offset, g_cbcr_offset; + b_cb_offset = (param->cb_factor*u_tmp)>>6; + r_cr_offset = (param->cr_factor*v_tmp)>>6; + g_cbcr_offset = (param->g_cb_factor*u_tmp + param->g_cr_factor*v_tmp)>>7; + + int16_t y_tmp; + y_tmp = (param->y_factor*(y_ptr1[0]-param->y_offset))>>7; + rgb_ptr1[0] = clamp(y_tmp + r_cr_offset); + rgb_ptr1[1] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr1[2] = clamp(y_tmp + b_cb_offset); + + y_tmp = (param->y_factor*(y_ptr1[1]-param->y_offset))>>7; + rgb_ptr1[3] = clamp(y_tmp + r_cr_offset); + rgb_ptr1[4] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr1[5] = clamp(y_tmp + b_cb_offset); + + y_tmp = (param->y_factor*(y_ptr2[0]-param->y_offset))>>7; + rgb_ptr2[0] = clamp(y_tmp + r_cr_offset); + rgb_ptr2[1] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr2[2] = clamp(y_tmp + b_cb_offset); + + y_tmp = (param->y_factor*(y_ptr2[1]-param->y_offset))>>7; + rgb_ptr2[3] = clamp(y_tmp + r_cr_offset); + rgb_ptr2[4] = clamp(y_tmp - g_cbcr_offset); + rgb_ptr2[5] = clamp(y_tmp + b_cb_offset); + + rgb_ptr1 += 6; + rgb_ptr2 += 6; + y_ptr1 += 2; + y_ptr2 += 2; + uv_ptr += 2; + } + } +} + + +#ifdef __SSE2__ + +//see rgb.txt +#define UNPACK_RGB24_32_STEP(RS1, RS2, RS3, RS4, RS5, RS6, RD1, RD2, RD3, RD4, RD5, RD6) \ +RD1 = _mm_unpacklo_epi8(RS1, RS4); \ +RD2 = _mm_unpackhi_epi8(RS1, RS4); \ +RD3 = _mm_unpacklo_epi8(RS2, RS5); \ +RD4 = _mm_unpackhi_epi8(RS2, RS5); \ +RD5 = _mm_unpacklo_epi8(RS3, RS6); \ +RD6 = _mm_unpackhi_epi8(RS3, RS6); + +#define RGB2YUV_16(R, G, B, Y, U, V) \ +Y = _mm_add_epi16(_mm_mullo_epi16(R, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(G, _mm_set1_epi16(param->g_factor))); \ +Y = _mm_add_epi16(Y, _mm_mullo_epi16(B, _mm_set1_epi16(param->b_factor))); \ +Y = _mm_srli_epi16(Y, 8); \ +U = _mm_mullo_epi16(_mm_sub_epi16(B, Y), _mm_set1_epi16(param->cb_factor)); \ +U = _mm_add_epi16(_mm_srai_epi16(U, 8), _mm_set1_epi16(128)); \ +V = _mm_mullo_epi16(_mm_sub_epi16(R, Y), _mm_set1_epi16(param->cr_factor)); \ +V = _mm_add_epi16(_mm_srai_epi16(V, 8), _mm_set1_epi16(128)); \ +Y = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(Y, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); + +#define RGB2YUV_32 \ + __m128i r_16, g_16, b_16; \ + __m128i y1_16, y2_16, cb1_16, cb2_16, cr1_16, cr2_16, Y, cb, cr; \ + __m128i tmp1, tmp2, tmp3, tmp4, tmp5, tmp6; \ + __m128i rgb1 = LOAD_SI128((const __m128i*)(rgb_ptr1)), \ + rgb2 = LOAD_SI128((const __m128i*)(rgb_ptr1+16)), \ + rgb3 = LOAD_SI128((const __m128i*)(rgb_ptr1+32)), \ + rgb4 = LOAD_SI128((const __m128i*)(rgb_ptr2)), \ + rgb5 = LOAD_SI128((const __m128i*)(rgb_ptr2+16)), \ + rgb6 = LOAD_SI128((const __m128i*)(rgb_ptr2+32)); \ + /* unpack rgb24 data to r, g and b data in separate channels*/ \ + /* see rgb.txt to get an idea of the algorithm, note that we only go to the next to last step*/ \ + /* here, because averaging in horizontal direction is easier like this*/ \ + /* The last step is applied further on the Y channel only*/ \ + UNPACK_RGB24_32_STEP(rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6) \ + UNPACK_RGB24_32_STEP(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, rgb1, rgb2, rgb3, rgb4, rgb5, rgb6) \ + UNPACK_RGB24_32_STEP(rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6) \ + UNPACK_RGB24_32_STEP(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, rgb1, rgb2, rgb3, rgb4, rgb5, rgb6) \ + /* first compute Y', (B-Y') and (R-Y'), in 16bits values, for the first line */ \ + /* Y is saved for each pixel, while only sums of (B-Y') and (R-Y') for pairs of adjacents pixels are saved*/ \ + r_16 = _mm_unpacklo_epi8(rgb1, _mm_setzero_si128()); \ + g_16 = _mm_unpacklo_epi8(rgb2, _mm_setzero_si128()); \ + b_16 = _mm_unpacklo_epi8(rgb3, _mm_setzero_si128()); \ + y1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y1_16 = _mm_add_epi16(y1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y1_16 = _mm_srli_epi16(y1_16, 8); \ + cb1_16 = _mm_sub_epi16(b_16, y1_16); \ + cr1_16 = _mm_sub_epi16(r_16, y1_16); \ + r_16 = _mm_unpacklo_epi8(rgb4, _mm_setzero_si128()); \ + g_16 = _mm_unpacklo_epi8(rgb5, _mm_setzero_si128()); \ + b_16 = _mm_unpacklo_epi8(rgb6, _mm_setzero_si128()); \ + y2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y2_16 = _mm_add_epi16(y2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y2_16 = _mm_srli_epi16(y2_16, 8); \ + cb1_16 = _mm_add_epi16(cb1_16, _mm_sub_epi16(b_16, y2_16)); \ + cr1_16 = _mm_add_epi16(cr1_16, _mm_sub_epi16(r_16, y2_16)); \ + /* Rescale Y' to Y, pack it to 8bit values and save it */ \ + y1_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y1_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + y2_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y2_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + Y = _mm_packus_epi16(y1_16, y2_16); \ + Y = _mm_unpackhi_epi8(_mm_slli_si128(Y, 8), Y); \ + SAVE_SI128((__m128i*)(y_ptr1), Y); \ + /* same for the second line, compute Y', (B-Y') and (R-Y'), in 16bits values */ \ + /* Y is saved for each pixel, while only sums of (B-Y') and (R-Y') for pairs of adjacents pixels are added to the previous values*/ \ + r_16 = _mm_unpackhi_epi8(rgb1, _mm_setzero_si128()); \ + g_16 = _mm_unpackhi_epi8(rgb2, _mm_setzero_si128()); \ + b_16 = _mm_unpackhi_epi8(rgb3, _mm_setzero_si128()); \ + y1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y1_16 = _mm_add_epi16(y1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y1_16 = _mm_srli_epi16(y1_16, 8); \ + cb1_16 = _mm_add_epi16(cb1_16, _mm_sub_epi16(b_16, y1_16)); \ + cr1_16 = _mm_add_epi16(cr1_16, _mm_sub_epi16(r_16, y1_16)); \ + r_16 = _mm_unpackhi_epi8(rgb4, _mm_setzero_si128()); \ + g_16 = _mm_unpackhi_epi8(rgb5, _mm_setzero_si128()); \ + b_16 = _mm_unpackhi_epi8(rgb6, _mm_setzero_si128()); \ + y2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y2_16 = _mm_add_epi16(y2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y2_16 = _mm_srli_epi16(y2_16, 8); \ + cb1_16 = _mm_add_epi16(cb1_16, _mm_sub_epi16(b_16, y2_16)); \ + cr1_16 = _mm_add_epi16(cr1_16, _mm_sub_epi16(r_16, y2_16)); \ + /* Rescale Y' to Y, pack it to 8bit values and save it */ \ + y1_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y1_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + y2_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y2_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + Y = _mm_packus_epi16(y1_16, y2_16); \ + Y = _mm_unpackhi_epi8(_mm_slli_si128(Y, 8), Y); \ + SAVE_SI128((__m128i*)(y_ptr2), Y); \ + /* Rescale Cb and Cr to their final range */ \ + cb1_16 = _mm_add_epi16(_mm_srai_epi16(_mm_mullo_epi16(_mm_srai_epi16(cb1_16, 2), _mm_set1_epi16(param->cb_factor)), 8), _mm_set1_epi16(128)); \ + cr1_16 = _mm_add_epi16(_mm_srai_epi16(_mm_mullo_epi16(_mm_srai_epi16(cr1_16, 2), _mm_set1_epi16(param->cr_factor)), 8), _mm_set1_epi16(128)); \ + \ + /* do the same again with next data */ \ + rgb1 = LOAD_SI128((const __m128i*)(rgb_ptr1+48)), \ + rgb2 = LOAD_SI128((const __m128i*)(rgb_ptr1+64)), \ + rgb3 = LOAD_SI128((const __m128i*)(rgb_ptr1+80)), \ + rgb4 = LOAD_SI128((const __m128i*)(rgb_ptr2+48)), \ + rgb5 = LOAD_SI128((const __m128i*)(rgb_ptr2+64)), \ + rgb6 = LOAD_SI128((const __m128i*)(rgb_ptr2+80)); \ + /* unpack rgb24 data to r, g and b data in separate channels*/ \ + /* see rgb.txt to get an idea of the algorithm, note that we only go to the next to last step*/ \ + /* here, because averaging in horizontal direction is easier like this*/ \ + /* The last step is applied further on the Y channel only*/ \ + UNPACK_RGB24_32_STEP(rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6) \ + UNPACK_RGB24_32_STEP(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, rgb1, rgb2, rgb3, rgb4, rgb5, rgb6) \ + UNPACK_RGB24_32_STEP(rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6) \ + UNPACK_RGB24_32_STEP(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, rgb1, rgb2, rgb3, rgb4, rgb5, rgb6) \ + /* first compute Y', (B-Y') and (R-Y'), in 16bits values, for the first line */ \ + /* Y is saved for each pixel, while only sums of (B-Y') and (R-Y') for pairs of adjacents pixels are saved*/ \ + r_16 = _mm_unpacklo_epi8(rgb1, _mm_setzero_si128()); \ + g_16 = _mm_unpacklo_epi8(rgb2, _mm_setzero_si128()); \ + b_16 = _mm_unpacklo_epi8(rgb3, _mm_setzero_si128()); \ + y1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y1_16 = _mm_add_epi16(y1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y1_16 = _mm_srli_epi16(y1_16, 8); \ + cb2_16 = _mm_sub_epi16(b_16, y1_16); \ + cr2_16 = _mm_sub_epi16(r_16, y1_16); \ + r_16 = _mm_unpacklo_epi8(rgb4, _mm_setzero_si128()); \ + g_16 = _mm_unpacklo_epi8(rgb5, _mm_setzero_si128()); \ + b_16 = _mm_unpacklo_epi8(rgb6, _mm_setzero_si128()); \ + y2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y2_16 = _mm_add_epi16(y2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y2_16 = _mm_srli_epi16(y2_16, 8); \ + cb2_16 = _mm_add_epi16(cb2_16, _mm_sub_epi16(b_16, y2_16)); \ + cr2_16 = _mm_add_epi16(cr2_16, _mm_sub_epi16(r_16, y2_16)); \ + /* Rescale Y' to Y, pack it to 8bit values and save it */ \ + y1_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y1_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + y2_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y2_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + Y = _mm_packus_epi16(y1_16, y2_16); \ + Y = _mm_unpackhi_epi8(_mm_slli_si128(Y, 8), Y); \ + SAVE_SI128((__m128i*)(y_ptr1+16), Y); \ + /* same for the second line, compute Y', (B-Y') and (R-Y'), in 16bits values */ \ + /* Y is saved for each pixel, while only sums of (B-Y') and (R-Y') for pairs of adjacents pixels are added to the previous values*/ \ + r_16 = _mm_unpackhi_epi8(rgb1, _mm_setzero_si128()); \ + g_16 = _mm_unpackhi_epi8(rgb2, _mm_setzero_si128()); \ + b_16 = _mm_unpackhi_epi8(rgb3, _mm_setzero_si128()); \ + y1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y1_16 = _mm_add_epi16(y1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y1_16 = _mm_srli_epi16(y1_16, 8); \ + cb2_16 = _mm_add_epi16(cb2_16, _mm_sub_epi16(b_16, y1_16)); \ + cr2_16 = _mm_add_epi16(cr2_16, _mm_sub_epi16(r_16, y1_16)); \ + r_16 = _mm_unpackhi_epi8(rgb4, _mm_setzero_si128()); \ + g_16 = _mm_unpackhi_epi8(rgb5, _mm_setzero_si128()); \ + b_16 = _mm_unpackhi_epi8(rgb6, _mm_setzero_si128()); \ + y2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y2_16 = _mm_add_epi16(y2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y2_16 = _mm_srli_epi16(y2_16, 8); \ + cb2_16 = _mm_add_epi16(cb2_16, _mm_sub_epi16(b_16, y2_16)); \ + cr2_16 = _mm_add_epi16(cr2_16, _mm_sub_epi16(r_16, y2_16)); \ + /* Rescale Y' to Y, pack it to 8bit values and save it */ \ + y1_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y1_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + y2_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y2_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + Y = _mm_packus_epi16(y1_16, y2_16); \ + Y = _mm_unpackhi_epi8(_mm_slli_si128(Y, 8), Y); \ + SAVE_SI128((__m128i*)(y_ptr2+16), Y); \ + /* Rescale Cb and Cr to their final range */ \ + cb2_16 = _mm_add_epi16(_mm_srai_epi16(_mm_mullo_epi16(_mm_srai_epi16(cb2_16, 2), _mm_set1_epi16(param->cb_factor)), 8), _mm_set1_epi16(128)); \ + cr2_16 = _mm_add_epi16(_mm_srai_epi16(_mm_mullo_epi16(_mm_srai_epi16(cr2_16, 2), _mm_set1_epi16(param->cr_factor)), 8), _mm_set1_epi16(128)); \ + /* Pack and save Cb Cr */ \ + cb = _mm_packus_epi16(cb1_16, cb2_16); \ + cr = _mm_packus_epi16(cr1_16, cr2_16); \ + SAVE_SI128((__m128i*)(u_ptr), cb); \ + SAVE_SI128((__m128i*)(v_ptr), cr); + + +void rgb24_yuv420_sse(uint32_t width, uint32_t height, + const uint8_t *RGB, uint32_t RGB_stride, + uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + YCbCrType yuv_type) +{ + #define LOAD_SI128 _mm_load_si128 + #define SAVE_SI128 _mm_stream_si128 + const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *u_ptr=U+(y/2)*UV_stride, + *v_ptr=V+(y/2)*UV_stride; + + for(x=0; x<(width-31); x+=32) + { + RGB2YUV_32 + + rgb_ptr1+=96; + rgb_ptr2+=96; + y_ptr1+=32; + y_ptr2+=32; + u_ptr+=16; + v_ptr+=16; + } + } + #undef LOAD_SI128 + #undef SAVE_SI128 +} + +void rgb24_yuv420_sseu(uint32_t width, uint32_t height, + const uint8_t *RGB, uint32_t RGB_stride, + uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + YCbCrType yuv_type) +{ + #define LOAD_SI128 _mm_loadu_si128 + #define SAVE_SI128 _mm_storeu_si128 + const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *u_ptr=U+(y/2)*UV_stride, + *v_ptr=V+(y/2)*UV_stride; + + for(x=0; x<(width-31); x+=32) + { + RGB2YUV_32 + + rgb_ptr1+=96; + rgb_ptr2+=96; + y_ptr1+=32; + y_ptr2+=32; + u_ptr+=16; + v_ptr+=16; + } + } + #undef LOAD_SI128 + #undef SAVE_SI128 +} + + +// see rgba.txt +#define UNPACK_RGB32_32_STEP(RS1, RS2, RS3, RS4, RS5, RS6, RS7, RS8, RD1, RD2, RD3, RD4, RD5, RD6, RD7, RD8) \ +RD1 = _mm_unpacklo_epi8(RS1, RS5); \ +RD2 = _mm_unpackhi_epi8(RS1, RS5); \ +RD3 = _mm_unpacklo_epi8(RS2, RS6); \ +RD4 = _mm_unpackhi_epi8(RS2, RS6); \ +RD5 = _mm_unpacklo_epi8(RS3, RS7); \ +RD6 = _mm_unpackhi_epi8(RS3, RS7); \ +RD7 = _mm_unpacklo_epi8(RS4, RS8); \ +RD8 = _mm_unpackhi_epi8(RS4, RS8); + + +#define RGBA2YUV_32 \ + __m128i r_16, g_16, b_16; \ + __m128i y1_16, y2_16, cb1_16, cb2_16, cr1_16, cr2_16, Y, cb, cr; \ + __m128i tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; \ + __m128i rgb1 = LOAD_SI128((const __m128i*)(rgb_ptr1)), \ + rgb2 = LOAD_SI128((const __m128i*)(rgb_ptr1+16)), \ + rgb3 = LOAD_SI128((const __m128i*)(rgb_ptr1+32)), \ + rgb4 = LOAD_SI128((const __m128i*)(rgb_ptr1+48)), \ + rgb5 = LOAD_SI128((const __m128i*)(rgb_ptr2)), \ + rgb6 = LOAD_SI128((const __m128i*)(rgb_ptr2+16)), \ + rgb7 = LOAD_SI128((const __m128i*)(rgb_ptr2+32)), \ + rgb8 = LOAD_SI128((const __m128i*)(rgb_ptr2+48)); \ + /* unpack rgb24 data to r, g and b data in separate channels*/ \ + /* see rgb.txt to get an idea of the algorithm, note that we only go to the next to last step*/ \ + /* here, because averaging in horizontal direction is easier like this*/ \ + /* The last step is applied further on the Y channel only*/ \ + UNPACK_RGB32_32_STEP(rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, rgb7, rgb8, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8) \ + UNPACK_RGB32_32_STEP(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, rgb7, rgb8) \ + UNPACK_RGB32_32_STEP(rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, rgb7, rgb8, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8) \ + UNPACK_RGB32_32_STEP(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, rgb7, rgb8) \ + /* first compute Y', (B-Y') and (R-Y'), in 16bits values, for the first line */ \ + /* Y is saved for each pixel, while only sums of (B-Y') and (R-Y') for pairs of adjacents pixels are saved*/ \ + r_16 = _mm_unpacklo_epi8(rgb1, _mm_setzero_si128()); \ + g_16 = _mm_unpacklo_epi8(rgb2, _mm_setzero_si128()); \ + b_16 = _mm_unpacklo_epi8(rgb3, _mm_setzero_si128()); \ + y1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y1_16 = _mm_add_epi16(y1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y1_16 = _mm_srli_epi16(y1_16, 8); \ + cb1_16 = _mm_sub_epi16(b_16, y1_16); \ + cr1_16 = _mm_sub_epi16(r_16, y1_16); \ + r_16 = _mm_unpacklo_epi8(rgb5, _mm_setzero_si128()); \ + g_16 = _mm_unpacklo_epi8(rgb6, _mm_setzero_si128()); \ + b_16 = _mm_unpacklo_epi8(rgb7, _mm_setzero_si128()); \ + y2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y2_16 = _mm_add_epi16(y2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y2_16 = _mm_srli_epi16(y2_16, 8); \ + cb1_16 = _mm_add_epi16(cb1_16, _mm_sub_epi16(b_16, y2_16)); \ + cr1_16 = _mm_add_epi16(cr1_16, _mm_sub_epi16(r_16, y2_16)); \ + /* Rescale Y' to Y, pack it to 8bit values and save it */ \ + y1_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y1_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + y2_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y2_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + Y = _mm_packus_epi16(y1_16, y2_16); \ + Y = _mm_unpackhi_epi8(_mm_slli_si128(Y, 8), Y); \ + SAVE_SI128((__m128i*)(y_ptr1), Y); \ + /* same for the second line, compute Y', (B-Y') and (R-Y'), in 16bits values */ \ + /* Y is saved for each pixel, while only sums of (B-Y') and (R-Y') for pairs of adjacents pixels are added to the previous values*/ \ + r_16 = _mm_unpackhi_epi8(rgb1, _mm_setzero_si128()); \ + g_16 = _mm_unpackhi_epi8(rgb2, _mm_setzero_si128()); \ + b_16 = _mm_unpackhi_epi8(rgb3, _mm_setzero_si128()); \ + y1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y1_16 = _mm_add_epi16(y1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y1_16 = _mm_srli_epi16(y1_16, 8); \ + cb1_16 = _mm_add_epi16(cb1_16, _mm_sub_epi16(b_16, y1_16)); \ + cr1_16 = _mm_add_epi16(cr1_16, _mm_sub_epi16(r_16, y1_16)); \ + r_16 = _mm_unpackhi_epi8(rgb5, _mm_setzero_si128()); \ + g_16 = _mm_unpackhi_epi8(rgb6, _mm_setzero_si128()); \ + b_16 = _mm_unpackhi_epi8(rgb7, _mm_setzero_si128()); \ + y2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y2_16 = _mm_add_epi16(y2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y2_16 = _mm_srli_epi16(y2_16, 8); \ + cb1_16 = _mm_add_epi16(cb1_16, _mm_sub_epi16(b_16, y2_16)); \ + cr1_16 = _mm_add_epi16(cr1_16, _mm_sub_epi16(r_16, y2_16)); \ + /* Rescale Y' to Y, pack it to 8bit values and save it */ \ + y1_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y1_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + y2_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y2_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + Y = _mm_packus_epi16(y1_16, y2_16); \ + Y = _mm_unpackhi_epi8(_mm_slli_si128(Y, 8), Y); \ + SAVE_SI128((__m128i*)(y_ptr2), Y); \ + /* Rescale Cb and Cr to their final range */ \ + cb1_16 = _mm_add_epi16(_mm_srai_epi16(_mm_mullo_epi16(_mm_srai_epi16(cb1_16, 2), _mm_set1_epi16(param->cb_factor)), 8), _mm_set1_epi16(128)); \ + cr1_16 = _mm_add_epi16(_mm_srai_epi16(_mm_mullo_epi16(_mm_srai_epi16(cr1_16, 2), _mm_set1_epi16(param->cr_factor)), 8), _mm_set1_epi16(128)); \ + \ + /* do the same again with next data */ \ + rgb1 = LOAD_SI128((const __m128i*)(rgb_ptr1+64)), \ + rgb2 = LOAD_SI128((const __m128i*)(rgb_ptr1+80)), \ + rgb3 = LOAD_SI128((const __m128i*)(rgb_ptr1+96)), \ + rgb4 = LOAD_SI128((const __m128i*)(rgb_ptr1+112)), \ + rgb5 = LOAD_SI128((const __m128i*)(rgb_ptr2+64)), \ + rgb6 = LOAD_SI128((const __m128i*)(rgb_ptr2+80)), \ + rgb7 = LOAD_SI128((const __m128i*)(rgb_ptr2+96)), \ + rgb8 = LOAD_SI128((const __m128i*)(rgb_ptr2+112)); \ + /* unpack rgb24 data to r, g and b data in separate channels*/ \ + /* see rgb.txt to get an idea of the algorithm, note that we only go to the next to last step*/ \ + /* here, because averaging in horizontal direction is easier like this*/ \ + /* The last step is applied further on the Y channel only*/ \ + UNPACK_RGB32_32_STEP(rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, rgb7, rgb8, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8) \ + UNPACK_RGB32_32_STEP(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, rgb7, rgb8) \ + UNPACK_RGB32_32_STEP(rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, rgb7, rgb8, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8) \ + UNPACK_RGB32_32_STEP(tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, rgb1, rgb2, rgb3, rgb4, rgb5, rgb6, rgb7, rgb8) \ + /* first compute Y', (B-Y') and (R-Y'), in 16bits values, for the first line */ \ + /* Y is saved for each pixel, while only sums of (B-Y') and (R-Y') for pairs of adjacents pixels are saved*/ \ + r_16 = _mm_unpacklo_epi8(rgb1, _mm_setzero_si128()); \ + g_16 = _mm_unpacklo_epi8(rgb2, _mm_setzero_si128()); \ + b_16 = _mm_unpacklo_epi8(rgb3, _mm_setzero_si128()); \ + y1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y1_16 = _mm_add_epi16(y1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y1_16 = _mm_srli_epi16(y1_16, 8); \ + cb2_16 = _mm_sub_epi16(b_16, y1_16); \ + cr2_16 = _mm_sub_epi16(r_16, y1_16); \ + r_16 = _mm_unpacklo_epi8(rgb5, _mm_setzero_si128()); \ + g_16 = _mm_unpacklo_epi8(rgb6, _mm_setzero_si128()); \ + b_16 = _mm_unpacklo_epi8(rgb7, _mm_setzero_si128()); \ + y2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y2_16 = _mm_add_epi16(y2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y2_16 = _mm_srli_epi16(y2_16, 8); \ + cb2_16 = _mm_add_epi16(cb2_16, _mm_sub_epi16(b_16, y2_16)); \ + cr2_16 = _mm_add_epi16(cr2_16, _mm_sub_epi16(r_16, y2_16)); \ + /* Rescale Y' to Y, pack it to 8bit values and save it */ \ + y1_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y1_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + y2_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y2_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + Y = _mm_packus_epi16(y1_16, y2_16); \ + Y = _mm_unpackhi_epi8(_mm_slli_si128(Y, 8), Y); \ + SAVE_SI128((__m128i*)(y_ptr1+16), Y); \ + /* same for the second line, compute Y', (B-Y') and (R-Y'), in 16bits values */ \ + /* Y is saved for each pixel, while only sums of (B-Y') and (R-Y') for pairs of adjacents pixels are added to the previous values*/ \ + r_16 = _mm_unpackhi_epi8(rgb1, _mm_setzero_si128()); \ + g_16 = _mm_unpackhi_epi8(rgb2, _mm_setzero_si128()); \ + b_16 = _mm_unpackhi_epi8(rgb3, _mm_setzero_si128()); \ + y1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y1_16 = _mm_add_epi16(y1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y1_16 = _mm_srli_epi16(y1_16, 8); \ + cb2_16 = _mm_add_epi16(cb2_16, _mm_sub_epi16(b_16, y1_16)); \ + cr2_16 = _mm_add_epi16(cr2_16, _mm_sub_epi16(r_16, y1_16)); \ + r_16 = _mm_unpackhi_epi8(rgb5, _mm_setzero_si128()); \ + g_16 = _mm_unpackhi_epi8(rgb6, _mm_setzero_si128()); \ + b_16 = _mm_unpackhi_epi8(rgb7, _mm_setzero_si128()); \ + y2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(param->r_factor)), \ + _mm_mullo_epi16(g_16, _mm_set1_epi16(param->g_factor))); \ + y2_16 = _mm_add_epi16(y2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(param->b_factor))); \ + y2_16 = _mm_srli_epi16(y2_16, 8); \ + cb2_16 = _mm_add_epi16(cb2_16, _mm_sub_epi16(b_16, y2_16)); \ + cr2_16 = _mm_add_epi16(cr2_16, _mm_sub_epi16(r_16, y2_16)); \ + /* Rescale Y' to Y, pack it to 8bit values and save it */ \ + y1_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y1_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + y2_16 = _mm_add_epi16(_mm_srli_epi16(_mm_mullo_epi16(y2_16, _mm_set1_epi16(param->y_factor)), 7), _mm_set1_epi16(param->y_offset)); \ + Y = _mm_packus_epi16(y1_16, y2_16); \ + Y = _mm_unpackhi_epi8(_mm_slli_si128(Y, 8), Y); \ + SAVE_SI128((__m128i*)(y_ptr2+16), Y); \ + /* Rescale Cb and Cr to their final range */ \ + cb2_16 = _mm_add_epi16(_mm_srai_epi16(_mm_mullo_epi16(_mm_srai_epi16(cb2_16, 2), _mm_set1_epi16(param->cb_factor)), 8), _mm_set1_epi16(128)); \ + cr2_16 = _mm_add_epi16(_mm_srai_epi16(_mm_mullo_epi16(_mm_srai_epi16(cr2_16, 2), _mm_set1_epi16(param->cr_factor)), 8), _mm_set1_epi16(128)); \ + /* Pack and save Cb Cr */ \ + cb = _mm_packus_epi16(cb1_16, cb2_16); \ + cr = _mm_packus_epi16(cr1_16, cr2_16); \ + SAVE_SI128((__m128i*)(u_ptr), cb); \ + SAVE_SI128((__m128i*)(v_ptr), cr); + +void rgb32_yuv420_sse(uint32_t width, uint32_t height, + const uint8_t *RGBA, uint32_t RGBA_stride, + uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + YCbCrType yuv_type) +{ + #define LOAD_SI128 _mm_load_si128 + #define SAVE_SI128 _mm_stream_si128 + const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *rgb_ptr1=RGBA+y*RGBA_stride, + *rgb_ptr2=RGBA+(y+1)*RGBA_stride; + + uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *u_ptr=U+(y/2)*UV_stride, + *v_ptr=V+(y/2)*UV_stride; + + for(x=0; x<(width-31); x+=32) + { + RGBA2YUV_32 + + rgb_ptr1+=128; + rgb_ptr2+=128; + y_ptr1+=32; + y_ptr2+=32; + u_ptr+=16; + v_ptr+=16; + } + } + #undef LOAD_SI128 + #undef SAVE_SI128 +} + +void rgb32_yuv420_sseu(uint32_t width, uint32_t height, + const uint8_t *RGBA, uint32_t RGBA_stride, + uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + YCbCrType yuv_type) +{ + #define LOAD_SI128 _mm_loadu_si128 + #define SAVE_SI128 _mm_storeu_si128 + const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *rgb_ptr1=RGBA+y*RGBA_stride, + *rgb_ptr2=RGBA+(y+1)*RGBA_stride; + + uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *u_ptr=U+(y/2)*UV_stride, + *v_ptr=V+(y/2)*UV_stride; + + for(x=0; x<(width-31); x+=32) + { + RGBA2YUV_32 + + rgb_ptr1+=128; + rgb_ptr2+=128; + y_ptr1+=32; + y_ptr2+=32; + u_ptr+=16; + v_ptr+=16; + } + } + #undef LOAD_SI128 + #undef SAVE_SI128 +} + +#endif + +#ifdef __SSE2__ + +#define UV2RGB_16(U,V,R1,G1,B1,R2,G2,B2) \ + r_tmp = _mm_srai_epi16(_mm_mullo_epi16(V, _mm_set1_epi16(param->cr_factor)), 6); \ + g_tmp = _mm_srai_epi16(_mm_add_epi16( \ + _mm_mullo_epi16(U, _mm_set1_epi16(param->g_cb_factor)), \ + _mm_mullo_epi16(V, _mm_set1_epi16(param->g_cr_factor))), 7); \ + b_tmp = _mm_srai_epi16(_mm_mullo_epi16(U, _mm_set1_epi16(param->cb_factor)), 6); \ + R1 = _mm_unpacklo_epi16(r_tmp, r_tmp); \ + G1 = _mm_unpacklo_epi16(g_tmp, g_tmp); \ + B1 = _mm_unpacklo_epi16(b_tmp, b_tmp); \ + R2 = _mm_unpackhi_epi16(r_tmp, r_tmp); \ + G2 = _mm_unpackhi_epi16(g_tmp, g_tmp); \ + B2 = _mm_unpackhi_epi16(b_tmp, b_tmp); \ + +#define ADD_Y2RGB_16(Y1,Y2,R1,G1,B1,R2,G2,B2) \ + Y1 = _mm_srai_epi16(_mm_mullo_epi16(Y1, _mm_set1_epi16(param->y_factor)), 7); \ + Y2 = _mm_srai_epi16(_mm_mullo_epi16(Y2, _mm_set1_epi16(param->y_factor)), 7); \ + \ + R1 = _mm_add_epi16(Y1, R1); \ + G1 = _mm_sub_epi16(Y1, G1); \ + B1 = _mm_add_epi16(Y1, B1); \ + R2 = _mm_add_epi16(Y2, R2); \ + G2 = _mm_sub_epi16(Y2, G2); \ + B2 = _mm_add_epi16(Y2, B2); \ + +#define PACK_RGB24_32_STEP(RS1, RS2, RS3, RS4, RS5, RS6, RD1, RD2, RD3, RD4, RD5, RD6) \ +RD1 = _mm_packus_epi16(_mm_and_si128(RS1,_mm_set1_epi16(0xFF)), _mm_and_si128(RS2,_mm_set1_epi16(0xFF))); \ +RD2 = _mm_packus_epi16(_mm_and_si128(RS3,_mm_set1_epi16(0xFF)), _mm_and_si128(RS4,_mm_set1_epi16(0xFF))); \ +RD3 = _mm_packus_epi16(_mm_and_si128(RS5,_mm_set1_epi16(0xFF)), _mm_and_si128(RS6,_mm_set1_epi16(0xFF))); \ +RD4 = _mm_packus_epi16(_mm_srli_epi16(RS1,8), _mm_srli_epi16(RS2,8)); \ +RD5 = _mm_packus_epi16(_mm_srli_epi16(RS3,8), _mm_srli_epi16(RS4,8)); \ +RD6 = _mm_packus_epi16(_mm_srli_epi16(RS5,8), _mm_srli_epi16(RS6,8)); \ + +#define PACK_RGB24_32(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \ +PACK_RGB24_32_STEP(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \ +PACK_RGB24_32_STEP(RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, R1, R2, G1, G2, B1, B2) \ +PACK_RGB24_32_STEP(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \ +PACK_RGB24_32_STEP(RGB1, RGB2, RGB3, RGB4, RGB5, RGB6, R1, R2, G1, G2, B1, B2) \ +PACK_RGB24_32_STEP(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \ + +#define LOAD_UV_PLANAR \ + __m128i u = LOAD_SI128((const __m128i*)(u_ptr)); \ + __m128i v = LOAD_SI128((const __m128i*)(v_ptr)); \ + +#define LOAD_UV_NV12 \ + __m128i uv1 = LOAD_SI128((const __m128i*)(uv_ptr)); \ + __m128i uv2 = LOAD_SI128((const __m128i*)(uv_ptr+16)); \ + __m128i u = _mm_packus_epi16(_mm_and_si128(uv1, _mm_set1_epi16(255)), _mm_and_si128(uv2, _mm_set1_epi16(255))); \ + uv1 = _mm_srli_epi16(uv1, 8); \ + uv2 = _mm_srli_epi16(uv2, 8); \ + __m128i v = _mm_packus_epi16(_mm_and_si128(uv1, _mm_set1_epi16(255)), _mm_and_si128(uv2, _mm_set1_epi16(255))); \ + +#define LOAD_UV_NV21 \ + __m128i uv1 = LOAD_SI128((const __m128i*)(uv_ptr)); \ + __m128i uv2 = LOAD_SI128((const __m128i*)(uv_ptr+16)); \ + __m128i v = _mm_packus_epi16(_mm_and_si128(uv1, _mm_set1_epi16(255)), _mm_and_si128(uv2, _mm_set1_epi16(255))); \ + uv1 = _mm_srli_epi16(uv1, 8); \ + uv2 = _mm_srli_epi16(uv2, 8); \ + __m128i u = _mm_packus_epi16(_mm_and_si128(uv1, _mm_set1_epi16(255)), _mm_and_si128(uv2, _mm_set1_epi16(255))); \ + +#define YUV2RGB_32 \ + __m128i r_tmp, g_tmp, b_tmp; \ + __m128i r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2; \ + __m128i r_uv_16_1, g_uv_16_1, b_uv_16_1, r_uv_16_2, g_uv_16_2, b_uv_16_2; \ + __m128i y_16_1, y_16_2; \ + \ + u = _mm_add_epi8(u, _mm_set1_epi8(-128)); \ + v = _mm_add_epi8(v, _mm_set1_epi8(-128)); \ + \ + /* process first 16 pixels of first line */\ + __m128i u_16 = _mm_srai_epi16(_mm_unpacklo_epi8(u, u), 8); \ + __m128i v_16 = _mm_srai_epi16(_mm_unpacklo_epi8(v, v), 8); \ + \ + UV2RGB_16(u_16, v_16, r_uv_16_1, g_uv_16_1, b_uv_16_1, r_uv_16_2, g_uv_16_2, b_uv_16_2) \ + r_16_1=r_uv_16_1; g_16_1=g_uv_16_1; b_16_1=b_uv_16_1; \ + r_16_2=r_uv_16_2; g_16_2=g_uv_16_2; b_16_2=b_uv_16_2; \ + \ + __m128i y = LOAD_SI128((const __m128i*)(y_ptr1)); \ + y = _mm_sub_epi8(y, _mm_set1_epi8(param->y_offset)); \ + y_16_1 = _mm_unpacklo_epi8(y, _mm_setzero_si128()); \ + y_16_2 = _mm_unpackhi_epi8(y, _mm_setzero_si128()); \ + \ + ADD_Y2RGB_16(y_16_1, y_16_2, r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2) \ + \ + __m128i r_8_11 = _mm_packus_epi16(r_16_1, r_16_2); \ + __m128i g_8_11 = _mm_packus_epi16(g_16_1, g_16_2); \ + __m128i b_8_11 = _mm_packus_epi16(b_16_1, b_16_2); \ + \ + /* process first 16 pixels of second line */\ + r_16_1=r_uv_16_1; g_16_1=g_uv_16_1; b_16_1=b_uv_16_1; \ + r_16_2=r_uv_16_2; g_16_2=g_uv_16_2; b_16_2=b_uv_16_2; \ + \ + y = LOAD_SI128((const __m128i*)(y_ptr2)); \ + y = _mm_sub_epi8(y, _mm_set1_epi8(param->y_offset)); \ + y_16_1 = _mm_unpacklo_epi8(y, _mm_setzero_si128()); \ + y_16_2 = _mm_unpackhi_epi8(y, _mm_setzero_si128()); \ + \ + ADD_Y2RGB_16(y_16_1, y_16_2, r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2) \ + \ + __m128i r_8_21 = _mm_packus_epi16(r_16_1, r_16_2); \ + __m128i g_8_21 = _mm_packus_epi16(g_16_1, g_16_2); \ + __m128i b_8_21 = _mm_packus_epi16(b_16_1, b_16_2); \ + \ + /* process last 16 pixels of first line */\ + u_16 = _mm_srai_epi16(_mm_unpackhi_epi8(u, u), 8); \ + v_16 = _mm_srai_epi16(_mm_unpackhi_epi8(v, v), 8); \ + \ + UV2RGB_16(u_16, v_16, r_uv_16_1, g_uv_16_1, b_uv_16_1, r_uv_16_2, g_uv_16_2, b_uv_16_2) \ + r_16_1=r_uv_16_1; g_16_1=g_uv_16_1; b_16_1=b_uv_16_1; \ + r_16_2=r_uv_16_2; g_16_2=g_uv_16_2; b_16_2=b_uv_16_2; \ + \ + y = LOAD_SI128((const __m128i*)(y_ptr1+16)); \ + y = _mm_sub_epi8(y, _mm_set1_epi8(param->y_offset)); \ + y_16_1 = _mm_unpacklo_epi8(y, _mm_setzero_si128()); \ + y_16_2 = _mm_unpackhi_epi8(y, _mm_setzero_si128()); \ + \ + ADD_Y2RGB_16(y_16_1, y_16_2, r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2) \ + \ + __m128i r_8_12 = _mm_packus_epi16(r_16_1, r_16_2); \ + __m128i g_8_12 = _mm_packus_epi16(g_16_1, g_16_2); \ + __m128i b_8_12 = _mm_packus_epi16(b_16_1, b_16_2); \ + \ + /* process last 16 pixels of second line */\ + r_16_1=r_uv_16_1; g_16_1=g_uv_16_1; b_16_1=b_uv_16_1; \ + r_16_2=r_uv_16_2; g_16_2=g_uv_16_2; b_16_2=b_uv_16_2; \ + \ + y = LOAD_SI128((const __m128i*)(y_ptr2+16)); \ + y = _mm_sub_epi8(y, _mm_set1_epi8(param->y_offset)); \ + y_16_1 = _mm_unpacklo_epi8(y, _mm_setzero_si128()); \ + y_16_2 = _mm_unpackhi_epi8(y, _mm_setzero_si128()); \ + \ + ADD_Y2RGB_16(y_16_1, y_16_2, r_16_1, g_16_1, b_16_1, r_16_2, g_16_2, b_16_2) \ + \ + __m128i r_8_22 = _mm_packus_epi16(r_16_1, r_16_2); \ + __m128i g_8_22 = _mm_packus_epi16(g_16_1, g_16_2); \ + __m128i b_8_22 = _mm_packus_epi16(b_16_1, b_16_2); \ + \ + __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6; \ + \ + PACK_RGB24_32(r_8_11, r_8_12, g_8_11, g_8_12, b_8_11, b_8_12, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6) \ + SAVE_SI128((__m128i*)(rgb_ptr1), rgb_1); \ + SAVE_SI128((__m128i*)(rgb_ptr1+16), rgb_2); \ + SAVE_SI128((__m128i*)(rgb_ptr1+32), rgb_3); \ + SAVE_SI128((__m128i*)(rgb_ptr1+48), rgb_4); \ + SAVE_SI128((__m128i*)(rgb_ptr1+64), rgb_5); \ + SAVE_SI128((__m128i*)(rgb_ptr1+80), rgb_6); \ + \ + PACK_RGB24_32(r_8_21, r_8_22, g_8_21, g_8_22, b_8_21, b_8_22, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6) \ + SAVE_SI128((__m128i*)(rgb_ptr2), rgb_1); \ + SAVE_SI128((__m128i*)(rgb_ptr2+16), rgb_2); \ + SAVE_SI128((__m128i*)(rgb_ptr2+32), rgb_3); \ + SAVE_SI128((__m128i*)(rgb_ptr2+48), rgb_4); \ + SAVE_SI128((__m128i*)(rgb_ptr2+64), rgb_5); \ + SAVE_SI128((__m128i*)(rgb_ptr2+80), rgb_6); \ + +#define YUV2RGB_32_PLANAR \ + LOAD_UV_PLANAR \ + YUV2RGB_32 + +#define YUV2RGB_32_NV12 \ + LOAD_UV_NV12 \ + YUV2RGB_32 + +#define YUV2RGB_32_NV21 \ + LOAD_UV_NV21 \ + YUV2RGB_32 + + +void yuv420_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *U, const uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + #define LOAD_SI128 _mm_load_si128 + #define SAVE_SI128 _mm_stream_si128 + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *u_ptr=U+(y/2)*UV_stride, + *v_ptr=V+(y/2)*UV_stride; + + uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + for(x=0; x<(width-31); x+=32) + { + YUV2RGB_32_PLANAR + + y_ptr1+=32; + y_ptr2+=32; + u_ptr+=16; + v_ptr+=16; + rgb_ptr1+=96; + rgb_ptr2+=96; + } + } + #undef LOAD_SI128 + #undef SAVE_SI128 +} + +void yuv420_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *U, const uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + #define LOAD_SI128 _mm_loadu_si128 + #define SAVE_SI128 _mm_storeu_si128 + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *u_ptr=U+(y/2)*UV_stride, + *v_ptr=V+(y/2)*UV_stride; + + uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + for(x=0; x<(width-31); x+=32) + { + YUV2RGB_32_PLANAR + + y_ptr1+=32; + y_ptr2+=32; + u_ptr+=16; + v_ptr+=16; + rgb_ptr1+=96; + rgb_ptr2+=96; + } + } + #undef LOAD_SI128 + #undef SAVE_SI128 +} + +void nv12_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *UV, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + #define LOAD_SI128 _mm_load_si128 + #define SAVE_SI128 _mm_stream_si128 + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *uv_ptr=UV+(y/2)*UV_stride; + + uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + for(x=0; x<(width-31); x+=32) + { + YUV2RGB_32_NV12 + + y_ptr1+=32; + y_ptr2+=32; + uv_ptr+=32; + rgb_ptr1+=96; + rgb_ptr2+=96; + } + } + #undef LOAD_SI128 + #undef SAVE_SI128 +} + +void nv12_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *UV, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + #define LOAD_SI128 _mm_loadu_si128 + #define SAVE_SI128 _mm_storeu_si128 + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *uv_ptr=UV+(y/2)*UV_stride; + + uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + for(x=0; x<(width-31); x+=32) + { + YUV2RGB_32_NV12 + + y_ptr1+=32; + y_ptr2+=32; + uv_ptr+=32; + rgb_ptr1+=96; + rgb_ptr2+=96; + } + } + #undef LOAD_SI128 + #undef SAVE_SI128 +} + +void nv21_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *UV, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + #define LOAD_SI128 _mm_load_si128 + #define SAVE_SI128 _mm_stream_si128 + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *uv_ptr=UV+(y/2)*UV_stride; + + uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + for(x=0; x<(width-31); x+=32) + { + YUV2RGB_32_NV21 + + y_ptr1+=32; + y_ptr2+=32; + uv_ptr+=32; + rgb_ptr1+=96; + rgb_ptr2+=96; + } + } + #undef LOAD_SI128 + #undef SAVE_SI128 +} + +void nv21_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *UV, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + #define LOAD_SI128 _mm_loadu_si128 + #define SAVE_SI128 _mm_storeu_si128 + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *uv_ptr=UV+(y/2)*UV_stride; + + uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + for(x=0; x<(width-31); x+=32) + { + YUV2RGB_32_NV21 + + y_ptr1+=32; + y_ptr2+=32; + uv_ptr+=32; + rgb_ptr1+=96; + rgb_ptr2+=96; + } + } + #undef LOAD_SI128 + #undef SAVE_SI128 +} + + + +#endif //__SSE2__ diff --git a/yuv_rgb.h b/yuv_rgb.h new file mode 100644 index 000000000..9f431a6bf --- /dev/null +++ b/yuv_rgb.h @@ -0,0 +1,155 @@ +// Copyright 2016 Adrien Descamps +// Distributed under BSD 3-Clause License + +// Provide optimized functions to convert images from 8bits yuv420 to rgb24 format + +// There are a few slightly different variations of the YCbCr color space with different parameters that +// change the conversion matrix. +// The three most common YCbCr color space, defined by BT.601, BT.709 and JPEG standard are implemented here. +// See the respective standards for details +// The matrix values used are derived from http://www.equasys.de/colorconversion.html + +// YUV420 is stored as three separate channels, with U and V (Cb and Cr) subsampled by a 2 factor +// For conversion from yuv to rgb, no interpolation is done, and the same UV value are used for 4 rgb pixels. This +// is suboptimal for image quality, but by far the fastest method. + +// For all methods, width and height should be even, if not, the last row/column of the result image won't be affected. +// For sse methods, if the width if not divisable by 32, the last (width%32) pixels of each line won't be affected. + +#include + +typedef enum +{ + YCBCR_JPEG, + YCBCR_601, + YCBCR_709 +} YCbCrType; + +#ifdef __cplusplus +extern "C" { +#endif + +// yuv to rgb, standard c implementation +void yuv420_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv to rgb, yuv in nv12 semi planar format +void nv12_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *uv, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv to rgb, yuv in nv12 semi planar format +void nv21_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *uv, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv to rgb, sse implementation +// pointers must be 16 byte aligned, and strides must be divisable by 16 +void yuv420_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv to rgb, sse implementation +// pointers do not need to be 16 byte aligned +void yuv420_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv nv12 to rgb, sse implementation +// pointers must be 16 byte aligned, and strides must be divisable by 16 +void nv12_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *uv, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv nv12 to rgb, sse implementation +// pointers do not need to be 16 byte aligned +void nv12_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *uv, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv nv21 to rgb, sse implementation +// pointers must be 16 byte aligned, and strides must be divisable by 16 +void nv21_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *uv, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv nv21 to rgb, sse implementation +// pointers do not need to be 16 byte aligned +void nv21_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *uv, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + + + + +// rgb to yuv, standard c implementation +void rgb24_yuv420_std( + uint32_t width, uint32_t height, + const uint8_t *rgb, uint32_t rgb_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + +// rgb to yuv, sse implementation +// pointers must be 16 byte aligned, and strides must be divisible by 16 +void rgb24_yuv420_sse( + uint32_t width, uint32_t height, + const uint8_t *rgb, uint32_t rgb_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + +// rgb to yuv, sse implementation +// pointers do not need to be 16 byte aligned +void rgb24_yuv420_sseu( + uint32_t width, uint32_t height, + const uint8_t *rgb, uint32_t rgb_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + +// rgba to yuv, standard c implementation +// alpha channel is ignored +void rgb32_yuv420_std( + uint32_t width, uint32_t height, + const uint8_t *rgba, uint32_t rgba_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + +// rgba to yuv, sse implementation +// pointers must be 16 byte aligned, and strides must be divisible by 16 +// alpha channel is ignored +void rgb32_yuv420_sse( + uint32_t width, uint32_t height, + const uint8_t *rgba, uint32_t rgba_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + +// rgba to yuv, sse implementation +// pointers do not need to be 16 byte aligned +// alpha channel is ignored +void rgb32_yuv420_sseu( + uint32_t width, uint32_t height, + const uint8_t *rgba, uint32_t rgba_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + +#ifdef __cplusplus +} +#endif From adbb75b808a19e87f2d1e3bfee6bae7766d73ead Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 29 Jan 2022 21:49:19 +0800 Subject: [PATCH 36/66] getOptionMessage --- src/connection.ts | 85 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 17 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index 80119511a..3d81d7b04 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -60,7 +60,9 @@ export default class Connection { const ws = new Websock(uri); this._ws = ws; this._id = id; - console.log(new Date() + ": Conntecting to rendezvoous server: " + uri + ", for " + id); + console.log( + new Date() + ": Conntecting to rendezvoous server: " + uri + ", for " + id + ); await ws.open(); console.log(new Date() + ": Connected to rendezvoous server"); const connType = rendezvous.ConnType.DEFAULT_CONN; @@ -197,7 +199,8 @@ export default class Connection { const msg = this._ws?.parseMessage(await this._ws?.next()); if (msg?.hash) { this._hash = msg?.hash; - if (!this._password) this.msgbox("input-password", "Password Required", ""); + if (!this._password) + this.msgbox("input-password", "Password Required", ""); this.login(this._password); } else if (msg?.testDelay) { const testDelay = msg?.testDelay; @@ -289,10 +292,43 @@ export default class Connection { myId: "web", // to-do myName: "web", // to-do password, + option: this.getOptionMessage(), }); this._ws?.sendMessage({ loginRequest }); } + getOptionMessage(): message.OptionMessage | undefined { + let n = 0; + const msg = message.OptionMessage.fromPartial({}); + const q = this.getImageQualityEnum(this._options["image-quality"], true); + const yes = message.OptionMessage_BoolOption.Yes; + if (q != undefined) { + msg.imageQuality = q; + n += 1; + } + if (this._options["show-remote-cursor"]) { + msg.showRemoteCursor = yes; + n += 1; + } + if (this._options["lock-after-session-end"]) { + msg.lockAfterSessionEnd = yes; + n += 1; + } + if (this._options["privacy-mode"]) { + msg.privacyMode = yes; + n += 1; + } + if (this._options["disable-audio"]) { + msg.disableAudio = yes; + n += 1; + } + if (this._options["disable-clipboard"]) { + msg.disableClipboard = yes; + n += 1; + } + return n > 0 ? msg : undefined; + } + handleVideoFrame(vf: message.VideoFrame) { if (!this._firstFrame) { this.msgbox("", "", ""); @@ -361,7 +397,8 @@ export default class Connection { this._options[name] = value; } - inputKey() { // name: string, x: number, y: number, alt: Boolean, ctrl: Boolean, shift: Boolean, command: Boolean) { + inputKey() { + // name: string, x: number, y: number, alt: Boolean, ctrl: Boolean, shift: Boolean, command: Boolean) { } inputString(seq: string) { @@ -369,7 +406,15 @@ export default class Connection { this._ws?.sendMessage({ keyEvent }); } - inputMouse(mask: number, x: number, y: number, alt: Boolean, ctrl: Boolean, shift: Boolean, command: Boolean) { + inputMouse( + mask: number, + x: number, + y: number, + alt: Boolean, + ctrl: Boolean, + shift: Boolean, + command: Boolean + ) { const mouseEvent = message.MouseEvent.fromPartial({ mask, x, y }); if (alt) mouseEvent.modifiers.push(message.ControlKey.Alt); if (ctrl) mouseEvent.modifiers.push(message.ControlKey.Control); @@ -381,44 +426,49 @@ export default class Connection { toggleOption(name: string) { const v = !this._options[name]; const option = message.OptionMessage.fromPartial({}); - const v2 = v ? message.OptionMessage_BoolOption.Yes : message.OptionMessage_BoolOption.No; + const v2 = v + ? message.OptionMessage_BoolOption.Yes + : message.OptionMessage_BoolOption.No; switch (name) { - case 'show-remote-cursor': + case "show-remote-cursor": option.showRemoteCursor = v2; break; - case 'disable-audio': + case "disable-audio": option.disableAudio = v2; break; - case 'disable-clipboard': + case "disable-clipboard": option.disableClipboard = v2; break; - case 'lock-after-session-end': + case "lock-after-session-end": option.lockAfterSessionEnd = v2; break; - case 'privacy-mode': + case "privacy-mode": option.privacyMode = v2; break; - case 'block-input': + case "block-input": option.blockInput = message.OptionMessage_BoolOption.Yes; break; - case 'unblock-input': + case "unblock-input": option.blockInput = message.OptionMessage_BoolOption.No; break; default: return; } - if (name.indexOf('block-input') < 0) this.setOption(name, v); + if (name.indexOf("block-input") < 0) this.setOption(name, v); const misc = message.Misc.fromPartial({ option }); this._ws?.sendMessage({ misc }); } - getImageQualityEnum(value: string, ignoreDefault: Boolean): message.ImageQuality | undefined { + getImageQualityEnum( + value: string, + ignoreDefault: Boolean + ): message.ImageQuality | undefined { switch (value) { - case 'low': + case "low": return message.ImageQuality.Low; - case 'best': + case "best": return message.ImageQuality.Best; - case 'balanced': + case "balanced": return ignoreDefault ? undefined : message.ImageQuality.Balanced; default: return undefined; @@ -426,6 +476,7 @@ export default class Connection { } setImageQuality(value: string) { + this.setOption("image-quality", value); const imageQuality = this.getImageQualityEnum(value, false); if (imageQuality == undefined) return; const option = message.OptionMessage.fromPartial({ imageQuality }); From 2cf2fb7804e89ed1dba86cf6ed885c99b16432d0 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 29 Jan 2022 23:05:29 +0800 Subject: [PATCH 37/66] yuv in another worker --- src/globals.js | 69 +++++++---------------------------------------- yuv.js | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 60 deletions(-) create mode 100644 yuv.js diff --git a/src/globals.js b/src/globals.js index c9452b349..6d199dfd8 100644 --- a/src/globals.js +++ b/src/globals.js @@ -5,7 +5,6 @@ import { CursorData } from "./message"; import { loadOpus, loadVp9 } from "./codec"; var decompressor; -var wasmExports; var currentFrame = undefined; var events = []; @@ -59,8 +58,14 @@ export function pushEvent(name, payload) { events.push(payload); } +const yuvWorker = new Worker("./yuv.js"); + +yuvWorker.onmessage = (e) => { + currentFrame = e.data; +} + export function draw(frame) { - currentFrame = I420ToARGB(frame); + yuvWorker.postMessage(frame); } export function setConn(conn) { @@ -73,6 +78,8 @@ export function getConn() { export async function startConn(id) { try { + currentFrame = undefined; + events = []; await curConn.start(id); } catch (e) { console.log(e); @@ -89,7 +96,6 @@ export function close() { export function newConn() { window.curConn?.close(); - events = []; const conn = new Connection(); setConn(conn); return conn; @@ -299,66 +305,9 @@ window.init = async () => { await initZstd(); } -let yPtr, yPtrLen, uPtr, uPtrLen, vPtr, vPtrLen, outPtr, outPtrLen; -// let testSpeed = [0, 0]; -export function I420ToARGB(yb) { - if (!wasmExports) return; - // testSpeed[0] += 1; - const tm0 = new Date().getTime(); - const { malloc, free, memory } = wasmExports; - const HEAPU8 = new Uint8Array(memory.buffer); - let n = yb.y.bytes.length; - if (yPtrLen != n) { - if (yPtr) free(yPtr); - yPtrLen = n; - yPtr = malloc(n); - } - HEAPU8.set(yb.y.bytes, yPtr); - n = yb.u.bytes.length; - if (uPtrLen != n) { - if (uPtr) free(uPtr); - uPtrLen = n; - uPtr = malloc(n); - } - HEAPU8.set(yb.u.bytes, uPtr); - n = yb.v.bytes.length; - if (vPtrLen != n) { - if (vPtr) free(vPtr); - vPtrLen = n; - vPtr = malloc(n); - } - HEAPU8.set(yb.v.bytes, vPtr); - const w = yb.format.displayWidth; - const h = yb.format.displayHeight; - n = w * h * 4; - if (outPtrLen != n) { - if (outPtr) free(outPtr); - outPtrLen = n; - outPtr = malloc(n); - HEAPU8.fill(255, outPtr, outPtr + n); - } - // const res = wasmExports.I420ToARGB(yPtr, yb.y.stride, uPtr, yb.u.stride, vPtr, yb.v.stride, outPtr, w * 4, w, h); - // const res = wasmExports.AVX_YUV_to_ARGB(outPtr, yPtr, yb.y.stride, uPtr, yb.u.stride, vPtr, yb.v.stride, w, h); - const res = wasmExports.yuv420_rgb24_std(w, h, yPtr, uPtr, vPtr, yb.y.stride, yb.v.stride, outPtr, w * 4, 1); - const out = HEAPU8.slice(outPtr, outPtr + n); - /* - testSpeed[1] += new Date().getTime() - tm0; - if (testSpeed[0] > 30) { - console.log(testSpeed[1] / testSpeed[0]); - testSpeed = [0, 0]; - } - */ - return out; -} - async function initZstd() { loadOpus(() => { }); loadVp9(() => { }); - const response = await fetch('yuv.wasm'); - const file = await response.arrayBuffer(); - const wasm = await WebAssembly.instantiate(file); - wasmExports = wasm.instance.exports; - console.log('yuv ready'); const tmp = new zstd.ZSTDDecoder(); await tmp.init(); console.log('zstd ready'); diff --git a/yuv.js b/yuv.js new file mode 100644 index 000000000..65199f3a8 --- /dev/null +++ b/yuv.js @@ -0,0 +1,73 @@ +var wasmExports; + +fetch('yuv.wasm').then(function (res) { return res.arrayBuffer(); }) + .then(function (file) { return WebAssembly.instantiate(file); }) + .then(function (wasm) { + wasmExports = wasm.instance.exports; + console.log('yuv ready'); + }); + +var yPtr, yPtrLen, uPtr, uPtrLen, vPtr, vPtrLen, outPtr, outPtrLen; +let testSpeed = [0, 0]; +function I420ToARGB(yb) { + if (!wasmExports) return; + testSpeed[0] += 1; + var tm0 = new Date().getTime(); + var { malloc, free, memory } = wasmExports; + var HEAPU8 = new Uint8Array(memory.buffer); + let n = yb.y.bytes.length; + if (yPtrLen != n) { + if (yPtr) free(yPtr); + yPtrLen = n; + yPtr = malloc(n); + } + HEAPU8.set(yb.y.bytes, yPtr); + n = yb.u.bytes.length; + if (uPtrLen != n) { + if (uPtr) free(uPtr); + uPtrLen = n; + uPtr = malloc(n); + } + HEAPU8.set(yb.u.bytes, uPtr); + n = yb.v.bytes.length; + if (vPtrLen != n) { + if (vPtr) free(vPtr); + vPtrLen = n; + vPtr = malloc(n); + } + HEAPU8.set(yb.v.bytes, vPtr); + var w = yb.format.displayWidth; + var h = yb.format.displayHeight; + n = w * h * 4; + if (outPtrLen != n) { + if (outPtr) free(outPtr); + outPtrLen = n; + outPtr = malloc(n); + HEAPU8.fill(255, outPtr, outPtr + n); + } + // var res = wasmExports.I420ToARGB(yPtr, yb.y.stride, uPtr, yb.u.stride, vPtr, yb.v.stride, outPtr, w * 4, w, h); + // var res = wasmExports.AVX_YUV_to_ARGB(outPtr, yPtr, yb.y.stride, uPtr, yb.u.stride, vPtr, yb.v.stride, w, h); + var res = wasmExports.yuv420_rgb24_std(w, h, yPtr, uPtr, vPtr, yb.y.stride, yb.v.stride, outPtr, w * 4, 1); + var out = HEAPU8.slice(outPtr, outPtr + n); + testSpeed[1] += new Date().getTime() - tm0; + if (testSpeed[0] > 30) { + console.log(testSpeed[1] / testSpeed[0]); + testSpeed = [0, 0]; + } + return out; +} + +var currentFrame; +self.addEventListener('message', (e) => { + currentFrame = e.data; +}); + +function run() { + if (currentFrame) { + self.postMessage(I420ToARGB(currentFrame)); + currentFrame = undefined; + } + setTimeout(run, 1); +} + +run(); \ No newline at end of file From f17aff8bb4667aebc646af5a3ff9d082e3320fe1 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sun, 30 Jan 2022 03:39:54 +0800 Subject: [PATCH 38/66] more api --- .gitignore | 1 + gen_js_from_hbb.py | 57 ++ src/common.ts | 66 +++ src/connection.ts | 249 +++++--- src/gen_js_from_hbb.ts | 743 +++++++++++++++++++++++ src/globals.js | 71 +-- src/message.ts | 1274 ++++++++++++++++++++-------------------- src/rendezvous.ts | 1042 ++++++++++++++++---------------- src/websock.ts | 10 +- ts_proto.py | 8 +- 10 files changed, 2237 insertions(+), 1284 deletions(-) create mode 100755 gen_js_from_hbb.py create mode 100644 src/common.ts create mode 100644 src/gen_js_from_hbb.ts mode change 100644 => 100755 ts_proto.py diff --git a/.gitignore b/.gitignore index f2ed50767..620c5689f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ dist-ssr *.local *log ogvjs +.vscode diff --git a/gen_js_from_hbb.py b/gen_js_from_hbb.py new file mode 100755 index 000000000..73a1f8ebe --- /dev/null +++ b/gen_js_from_hbb.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +import os +import glob +from tabnanny import check + +def main(): + print('export const LANGS = {') + for fn in glob.glob('../hbb/src/lang/*'): + lang = os.path.basename(fn)[:-3] + print(' %s: {'%lang) + for ln in open(fn): + ln = ln.strip() + if ln.startswith('("'): + toks = ln.split('", "') + assert(len(toks) == 2) + a = toks[0][2:] + b = toks[1][:-3] + print(' "%s": "%s",'%(a, b)) + print(' },') + print('}') + check_if_retry = ['', False] + KEY_MAP = ['', False] + for ln in open('../hbb/src/client.rs'): + ln = ln.strip() + if 'check_if_retry' in ln: + check_if_retry[1] = True + continue + if ln.startswith('}') and check_if_retry[1]: + check_if_retry[1] = False + continue + if check_if_retry[1]: + check_if_retry[0] += ln + '\n' + if 'KEY_MAP' in ln: + KEY_MAP[1] = True + continue + if '.collect' in ln and KEY_MAP[1]: + KEY_MAP[1] = False + continue + if KEY_MAP[1] and ln.startswith('('): + toks = ln.split('", Key::') + assert(len(toks) == 2) + a = toks[0][2:] + b = toks[1].replace('ControlKey(ControlKey::', '').replace("Chr('", '').replace("' as _)),", '').replace(')),', '') + KEY_MAP[0] += ' "%s": "%s",\n'%(a, b) + print() + print('export function checkIfRetry(msgtype: string, title: string, text: string) {') + print(' return %s'%check_if_retry[0].replace('to_lowercase', 'toLowerCase').replace('contains', 'indexOf').replace('!', '').replace('")', '") < 0')) + print(';}') + print() + print('export const KEY_MAP: any = {') + print(KEY_MAP[0]) + print('}') + + + +main() \ No newline at end of file diff --git a/src/common.ts b/src/common.ts new file mode 100644 index 000000000..80125848b --- /dev/null +++ b/src/common.ts @@ -0,0 +1,66 @@ +import * as zstd from "zstddec"; +import { KeyEvent, controlKeyFromJSON, ControlKey } from "./message"; +import { KEY_MAP, LANGS } from "./gen_js_from_hbb"; + +let decompressor: zstd.ZSTDDecoder; + +export async function initZstd() { + const tmp = new zstd.ZSTDDecoder(); + await tmp.init(); + console.log("zstd ready"); + decompressor = tmp; +} + +export async function decompress(compressedArray: Uint8Array) { + const MAX = 1024 * 1024 * 64; + const MIN = 1024 * 1024; + let n = 30 * compressedArray.length; + if (n > MAX) { + n = MAX; + } + if (n < MIN) { + n = MIN; + } + try { + if (!decompressor) { + await initZstd(); + } + return decompressor.decode(compressedArray, n); + } catch (e) { + console.error("decompress failed: " + e); + return undefined; + } +} + +export function translate(locale: string, text: string): string { + const lang = locale.substr(locale.length - 2).toLowerCase(); + let en = LANGS.en as any; + let dict = (LANGS as any)[lang]; + if (!dict) dict = en; + let res = dict[text]; + if (!res && lang != "en") res = en[text]; + return res || text; +} + +const zCode = "z".charCodeAt(0); +const aCode = "a".charCodeAt(0); + +export function mapKey(name: string) { + const tmp = KEY_MAP[name]; + if (!tmp) return undefined; + if (tmp.length == 1) { + const chr = tmp.charCodeAt(0); + if (chr > zCode || chr < aCode) + return KeyEvent.fromPartial({ unicode: chr }); + else return KeyEvent.fromPartial({ chr }); + } + const control_key = controlKeyFromJSON(name); + if (control_key == ControlKey.UNRECOGNIZED) { + console.error("Unknown control key " + name); + } + return KeyEvent.fromPartial({ control_key }); +} + +export async function sleep(ms: number) { + await new Promise((r) => setTimeout(r, ms)); +} diff --git a/src/connection.ts b/src/connection.ts index 3d81d7b04..27998bab5 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -4,6 +4,7 @@ import * as rendezvous from "./rendezvous.js"; import { loadVp9, loadOpus } from "./codec"; import * as sha256 from "fast-sha256"; import * as globals from "./globals"; +import { decompress, mapKey, sleep } from "./common"; const PORT = 21116; const HOST = "rs-sg.rustdesk.com"; @@ -65,20 +66,20 @@ export default class Connection { ); await ws.open(); console.log(new Date() + ": Connected to rendezvoous server"); - const connType = rendezvous.ConnType.DEFAULT_CONN; - const natType = rendezvous.NatType.SYMMETRIC; - const punchHoleRequest = rendezvous.PunchHoleRequest.fromPartial({ + const conn_type = rendezvous.ConnType.DEFAULT_CONN; + const nat_type = rendezvous.NatType.SYMMETRIC; + const punch_hole_request = rendezvous.PunchHoleRequest.fromPartial({ id, - licenceKey: localStorage.getItem("key") || undefined, - connType, - natType, + licence_key: localStorage.getItem("key") || undefined, + conn_type, + nat_type, }); - ws.sendRendezvous({ punchHoleRequest }); + ws.sendRendezvous({ punch_hole_request }); const msg = ws.parseRendezvous(await ws.next()); ws.close(); console.log(new Date() + ": Got relay response"); - const phr = msg.punchHoleResponse; - const rr = msg.relayResponse; + const phr = msg.punch_hole_response; + const rr = msg.relay_response; if (phr) { if (phr.failure != rendezvous.PunchHoleResponse_Failure.UNRECOGNIZED) { switch (phr?.failure) { @@ -92,8 +93,8 @@ export default class Connection { this.msgbox("error", "Error", "Key mismatch"); break; default: - if (phr?.otherFailure) { - this.msgbox("error", "Error", phr?.otherFailure); + if (phr?.other_failure) { + this.msgbox("error", "Error", phr?.other_failure); } } } @@ -104,7 +105,7 @@ export default class Connection { async connectRelay(rr: rendezvous.RelayResponse) { const pk = rr.pk; - let uri = rr.relayServer; + let uri = rr.relay_server; if (uri) { uri = getrUriFromRs(uri); } else { @@ -116,11 +117,11 @@ export default class Connection { await ws.open(); console.log(new Date() + ": Connected to relay server"); this._ws = ws; - const requestRelay = rendezvous.RequestRelay.fromPartial({ - licenceKey: localStorage.getItem("key") || undefined, + const request_relay = rendezvous.RequestRelay.fromPartial({ + licence_key: localStorage.getItem("key") || undefined, uuid, }); - ws.sendRendezvous({ requestRelay }); + ws.sendRendezvous({ request_relay }); const secure = (await this.secure(pk)) || false; globals.pushEvent("connection_ready", { secure, direct: false }); await this.msgLoop(); @@ -149,7 +150,7 @@ export default class Connection { return; } const msg = this._ws?.parseMessage(await this._ws?.next()); - let signedId: any = msg?.signedId; + let signedId: any = msg?.signed_id; if (!signedId) { console.error("Handshake failed: invalid message type"); this._ws?.sendMessage({}); @@ -161,8 +162,8 @@ export default class Connection { console.error(e); // fall back to non-secure connection in case pk mismatch console.error("pk mismatch, fall back to non-secure"); - const publicKey = message.PublicKey.fromPartial({}); - this._ws?.sendMessage({ publicKey }); + const public_key = message.PublicKey.fromPartial({}); + this._ws?.sendMessage({ public_key }); return; } signedId = new TextDecoder().decode(signedId!); @@ -182,15 +183,16 @@ export default class Connection { this._ws?.sendMessage({}); return; } - const [mySk, asymmetricValue] = globals.genBoxKeyPair(); - const secretKey = globals.genSecretKey(); - const symmetricValue = globals.seal(secretKey, theirPk, mySk); - const publicKey = message.PublicKey.fromPartial({ - asymmetricValue, - symmetricValue, + const [mySk, asymmetric_value] = globals.genBoxKeyPair(); + const secret_key = globals.genSecretKey(); + const symmetric_value = globals.seal(secret_key, theirPk, mySk); + const public_key = message.PublicKey.fromPartial({ + asymmetric_value, + symmetric_value, }); - this._ws?.sendMessage({ publicKey }); - this._ws?.setSecretKey(secretKey); + this._ws?.sendMessage({ public_key }); + this._ws?.setSecretKey(secret_key); + console.log("secured"); return true; } @@ -202,35 +204,41 @@ export default class Connection { if (!this._password) this.msgbox("input-password", "Password Required", ""); this.login(this._password); - } else if (msg?.testDelay) { - const testDelay = msg?.testDelay; - if (!testDelay.fromClient) { - this._ws?.sendMessage({ testDelay }); + } else if (msg?.test_delay) { + const test_delay = msg?.test_delay; + if (!test_delay.from_client) { + this._ws?.sendMessage({ test_delay }); } - } else if (msg?.loginResponse) { - const r = msg?.loginResponse; + } else if (msg?.login_response) { + const r = msg?.login_response; if (r.error) { this.msgbox("error", "Error", r.error); - } else if (r.peerInfo) { - this.handlePeerInfo(r.peerInfo); + } else if (r.peer_info) { + this.handlePeerInfo(r.peer_info); } - } else if (msg?.videoFrame) { - this.handleVideoFrame(msg?.videoFrame!); + } else if (msg?.video_frame) { + this.handleVideoFrame(msg?.video_frame!); } else if (msg?.clipboard) { const cb = msg?.clipboard; - if (cb.compress) cb.content = await globals.decompress(cb.content)!; + if (cb.compress) { + const c = await decompress(cb.content); + if (!c) continue; + cb.content = c; + } globals.pushEvent("clipboard", cb); - } else if (msg?.cursorData) { - const cd = msg?.cursorData; - cd.colors = await globals.decompress(cd.colors)!; + } else if (msg?.cursor_data) { + const cd = msg?.cursor_data; + const c = await decompress(cd.colors); + if (!c) continue; + cd.colors = c; globals.pushEvent("cursor_data", cd); - } else if (msg?.cursorId) { - globals.pushEvent("cursor_id", { id: msg?.cursorId }); - } else if (msg?.cursorPosition) { - globals.pushEvent("cursor_position", msg?.cursorPosition); + } else if (msg?.cursor_id) { + globals.pushEvent("cursor_id", { id: msg?.cursor_id }); + } else if (msg?.cursor_position) { + globals.pushEvent("cursor_position", msg?.cursor_position); } else if (msg?.misc) { this.handleMisc(msg?.misc); - } else if (msg?.audioFrame) { + } else if (msg?.audio_frame) { // } } @@ -254,7 +262,7 @@ export default class Connection { refresh() { const misc = message.Misc.fromPartial({ - refreshVideo: true, + refresh_video: true, }); this._ws?.sendMessage({ misc }); } @@ -287,14 +295,14 @@ export default class Connection { } _sendLoginMessage(password: Uint8Array | undefined = undefined) { - const loginRequest = message.LoginRequest.fromPartial({ + const login_request = message.LoginRequest.fromPartial({ username: this._id!, - myId: "web", // to-do - myName: "web", // to-do + my_id: "web", // to-do + my_name: "web", // to-do password, option: this.getOptionMessage(), }); - this._ws?.sendMessage({ loginRequest }); + this._ws?.sendMessage({ login_request }); } getOptionMessage(): message.OptionMessage | undefined { @@ -303,27 +311,27 @@ export default class Connection { const q = this.getImageQualityEnum(this._options["image-quality"], true); const yes = message.OptionMessage_BoolOption.Yes; if (q != undefined) { - msg.imageQuality = q; + msg.image_quality = q; n += 1; } if (this._options["show-remote-cursor"]) { - msg.showRemoteCursor = yes; + msg.show_remote_cursor = yes; n += 1; } if (this._options["lock-after-session-end"]) { - msg.lockAfterSessionEnd = yes; + msg.lock_after_session_end = yes; n += 1; } if (this._options["privacy-mode"]) { - msg.privacyMode = yes; + msg.privacy_mode = yes; n += 1; } if (this._options["disable-audio"]) { - msg.disableAudio = yes; + msg.disable_audio = yes; n += 1; } if (this._options["disable-clipboard"]) { - msg.disableClipboard = yes; + msg.disable_clipboard = yes; n += 1; } return n > 0 ? msg : undefined; @@ -358,10 +366,10 @@ export default class Connection { } handleMisc(misc: message.Misc) { - if (misc.audioFormat) { + if (misc.audio_format) { // - } else if (misc.permissionInfo) { - const p = misc.permissionInfo; + } else if (misc.permission_info) { + const p = misc.permission_info; console.info("Change permission " + p.permission + " -> " + p.enabled); let name; switch (p.permission) { @@ -378,10 +386,10 @@ export default class Connection { return; } globals.pushEvent("permission", { [name]: p.enabled }); - } else if (misc.switchDisplay) { - globals.pushEvent("switch_display", misc.switchDisplay); - } else if (misc.closeReason) { - this.msgbox("error", "Connection Error", misc.closeReason); + } else if (misc.switch_display) { + globals.pushEvent("switch_display", misc.switch_display); + } else if (misc.close_reason) { + this.msgbox("error", "Connection Error", misc.close_reason); } } @@ -397,30 +405,87 @@ export default class Connection { this._options[name] = value; } - inputKey() { - // name: string, x: number, y: number, alt: Boolean, ctrl: Boolean, shift: Boolean, command: Boolean) { - } - - inputString(seq: string) { - const keyEvent = message.KeyEvent.fromPartial({ seq }); - this._ws?.sendMessage({ keyEvent }); - } - - inputMouse( - mask: number, - x: number, - y: number, + inputKey( + name: string, alt: Boolean, ctrl: Boolean, shift: Boolean, command: Boolean ) { - const mouseEvent = message.MouseEvent.fromPartial({ mask, x, y }); - if (alt) mouseEvent.modifiers.push(message.ControlKey.Alt); - if (ctrl) mouseEvent.modifiers.push(message.ControlKey.Control); - if (shift) mouseEvent.modifiers.push(message.ControlKey.Shift); - if (command) mouseEvent.modifiers.push(message.ControlKey.Meta); - this._ws?.sendMessage({ mouseEvent }); + const key_event = mapKey(name); + if (!key_event) return; + key_event.press = true; + key_event.modifiers = this.getMod(alt, ctrl, shift, command); + this._ws?.sendMessage({ key_event }); + } + + ctrlAltDel() { + const key_event = message.KeyEvent.fromPartial({ down: true }); + if (this._peerInfo?.platform == "Windows") { + key_event.control_key = message.ControlKey.CtrlAltDel; + } else { + key_event.control_key = message.ControlKey.Delete; + key_event.modifiers = this.getMod(true, true, false, false); + } + this._ws?.sendMessage({ key_event }); + } + + inputString(seq: string) { + const key_event = message.KeyEvent.fromPartial({ seq }); + this._ws?.sendMessage({ key_event }); + } + + switchDisplay(display: number) { + const switch_display = message.SwitchDisplay.fromPartial({ display }); + const misc = message.Misc.fromPartial({ switch_display }); + this._ws?.sendMessage({ misc }); + } + + async inputOsPassword(seq: string) { + this.inputMouse(); + await sleep(50); + this.inputMouse(0, 3, 3); + await sleep(50); + this.inputMouse(1 | (1 << 3)); + this.inputMouse(2 | (1 << 3)); + await sleep(1200); + const key_event = message.KeyEvent.fromPartial({ press: true, seq }); + this._ws?.sendMessage({ key_event }); + } + + lockScreen() { + const key_event = message.KeyEvent.fromPartial({ + down: true, + control_key: message.ControlKey.LockScreen, + }); + this._ws?.sendMessage({ key_event }); + } + + getMod(alt: Boolean, ctrl: Boolean, shift: Boolean, command: Boolean) { + const mod: message.ControlKey[] = []; + if (alt) mod.push(message.ControlKey.Alt); + if (ctrl) mod.push(message.ControlKey.Control); + if (shift) mod.push(message.ControlKey.Shift); + if (command) mod.push(message.ControlKey.Meta); + return mod; + } + + inputMouse( + mask: number = 0, + x: number = 0, + y: number = 0, + alt: Boolean = false, + ctrl: Boolean = false, + shift: Boolean = false, + command: Boolean = false + ) { + const mouse_event = message.MouseEvent.fromPartial({ + mask, + x, + y, + modifiers: this.getMod(alt, ctrl, shift, command), + }); + this._ws?.sendMessage({ mouse_event }); } toggleOption(name: string) { @@ -431,25 +496,25 @@ export default class Connection { : message.OptionMessage_BoolOption.No; switch (name) { case "show-remote-cursor": - option.showRemoteCursor = v2; + option.show_remote_cursor = v2; break; case "disable-audio": - option.disableAudio = v2; + option.disable_audio = v2; break; case "disable-clipboard": - option.disableClipboard = v2; + option.disable_clipboard = v2; break; case "lock-after-session-end": - option.lockAfterSessionEnd = v2; + option.lock_after_session_end = v2; break; case "privacy-mode": - option.privacyMode = v2; + option.privacy_mode = v2; break; case "block-input": - option.blockInput = message.OptionMessage_BoolOption.Yes; + option.block_input = message.OptionMessage_BoolOption.Yes; break; case "unblock-input": - option.blockInput = message.OptionMessage_BoolOption.No; + option.block_input = message.OptionMessage_BoolOption.No; break; default: return; @@ -477,9 +542,9 @@ export default class Connection { setImageQuality(value: string) { this.setOption("image-quality", value); - const imageQuality = this.getImageQualityEnum(value, false); - if (imageQuality == undefined) return; - const option = message.OptionMessage.fromPartial({ imageQuality }); + const image_quality = this.getImageQualityEnum(value, false); + if (image_quality == undefined) return; + const option = message.OptionMessage.fromPartial({ image_quality }); const misc = message.Misc.fromPartial({ option }); this._ws?.sendMessage({ misc }); } diff --git a/src/gen_js_from_hbb.ts b/src/gen_js_from_hbb.ts new file mode 100644 index 000000000..e9af6cf20 --- /dev/null +++ b/src/gen_js_from_hbb.ts @@ -0,0 +1,743 @@ +export const LANGS = { + cn: { + "Status": "状态", + "Your Desktop": "你的桌面", + "desk_tip": "你的桌面可以通过下面的ID和密码访问。", + "Password": "密码", + "Ready": "就绪", + "connecting_status": "正在接入RustDesk网络...", + "Enable Service": "允许服务", + "Start Service": "启动服务", + "Service is not running": "服务没有启动", + "not_ready_status": "未就绪,请检查网络连接", + "Control Remote Desktop": "控制远程桌面", + "Transfer File": "传输文件", + "Connect": "连接", + "Recent Sessions": "最近访问过", + "Address Book": "地址簿", + "Confirmation": "确认", + "TCP Tunneling": "TCP隧道", + "Remove": "删除", + "Refresh random password": "刷新随机密码", + "Set your own password": "设置密码", + "Enable Keyboard/Mouse": "允许控制键盘/鼠标", + "Enable Clipboard": "允许同步剪贴板", + "Enable File Transfer": "允许传输文件", + "Enable TCP Tunneling": "允许建立TCP隧道", + "IP Whitelisting": "IP白名单", + "ID/Relay Server": "ID/中继服务器", + "Stop service": "停止服务", + "Change ID": "改变ID", + "Website": "网站", + "About": "关于", + "Mute": "静音", + "Audio Input": "音频输入", + "ID Server": "ID服务器", + "Relay Server": "中继服务器", + "API Server": "API服务器", + "invalid_http": "必须以http://或者https://开头", + "Invalid IP": "无效IP", + "id_change_tip": "只可以使用字母a-z, A-Z, 0-9, _ (下划线)。首字母必须是a-z, A-Z。长度在6与16之间。", + "Invalid format": "无效格式", + "This function is turned off by the server": "服务器关闭了此功能", + "Not available": "已被占用", + "Too frequent": "修改太频繁,请稍后再试", + "Cancel": "取消", + "Skip": "跳过", + "Close": "关闭", + "Retry": "再试", + "OK": "确认", + "Password Required": "需要密码", + "Please enter your password": "请输入密码", + "Remember password": "记住密码", + "Wrong Password": "密码错误", + "Do you want to enter again?": "还想输入一次吗?", + "Connection Error": "连接错误", + "Error": "错误", + "Reset by the peer": "连接被对方关闭", + "Connecting...": "正在连接...", + "Connection in progress. Please wait.": "连接进行中,请稍等。", + "Please try 1 minute later": "一分钟后再试", + "Login Error": "登录错误", + "Successful": "成功", + "Connected, waiting for image...": "已连接,等待画面传输...", + "Name": "文件名", + "Modified": "修改时间", + "Size": "大小", + "Show Hidden Files": "显示隐藏文件", + "Receive": "接受", + "Send": "发送", + "Remote Computer": "远程电脑", + "Local Computer": "本地电脑", + "Confirm Delete": "确认删除", + "Are you sure you want to delete this file?": "是否删除此文件?", + "Do this for all conflicts": "应用于其它冲突", + "Deleting": "正在删除", + "files": "文件", + "Waiting": "等待...", + "Finished": "完成", + "Custom Image Quality": "设置画面质量", + "Privacy mode": "隐私模式", + "Block user input": "阻止用户输入", + "Unblock user input": "取消阻止用户输入", + "Adjust Window": "调节窗口", + "Original": "原始比例", + "Shrink": "收缩", + "Stretch": "伸展", + "Good image quality": "好画质", + "Balanced": "一般画质", + "Optimize reaction time": "优化反应时间", + "Custom": "自定义画质", + "Show remote cursor": "显示远程光标", + "Disable clipboard": "禁止剪贴板", + "Lock after session end": "断开后锁定远程电脑", + "Insert": "插入", + "Insert Lock": "锁定远程电脑", + "Refresh": "刷新画面", + "ID does not exist": "ID不存在", + "Failed to connect to rendezvous server": "连接注册服务器失败", + "Please try later": "请稍后再试", + "Remote desktop is offline": "远程电脑不在线", + "Key mismatch": "Key不匹配", + "Timeout": "连接超时", + "Failed to connect to relay server": "无法连接到中继服务器", + "Failed to connect via rendezvous server": "无法通过注册服务器建立连接", + "Failed to connect via relay server": "无法通过中继服务器建立连接", + "Failed to make direct connection to remote desktop": "无法建立直接连接", + "Set Password": "设置密码", + "OS Password": "操作系统密码", + "install_tip": "你正在运行未安装版本,由于UAC限制,作为被控端,会在某些情况下无法控制鼠标键盘,或者录制屏幕,请点击下面的按钮将RustDesk安装到系统,从而规避上述问题。", + "Click to upgrade": "点击这里升级", + "Click to download": "点击这里下载", + "Click to update": "点击这里更新", + "Configuration Permissions": "配置权限", + "Configure": "配置", + "config_acc": "为了能够远程控制你的桌面, 请给予RustDesk\"辅助功能\" 权限。", + "config_screen": "为了能够远程访问你的桌面, 请给予RustDesk\"屏幕录制\" 权限。", + "Installing ...": "安装 ...", + "Install": "安装", + "Installation": "安装", + "Installation Path": "安装路径", + "Create start menu shortcuts": "创建启动菜单快捷方式", + "Create desktop icon": "创建桌面图标", + "agreement_tip": "开始安装即表示接受许可协议。", + "Accept and Install": "同意并安装", + "End-user license agreement": "用户协议", + "Generating ...": "正在产生 ...", + "Your installation is lower version.": "你安装的版本比当前运行的低。", + "not_close_tcp_tip": "请在使用隧道的时候,不要关闭本窗口", + "Listening ...": "正在等待隧道连接 ...", + "Remote Host": "远程主机", + "Remote Port": "远程端口", + "Action": "动作", + "Add": "添加", + "Local Port": "本地端口", + "setup_server_tip": "如果需要更快连接速度,你可以选择自建服务器", + "Too short, at least 6 characters.": "太短了,至少6个字符", + "The confirmation is not identical.": "两次输入不匹配", + "Permissions": "权限", + "Accept": "接受", + "Dismiss": "拒绝", + "Disconnect": "断开连接", + "Allow using keyboard and mouse": "允许使用键盘鼠标", + "Allow using clipboard": "允许使用剪贴板", + "Allow hearing sound": "允许听到声音", + "Connected": "已经连接", + "Direct and encrypted connection": "加密直连", + "Relayed and encrypted connection": "加密中继连接", + "Direct and unencrypted connection": "非加密直连", + "Relayed and unencrypted connection": "非加密中继连接", + "Enter Remote ID": "输入对方ID", + "Enter your password": "输入密码", + "Logging in...": "正在登录...", + "Enable RDP session sharing": "允许RDP会话共享", + "Auto Login": "自动登录(设置断开后锁定才有效)", + "Enable Direct IP Access": "允许IP直接访问", + "Rename": "改名", + "Space": "空格", + "Create Desktop Shortcut": "创建桌面快捷方式", + "Change Path": "改变路径", + "Create Folder": "创建文件夹", + "Please enter the folder name": "请输入文件夹名称", + "Fix it": "修复", + "Warning": "警告", + "Login screen using Wayland is not supported": "不支持使用 Wayland 登录界面", + "Reboot required": "重启后才能生效", + "Unsupported display server ": "不支持当前显示服务器", + "x11 expected": "请切换到 x11", + "Port": "端口", + "Settings": "设置", + "Username": " 用户名", + "Invalid port": "无效端口", + "Closed manually by the peer": "被对方手动关闭", + "Enable remote configuration modification": "允许远程修改配置", + "Run without install": "无安装运行", + "Always connected via relay": "强制走中继连接", + "Always connect via relay": "强制走中继连接", + "whitelist_tip": "只有白名单里的ip才能访问我", + "Login": "登录", + "Logout": "登出", + "Tags": "标签", + "Search ID": "查找ID", + "Current Wayland display server is not supported": "不支持 Wayland 显示服务器", + "whitelist_sep": "可以使用逗号,分号,空格或者换行符作为分隔符", + "Add ID": "增加ID", + "Add Tag": "增加标签", + "Unselect all tags": "取消选择所有标签", + "Network error": "网络错误", + "Username missed": "用户名没有填写", + "Password missed": "密码没有填写", + "Wrong credentials": "用户名或者密码错误", + "Edit Tag": "修改标签", + "Unremember Password": "忘掉密码", + "Favorites": "收藏", + "Add to Favorites": "加入到收藏", + "Remove from Favorites": "从收藏中删除", + "Empty": "空空如也", + "Invalid folder name": "无效文件夹名称", + "Socks5 Proxy": "Socks5 代理", + "Hostname": "主机名", + "Discovered": "已发现", + "install_daemon_tip": "为了开机启动,请安装系统服务。", + }, + it: { + "Status": "Stato", + "Your Desktop": "Il tuo desktop", + "desk_tip": "Puoi accedere al tuo desktop usando l'ID e la password riportati qui.", + "Password": "Password", + "Ready": "Pronto", + "connecting_status": "Connessione alla rete RustDesk in corso...", + "Enable Service": "Abilita servizio", + "Start Service": "Avvia servizio", + "Service is not running": "Il servizio non è in esecuzione", + "not_ready_status": "Non pronto. Verifica la tua connessione", + "Control Remote Desktop": "Controlla una scrivania remota", + "Transfer File": "Trasferisci file", + "Connect": "Connetti", + "Recent Sessions": "Sessioni recenti", + "Address Book": "Rubrica", + "Confirmation": "Conferma", + "TCP Tunneling": "Tunnel TCP", + "Remove": "Rimuovi", + "Refresh random password": "Nuova password casuale", + "Set your own password": "Imposta la tua password", + "Enable Keyboard/Mouse": "Abilita tastiera/mouse", + "Enable Clipboard": "Abilita appunti", + "Enable File Transfer": "Abilita trasferimento file", + "Enable TCP Tunneling": "Abilita tunnel TCP", + "IP Whitelisting": "IP autorizzati", + "ID/Relay Server": "Server ID/Relay", + "Stop service": "Arresta servizio", + "Change ID": "Cambia ID", + "Website": "Sito web", + "About": "Informazioni", + "Mute": "Silenzia", + "Audio Input": "Input audio", + "ID Server": "ID server", + "Relay Server": "Server relay", + "API Server": "Server API", + "invalid_http": "deve iniziare con http:// o https://", + "Invalid IP": "Indirizzo IP non valido", + "id_change_tip": "Puoi usare solo i caratteri a-z, A-Z, 0-9 e _ (underscore). Il primo carattere deve essere a-z o A-Z. La lunghezza deve essere fra 6 e 16 caratteri.", + "Invalid format": "Formato non valido", + "This function is turned off by the server": "Questa funzione è disabilitata sul server", + "Not available": "Non disponibile", + "Too frequent": "Troppo frequente", + "Cancel": "Annulla", + "Skip": "Ignora", + "Close": "Chiudi", + "Retry": "Riprova", + "OK": "OK", + "Password Required": "Password richiesta", + "Please enter your password": "Inserisci la tua password", + "Remember password": "Ricorda password", + "Wrong Password": "Password errata", + "Do you want to enter again?": "Vuoi riprovare?", + "Connection Error": "Errore di connessione", + "Error": "Errore", + "Reset by the peer": "Reimpostata dal peer", + "Connecting...": "Connessione...", + "Connection in progress. Please wait.": "Connessione in corso. Attendi.", + "Please try 1 minute later": "Per favore riprova fra 1 minuto", + "Login Error": "Errore di login", + "Successful": "Successo", + "Connected, waiting for image...": "Connesso, in attesa dell'immagine...", + "Name": "Nome", + "Modified": "Modificato", + "Size": "Dimensione", + "Show Hidden Files": "Mostra file nascosti", + "Receive": "Ricevi", + "Send": "Invia", + "Remote Computer": "Computer remoto", + "Local Computer": "Computer locale", + "Confirm Delete": "Conferma cancellazione", + "Are you sure you want to delete this file?": "Vuoi davvero eliminare questo file?", + "Do this for all conflicts": "Ricorca questa scelta per tutti i conflitti", + "Deleting": "Cancellazione di", + "files": "file", + "Waiting": "In attesa", + "Finished": "Terminato", + "Custom Image Quality": "Qualità immagine personalizzata", + "Privacy mode": "Modalità privacy", + "Block user input": "Blocca l'input dell'utente", + "Unblock user input": "Sbloccare l'input dell'utente", + "Adjust Window": "Adatta la finestra", + "Original": "Originale", + "Shrink": "Restringi", + "Stretch": "Allarga", + "Good image quality": "Buona qualità immagine", + "Balanced": "Bilanciato", + "Optimize reaction time": "Ottimizza il tempo di reazione", + "Custom": "Personalizzato", + "Show remote cursor": "Mostra il cursore remoto", + "Disable clipboard": "Disabilita appunti", + "Lock after session end": "Blocca al termine della sessione", + "Insert": "Inserisci", + "Insert Lock": "Blocco inserimento", + "Refresh": "Aggiorna", + "ID does not exist": "L'ID non esiste", + "Failed to connect to rendezvous server": "Errore di connessione al server rendezvous", + "Please try later": "Riprova più tardi", + "Remote desktop is offline": "Il desktop remoto è offline", + "Key mismatch": "La chiave non corrisponde", + "Timeout": "Timeout", + "Failed to connect to relay server": "Errore di connessione al server relay", + "Failed to connect via rendezvous server": "Errore di connessione tramite il server rendezvous", + "Failed to connect via relay server": "Errore di connessione tramite il server relay", + "Failed to make direct connection to remote desktop": "Impossibile connettersi direttamente al desktop remoto", + "Set Password": "Imposta password", + "OS Password": "Password del sistema operativo", + "install_tip": "A causa del Controllo Account Utente, RustDesk potrebbe non funzionare correttamente come desktop remoto. Per evitare questo problema, fai click sul tasto qui sotto per installare RustDesk a livello di sistema.", + "Click to upgrade": "Fai click per aggiornare", + "Click to download": "Cliquez per scaricare", + "Click to update": "Fare clic per aggiornare", + "Configuration Permissions": "Permessi di configurazione", + "Configure": "Configura", + "config_acc": "Per controllare il tuo desktop dall'esterno, devi fornire a RustDesk il permesso \"Accessibilità\".", + "config_screen": "Per controllare il tuo desktop dall'esterno, devi fornire a RustDesk il permesso \"Registrazione schermo\".", + "Installing ...": "Installazione ...", + "Install": "Installa", + "Installation": "Installazione", + "Installation Path": "Percorso di installazione", + "Create start menu shortcuts": "Crea i collegamenti nel menu di avvio", + "Create desktop icon": "Crea un'icona sul desktop", + "agreement_tip": "Avviando l'installazione, accetti i termini del contratto di licenza.", + "Accept and Install": "Accetta e installa", + "End-user license agreement": "Contratto di licenza con l'utente finale", + "Generating ...": "Generazione ...", + "Your installation is lower version.": "La tua installazione non è aggiornata.", + "not_close_tcp_tip": "Non chiudere questa finestra mentre stai usando il tunnel", + "Listening ...": "In ascolto ...", + "Remote Host": "Host remoto", + "Remote Port": "Porta remota", + "Action": "Azione", + "Add": "Aggiungi", + "Local Port": "Porta locale", + "setup_server_tip": "Per una connessione più veloce, configura un tuo server", + "Too short, at least 6 characters.": "Troppo breve, almeno 6 caratteri", + "The confirmation is not identical.": "La conferma non corrisponde", + "Permissions": "Permessi", + "Accept": "Accetta", + "Dismiss": "Rifiuta", + "Disconnect": "Disconnetti", + "Allow using keyboard and mouse": "Consenti l'uso di tastiera e mouse", + "Allow using clipboard": "Consenti l'uso degli appunti", + "Allow hearing sound": "Consenti la riproduzione dell'audio", + "Connected": "Connesso", + "Direct and encrypted connection": "Connessione diretta e cifrata", + "Relayed and encrypted connection": "Connessione tramite relay e cifrata", + "Direct and unencrypted connection": "Connessione diretta e non cifrata", + "Relayed and unencrypted connection": "Connessione tramite relay e non cifrata", + "Enter Remote ID": "Inserisci l'ID remoto", + "Enter your password": "Inserisci la tua password", + "Logging in...": "Autenticazione...", + "Enable RDP session sharing": "Abilita la condivisione della sessione RDP", + "Auto Login": "Login automatico", + "Enable Direct IP Access": "Abilita l'accesso diretto tramite IP", + "Rename": "Rinomina", + "Space": "Spazio", + "Create Desktop Shortcut": "Crea collegamento sul desktop", + "Change Path": "Cambia percorso", + "Create Folder": "Crea cartella", + "Please enter the folder name": "Inserisci il nome della cartella", + "Fix it": "Risolvi", + "Warning": "Avviso", + "Login screen using Wayland is not supported": "La schermata di login non è supportata utilizzando Wayland", + "Reboot required": "Riavvio necessario", + "Unsupported display server ": "Display server non supportato", + "x11 expected": "x11 necessario", + "Port": "Porta", + "Settings": "Impostazioni", + "Username": " Nome utente", + "Invalid port": "Porta non valida", + "Closed manually by the peer": "Chiuso manualmente dal peer", + "Enable remote configuration modification": "Abilita la modifica remota della configurazione", + "Run without install": "Avvia senza installare", + "Always connected via relay": "Connesso sempre tramite relay", + "Always connect via relay": "Connetti sempre tramite relay", + "whitelist_tip": "Solo gli indirizzi IP autorizzati possono connettersi a questo desktop", + "Login": "Accedi", + "Logout": "Esci", + "Tags": "Tag", + "Search ID": "Cerca ID", + "Current Wayland display server is not supported": "Questo display server Wayland non è supportato", + "whitelist_sep": "Separati da virgola, punto e virgola, spazio o a capo", + "Add ID": "Aggiungi ID", + "Add Tag": "Aggiungi tag", + "Unselect all tags": "Deseleziona tutti i tag", + "Network error": "Errore di rete", + "Username missed": "Nome utente dimenticato", + "Password missed": "Password dimenticata", + "Wrong credentials": "Credenziali errate", + "Edit Tag": "Modifica tag", + "Invalid folder name": "Nome della cartella non valido", + "Hostname": "Nome host", + "Discovered": "Scoperto", + }, + en: { + "desk_tip": "Your desktop can be accessed with this ID and password.", + "connecting_status": "Connecting to the RustDesk network...", + "not_ready_status": "Not ready. Please check your connection", + "id_change_tip": "Only a-z, A-Z, 0-9 and _ (underscore) characters allowed. The first letter must be a-z, A-Z. Length between 6 and 16.", + "install_tip": "Due to UAC, RustDesk can not work properly as the remote side in some cases. To avoid UAC, please click the button below to install RustDesk to the system.", + "config_acc": "In order to control your Desktop remotely, you need to grant RustDesk \"Accessibility\" permissions.", + "config_screen": "In order to access your Desktop remotely, you need to grant RustDesk \"Screen Recording\" permissions.", + "agreement_tip": "By starting the installation, you accept the license agreement.", + "not_close_tcp_tip": "Don't close this window while you are using the tunnel", + "setup_server_tip": "For faster connection, please set up your own server", + "Auto Login": "Auto Login (Only valid if you set \"Lock after session end\")", + "whitelist_tip": "Only whitelisted IP can access me", + "whitelist_sep": "Seperated by comma, semicolon, spaces or new line", + "Wrong credentials": "Wrong username or password", + "invalid_http": "must start with http:// or https://", + "install_daemon_tip": "For starting on boot, you need to install system service.", + }, + fr: { + "Status": "Statut", + "Your Desktop": "Votre bureau", + "desk_tip": "Votre bureau est accessible via l'identifiant et le mot de passe ci-dessous.", + "Password": "Mot de passe", + "Ready": "Prêt", + "connecting_status": "Connexion au réseau RustDesk...", + "Enable Service": "Autoriser le service", + "Start Service": "Démarrer le service", + "Service is not running": "Le service ne fonctionne pas", + "not_ready_status": "Pas prêt, veuillez vérifier la connexion réseau", + "Control Remote Desktop": "Contrôler le bureau à distance", + "Transfer File": "Transférer le fichier", + "Connect": "Connecter", + "Recent Sessions": "Sessions récentes", + "Address Book": "Carnet d'adresses", + "Confirmation": "Confirmation", + "TCP Tunneling": "Tunneling TCP", + "Remove": "Supprimer", + "Refresh random password": "Actualiser le mot de passe aléatoire", + "Set your own password": "Définir votre propre mot de passe", + "Enable Keyboard/Mouse": "Activer le contrôle clavier/souris", + "Enable Clipboard": "Activer la synchronisation du presse-papiers", + "Enable File Transfer": "Activer le transfert de fichiers", + "Enable TCP Tunneling": "Activer le tunneling TCP", + "IP Whitelisting": "Liste blanche IP", + "ID/Relay Server": "ID/Serveur Relais", + "Stop service": "Arrêter service", + "Change ID": "Changer d'ID", + "Website": "Site Web", + "About": "Sur", + "Mute": "Muet", + "Audio Input": "Entrée audio", + "ID Server": "Serveur ID", + "Relay Server": "Serveur Relais", + "API Server": "Serveur API", + "invalid_http": "Doit commencer par http:// ou https://", + "Invalid IP": "IP invalide", + "id_change_tip": "Seules les lettres a-z, A-Z, 0-9, _ (trait de soulignement) peuvent être utilisées. La première lettre doit être a-z, A-Z. La longueur est comprise entre 6 et 16.", + "Invalid format": "Format invalide", + "This function is turned off by the server": "Cette fonction est désactivée par le serveur", + "Not available": "Indisponible", + "Too frequent": "Modifier trop fréquemment, veuillez réessayer plus tard", + "Cancel": "Annuler", + "Skip": "Ignorer", + "Close": "Fermer", + "Retry": "Réessayer", + "OK": "Confirmer", + "Password Required": "Mot de passe requis", + "Please enter your password": "Veuillez saisir votre mot de passe", + "Remember password": "Mémoriser le mot de passe", + "Wrong Password": "Mauvais mot de passe", + "Do you want to enter again?": "Voulez-vous participer à nouveau?", + "Connection Error": "Erreur de connexion", + "Error": "Erreur", + "Reset by the peer": "La connexion a été fermée par le pair", + "Connecting...": "Connexion...", + "Connection in progress. Please wait.": "Connexion en cours. Veuillez patienter.", + "Please try 1 minute later": "Réessayez dans une minute", + "Login Error": "Erreur de connexion", + "Successful": "Succès", + "Connected, waiting for image...": "Connecté, en attente de transmission d'image...", + "Name": "Nom du fichier", + "Modified": "Modifié", + "Size": "Taille", + "Show Hidden Files": "Afficher les fichiers cachés", + "Receive": "Accepter", + "Send": "Envoyer", + "Remote Computer": "Ordinateur distant", + "Local Computer": "Ordinateur local", + "Confirm Delete": "Confirmer la suppression", + "Are you sure you want to delete this file?": "Voulez-vous vraiment supprimer ce fichier?", + "Do this for all conflicts": "Appliquer à d'autres conflits", + "Deleting": "Suppression", + "files": "fichier", + "Waiting": "En attente en attente...", + "Finished": "Terminé", + "Custom Image Quality": "Définir la qualité d'image", + "Privacy mode": "Mode privé", + "Block user input": "Bloquer la saisie de l'utilisateur", + "Unblock user input": "Débloquer l'entrée de l'utilisateur", + "Adjust Window": "Ajuster la fenêtre", + "Original": "Ratio d'origine", + "Shrink": "Rétréci", + "Stretch": "Étirer", + "Good image quality": "Bonne qualité d'image", + "Balanced": "Qualité d'image normale", + "Optimize reaction time": "Optimiser le temps de réaction", + "Custom": "Qualité d'image personnalisée", + "Show remote cursor": "Afficher le curseur distant", + "Disable clipboard": "Désactiver le presse-papiers", + "Lock after session end": "Verrouiller l'ordinateur distant après la déconnexion", + "Insert": "Insérer", + "Insert Lock": "Verrouiller l'ordinateur distant", + "Refresh": "Rafraîchir l'écran", + "ID does not exist": "L'ID n'existe pas", + "Failed to connect to rendezvous server": "Échec de la connexion au serveur de rendez-vous", + "Please try later": "Veuillez essayer plus tard", + "Remote desktop is offline": "Le bureau à distance est hors ligne", + "Key mismatch": "Discordance de clé", + "Timeout": "Connexion expirée", + "Failed to connect to relay server": "Échec de la connexion au serveur relais", + "Failed to connect via rendezvous server": "Échec de l'établissement d'une connexion via le serveur de rendez-vous", + "Failed to connect via relay server": "Impossible d'établir une connexion via le serveur relais", + "Failed to make direct connection to remote desktop": "Impossible d'établir une connexion directe", + "Set Password": "Définir le mot de passe", + "OS Password": "Mot de passe du système d'exploitation", + "install_tip": "Vous utilisez une version désinstallée. En raison des restrictions UAC, en tant que terminal contrôlé, dans certains cas, il ne sera pas en mesure de contrôler la souris et le clavier ou d'enregistrer l'écran. Veuillez cliquer sur le bouton ci-dessous pour installer RustDesk au système pour éviter la question ci-dessus.", + "Click to upgrade": "Cliquez pour mettre à niveau", + "Click to download": "Cliquez pour télécharger", + "Click to update": "Cliquez pour mettre à jour", + "Configuration Permissions": "Autorisations de configuration", + "Configure": "Configurer", + "config_acc": "Afin de pouvoir contrôler votre bureau à distance, veuillez donner l'autorisation\"accessibilité\" à RustDesk.", + "config_screen": "Afin de pouvoir accéder à votre bureau à distance, veuillez donner l'autorisation à RustDesk\"enregistrement d'écran\".", + "Installing ...": "Installation ...", + "Install": "Installer", + "Installation": "Installation", + "Installation Path": "Chemin d'installation", + "Create start menu shortcuts": "Créer des raccourcis dans le menu démarrer", + "Create desktop icon": "Créer une icône sur le bureau", + "agreement_tip": "Démarrer l'installation signifie accepter le contrat de licence.", + "Accept and Install": "Accepter et installer", + "End-user license agreement": "Contrat d'utilisateur", + "Generating ...": "Génération ...", + "Your installation is lower version.": "La version que vous avez installée est inférieure à la version en cours d'exécution.", + "not_close_tcp_tip": "Veuillez ne pas fermer cette fenêtre lors de l'utilisation du tunnel", + "Listening ...": "En attente de connexion tunnel...", + "Remote Host": "Hôte distant", + "Remote Port": "Port distant", + "Action": "Action", + "Add": "Ajouter", + "Local Port": "Port local", + "setup_server_tip": "Si vous avez besoin d'une vitesse de connexion plus rapide, vous pouvez choisir de créer votre propre serveur", + "Too short, at least 6 characters.": "Trop court, au moins 6 caractères.", + "The confirmation is not identical.": "Les deux entrées ne correspondent pas", + "Permissions": "Autorisations", + "Accept": "Accepter", + "Dismiss": "Rejeter", + "Disconnect": "Déconnecter", + "Allow using keyboard and mouse": "Autoriser l'utilisation du clavier et de la souris", + "Allow using clipboard": "Autoriser l'utilisation du presse-papiers", + "Allow hearing sound": "Autoriser l'audition du son", + "Connected": "Connecté", + "Direct and encrypted connection": "Connexion directe cryptée", + "Relayed and encrypted connection": "Connexion relais cryptée", + "Direct and unencrypted connection": "Connexion directe non cryptée", + "Relayed and unencrypted connection": "Connexion relais non cryptée", + "Enter Remote ID": "Entrez l'ID à distance", + "Enter your password": "Entrez votre mot de passe", + "Logging in...": "Se connecter...", + "Enable RDP session sharing": "Activer le partage de session RDP", + "Auto Login": "Connexion automatique (le verrouillage ne sera effectif qu'après la déconnexion du paramètre)", + "Enable Direct IP Access": "Autoriser l'accès direct IP", + "Rename": "Renommer", + "Space": "Espace", + "Create Desktop Shortcut": "Créer un raccourci sur le bureau", + "Change Path": "Changer de chemin", + "Create Folder": "Créer un dossier", + "Please enter the folder name": "Veuillez saisir le nom du dossier", + "Fix it": "Réparez-le", + "Warning": "Avertissement", + "Login screen using Wayland is not supported": "L'écran de connexion utilisant Wayland n'est pas pris en charge", + "Reboot required": "Redémarrage pour prendre effet", + "Unsupported display server ": "Le serveur d'affichage actuel n'est pas pris en charge", + "x11 expected": "Veuillez passer à x11", + "Port": "Port", + "Settings": "Paramètres", + "Username": " Nom d'utilisateur", + "Invalid port": "Port invalide", + "Closed manually by the peer": "Fermé manuellement par le pair", + "Enable remote configuration modification": "Autoriser la modification de la configuration à distance", + "Run without install": "Exécuter sans installer", + "Always connected via relay": "Forcer la connexion relais", + "Always connect via relay": "Forcer la connexion relais", + "whitelist_tip": "Seul l'ip dans la liste blanche peut m'accéder", + "Login": "Connexion", + "Logout": "Déconnexion", + "Tags": "Étiqueter", + "Search ID": "Identifiant de recherche", + "Current Wayland display server is not supported": "Le serveur d'affichage Wayland n'est pas pris en charge", + "whitelist_sep": "Vous pouvez utiliser une virgule, un point-virgule, un espace ou une nouvelle ligne comme séparateur", + "Add ID": "Ajouter ID", + "Add Tag": "Ajouter une balise", + "Unselect all tags": "Désélectionner toutes les balises", + "Network error": "Erreur réseau", + "Username missed": "Nom d'utilisateur manqué", + "Password missed": "Mot de passe manqué", + "Wrong credentials": "Identifiant ou mot de passe erroné", + "Edit Tag": "Modifier la balise", + "Invalid folder name": "Nom de dossier invalide", + "Hostname": "nom d'hôte", + "Discovered": "Découvert", + }, +} + +export function checkIfRetry(msgtype: string, title: string, text: string) { + return msgtype == "error" +&& title == "Connection Error" +&& text.toLowerCase().indexOf("offline") < 0 +&& text.toLowerCase().indexOf("exist") < 0 +&& text.toLowerCase().indexOf("handshake") < 0 +&& text.toLowerCase().indexOf("failed") < 0 +&& text.toLowerCase().indexOf("resolve") < 0 +&& text.toLowerCase().indexOf("mismatch") < 0 +&& text.toLowerCase().indexOf("manually") < 0 + +;} + +export const KEY_MAP: any = { + "VK_A": "a", + "VK_B": "b", + "VK_C": "c", + "VK_D": "d", + "VK_E": "e", + "VK_F": "f", + "VK_G": "g", + "VK_H": "h", + "VK_I": "i", + "VK_J": "j", + "VK_K": "k", + "VK_L": "l", + "VK_M": "m", + "VK_N": "n", + "VK_O": "o", + "VK_P": "p", + "VK_Q": "q", + "VK_R": "r", + "VK_S": "s", + "VK_T": "t", + "VK_U": "u", + "VK_V": "v", + "VK_W": "w", + "VK_X": "x", + "VK_Y": "y", + "VK_Z": "z", + "VK_0": "0", + "VK_1": "1", + "VK_2": "2", + "VK_3": "3", + "VK_4": "4", + "VK_5": "5", + "VK_6": "6", + "VK_7": "7", + "VK_8": "8", + "VK_9": "9", + "VK_COMMA": ",", + "VK_SLASH": "/", + "VK_SEMICOLON": ";", + "VK_QUOTE": "\'", + "VK_LBRACKET": "[", + "VK_RBRACKET": "]", + "VK_BACKSLASH": "\\", + "VK_MINUS": "-", + "VK_PLUS": "= // it is =, but sciter return VK_PLUS", + "VK_DIVIDE": "Divide // numpad", + "VK_MULTIPLY": "Multiply // numpad", + "VK_SUBTRACT": "Subtract // numpad", + "VK_ADD": "Add // numpad", + "VK_DECIMAL": "Decimal // numpad", + "VK_F1": "F1", + "VK_F2": "F2", + "VK_F3": "F3", + "VK_F4": "F4", + "VK_F5": "F5", + "VK_F6": "F6", + "VK_F7": "F7", + "VK_F8": "F8", + "VK_F9": "F9", + "VK_F10": "F10", + "VK_F11": "F11", + "VK_F12": "F12", + "VK_ENTER": "Return", + "VK_CANCEL": "Cancel", + "VK_BACK": "Backspace", + "VK_TAB": "Tab", + "VK_CLEAR": "Clear", + "VK_RETURN": "Return", + "VK_SHIFT": "Shift", + "VK_CONTROL": "Control", + "VK_MENU": "Alt", + "VK_PAUSE": "Pause", + "VK_CAPITAL": "CapsLock", + "VK_KANA": "Kana", + "VK_HANGUL": "Hangul", + "VK_JUNJA": "Junja", + "VK_FINAL": "Final", + "VK_HANJA": "Hanja", + "VK_KANJI": "Kanji", + "VK_ESCAPE": "Escape", + "VK_CONVERT": "Convert", + "VK_SPACE": "Space", + "VK_PRIOR": "PageUp", + "VK_NEXT": "PageDown", + "VK_END": "End", + "VK_HOME": "Home", + "VK_LEFT": "LeftArrow", + "VK_UP": "UpArrow", + "VK_RIGHT": "RightArrow", + "VK_DOWN": "DownArrow", + "VK_SELECT": "Select", + "VK_PRINT": "Print", + "VK_EXECUTE": "Execute", + "VK_SNAPSHOT": "Snapshot", + "VK_INSERT": "Insert", + "VK_DELETE": "Delete", + "VK_HELP": "Help", + "VK_SLEEP": "Sleep", + "VK_SEPARATOR": "Separator", + "VK_NUMPAD0": "Numpad0", + "VK_NUMPAD1": "Numpad1", + "VK_NUMPAD2": "Numpad2", + "VK_NUMPAD3": "Numpad3", + "VK_NUMPAD4": "Numpad4", + "VK_NUMPAD5": "Numpad5", + "VK_NUMPAD6": "Numpad6", + "VK_NUMPAD7": "Numpad7", + "VK_NUMPAD8": "Numpad8", + "VK_NUMPAD9": "Numpad9", + "Apps": "Apps", + "Meta": "Meta", + "RAlt": "RAlt", + "RWin": "RWin", + "RControl": "RControl", + "RShift": "RShift", + "CTRL_ALT_DEL": "CtrlAltDel", + "LOCK_SCREEN": "LockScreen", + +} diff --git a/src/globals.js b/src/globals.js index 6d199dfd8..3e30d9d5b 100644 --- a/src/globals.js +++ b/src/globals.js @@ -1,10 +1,9 @@ import Connection from "./connection"; import _sodium from "libsodium-wrappers"; -import * as zstd from 'zstddec'; import { CursorData } from "./message"; import { loadOpus, loadVp9 } from "./codec"; - -var decompressor; +import { checkIfRetry } from "./gen_js_from_hbb"; +import { initZstd, translate } from "./common"; var currentFrame = undefined; var events = []; @@ -21,15 +20,7 @@ export function msgbox(type, title, text) { if (!events) return; if (!type || (type == 'error' && !text)) return; const text2 = text.toLowerCase(); - var hasRetry = type == "error" - && title == "Connection Error" - && text2.indexOf("offline") < 0 - && text2.indexOf("exist") < 0 - && text2.indexOf("handshake") < 0 - && text2.indexOf("failed") < 0 - && text2.indexOf("resolve") < 0 - && text2.indexOf("mismatch") < 0 - && text2.indexOf("manually") < 0; + var hasRetry = checkIfRetry(type, title, text); events.push({ name: 'msgbox', type, title, text, hasRetry }); } @@ -37,16 +28,7 @@ function jsonfyForDart(payload) { var tmp = {}; for (const [key, value] of Object.entries(payload)) { if (!key) continue; - var newName = ''; - for (var i = 0; i < key.length; ++i) { - var ch = key[i]; - if (ch.toUpperCase() == ch) { - newName += '_' + ch.toLowerCase(); - } else { - newName += ch; - } - } - tmp[newName] = value instanceof Uint8Array ? '[' + value.toString() + ']' : JSON.stringify(value); + tmp[key] = value instanceof Uint8Array ? '[' + value.toString() + ']' : JSON.stringify(value); } return tmp; } @@ -153,26 +135,6 @@ export function decrypt(signed, nonce, key) { return sodium.crypto_secretbox_open_easy(signed, makeOnce(nonce), key); } -export async function decompress(compressedArray) { - const MAX = 1024 * 1024 * 64; - const MIN = 1024 * 1024; - let n = 30 * compressedArray.length; - if (n > MAX) { - n = MAX; - } - if (n < MIN) { - n = MIN; - } - try { - if (!decompressor) { - await initZstd(); - } - return decompressor.decode(compressedArray, n); - } catch (e) { - console.error('decompress failed: ' + e); - } -} - window.setByName = (name, value) => { try { value = JSON.parse(value); @@ -204,7 +166,7 @@ window.setByName = (name, value) => { curConn.lockScreen(); break; case 'ctrl_alt_del': - curConn.ctrlAltDe(); + curConn.ctrlAltDel(); break; case 'switch_display': curConn.switchDisplay(value); @@ -252,7 +214,7 @@ window.setByName = (name, value) => { curConn.setOption(value.name, value.value); break; case 'input_os_password': - curConn.inputOsPassword(value, true); + curConn.inputOsPassword(value); break; default: break; @@ -266,13 +228,10 @@ window.getByName = (name, arg) => { switch (name) { case 'peers': return localStorage.getItem('peers') || '[]'; - break; case 'remote_id': return localStorage.getItem('remote-id') || ''; - break; case 'remember': return curConn.getRemember(); - break; case 'event': if (events && events.length) { const e = events[0]; @@ -282,19 +241,14 @@ window.getByName = (name, arg) => { break; case 'toggle_option': return curConn.getOption(arg); - break; case 'option': return localStorage.getItem(arg); - break; case 'image_quality': return curConn.getImageQuality(); - break; case 'translate': - return arg.text; - break; + return translate(arg.locale, arg.text); case 'peer_option': return curConn.getOption(arg); - break; case 'test_if_valid_server': break; } @@ -302,14 +256,7 @@ window.getByName = (name, arg) => { } window.init = async () => { - await initZstd(); -} - -async function initZstd() { loadOpus(() => { }); loadVp9(() => { }); - const tmp = new zstd.ZSTDDecoder(); - await tmp.init(); - console.log('zstd ready'); - decompressor = tmp; -} + await initZstd(); +} \ No newline at end of file diff --git a/src/message.ts b/src/message.ts index 44405e14b..6f338f12e 100644 --- a/src/message.ts +++ b/src/message.ts @@ -631,17 +631,17 @@ export interface PortForward { export interface FileTransfer { dir: string; - showHidden: boolean; + show_hidden: boolean; } export interface LoginRequest { username: string; password: Uint8Array; - myId: string; - myName: string; + my_id: string; + my_name: string; option: OptionMessage | undefined; - fileTransfer: FileTransfer | undefined; - portForward: PortForward | undefined; + file_transfer: FileTransfer | undefined; + port_forward: PortForward | undefined; } export interface ChatMessage { @@ -653,14 +653,14 @@ export interface PeerInfo { hostname: string; platform: string; displays: DisplayInfo[]; - currentDisplay: number; - sasEnabled: boolean; + current_display: number; + sas_enabled: boolean; version: string; } export interface LoginResponse { error: string | undefined; - peerInfo: PeerInfo | undefined; + peer_info: PeerInfo | undefined; } export interface MouseEvent { @@ -673,7 +673,7 @@ export interface MouseEvent { export interface KeyEvent { down: boolean; press: boolean; - controlKey: ControlKey | undefined; + control_key: ControlKey | undefined; chr: number | undefined; unicode: number | undefined; seq: string | undefined; @@ -705,11 +705,11 @@ export interface Clipboard { } export interface FileEntry { - entryType: FileType; + entry_type: FileType; name: string; - isHidden: boolean; + is_hidden: boolean; size: number; - modifiedTime: number; + modified_time: number; } export interface FileDirectory { @@ -720,23 +720,23 @@ export interface FileDirectory { export interface ReadDir { path: string; - includeHidden: boolean; + include_hidden: boolean; } export interface ReadAllFiles { id: number; path: string; - includeHidden: boolean; + include_hidden: boolean; } export interface FileAction { - readDir: ReadDir | undefined; + read_dir: ReadDir | undefined; send: FileTransferSendRequest | undefined; receive: FileTransferReceiveRequest | undefined; create: FileDirCreate | undefined; - removeDir: FileRemoveDir | undefined; - removeFile: FileRemoveFile | undefined; - allFiles: ReadAllFiles | undefined; + remove_dir: FileRemoveDir | undefined; + remove_file: FileRemoveFile | undefined; + all_files: ReadAllFiles | undefined; cancel: FileTransferCancel | undefined; } @@ -753,7 +753,7 @@ export interface FileResponse { export interface FileTransferBlock { id: number; - fileNum: number; + file_num: number; data: Uint8Array; compressed: boolean; } @@ -761,18 +761,18 @@ export interface FileTransferBlock { export interface FileTransferError { id: number; error: string; - fileNum: number; + file_num: number; } export interface FileTransferSendRequest { id: number; path: string; - includeHidden: boolean; + include_hidden: boolean; } export interface FileTransferDone { id: number; - fileNum: number; + file_num: number; } export interface FileTransferReceiveRequest { @@ -791,7 +791,7 @@ export interface FileRemoveDir { export interface FileRemoveFile { id: number; path: string; - fileNum: number; + file_num: number; } export interface FileDirCreate { @@ -855,14 +855,14 @@ export function permissionInfo_PermissionToJSON( } export interface OptionMessage { - imageQuality: ImageQuality; - lockAfterSessionEnd: OptionMessage_BoolOption; - showRemoteCursor: OptionMessage_BoolOption; - privacyMode: OptionMessage_BoolOption; - blockInput: OptionMessage_BoolOption; - customImageQuality: number; - disableAudio: OptionMessage_BoolOption; - disableClipboard: OptionMessage_BoolOption; + image_quality: ImageQuality; + lock_after_session_end: OptionMessage_BoolOption; + show_remote_cursor: OptionMessage_BoolOption; + privacy_mode: OptionMessage_BoolOption; + block_input: OptionMessage_BoolOption; + custom_image_quality: number; + disable_audio: OptionMessage_BoolOption; + disable_clipboard: OptionMessage_BoolOption; } export enum OptionMessage_BoolOption { @@ -914,12 +914,12 @@ export interface OptionResponse { export interface TestDelay { time: number; - fromClient: boolean; + from_client: boolean; } export interface PublicKey { - asymmetricValue: Uint8Array; - symmetricValue: Uint8Array; + asymmetric_value: Uint8Array; + symmetric_value: Uint8Array; } export interface SignedId { @@ -927,7 +927,7 @@ export interface SignedId { } export interface AudioFormat { - sampleRate: number; + sample_rate: number; channels: number; } @@ -936,33 +936,33 @@ export interface AudioFrame { } export interface Misc { - chatMessage: ChatMessage | undefined; - switchDisplay: SwitchDisplay | undefined; - permissionInfo: PermissionInfo | undefined; + chat_message: ChatMessage | undefined; + switch_display: SwitchDisplay | undefined; + permission_info: PermissionInfo | undefined; option: OptionMessage | undefined; - audioFormat: AudioFormat | undefined; - closeReason: string | undefined; - refreshVideo: boolean | undefined; - optionResponse: OptionResponse | undefined; + audio_format: AudioFormat | undefined; + close_reason: string | undefined; + refresh_video: boolean | undefined; + option_response: OptionResponse | undefined; } export interface Message { - signedId: SignedId | undefined; - publicKey: PublicKey | undefined; - testDelay: TestDelay | undefined; - videoFrame: VideoFrame | undefined; - loginRequest: LoginRequest | undefined; - loginResponse: LoginResponse | undefined; + signed_id: SignedId | undefined; + public_key: PublicKey | undefined; + test_delay: TestDelay | undefined; + video_frame: VideoFrame | undefined; + login_request: LoginRequest | undefined; + login_response: LoginResponse | undefined; hash: Hash | undefined; - mouseEvent: MouseEvent | undefined; - audioFrame: AudioFrame | undefined; - cursorData: CursorData | undefined; - cursorPosition: CursorPosition | undefined; - cursorId: number | undefined; - keyEvent: KeyEvent | undefined; + mouse_event: MouseEvent | undefined; + audio_frame: AudioFrame | undefined; + cursor_data: CursorData | undefined; + cursor_position: CursorPosition | undefined; + cursor_id: number | undefined; + key_event: KeyEvent | undefined; clipboard: Clipboard | undefined; - fileAction: FileAction | undefined; - fileResponse: FileResponse | undefined; + file_action: FileAction | undefined; + file_response: FileResponse | undefined; misc: Misc | undefined; } @@ -1447,7 +1447,7 @@ export const PortForward = { }; function createBaseFileTransfer(): FileTransfer { - return { dir: "", showHidden: false }; + return { dir: "", show_hidden: false }; } export const FileTransfer = { @@ -1458,8 +1458,8 @@ export const FileTransfer = { if (message.dir !== "") { writer.uint32(10).string(message.dir); } - if (message.showHidden === true) { - writer.uint32(16).bool(message.showHidden); + if (message.show_hidden === true) { + writer.uint32(16).bool(message.show_hidden); } return writer; }, @@ -1475,7 +1475,7 @@ export const FileTransfer = { message.dir = reader.string(); break; case 2: - message.showHidden = reader.bool(); + message.show_hidden = reader.bool(); break; default: reader.skipType(tag & 7); @@ -1488,14 +1488,17 @@ export const FileTransfer = { fromJSON(object: any): FileTransfer { return { dir: isSet(object.dir) ? String(object.dir) : "", - showHidden: isSet(object.showHidden) ? Boolean(object.showHidden) : false, + show_hidden: isSet(object.show_hidden) + ? Boolean(object.show_hidden) + : false, }; }, toJSON(message: FileTransfer): unknown { const obj: any = {}; message.dir !== undefined && (obj.dir = message.dir); - message.showHidden !== undefined && (obj.showHidden = message.showHidden); + message.show_hidden !== undefined && + (obj.show_hidden = message.show_hidden); return obj; }, @@ -1504,7 +1507,7 @@ export const FileTransfer = { ): FileTransfer { const message = createBaseFileTransfer(); message.dir = object.dir ?? ""; - message.showHidden = object.showHidden ?? false; + message.show_hidden = object.show_hidden ?? false; return message; }, }; @@ -1513,11 +1516,11 @@ function createBaseLoginRequest(): LoginRequest { return { username: "", password: new Uint8Array(), - myId: "", - myName: "", + my_id: "", + my_name: "", option: undefined, - fileTransfer: undefined, - portForward: undefined, + file_transfer: undefined, + port_forward: undefined, }; } @@ -1532,24 +1535,24 @@ export const LoginRequest = { if (message.password.length !== 0) { writer.uint32(18).bytes(message.password); } - if (message.myId !== "") { - writer.uint32(34).string(message.myId); + if (message.my_id !== "") { + writer.uint32(34).string(message.my_id); } - if (message.myName !== "") { - writer.uint32(42).string(message.myName); + if (message.my_name !== "") { + writer.uint32(42).string(message.my_name); } if (message.option !== undefined) { OptionMessage.encode(message.option, writer.uint32(50).fork()).ldelim(); } - if (message.fileTransfer !== undefined) { + if (message.file_transfer !== undefined) { FileTransfer.encode( - message.fileTransfer, + message.file_transfer, writer.uint32(58).fork() ).ldelim(); } - if (message.portForward !== undefined) { + if (message.port_forward !== undefined) { PortForward.encode( - message.portForward, + message.port_forward, writer.uint32(66).fork() ).ldelim(); } @@ -1570,19 +1573,19 @@ export const LoginRequest = { message.password = reader.bytes(); break; case 4: - message.myId = reader.string(); + message.my_id = reader.string(); break; case 5: - message.myName = reader.string(); + message.my_name = reader.string(); break; case 6: message.option = OptionMessage.decode(reader, reader.uint32()); break; case 7: - message.fileTransfer = FileTransfer.decode(reader, reader.uint32()); + message.file_transfer = FileTransfer.decode(reader, reader.uint32()); break; case 8: - message.portForward = PortForward.decode(reader, reader.uint32()); + message.port_forward = PortForward.decode(reader, reader.uint32()); break; default: reader.skipType(tag & 7); @@ -1598,16 +1601,16 @@ export const LoginRequest = { password: isSet(object.password) ? bytesFromBase64(object.password) : new Uint8Array(), - myId: isSet(object.myId) ? String(object.myId) : "", - myName: isSet(object.myName) ? String(object.myName) : "", + my_id: isSet(object.my_id) ? String(object.my_id) : "", + my_name: isSet(object.my_name) ? String(object.my_name) : "", option: isSet(object.option) ? OptionMessage.fromJSON(object.option) : undefined, - fileTransfer: isSet(object.fileTransfer) - ? FileTransfer.fromJSON(object.fileTransfer) + file_transfer: isSet(object.file_transfer) + ? FileTransfer.fromJSON(object.file_transfer) : undefined, - portForward: isSet(object.portForward) - ? PortForward.fromJSON(object.portForward) + port_forward: isSet(object.port_forward) + ? PortForward.fromJSON(object.port_forward) : undefined, }; }, @@ -1619,19 +1622,19 @@ export const LoginRequest = { (obj.password = base64FromBytes( message.password !== undefined ? message.password : new Uint8Array() )); - message.myId !== undefined && (obj.myId = message.myId); - message.myName !== undefined && (obj.myName = message.myName); + message.my_id !== undefined && (obj.my_id = message.my_id); + message.my_name !== undefined && (obj.my_name = message.my_name); message.option !== undefined && (obj.option = message.option ? OptionMessage.toJSON(message.option) : undefined); - message.fileTransfer !== undefined && - (obj.fileTransfer = message.fileTransfer - ? FileTransfer.toJSON(message.fileTransfer) + message.file_transfer !== undefined && + (obj.file_transfer = message.file_transfer + ? FileTransfer.toJSON(message.file_transfer) : undefined); - message.portForward !== undefined && - (obj.portForward = message.portForward - ? PortForward.toJSON(message.portForward) + message.port_forward !== undefined && + (obj.port_forward = message.port_forward + ? PortForward.toJSON(message.port_forward) : undefined); return obj; }, @@ -1642,19 +1645,19 @@ export const LoginRequest = { const message = createBaseLoginRequest(); message.username = object.username ?? ""; message.password = object.password ?? new Uint8Array(); - message.myId = object.myId ?? ""; - message.myName = object.myName ?? ""; + message.my_id = object.my_id ?? ""; + message.my_name = object.my_name ?? ""; message.option = object.option !== undefined && object.option !== null ? OptionMessage.fromPartial(object.option) : undefined; - message.fileTransfer = - object.fileTransfer !== undefined && object.fileTransfer !== null - ? FileTransfer.fromPartial(object.fileTransfer) + message.file_transfer = + object.file_transfer !== undefined && object.file_transfer !== null + ? FileTransfer.fromPartial(object.file_transfer) : undefined; - message.portForward = - object.portForward !== undefined && object.portForward !== null - ? PortForward.fromPartial(object.portForward) + message.port_forward = + object.port_forward !== undefined && object.port_forward !== null + ? PortForward.fromPartial(object.port_forward) : undefined; return message; }, @@ -1720,8 +1723,8 @@ function createBasePeerInfo(): PeerInfo { hostname: "", platform: "", displays: [], - currentDisplay: 0, - sasEnabled: false, + current_display: 0, + sas_enabled: false, version: "", }; } @@ -1743,11 +1746,11 @@ export const PeerInfo = { for (const v of message.displays) { DisplayInfo.encode(v!, writer.uint32(34).fork()).ldelim(); } - if (message.currentDisplay !== 0) { - writer.uint32(40).int32(message.currentDisplay); + if (message.current_display !== 0) { + writer.uint32(40).int32(message.current_display); } - if (message.sasEnabled === true) { - writer.uint32(48).bool(message.sasEnabled); + if (message.sas_enabled === true) { + writer.uint32(48).bool(message.sas_enabled); } if (message.version !== "") { writer.uint32(58).string(message.version); @@ -1775,10 +1778,10 @@ export const PeerInfo = { message.displays.push(DisplayInfo.decode(reader, reader.uint32())); break; case 5: - message.currentDisplay = reader.int32(); + message.current_display = reader.int32(); break; case 6: - message.sasEnabled = reader.bool(); + message.sas_enabled = reader.bool(); break; case 7: message.version = reader.string(); @@ -1799,10 +1802,12 @@ export const PeerInfo = { displays: Array.isArray(object?.displays) ? object.displays.map((e: any) => DisplayInfo.fromJSON(e)) : [], - currentDisplay: isSet(object.currentDisplay) - ? Number(object.currentDisplay) + current_display: isSet(object.current_display) + ? Number(object.current_display) : 0, - sasEnabled: isSet(object.sasEnabled) ? Boolean(object.sasEnabled) : false, + sas_enabled: isSet(object.sas_enabled) + ? Boolean(object.sas_enabled) + : false, version: isSet(object.version) ? String(object.version) : "", }; }, @@ -1819,9 +1824,10 @@ export const PeerInfo = { } else { obj.displays = []; } - message.currentDisplay !== undefined && - (obj.currentDisplay = Math.round(message.currentDisplay)); - message.sasEnabled !== undefined && (obj.sasEnabled = message.sasEnabled); + message.current_display !== undefined && + (obj.current_display = Math.round(message.current_display)); + message.sas_enabled !== undefined && + (obj.sas_enabled = message.sas_enabled); message.version !== undefined && (obj.version = message.version); return obj; }, @@ -1833,15 +1839,15 @@ export const PeerInfo = { message.platform = object.platform ?? ""; message.displays = object.displays?.map((e) => DisplayInfo.fromPartial(e)) || []; - message.currentDisplay = object.currentDisplay ?? 0; - message.sasEnabled = object.sasEnabled ?? false; + message.current_display = object.current_display ?? 0; + message.sas_enabled = object.sas_enabled ?? false; message.version = object.version ?? ""; return message; }, }; function createBaseLoginResponse(): LoginResponse { - return { error: undefined, peerInfo: undefined }; + return { error: undefined, peer_info: undefined }; } export const LoginResponse = { @@ -1852,8 +1858,8 @@ export const LoginResponse = { if (message.error !== undefined) { writer.uint32(10).string(message.error); } - if (message.peerInfo !== undefined) { - PeerInfo.encode(message.peerInfo, writer.uint32(18).fork()).ldelim(); + if (message.peer_info !== undefined) { + PeerInfo.encode(message.peer_info, writer.uint32(18).fork()).ldelim(); } return writer; }, @@ -1869,7 +1875,7 @@ export const LoginResponse = { message.error = reader.string(); break; case 2: - message.peerInfo = PeerInfo.decode(reader, reader.uint32()); + message.peer_info = PeerInfo.decode(reader, reader.uint32()); break; default: reader.skipType(tag & 7); @@ -1882,8 +1888,8 @@ export const LoginResponse = { fromJSON(object: any): LoginResponse { return { error: isSet(object.error) ? String(object.error) : undefined, - peerInfo: isSet(object.peerInfo) - ? PeerInfo.fromJSON(object.peerInfo) + peer_info: isSet(object.peer_info) + ? PeerInfo.fromJSON(object.peer_info) : undefined, }; }, @@ -1891,9 +1897,9 @@ export const LoginResponse = { toJSON(message: LoginResponse): unknown { const obj: any = {}; message.error !== undefined && (obj.error = message.error); - message.peerInfo !== undefined && - (obj.peerInfo = message.peerInfo - ? PeerInfo.toJSON(message.peerInfo) + message.peer_info !== undefined && + (obj.peer_info = message.peer_info + ? PeerInfo.toJSON(message.peer_info) : undefined); return obj; }, @@ -1903,9 +1909,9 @@ export const LoginResponse = { ): LoginResponse { const message = createBaseLoginResponse(); message.error = object.error ?? undefined; - message.peerInfo = - object.peerInfo !== undefined && object.peerInfo !== null - ? PeerInfo.fromPartial(object.peerInfo) + message.peer_info = + object.peer_info !== undefined && object.peer_info !== null + ? PeerInfo.fromPartial(object.peer_info) : undefined; return message; }, @@ -2011,7 +2017,7 @@ function createBaseKeyEvent(): KeyEvent { return { down: false, press: false, - controlKey: undefined, + control_key: undefined, chr: undefined, unicode: undefined, seq: undefined, @@ -2030,8 +2036,8 @@ export const KeyEvent = { if (message.press === true) { writer.uint32(16).bool(message.press); } - if (message.controlKey !== undefined) { - writer.uint32(24).int32(message.controlKey); + if (message.control_key !== undefined) { + writer.uint32(24).int32(message.control_key); } if (message.chr !== undefined) { writer.uint32(32).uint32(message.chr); @@ -2064,7 +2070,7 @@ export const KeyEvent = { message.press = reader.bool(); break; case 3: - message.controlKey = reader.int32() as any; + message.control_key = reader.int32() as any; break; case 4: message.chr = reader.uint32(); @@ -2097,8 +2103,8 @@ export const KeyEvent = { return { down: isSet(object.down) ? Boolean(object.down) : false, press: isSet(object.press) ? Boolean(object.press) : false, - controlKey: isSet(object.controlKey) - ? controlKeyFromJSON(object.controlKey) + control_key: isSet(object.control_key) + ? controlKeyFromJSON(object.control_key) : undefined, chr: isSet(object.chr) ? Number(object.chr) : undefined, unicode: isSet(object.unicode) ? Number(object.unicode) : undefined, @@ -2113,10 +2119,10 @@ export const KeyEvent = { const obj: any = {}; message.down !== undefined && (obj.down = message.down); message.press !== undefined && (obj.press = message.press); - message.controlKey !== undefined && - (obj.controlKey = - message.controlKey !== undefined - ? controlKeyToJSON(message.controlKey) + message.control_key !== undefined && + (obj.control_key = + message.control_key !== undefined + ? controlKeyToJSON(message.control_key) : undefined); message.chr !== undefined && (obj.chr = Math.round(message.chr)); message.unicode !== undefined && @@ -2134,7 +2140,7 @@ export const KeyEvent = { const message = createBaseKeyEvent(); message.down = object.down ?? false; message.press = object.press ?? false; - message.controlKey = object.controlKey ?? undefined; + message.control_key = object.control_key ?? undefined; message.chr = object.chr ?? undefined; message.unicode = object.unicode ?? undefined; message.seq = object.seq ?? undefined; @@ -2444,7 +2450,13 @@ export const Clipboard = { }; function createBaseFileEntry(): FileEntry { - return { entryType: 0, name: "", isHidden: false, size: 0, modifiedTime: 0 }; + return { + entry_type: 0, + name: "", + is_hidden: false, + size: 0, + modified_time: 0, + }; } export const FileEntry = { @@ -2452,20 +2464,20 @@ export const FileEntry = { message: FileEntry, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.entryType !== 0) { - writer.uint32(8).int32(message.entryType); + if (message.entry_type !== 0) { + writer.uint32(8).int32(message.entry_type); } if (message.name !== "") { writer.uint32(18).string(message.name); } - if (message.isHidden === true) { - writer.uint32(24).bool(message.isHidden); + if (message.is_hidden === true) { + writer.uint32(24).bool(message.is_hidden); } if (message.size !== 0) { writer.uint32(32).uint64(message.size); } - if (message.modifiedTime !== 0) { - writer.uint32(40).uint64(message.modifiedTime); + if (message.modified_time !== 0) { + writer.uint32(40).uint64(message.modified_time); } return writer; }, @@ -2478,19 +2490,19 @@ export const FileEntry = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.entryType = reader.int32() as any; + message.entry_type = reader.int32() as any; break; case 2: message.name = reader.string(); break; case 3: - message.isHidden = reader.bool(); + message.is_hidden = reader.bool(); break; case 4: message.size = longToNumber(reader.uint64() as Long); break; case 5: - message.modifiedTime = longToNumber(reader.uint64() as Long); + message.modified_time = longToNumber(reader.uint64() as Long); break; default: reader.skipType(tag & 7); @@ -2502,27 +2514,27 @@ export const FileEntry = { fromJSON(object: any): FileEntry { return { - entryType: isSet(object.entryType) - ? fileTypeFromJSON(object.entryType) + entry_type: isSet(object.entry_type) + ? fileTypeFromJSON(object.entry_type) : 0, name: isSet(object.name) ? String(object.name) : "", - isHidden: isSet(object.isHidden) ? Boolean(object.isHidden) : false, + is_hidden: isSet(object.is_hidden) ? Boolean(object.is_hidden) : false, size: isSet(object.size) ? Number(object.size) : 0, - modifiedTime: isSet(object.modifiedTime) - ? Number(object.modifiedTime) + modified_time: isSet(object.modified_time) + ? Number(object.modified_time) : 0, }; }, toJSON(message: FileEntry): unknown { const obj: any = {}; - message.entryType !== undefined && - (obj.entryType = fileTypeToJSON(message.entryType)); + message.entry_type !== undefined && + (obj.entry_type = fileTypeToJSON(message.entry_type)); message.name !== undefined && (obj.name = message.name); - message.isHidden !== undefined && (obj.isHidden = message.isHidden); + message.is_hidden !== undefined && (obj.is_hidden = message.is_hidden); message.size !== undefined && (obj.size = Math.round(message.size)); - message.modifiedTime !== undefined && - (obj.modifiedTime = Math.round(message.modifiedTime)); + message.modified_time !== undefined && + (obj.modified_time = Math.round(message.modified_time)); return obj; }, @@ -2530,11 +2542,11 @@ export const FileEntry = { object: I ): FileEntry { const message = createBaseFileEntry(); - message.entryType = object.entryType ?? 0; + message.entry_type = object.entry_type ?? 0; message.name = object.name ?? ""; - message.isHidden = object.isHidden ?? false; + message.is_hidden = object.is_hidden ?? false; message.size = object.size ?? 0; - message.modifiedTime = object.modifiedTime ?? 0; + message.modified_time = object.modified_time ?? 0; return message; }, }; @@ -2621,7 +2633,7 @@ export const FileDirectory = { }; function createBaseReadDir(): ReadDir { - return { path: "", includeHidden: false }; + return { path: "", include_hidden: false }; } export const ReadDir = { @@ -2632,8 +2644,8 @@ export const ReadDir = { if (message.path !== "") { writer.uint32(10).string(message.path); } - if (message.includeHidden === true) { - writer.uint32(16).bool(message.includeHidden); + if (message.include_hidden === true) { + writer.uint32(16).bool(message.include_hidden); } return writer; }, @@ -2649,7 +2661,7 @@ export const ReadDir = { message.path = reader.string(); break; case 2: - message.includeHidden = reader.bool(); + message.include_hidden = reader.bool(); break; default: reader.skipType(tag & 7); @@ -2662,8 +2674,8 @@ export const ReadDir = { fromJSON(object: any): ReadDir { return { path: isSet(object.path) ? String(object.path) : "", - includeHidden: isSet(object.includeHidden) - ? Boolean(object.includeHidden) + include_hidden: isSet(object.include_hidden) + ? Boolean(object.include_hidden) : false, }; }, @@ -2671,21 +2683,21 @@ export const ReadDir = { toJSON(message: ReadDir): unknown { const obj: any = {}; message.path !== undefined && (obj.path = message.path); - message.includeHidden !== undefined && - (obj.includeHidden = message.includeHidden); + message.include_hidden !== undefined && + (obj.include_hidden = message.include_hidden); return obj; }, fromPartial, I>>(object: I): ReadDir { const message = createBaseReadDir(); message.path = object.path ?? ""; - message.includeHidden = object.includeHidden ?? false; + message.include_hidden = object.include_hidden ?? false; return message; }, }; function createBaseReadAllFiles(): ReadAllFiles { - return { id: 0, path: "", includeHidden: false }; + return { id: 0, path: "", include_hidden: false }; } export const ReadAllFiles = { @@ -2699,8 +2711,8 @@ export const ReadAllFiles = { if (message.path !== "") { writer.uint32(18).string(message.path); } - if (message.includeHidden === true) { - writer.uint32(24).bool(message.includeHidden); + if (message.include_hidden === true) { + writer.uint32(24).bool(message.include_hidden); } return writer; }, @@ -2719,7 +2731,7 @@ export const ReadAllFiles = { message.path = reader.string(); break; case 3: - message.includeHidden = reader.bool(); + message.include_hidden = reader.bool(); break; default: reader.skipType(tag & 7); @@ -2733,8 +2745,8 @@ export const ReadAllFiles = { return { id: isSet(object.id) ? Number(object.id) : 0, path: isSet(object.path) ? String(object.path) : "", - includeHidden: isSet(object.includeHidden) - ? Boolean(object.includeHidden) + include_hidden: isSet(object.include_hidden) + ? Boolean(object.include_hidden) : false, }; }, @@ -2743,8 +2755,8 @@ export const ReadAllFiles = { const obj: any = {}; message.id !== undefined && (obj.id = Math.round(message.id)); message.path !== undefined && (obj.path = message.path); - message.includeHidden !== undefined && - (obj.includeHidden = message.includeHidden); + message.include_hidden !== undefined && + (obj.include_hidden = message.include_hidden); return obj; }, @@ -2754,20 +2766,20 @@ export const ReadAllFiles = { const message = createBaseReadAllFiles(); message.id = object.id ?? 0; message.path = object.path ?? ""; - message.includeHidden = object.includeHidden ?? false; + message.include_hidden = object.include_hidden ?? false; return message; }, }; function createBaseFileAction(): FileAction { return { - readDir: undefined, + read_dir: undefined, send: undefined, receive: undefined, create: undefined, - removeDir: undefined, - removeFile: undefined, - allFiles: undefined, + remove_dir: undefined, + remove_file: undefined, + all_files: undefined, cancel: undefined, }; } @@ -2777,8 +2789,8 @@ export const FileAction = { message: FileAction, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.readDir !== undefined) { - ReadDir.encode(message.readDir, writer.uint32(10).fork()).ldelim(); + if (message.read_dir !== undefined) { + ReadDir.encode(message.read_dir, writer.uint32(10).fork()).ldelim(); } if (message.send !== undefined) { FileTransferSendRequest.encode( @@ -2795,20 +2807,20 @@ export const FileAction = { if (message.create !== undefined) { FileDirCreate.encode(message.create, writer.uint32(34).fork()).ldelim(); } - if (message.removeDir !== undefined) { + if (message.remove_dir !== undefined) { FileRemoveDir.encode( - message.removeDir, + message.remove_dir, writer.uint32(42).fork() ).ldelim(); } - if (message.removeFile !== undefined) { + if (message.remove_file !== undefined) { FileRemoveFile.encode( - message.removeFile, + message.remove_file, writer.uint32(50).fork() ).ldelim(); } - if (message.allFiles !== undefined) { - ReadAllFiles.encode(message.allFiles, writer.uint32(58).fork()).ldelim(); + if (message.all_files !== undefined) { + ReadAllFiles.encode(message.all_files, writer.uint32(58).fork()).ldelim(); } if (message.cancel !== undefined) { FileTransferCancel.encode( @@ -2827,7 +2839,7 @@ export const FileAction = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.readDir = ReadDir.decode(reader, reader.uint32()); + message.read_dir = ReadDir.decode(reader, reader.uint32()); break; case 2: message.send = FileTransferSendRequest.decode( @@ -2845,13 +2857,13 @@ export const FileAction = { message.create = FileDirCreate.decode(reader, reader.uint32()); break; case 5: - message.removeDir = FileRemoveDir.decode(reader, reader.uint32()); + message.remove_dir = FileRemoveDir.decode(reader, reader.uint32()); break; case 6: - message.removeFile = FileRemoveFile.decode(reader, reader.uint32()); + message.remove_file = FileRemoveFile.decode(reader, reader.uint32()); break; case 7: - message.allFiles = ReadAllFiles.decode(reader, reader.uint32()); + message.all_files = ReadAllFiles.decode(reader, reader.uint32()); break; case 8: message.cancel = FileTransferCancel.decode(reader, reader.uint32()); @@ -2866,8 +2878,8 @@ export const FileAction = { fromJSON(object: any): FileAction { return { - readDir: isSet(object.readDir) - ? ReadDir.fromJSON(object.readDir) + read_dir: isSet(object.read_dir) + ? ReadDir.fromJSON(object.read_dir) : undefined, send: isSet(object.send) ? FileTransferSendRequest.fromJSON(object.send) @@ -2878,14 +2890,14 @@ export const FileAction = { create: isSet(object.create) ? FileDirCreate.fromJSON(object.create) : undefined, - removeDir: isSet(object.removeDir) - ? FileRemoveDir.fromJSON(object.removeDir) + remove_dir: isSet(object.remove_dir) + ? FileRemoveDir.fromJSON(object.remove_dir) : undefined, - removeFile: isSet(object.removeFile) - ? FileRemoveFile.fromJSON(object.removeFile) + remove_file: isSet(object.remove_file) + ? FileRemoveFile.fromJSON(object.remove_file) : undefined, - allFiles: isSet(object.allFiles) - ? ReadAllFiles.fromJSON(object.allFiles) + all_files: isSet(object.all_files) + ? ReadAllFiles.fromJSON(object.all_files) : undefined, cancel: isSet(object.cancel) ? FileTransferCancel.fromJSON(object.cancel) @@ -2895,9 +2907,9 @@ export const FileAction = { toJSON(message: FileAction): unknown { const obj: any = {}; - message.readDir !== undefined && - (obj.readDir = message.readDir - ? ReadDir.toJSON(message.readDir) + message.read_dir !== undefined && + (obj.read_dir = message.read_dir + ? ReadDir.toJSON(message.read_dir) : undefined); message.send !== undefined && (obj.send = message.send @@ -2911,17 +2923,17 @@ export const FileAction = { (obj.create = message.create ? FileDirCreate.toJSON(message.create) : undefined); - message.removeDir !== undefined && - (obj.removeDir = message.removeDir - ? FileRemoveDir.toJSON(message.removeDir) + message.remove_dir !== undefined && + (obj.remove_dir = message.remove_dir + ? FileRemoveDir.toJSON(message.remove_dir) : undefined); - message.removeFile !== undefined && - (obj.removeFile = message.removeFile - ? FileRemoveFile.toJSON(message.removeFile) + message.remove_file !== undefined && + (obj.remove_file = message.remove_file + ? FileRemoveFile.toJSON(message.remove_file) : undefined); - message.allFiles !== undefined && - (obj.allFiles = message.allFiles - ? ReadAllFiles.toJSON(message.allFiles) + message.all_files !== undefined && + (obj.all_files = message.all_files + ? ReadAllFiles.toJSON(message.all_files) : undefined); message.cancel !== undefined && (obj.cancel = message.cancel @@ -2934,9 +2946,9 @@ export const FileAction = { object: I ): FileAction { const message = createBaseFileAction(); - message.readDir = - object.readDir !== undefined && object.readDir !== null - ? ReadDir.fromPartial(object.readDir) + message.read_dir = + object.read_dir !== undefined && object.read_dir !== null + ? ReadDir.fromPartial(object.read_dir) : undefined; message.send = object.send !== undefined && object.send !== null @@ -2950,17 +2962,17 @@ export const FileAction = { object.create !== undefined && object.create !== null ? FileDirCreate.fromPartial(object.create) : undefined; - message.removeDir = - object.removeDir !== undefined && object.removeDir !== null - ? FileRemoveDir.fromPartial(object.removeDir) + message.remove_dir = + object.remove_dir !== undefined && object.remove_dir !== null + ? FileRemoveDir.fromPartial(object.remove_dir) : undefined; - message.removeFile = - object.removeFile !== undefined && object.removeFile !== null - ? FileRemoveFile.fromPartial(object.removeFile) + message.remove_file = + object.remove_file !== undefined && object.remove_file !== null + ? FileRemoveFile.fromPartial(object.remove_file) : undefined; - message.allFiles = - object.allFiles !== undefined && object.allFiles !== null - ? ReadAllFiles.fromPartial(object.allFiles) + message.all_files = + object.all_files !== undefined && object.all_files !== null + ? ReadAllFiles.fromPartial(object.all_files) : undefined; message.cancel = object.cancel !== undefined && object.cancel !== null @@ -3145,7 +3157,7 @@ export const FileResponse = { }; function createBaseFileTransferBlock(): FileTransferBlock { - return { id: 0, fileNum: 0, data: new Uint8Array(), compressed: false }; + return { id: 0, file_num: 0, data: new Uint8Array(), compressed: false }; } export const FileTransferBlock = { @@ -3156,8 +3168,8 @@ export const FileTransferBlock = { if (message.id !== 0) { writer.uint32(8).int32(message.id); } - if (message.fileNum !== 0) { - writer.uint32(16).sint32(message.fileNum); + if (message.file_num !== 0) { + writer.uint32(16).sint32(message.file_num); } if (message.data.length !== 0) { writer.uint32(26).bytes(message.data); @@ -3179,7 +3191,7 @@ export const FileTransferBlock = { message.id = reader.int32(); break; case 2: - message.fileNum = reader.sint32(); + message.file_num = reader.sint32(); break; case 3: message.data = reader.bytes(); @@ -3198,7 +3210,7 @@ export const FileTransferBlock = { fromJSON(object: any): FileTransferBlock { return { id: isSet(object.id) ? Number(object.id) : 0, - fileNum: isSet(object.fileNum) ? Number(object.fileNum) : 0, + file_num: isSet(object.file_num) ? Number(object.file_num) : 0, data: isSet(object.data) ? bytesFromBase64(object.data) : new Uint8Array(), @@ -3209,8 +3221,8 @@ export const FileTransferBlock = { toJSON(message: FileTransferBlock): unknown { const obj: any = {}; message.id !== undefined && (obj.id = Math.round(message.id)); - message.fileNum !== undefined && - (obj.fileNum = Math.round(message.fileNum)); + message.file_num !== undefined && + (obj.file_num = Math.round(message.file_num)); message.data !== undefined && (obj.data = base64FromBytes( message.data !== undefined ? message.data : new Uint8Array() @@ -3224,7 +3236,7 @@ export const FileTransferBlock = { ): FileTransferBlock { const message = createBaseFileTransferBlock(); message.id = object.id ?? 0; - message.fileNum = object.fileNum ?? 0; + message.file_num = object.file_num ?? 0; message.data = object.data ?? new Uint8Array(); message.compressed = object.compressed ?? false; return message; @@ -3232,7 +3244,7 @@ export const FileTransferBlock = { }; function createBaseFileTransferError(): FileTransferError { - return { id: 0, error: "", fileNum: 0 }; + return { id: 0, error: "", file_num: 0 }; } export const FileTransferError = { @@ -3246,8 +3258,8 @@ export const FileTransferError = { if (message.error !== "") { writer.uint32(18).string(message.error); } - if (message.fileNum !== 0) { - writer.uint32(24).sint32(message.fileNum); + if (message.file_num !== 0) { + writer.uint32(24).sint32(message.file_num); } return writer; }, @@ -3266,7 +3278,7 @@ export const FileTransferError = { message.error = reader.string(); break; case 3: - message.fileNum = reader.sint32(); + message.file_num = reader.sint32(); break; default: reader.skipType(tag & 7); @@ -3280,7 +3292,7 @@ export const FileTransferError = { return { id: isSet(object.id) ? Number(object.id) : 0, error: isSet(object.error) ? String(object.error) : "", - fileNum: isSet(object.fileNum) ? Number(object.fileNum) : 0, + file_num: isSet(object.file_num) ? Number(object.file_num) : 0, }; }, @@ -3288,8 +3300,8 @@ export const FileTransferError = { const obj: any = {}; message.id !== undefined && (obj.id = Math.round(message.id)); message.error !== undefined && (obj.error = message.error); - message.fileNum !== undefined && - (obj.fileNum = Math.round(message.fileNum)); + message.file_num !== undefined && + (obj.file_num = Math.round(message.file_num)); return obj; }, @@ -3299,13 +3311,13 @@ export const FileTransferError = { const message = createBaseFileTransferError(); message.id = object.id ?? 0; message.error = object.error ?? ""; - message.fileNum = object.fileNum ?? 0; + message.file_num = object.file_num ?? 0; return message; }, }; function createBaseFileTransferSendRequest(): FileTransferSendRequest { - return { id: 0, path: "", includeHidden: false }; + return { id: 0, path: "", include_hidden: false }; } export const FileTransferSendRequest = { @@ -3319,8 +3331,8 @@ export const FileTransferSendRequest = { if (message.path !== "") { writer.uint32(18).string(message.path); } - if (message.includeHidden === true) { - writer.uint32(24).bool(message.includeHidden); + if (message.include_hidden === true) { + writer.uint32(24).bool(message.include_hidden); } return writer; }, @@ -3342,7 +3354,7 @@ export const FileTransferSendRequest = { message.path = reader.string(); break; case 3: - message.includeHidden = reader.bool(); + message.include_hidden = reader.bool(); break; default: reader.skipType(tag & 7); @@ -3356,8 +3368,8 @@ export const FileTransferSendRequest = { return { id: isSet(object.id) ? Number(object.id) : 0, path: isSet(object.path) ? String(object.path) : "", - includeHidden: isSet(object.includeHidden) - ? Boolean(object.includeHidden) + include_hidden: isSet(object.include_hidden) + ? Boolean(object.include_hidden) : false, }; }, @@ -3366,8 +3378,8 @@ export const FileTransferSendRequest = { const obj: any = {}; message.id !== undefined && (obj.id = Math.round(message.id)); message.path !== undefined && (obj.path = message.path); - message.includeHidden !== undefined && - (obj.includeHidden = message.includeHidden); + message.include_hidden !== undefined && + (obj.include_hidden = message.include_hidden); return obj; }, @@ -3377,13 +3389,13 @@ export const FileTransferSendRequest = { const message = createBaseFileTransferSendRequest(); message.id = object.id ?? 0; message.path = object.path ?? ""; - message.includeHidden = object.includeHidden ?? false; + message.include_hidden = object.include_hidden ?? false; return message; }, }; function createBaseFileTransferDone(): FileTransferDone { - return { id: 0, fileNum: 0 }; + return { id: 0, file_num: 0 }; } export const FileTransferDone = { @@ -3394,8 +3406,8 @@ export const FileTransferDone = { if (message.id !== 0) { writer.uint32(8).int32(message.id); } - if (message.fileNum !== 0) { - writer.uint32(16).sint32(message.fileNum); + if (message.file_num !== 0) { + writer.uint32(16).sint32(message.file_num); } return writer; }, @@ -3411,7 +3423,7 @@ export const FileTransferDone = { message.id = reader.int32(); break; case 2: - message.fileNum = reader.sint32(); + message.file_num = reader.sint32(); break; default: reader.skipType(tag & 7); @@ -3424,15 +3436,15 @@ export const FileTransferDone = { fromJSON(object: any): FileTransferDone { return { id: isSet(object.id) ? Number(object.id) : 0, - fileNum: isSet(object.fileNum) ? Number(object.fileNum) : 0, + file_num: isSet(object.file_num) ? Number(object.file_num) : 0, }; }, toJSON(message: FileTransferDone): unknown { const obj: any = {}; message.id !== undefined && (obj.id = Math.round(message.id)); - message.fileNum !== undefined && - (obj.fileNum = Math.round(message.fileNum)); + message.file_num !== undefined && + (obj.file_num = Math.round(message.file_num)); return obj; }, @@ -3441,7 +3453,7 @@ export const FileTransferDone = { ): FileTransferDone { const message = createBaseFileTransferDone(); message.id = object.id ?? 0; - message.fileNum = object.fileNum ?? 0; + message.file_num = object.file_num ?? 0; return message; }, }; @@ -3602,7 +3614,7 @@ export const FileRemoveDir = { }; function createBaseFileRemoveFile(): FileRemoveFile { - return { id: 0, path: "", fileNum: 0 }; + return { id: 0, path: "", file_num: 0 }; } export const FileRemoveFile = { @@ -3616,8 +3628,8 @@ export const FileRemoveFile = { if (message.path !== "") { writer.uint32(18).string(message.path); } - if (message.fileNum !== 0) { - writer.uint32(24).sint32(message.fileNum); + if (message.file_num !== 0) { + writer.uint32(24).sint32(message.file_num); } return writer; }, @@ -3636,7 +3648,7 @@ export const FileRemoveFile = { message.path = reader.string(); break; case 3: - message.fileNum = reader.sint32(); + message.file_num = reader.sint32(); break; default: reader.skipType(tag & 7); @@ -3650,7 +3662,7 @@ export const FileRemoveFile = { return { id: isSet(object.id) ? Number(object.id) : 0, path: isSet(object.path) ? String(object.path) : "", - fileNum: isSet(object.fileNum) ? Number(object.fileNum) : 0, + file_num: isSet(object.file_num) ? Number(object.file_num) : 0, }; }, @@ -3658,8 +3670,8 @@ export const FileRemoveFile = { const obj: any = {}; message.id !== undefined && (obj.id = Math.round(message.id)); message.path !== undefined && (obj.path = message.path); - message.fileNum !== undefined && - (obj.fileNum = Math.round(message.fileNum)); + message.file_num !== undefined && + (obj.file_num = Math.round(message.file_num)); return obj; }, @@ -3669,7 +3681,7 @@ export const FileRemoveFile = { const message = createBaseFileRemoveFile(); message.id = object.id ?? 0; message.path = object.path ?? ""; - message.fileNum = object.fileNum ?? 0; + message.file_num = object.file_num ?? 0; return message; }, }; @@ -3896,14 +3908,14 @@ export const PermissionInfo = { function createBaseOptionMessage(): OptionMessage { return { - imageQuality: 0, - lockAfterSessionEnd: 0, - showRemoteCursor: 0, - privacyMode: 0, - blockInput: 0, - customImageQuality: 0, - disableAudio: 0, - disableClipboard: 0, + image_quality: 0, + lock_after_session_end: 0, + show_remote_cursor: 0, + privacy_mode: 0, + block_input: 0, + custom_image_quality: 0, + disable_audio: 0, + disable_clipboard: 0, }; } @@ -3912,29 +3924,29 @@ export const OptionMessage = { message: OptionMessage, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.imageQuality !== 0) { - writer.uint32(8).int32(message.imageQuality); + if (message.image_quality !== 0) { + writer.uint32(8).int32(message.image_quality); } - if (message.lockAfterSessionEnd !== 0) { - writer.uint32(16).int32(message.lockAfterSessionEnd); + if (message.lock_after_session_end !== 0) { + writer.uint32(16).int32(message.lock_after_session_end); } - if (message.showRemoteCursor !== 0) { - writer.uint32(24).int32(message.showRemoteCursor); + if (message.show_remote_cursor !== 0) { + writer.uint32(24).int32(message.show_remote_cursor); } - if (message.privacyMode !== 0) { - writer.uint32(32).int32(message.privacyMode); + if (message.privacy_mode !== 0) { + writer.uint32(32).int32(message.privacy_mode); } - if (message.blockInput !== 0) { - writer.uint32(40).int32(message.blockInput); + if (message.block_input !== 0) { + writer.uint32(40).int32(message.block_input); } - if (message.customImageQuality !== 0) { - writer.uint32(48).int32(message.customImageQuality); + if (message.custom_image_quality !== 0) { + writer.uint32(48).int32(message.custom_image_quality); } - if (message.disableAudio !== 0) { - writer.uint32(56).int32(message.disableAudio); + if (message.disable_audio !== 0) { + writer.uint32(56).int32(message.disable_audio); } - if (message.disableClipboard !== 0) { - writer.uint32(64).int32(message.disableClipboard); + if (message.disable_clipboard !== 0) { + writer.uint32(64).int32(message.disable_clipboard); } return writer; }, @@ -3947,28 +3959,28 @@ export const OptionMessage = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.imageQuality = reader.int32() as any; + message.image_quality = reader.int32() as any; break; case 2: - message.lockAfterSessionEnd = reader.int32() as any; + message.lock_after_session_end = reader.int32() as any; break; case 3: - message.showRemoteCursor = reader.int32() as any; + message.show_remote_cursor = reader.int32() as any; break; case 4: - message.privacyMode = reader.int32() as any; + message.privacy_mode = reader.int32() as any; break; case 5: - message.blockInput = reader.int32() as any; + message.block_input = reader.int32() as any; break; case 6: - message.customImageQuality = reader.int32(); + message.custom_image_quality = reader.int32(); break; case 7: - message.disableAudio = reader.int32() as any; + message.disable_audio = reader.int32() as any; break; case 8: - message.disableClipboard = reader.int32() as any; + message.disable_clipboard = reader.int32() as any; break; default: reader.skipType(tag & 7); @@ -3980,56 +3992,58 @@ export const OptionMessage = { fromJSON(object: any): OptionMessage { return { - imageQuality: isSet(object.imageQuality) - ? imageQualityFromJSON(object.imageQuality) + image_quality: isSet(object.image_quality) + ? imageQualityFromJSON(object.image_quality) : 0, - lockAfterSessionEnd: isSet(object.lockAfterSessionEnd) - ? optionMessage_BoolOptionFromJSON(object.lockAfterSessionEnd) + lock_after_session_end: isSet(object.lock_after_session_end) + ? optionMessage_BoolOptionFromJSON(object.lock_after_session_end) : 0, - showRemoteCursor: isSet(object.showRemoteCursor) - ? optionMessage_BoolOptionFromJSON(object.showRemoteCursor) + show_remote_cursor: isSet(object.show_remote_cursor) + ? optionMessage_BoolOptionFromJSON(object.show_remote_cursor) : 0, - privacyMode: isSet(object.privacyMode) - ? optionMessage_BoolOptionFromJSON(object.privacyMode) + privacy_mode: isSet(object.privacy_mode) + ? optionMessage_BoolOptionFromJSON(object.privacy_mode) : 0, - blockInput: isSet(object.blockInput) - ? optionMessage_BoolOptionFromJSON(object.blockInput) + block_input: isSet(object.block_input) + ? optionMessage_BoolOptionFromJSON(object.block_input) : 0, - customImageQuality: isSet(object.customImageQuality) - ? Number(object.customImageQuality) + custom_image_quality: isSet(object.custom_image_quality) + ? Number(object.custom_image_quality) : 0, - disableAudio: isSet(object.disableAudio) - ? optionMessage_BoolOptionFromJSON(object.disableAudio) + disable_audio: isSet(object.disable_audio) + ? optionMessage_BoolOptionFromJSON(object.disable_audio) : 0, - disableClipboard: isSet(object.disableClipboard) - ? optionMessage_BoolOptionFromJSON(object.disableClipboard) + disable_clipboard: isSet(object.disable_clipboard) + ? optionMessage_BoolOptionFromJSON(object.disable_clipboard) : 0, }; }, toJSON(message: OptionMessage): unknown { const obj: any = {}; - message.imageQuality !== undefined && - (obj.imageQuality = imageQualityToJSON(message.imageQuality)); - message.lockAfterSessionEnd !== undefined && - (obj.lockAfterSessionEnd = optionMessage_BoolOptionToJSON( - message.lockAfterSessionEnd + message.image_quality !== undefined && + (obj.image_quality = imageQualityToJSON(message.image_quality)); + message.lock_after_session_end !== undefined && + (obj.lock_after_session_end = optionMessage_BoolOptionToJSON( + message.lock_after_session_end )); - message.showRemoteCursor !== undefined && - (obj.showRemoteCursor = optionMessage_BoolOptionToJSON( - message.showRemoteCursor + message.show_remote_cursor !== undefined && + (obj.show_remote_cursor = optionMessage_BoolOptionToJSON( + message.show_remote_cursor )); - message.privacyMode !== undefined && - (obj.privacyMode = optionMessage_BoolOptionToJSON(message.privacyMode)); - message.blockInput !== undefined && - (obj.blockInput = optionMessage_BoolOptionToJSON(message.blockInput)); - message.customImageQuality !== undefined && - (obj.customImageQuality = Math.round(message.customImageQuality)); - message.disableAudio !== undefined && - (obj.disableAudio = optionMessage_BoolOptionToJSON(message.disableAudio)); - message.disableClipboard !== undefined && - (obj.disableClipboard = optionMessage_BoolOptionToJSON( - message.disableClipboard + message.privacy_mode !== undefined && + (obj.privacy_mode = optionMessage_BoolOptionToJSON(message.privacy_mode)); + message.block_input !== undefined && + (obj.block_input = optionMessage_BoolOptionToJSON(message.block_input)); + message.custom_image_quality !== undefined && + (obj.custom_image_quality = Math.round(message.custom_image_quality)); + message.disable_audio !== undefined && + (obj.disable_audio = optionMessage_BoolOptionToJSON( + message.disable_audio + )); + message.disable_clipboard !== undefined && + (obj.disable_clipboard = optionMessage_BoolOptionToJSON( + message.disable_clipboard )); return obj; }, @@ -4038,14 +4052,14 @@ export const OptionMessage = { object: I ): OptionMessage { const message = createBaseOptionMessage(); - message.imageQuality = object.imageQuality ?? 0; - message.lockAfterSessionEnd = object.lockAfterSessionEnd ?? 0; - message.showRemoteCursor = object.showRemoteCursor ?? 0; - message.privacyMode = object.privacyMode ?? 0; - message.blockInput = object.blockInput ?? 0; - message.customImageQuality = object.customImageQuality ?? 0; - message.disableAudio = object.disableAudio ?? 0; - message.disableClipboard = object.disableClipboard ?? 0; + message.image_quality = object.image_quality ?? 0; + message.lock_after_session_end = object.lock_after_session_end ?? 0; + message.show_remote_cursor = object.show_remote_cursor ?? 0; + message.privacy_mode = object.privacy_mode ?? 0; + message.block_input = object.block_input ?? 0; + message.custom_image_quality = object.custom_image_quality ?? 0; + message.disable_audio = object.disable_audio ?? 0; + message.disable_clipboard = object.disable_clipboard ?? 0; return message; }, }; @@ -4118,7 +4132,7 @@ export const OptionResponse = { }; function createBaseTestDelay(): TestDelay { - return { time: 0, fromClient: false }; + return { time: 0, from_client: false }; } export const TestDelay = { @@ -4129,8 +4143,8 @@ export const TestDelay = { if (message.time !== 0) { writer.uint32(8).int64(message.time); } - if (message.fromClient === true) { - writer.uint32(16).bool(message.fromClient); + if (message.from_client === true) { + writer.uint32(16).bool(message.from_client); } return writer; }, @@ -4146,7 +4160,7 @@ export const TestDelay = { message.time = longToNumber(reader.int64() as Long); break; case 2: - message.fromClient = reader.bool(); + message.from_client = reader.bool(); break; default: reader.skipType(tag & 7); @@ -4159,14 +4173,17 @@ export const TestDelay = { fromJSON(object: any): TestDelay { return { time: isSet(object.time) ? Number(object.time) : 0, - fromClient: isSet(object.fromClient) ? Boolean(object.fromClient) : false, + from_client: isSet(object.from_client) + ? Boolean(object.from_client) + : false, }; }, toJSON(message: TestDelay): unknown { const obj: any = {}; message.time !== undefined && (obj.time = Math.round(message.time)); - message.fromClient !== undefined && (obj.fromClient = message.fromClient); + message.from_client !== undefined && + (obj.from_client = message.from_client); return obj; }, @@ -4175,15 +4192,15 @@ export const TestDelay = { ): TestDelay { const message = createBaseTestDelay(); message.time = object.time ?? 0; - message.fromClient = object.fromClient ?? false; + message.from_client = object.from_client ?? false; return message; }, }; function createBasePublicKey(): PublicKey { return { - asymmetricValue: new Uint8Array(), - symmetricValue: new Uint8Array(), + asymmetric_value: new Uint8Array(), + symmetric_value: new Uint8Array(), }; } @@ -4192,11 +4209,11 @@ export const PublicKey = { message: PublicKey, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.asymmetricValue.length !== 0) { - writer.uint32(10).bytes(message.asymmetricValue); + if (message.asymmetric_value.length !== 0) { + writer.uint32(10).bytes(message.asymmetric_value); } - if (message.symmetricValue.length !== 0) { - writer.uint32(18).bytes(message.symmetricValue); + if (message.symmetric_value.length !== 0) { + writer.uint32(18).bytes(message.symmetric_value); } return writer; }, @@ -4209,10 +4226,10 @@ export const PublicKey = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.asymmetricValue = reader.bytes(); + message.asymmetric_value = reader.bytes(); break; case 2: - message.symmetricValue = reader.bytes(); + message.symmetric_value = reader.bytes(); break; default: reader.skipType(tag & 7); @@ -4224,27 +4241,27 @@ export const PublicKey = { fromJSON(object: any): PublicKey { return { - asymmetricValue: isSet(object.asymmetricValue) - ? bytesFromBase64(object.asymmetricValue) + asymmetric_value: isSet(object.asymmetric_value) + ? bytesFromBase64(object.asymmetric_value) : new Uint8Array(), - symmetricValue: isSet(object.symmetricValue) - ? bytesFromBase64(object.symmetricValue) + symmetric_value: isSet(object.symmetric_value) + ? bytesFromBase64(object.symmetric_value) : new Uint8Array(), }; }, toJSON(message: PublicKey): unknown { const obj: any = {}; - message.asymmetricValue !== undefined && - (obj.asymmetricValue = base64FromBytes( - message.asymmetricValue !== undefined - ? message.asymmetricValue + message.asymmetric_value !== undefined && + (obj.asymmetric_value = base64FromBytes( + message.asymmetric_value !== undefined + ? message.asymmetric_value : new Uint8Array() )); - message.symmetricValue !== undefined && - (obj.symmetricValue = base64FromBytes( - message.symmetricValue !== undefined - ? message.symmetricValue + message.symmetric_value !== undefined && + (obj.symmetric_value = base64FromBytes( + message.symmetric_value !== undefined + ? message.symmetric_value : new Uint8Array() )); return obj; @@ -4254,8 +4271,8 @@ export const PublicKey = { object: I ): PublicKey { const message = createBasePublicKey(); - message.asymmetricValue = object.asymmetricValue ?? new Uint8Array(); - message.symmetricValue = object.symmetricValue ?? new Uint8Array(); + message.asymmetric_value = object.asymmetric_value ?? new Uint8Array(); + message.symmetric_value = object.symmetric_value ?? new Uint8Array(); return message; }, }; @@ -4316,7 +4333,7 @@ export const SignedId = { }; function createBaseAudioFormat(): AudioFormat { - return { sampleRate: 0, channels: 0 }; + return { sample_rate: 0, channels: 0 }; } export const AudioFormat = { @@ -4324,8 +4341,8 @@ export const AudioFormat = { message: AudioFormat, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.sampleRate !== 0) { - writer.uint32(8).uint32(message.sampleRate); + if (message.sample_rate !== 0) { + writer.uint32(8).uint32(message.sample_rate); } if (message.channels !== 0) { writer.uint32(16).uint32(message.channels); @@ -4341,7 +4358,7 @@ export const AudioFormat = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.sampleRate = reader.uint32(); + message.sample_rate = reader.uint32(); break; case 2: message.channels = reader.uint32(); @@ -4356,15 +4373,15 @@ export const AudioFormat = { fromJSON(object: any): AudioFormat { return { - sampleRate: isSet(object.sampleRate) ? Number(object.sampleRate) : 0, + sample_rate: isSet(object.sample_rate) ? Number(object.sample_rate) : 0, channels: isSet(object.channels) ? Number(object.channels) : 0, }; }, toJSON(message: AudioFormat): unknown { const obj: any = {}; - message.sampleRate !== undefined && - (obj.sampleRate = Math.round(message.sampleRate)); + message.sample_rate !== undefined && + (obj.sample_rate = Math.round(message.sample_rate)); message.channels !== undefined && (obj.channels = Math.round(message.channels)); return obj; @@ -4374,7 +4391,7 @@ export const AudioFormat = { object: I ): AudioFormat { const message = createBaseAudioFormat(); - message.sampleRate = object.sampleRate ?? 0; + message.sample_rate = object.sample_rate ?? 0; message.channels = object.channels ?? 0; return message; }, @@ -4441,55 +4458,55 @@ export const AudioFrame = { function createBaseMisc(): Misc { return { - chatMessage: undefined, - switchDisplay: undefined, - permissionInfo: undefined, + chat_message: undefined, + switch_display: undefined, + permission_info: undefined, option: undefined, - audioFormat: undefined, - closeReason: undefined, - refreshVideo: undefined, - optionResponse: undefined, + audio_format: undefined, + close_reason: undefined, + refresh_video: undefined, + option_response: undefined, }; } export const Misc = { encode(message: Misc, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.chatMessage !== undefined) { + if (message.chat_message !== undefined) { ChatMessage.encode( - message.chatMessage, + message.chat_message, writer.uint32(34).fork() ).ldelim(); } - if (message.switchDisplay !== undefined) { + if (message.switch_display !== undefined) { SwitchDisplay.encode( - message.switchDisplay, + message.switch_display, writer.uint32(42).fork() ).ldelim(); } - if (message.permissionInfo !== undefined) { + if (message.permission_info !== undefined) { PermissionInfo.encode( - message.permissionInfo, + message.permission_info, writer.uint32(50).fork() ).ldelim(); } if (message.option !== undefined) { OptionMessage.encode(message.option, writer.uint32(58).fork()).ldelim(); } - if (message.audioFormat !== undefined) { + if (message.audio_format !== undefined) { AudioFormat.encode( - message.audioFormat, + message.audio_format, writer.uint32(66).fork() ).ldelim(); } - if (message.closeReason !== undefined) { - writer.uint32(74).string(message.closeReason); + if (message.close_reason !== undefined) { + writer.uint32(74).string(message.close_reason); } - if (message.refreshVideo !== undefined) { - writer.uint32(80).bool(message.refreshVideo); + if (message.refresh_video !== undefined) { + writer.uint32(80).bool(message.refresh_video); } - if (message.optionResponse !== undefined) { + if (message.option_response !== undefined) { OptionResponse.encode( - message.optionResponse, + message.option_response, writer.uint32(90).fork() ).ldelim(); } @@ -4504,13 +4521,16 @@ export const Misc = { const tag = reader.uint32(); switch (tag >>> 3) { case 4: - message.chatMessage = ChatMessage.decode(reader, reader.uint32()); + message.chat_message = ChatMessage.decode(reader, reader.uint32()); break; case 5: - message.switchDisplay = SwitchDisplay.decode(reader, reader.uint32()); + message.switch_display = SwitchDisplay.decode( + reader, + reader.uint32() + ); break; case 6: - message.permissionInfo = PermissionInfo.decode( + message.permission_info = PermissionInfo.decode( reader, reader.uint32() ); @@ -4519,16 +4539,16 @@ export const Misc = { message.option = OptionMessage.decode(reader, reader.uint32()); break; case 8: - message.audioFormat = AudioFormat.decode(reader, reader.uint32()); + message.audio_format = AudioFormat.decode(reader, reader.uint32()); break; case 9: - message.closeReason = reader.string(); + message.close_reason = reader.string(); break; case 10: - message.refreshVideo = reader.bool(); + message.refresh_video = reader.bool(); break; case 11: - message.optionResponse = OptionResponse.decode( + message.option_response = OptionResponse.decode( reader, reader.uint32() ); @@ -4543,93 +4563,93 @@ export const Misc = { fromJSON(object: any): Misc { return { - chatMessage: isSet(object.chatMessage) - ? ChatMessage.fromJSON(object.chatMessage) + chat_message: isSet(object.chat_message) + ? ChatMessage.fromJSON(object.chat_message) : undefined, - switchDisplay: isSet(object.switchDisplay) - ? SwitchDisplay.fromJSON(object.switchDisplay) + switch_display: isSet(object.switch_display) + ? SwitchDisplay.fromJSON(object.switch_display) : undefined, - permissionInfo: isSet(object.permissionInfo) - ? PermissionInfo.fromJSON(object.permissionInfo) + permission_info: isSet(object.permission_info) + ? PermissionInfo.fromJSON(object.permission_info) : undefined, option: isSet(object.option) ? OptionMessage.fromJSON(object.option) : undefined, - audioFormat: isSet(object.audioFormat) - ? AudioFormat.fromJSON(object.audioFormat) + audio_format: isSet(object.audio_format) + ? AudioFormat.fromJSON(object.audio_format) : undefined, - closeReason: isSet(object.closeReason) - ? String(object.closeReason) + close_reason: isSet(object.close_reason) + ? String(object.close_reason) : undefined, - refreshVideo: isSet(object.refreshVideo) - ? Boolean(object.refreshVideo) + refresh_video: isSet(object.refresh_video) + ? Boolean(object.refresh_video) : undefined, - optionResponse: isSet(object.optionResponse) - ? OptionResponse.fromJSON(object.optionResponse) + option_response: isSet(object.option_response) + ? OptionResponse.fromJSON(object.option_response) : undefined, }; }, toJSON(message: Misc): unknown { const obj: any = {}; - message.chatMessage !== undefined && - (obj.chatMessage = message.chatMessage - ? ChatMessage.toJSON(message.chatMessage) + message.chat_message !== undefined && + (obj.chat_message = message.chat_message + ? ChatMessage.toJSON(message.chat_message) : undefined); - message.switchDisplay !== undefined && - (obj.switchDisplay = message.switchDisplay - ? SwitchDisplay.toJSON(message.switchDisplay) + message.switch_display !== undefined && + (obj.switch_display = message.switch_display + ? SwitchDisplay.toJSON(message.switch_display) : undefined); - message.permissionInfo !== undefined && - (obj.permissionInfo = message.permissionInfo - ? PermissionInfo.toJSON(message.permissionInfo) + message.permission_info !== undefined && + (obj.permission_info = message.permission_info + ? PermissionInfo.toJSON(message.permission_info) : undefined); message.option !== undefined && (obj.option = message.option ? OptionMessage.toJSON(message.option) : undefined); - message.audioFormat !== undefined && - (obj.audioFormat = message.audioFormat - ? AudioFormat.toJSON(message.audioFormat) + message.audio_format !== undefined && + (obj.audio_format = message.audio_format + ? AudioFormat.toJSON(message.audio_format) : undefined); - message.closeReason !== undefined && - (obj.closeReason = message.closeReason); - message.refreshVideo !== undefined && - (obj.refreshVideo = message.refreshVideo); - message.optionResponse !== undefined && - (obj.optionResponse = message.optionResponse - ? OptionResponse.toJSON(message.optionResponse) + message.close_reason !== undefined && + (obj.close_reason = message.close_reason); + message.refresh_video !== undefined && + (obj.refresh_video = message.refresh_video); + message.option_response !== undefined && + (obj.option_response = message.option_response + ? OptionResponse.toJSON(message.option_response) : undefined); return obj; }, fromPartial, I>>(object: I): Misc { const message = createBaseMisc(); - message.chatMessage = - object.chatMessage !== undefined && object.chatMessage !== null - ? ChatMessage.fromPartial(object.chatMessage) + message.chat_message = + object.chat_message !== undefined && object.chat_message !== null + ? ChatMessage.fromPartial(object.chat_message) : undefined; - message.switchDisplay = - object.switchDisplay !== undefined && object.switchDisplay !== null - ? SwitchDisplay.fromPartial(object.switchDisplay) + message.switch_display = + object.switch_display !== undefined && object.switch_display !== null + ? SwitchDisplay.fromPartial(object.switch_display) : undefined; - message.permissionInfo = - object.permissionInfo !== undefined && object.permissionInfo !== null - ? PermissionInfo.fromPartial(object.permissionInfo) + message.permission_info = + object.permission_info !== undefined && object.permission_info !== null + ? PermissionInfo.fromPartial(object.permission_info) : undefined; message.option = object.option !== undefined && object.option !== null ? OptionMessage.fromPartial(object.option) : undefined; - message.audioFormat = - object.audioFormat !== undefined && object.audioFormat !== null - ? AudioFormat.fromPartial(object.audioFormat) + message.audio_format = + object.audio_format !== undefined && object.audio_format !== null + ? AudioFormat.fromPartial(object.audio_format) : undefined; - message.closeReason = object.closeReason ?? undefined; - message.refreshVideo = object.refreshVideo ?? undefined; - message.optionResponse = - object.optionResponse !== undefined && object.optionResponse !== null - ? OptionResponse.fromPartial(object.optionResponse) + message.close_reason = object.close_reason ?? undefined; + message.refresh_video = object.refresh_video ?? undefined; + message.option_response = + object.option_response !== undefined && object.option_response !== null + ? OptionResponse.fromPartial(object.option_response) : undefined; return message; }, @@ -4637,22 +4657,22 @@ export const Misc = { function createBaseMessage(): Message { return { - signedId: undefined, - publicKey: undefined, - testDelay: undefined, - videoFrame: undefined, - loginRequest: undefined, - loginResponse: undefined, + signed_id: undefined, + public_key: undefined, + test_delay: undefined, + video_frame: undefined, + login_request: undefined, + login_response: undefined, hash: undefined, - mouseEvent: undefined, - audioFrame: undefined, - cursorData: undefined, - cursorPosition: undefined, - cursorId: undefined, - keyEvent: undefined, + mouse_event: undefined, + audio_frame: undefined, + cursor_data: undefined, + cursor_position: undefined, + cursor_id: undefined, + key_event: undefined, clipboard: undefined, - fileAction: undefined, - fileResponse: undefined, + file_action: undefined, + file_response: undefined, misc: undefined, }; } @@ -4662,63 +4682,66 @@ export const Message = { message: Message, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.signedId !== undefined) { - SignedId.encode(message.signedId, writer.uint32(26).fork()).ldelim(); + if (message.signed_id !== undefined) { + SignedId.encode(message.signed_id, writer.uint32(26).fork()).ldelim(); } - if (message.publicKey !== undefined) { - PublicKey.encode(message.publicKey, writer.uint32(34).fork()).ldelim(); + if (message.public_key !== undefined) { + PublicKey.encode(message.public_key, writer.uint32(34).fork()).ldelim(); } - if (message.testDelay !== undefined) { - TestDelay.encode(message.testDelay, writer.uint32(42).fork()).ldelim(); + if (message.test_delay !== undefined) { + TestDelay.encode(message.test_delay, writer.uint32(42).fork()).ldelim(); } - if (message.videoFrame !== undefined) { - VideoFrame.encode(message.videoFrame, writer.uint32(50).fork()).ldelim(); + if (message.video_frame !== undefined) { + VideoFrame.encode(message.video_frame, writer.uint32(50).fork()).ldelim(); } - if (message.loginRequest !== undefined) { + if (message.login_request !== undefined) { LoginRequest.encode( - message.loginRequest, + message.login_request, writer.uint32(58).fork() ).ldelim(); } - if (message.loginResponse !== undefined) { + if (message.login_response !== undefined) { LoginResponse.encode( - message.loginResponse, + message.login_response, writer.uint32(66).fork() ).ldelim(); } if (message.hash !== undefined) { Hash.encode(message.hash, writer.uint32(74).fork()).ldelim(); } - if (message.mouseEvent !== undefined) { - MouseEvent.encode(message.mouseEvent, writer.uint32(82).fork()).ldelim(); + if (message.mouse_event !== undefined) { + MouseEvent.encode(message.mouse_event, writer.uint32(82).fork()).ldelim(); } - if (message.audioFrame !== undefined) { - AudioFrame.encode(message.audioFrame, writer.uint32(90).fork()).ldelim(); + if (message.audio_frame !== undefined) { + AudioFrame.encode(message.audio_frame, writer.uint32(90).fork()).ldelim(); } - if (message.cursorData !== undefined) { - CursorData.encode(message.cursorData, writer.uint32(98).fork()).ldelim(); + if (message.cursor_data !== undefined) { + CursorData.encode(message.cursor_data, writer.uint32(98).fork()).ldelim(); } - if (message.cursorPosition !== undefined) { + if (message.cursor_position !== undefined) { CursorPosition.encode( - message.cursorPosition, + message.cursor_position, writer.uint32(106).fork() ).ldelim(); } - if (message.cursorId !== undefined) { - writer.uint32(112).uint64(message.cursorId); + if (message.cursor_id !== undefined) { + writer.uint32(112).uint64(message.cursor_id); } - if (message.keyEvent !== undefined) { - KeyEvent.encode(message.keyEvent, writer.uint32(122).fork()).ldelim(); + if (message.key_event !== undefined) { + KeyEvent.encode(message.key_event, writer.uint32(122).fork()).ldelim(); } if (message.clipboard !== undefined) { Clipboard.encode(message.clipboard, writer.uint32(130).fork()).ldelim(); } - if (message.fileAction !== undefined) { - FileAction.encode(message.fileAction, writer.uint32(138).fork()).ldelim(); + if (message.file_action !== undefined) { + FileAction.encode( + message.file_action, + writer.uint32(138).fork() + ).ldelim(); } - if (message.fileResponse !== undefined) { + if (message.file_response !== undefined) { FileResponse.encode( - message.fileResponse, + message.file_response, writer.uint32(146).fork() ).ldelim(); } @@ -4736,55 +4759,58 @@ export const Message = { const tag = reader.uint32(); switch (tag >>> 3) { case 3: - message.signedId = SignedId.decode(reader, reader.uint32()); + message.signed_id = SignedId.decode(reader, reader.uint32()); break; case 4: - message.publicKey = PublicKey.decode(reader, reader.uint32()); + message.public_key = PublicKey.decode(reader, reader.uint32()); break; case 5: - message.testDelay = TestDelay.decode(reader, reader.uint32()); + message.test_delay = TestDelay.decode(reader, reader.uint32()); break; case 6: - message.videoFrame = VideoFrame.decode(reader, reader.uint32()); + message.video_frame = VideoFrame.decode(reader, reader.uint32()); break; case 7: - message.loginRequest = LoginRequest.decode(reader, reader.uint32()); + message.login_request = LoginRequest.decode(reader, reader.uint32()); break; case 8: - message.loginResponse = LoginResponse.decode(reader, reader.uint32()); + message.login_response = LoginResponse.decode( + reader, + reader.uint32() + ); break; case 9: message.hash = Hash.decode(reader, reader.uint32()); break; case 10: - message.mouseEvent = MouseEvent.decode(reader, reader.uint32()); + message.mouse_event = MouseEvent.decode(reader, reader.uint32()); break; case 11: - message.audioFrame = AudioFrame.decode(reader, reader.uint32()); + message.audio_frame = AudioFrame.decode(reader, reader.uint32()); break; case 12: - message.cursorData = CursorData.decode(reader, reader.uint32()); + message.cursor_data = CursorData.decode(reader, reader.uint32()); break; case 13: - message.cursorPosition = CursorPosition.decode( + message.cursor_position = CursorPosition.decode( reader, reader.uint32() ); break; case 14: - message.cursorId = longToNumber(reader.uint64() as Long); + message.cursor_id = longToNumber(reader.uint64() as Long); break; case 15: - message.keyEvent = KeyEvent.decode(reader, reader.uint32()); + message.key_event = KeyEvent.decode(reader, reader.uint32()); break; case 16: message.clipboard = Clipboard.decode(reader, reader.uint32()); break; case 17: - message.fileAction = FileAction.decode(reader, reader.uint32()); + message.file_action = FileAction.decode(reader, reader.uint32()); break; case 18: - message.fileResponse = FileResponse.decode(reader, reader.uint32()); + message.file_response = FileResponse.decode(reader, reader.uint32()); break; case 19: message.misc = Misc.decode(reader, reader.uint32()); @@ -4799,49 +4825,49 @@ export const Message = { fromJSON(object: any): Message { return { - signedId: isSet(object.signedId) - ? SignedId.fromJSON(object.signedId) + signed_id: isSet(object.signed_id) + ? SignedId.fromJSON(object.signed_id) : undefined, - publicKey: isSet(object.publicKey) - ? PublicKey.fromJSON(object.publicKey) + public_key: isSet(object.public_key) + ? PublicKey.fromJSON(object.public_key) : undefined, - testDelay: isSet(object.testDelay) - ? TestDelay.fromJSON(object.testDelay) + test_delay: isSet(object.test_delay) + ? TestDelay.fromJSON(object.test_delay) : undefined, - videoFrame: isSet(object.videoFrame) - ? VideoFrame.fromJSON(object.videoFrame) + video_frame: isSet(object.video_frame) + ? VideoFrame.fromJSON(object.video_frame) : undefined, - loginRequest: isSet(object.loginRequest) - ? LoginRequest.fromJSON(object.loginRequest) + login_request: isSet(object.login_request) + ? LoginRequest.fromJSON(object.login_request) : undefined, - loginResponse: isSet(object.loginResponse) - ? LoginResponse.fromJSON(object.loginResponse) + login_response: isSet(object.login_response) + ? LoginResponse.fromJSON(object.login_response) : undefined, hash: isSet(object.hash) ? Hash.fromJSON(object.hash) : undefined, - mouseEvent: isSet(object.mouseEvent) - ? MouseEvent.fromJSON(object.mouseEvent) + mouse_event: isSet(object.mouse_event) + ? MouseEvent.fromJSON(object.mouse_event) : undefined, - audioFrame: isSet(object.audioFrame) - ? AudioFrame.fromJSON(object.audioFrame) + audio_frame: isSet(object.audio_frame) + ? AudioFrame.fromJSON(object.audio_frame) : undefined, - cursorData: isSet(object.cursorData) - ? CursorData.fromJSON(object.cursorData) + cursor_data: isSet(object.cursor_data) + ? CursorData.fromJSON(object.cursor_data) : undefined, - cursorPosition: isSet(object.cursorPosition) - ? CursorPosition.fromJSON(object.cursorPosition) + cursor_position: isSet(object.cursor_position) + ? CursorPosition.fromJSON(object.cursor_position) : undefined, - cursorId: isSet(object.cursorId) ? Number(object.cursorId) : undefined, - keyEvent: isSet(object.keyEvent) - ? KeyEvent.fromJSON(object.keyEvent) + cursor_id: isSet(object.cursor_id) ? Number(object.cursor_id) : undefined, + key_event: isSet(object.key_event) + ? KeyEvent.fromJSON(object.key_event) : undefined, clipboard: isSet(object.clipboard) ? Clipboard.fromJSON(object.clipboard) : undefined, - fileAction: isSet(object.fileAction) - ? FileAction.fromJSON(object.fileAction) + file_action: isSet(object.file_action) + ? FileAction.fromJSON(object.file_action) : undefined, - fileResponse: isSet(object.fileResponse) - ? FileResponse.fromJSON(object.fileResponse) + file_response: isSet(object.file_response) + ? FileResponse.fromJSON(object.file_response) : undefined, misc: isSet(object.misc) ? Misc.fromJSON(object.misc) : undefined, }; @@ -4849,65 +4875,65 @@ export const Message = { toJSON(message: Message): unknown { const obj: any = {}; - message.signedId !== undefined && - (obj.signedId = message.signedId - ? SignedId.toJSON(message.signedId) + message.signed_id !== undefined && + (obj.signed_id = message.signed_id + ? SignedId.toJSON(message.signed_id) : undefined); - message.publicKey !== undefined && - (obj.publicKey = message.publicKey - ? PublicKey.toJSON(message.publicKey) + message.public_key !== undefined && + (obj.public_key = message.public_key + ? PublicKey.toJSON(message.public_key) : undefined); - message.testDelay !== undefined && - (obj.testDelay = message.testDelay - ? TestDelay.toJSON(message.testDelay) + message.test_delay !== undefined && + (obj.test_delay = message.test_delay + ? TestDelay.toJSON(message.test_delay) : undefined); - message.videoFrame !== undefined && - (obj.videoFrame = message.videoFrame - ? VideoFrame.toJSON(message.videoFrame) + message.video_frame !== undefined && + (obj.video_frame = message.video_frame + ? VideoFrame.toJSON(message.video_frame) : undefined); - message.loginRequest !== undefined && - (obj.loginRequest = message.loginRequest - ? LoginRequest.toJSON(message.loginRequest) + message.login_request !== undefined && + (obj.login_request = message.login_request + ? LoginRequest.toJSON(message.login_request) : undefined); - message.loginResponse !== undefined && - (obj.loginResponse = message.loginResponse - ? LoginResponse.toJSON(message.loginResponse) + message.login_response !== undefined && + (obj.login_response = message.login_response + ? LoginResponse.toJSON(message.login_response) : undefined); message.hash !== undefined && (obj.hash = message.hash ? Hash.toJSON(message.hash) : undefined); - message.mouseEvent !== undefined && - (obj.mouseEvent = message.mouseEvent - ? MouseEvent.toJSON(message.mouseEvent) + message.mouse_event !== undefined && + (obj.mouse_event = message.mouse_event + ? MouseEvent.toJSON(message.mouse_event) : undefined); - message.audioFrame !== undefined && - (obj.audioFrame = message.audioFrame - ? AudioFrame.toJSON(message.audioFrame) + message.audio_frame !== undefined && + (obj.audio_frame = message.audio_frame + ? AudioFrame.toJSON(message.audio_frame) : undefined); - message.cursorData !== undefined && - (obj.cursorData = message.cursorData - ? CursorData.toJSON(message.cursorData) + message.cursor_data !== undefined && + (obj.cursor_data = message.cursor_data + ? CursorData.toJSON(message.cursor_data) : undefined); - message.cursorPosition !== undefined && - (obj.cursorPosition = message.cursorPosition - ? CursorPosition.toJSON(message.cursorPosition) + message.cursor_position !== undefined && + (obj.cursor_position = message.cursor_position + ? CursorPosition.toJSON(message.cursor_position) : undefined); - message.cursorId !== undefined && - (obj.cursorId = Math.round(message.cursorId)); - message.keyEvent !== undefined && - (obj.keyEvent = message.keyEvent - ? KeyEvent.toJSON(message.keyEvent) + message.cursor_id !== undefined && + (obj.cursor_id = Math.round(message.cursor_id)); + message.key_event !== undefined && + (obj.key_event = message.key_event + ? KeyEvent.toJSON(message.key_event) : undefined); message.clipboard !== undefined && (obj.clipboard = message.clipboard ? Clipboard.toJSON(message.clipboard) : undefined); - message.fileAction !== undefined && - (obj.fileAction = message.fileAction - ? FileAction.toJSON(message.fileAction) + message.file_action !== undefined && + (obj.file_action = message.file_action + ? FileAction.toJSON(message.file_action) : undefined); - message.fileResponse !== undefined && - (obj.fileResponse = message.fileResponse - ? FileResponse.toJSON(message.fileResponse) + message.file_response !== undefined && + (obj.file_response = message.file_response + ? FileResponse.toJSON(message.file_response) : undefined); message.misc !== undefined && (obj.misc = message.misc ? Misc.toJSON(message.misc) : undefined); @@ -4916,66 +4942,66 @@ export const Message = { fromPartial, I>>(object: I): Message { const message = createBaseMessage(); - message.signedId = - object.signedId !== undefined && object.signedId !== null - ? SignedId.fromPartial(object.signedId) + message.signed_id = + object.signed_id !== undefined && object.signed_id !== null + ? SignedId.fromPartial(object.signed_id) : undefined; - message.publicKey = - object.publicKey !== undefined && object.publicKey !== null - ? PublicKey.fromPartial(object.publicKey) + message.public_key = + object.public_key !== undefined && object.public_key !== null + ? PublicKey.fromPartial(object.public_key) : undefined; - message.testDelay = - object.testDelay !== undefined && object.testDelay !== null - ? TestDelay.fromPartial(object.testDelay) + message.test_delay = + object.test_delay !== undefined && object.test_delay !== null + ? TestDelay.fromPartial(object.test_delay) : undefined; - message.videoFrame = - object.videoFrame !== undefined && object.videoFrame !== null - ? VideoFrame.fromPartial(object.videoFrame) + message.video_frame = + object.video_frame !== undefined && object.video_frame !== null + ? VideoFrame.fromPartial(object.video_frame) : undefined; - message.loginRequest = - object.loginRequest !== undefined && object.loginRequest !== null - ? LoginRequest.fromPartial(object.loginRequest) + message.login_request = + object.login_request !== undefined && object.login_request !== null + ? LoginRequest.fromPartial(object.login_request) : undefined; - message.loginResponse = - object.loginResponse !== undefined && object.loginResponse !== null - ? LoginResponse.fromPartial(object.loginResponse) + message.login_response = + object.login_response !== undefined && object.login_response !== null + ? LoginResponse.fromPartial(object.login_response) : undefined; message.hash = object.hash !== undefined && object.hash !== null ? Hash.fromPartial(object.hash) : undefined; - message.mouseEvent = - object.mouseEvent !== undefined && object.mouseEvent !== null - ? MouseEvent.fromPartial(object.mouseEvent) + message.mouse_event = + object.mouse_event !== undefined && object.mouse_event !== null + ? MouseEvent.fromPartial(object.mouse_event) : undefined; - message.audioFrame = - object.audioFrame !== undefined && object.audioFrame !== null - ? AudioFrame.fromPartial(object.audioFrame) + message.audio_frame = + object.audio_frame !== undefined && object.audio_frame !== null + ? AudioFrame.fromPartial(object.audio_frame) : undefined; - message.cursorData = - object.cursorData !== undefined && object.cursorData !== null - ? CursorData.fromPartial(object.cursorData) + message.cursor_data = + object.cursor_data !== undefined && object.cursor_data !== null + ? CursorData.fromPartial(object.cursor_data) : undefined; - message.cursorPosition = - object.cursorPosition !== undefined && object.cursorPosition !== null - ? CursorPosition.fromPartial(object.cursorPosition) + message.cursor_position = + object.cursor_position !== undefined && object.cursor_position !== null + ? CursorPosition.fromPartial(object.cursor_position) : undefined; - message.cursorId = object.cursorId ?? undefined; - message.keyEvent = - object.keyEvent !== undefined && object.keyEvent !== null - ? KeyEvent.fromPartial(object.keyEvent) + message.cursor_id = object.cursor_id ?? undefined; + message.key_event = + object.key_event !== undefined && object.key_event !== null + ? KeyEvent.fromPartial(object.key_event) : undefined; message.clipboard = object.clipboard !== undefined && object.clipboard !== null ? Clipboard.fromPartial(object.clipboard) : undefined; - message.fileAction = - object.fileAction !== undefined && object.fileAction !== null - ? FileAction.fromPartial(object.fileAction) + message.file_action = + object.file_action !== undefined && object.file_action !== null + ? FileAction.fromPartial(object.file_action) : undefined; - message.fileResponse = - object.fileResponse !== undefined && object.fileResponse !== null - ? FileResponse.fromPartial(object.fileResponse) + message.file_response = + object.file_response !== undefined && object.file_response !== null + ? FileResponse.fromPartial(object.file_response) : undefined; message.misc = object.misc !== undefined && object.misc !== null diff --git a/src/rendezvous.ts b/src/rendezvous.ts index 33fab950b..bf24c70f7 100644 --- a/src/rendezvous.ts +++ b/src/rendezvous.ts @@ -92,20 +92,20 @@ export interface RegisterPeer { } export interface RegisterPeerResponse { - requestPk: boolean; + request_pk: boolean; } export interface PunchHoleRequest { id: string; - natType: NatType; - licenceKey: string; - connType: ConnType; + nat_type: NatType; + licence_key: string; + conn_type: ConnType; } export interface PunchHole { - socketAddr: Uint8Array; - relayServer: string; - natType: NatType; + socket_addr: Uint8Array; + relay_server: string; + nat_type: NatType; } export interface TestNatRequest { @@ -120,10 +120,10 @@ export interface TestNatResponse { } export interface PunchHoleSent { - socketAddr: Uint8Array; + socket_addr: Uint8Array; id: string; - relayServer: string; - natType: NatType; + relay_server: string; + nat_type: NatType; version: string; } @@ -131,7 +131,7 @@ export interface RegisterPk { id: string; uuid: Uint8Array; pk: Uint8Array; - oldId: string; + old_id: string; } export interface RegisterPkResponse { @@ -205,13 +205,13 @@ export function registerPkResponse_ResultToJSON( } export interface PunchHoleResponse { - socketAddr: Uint8Array; + socket_addr: Uint8Array; pk: Uint8Array; failure: PunchHoleResponse_Failure; - relayServer: string; - natType: NatType | undefined; - isLocal: boolean | undefined; - otherFailure: string; + relay_server: string; + nat_type: NatType | undefined; + is_local: boolean | undefined; + other_failure: string; } export enum PunchHoleResponse_Failure { @@ -264,26 +264,26 @@ export function punchHoleResponse_FailureToJSON( export interface ConfigUpdate { serial: number; - rendezvousServers: string[]; + rendezvous_servers: string[]; } export interface RequestRelay { id: string; uuid: string; - socketAddr: Uint8Array; - relayServer: string; + socket_addr: Uint8Array; + relay_server: string; secure: boolean; - licenceKey: string; - connType: ConnType; + licence_key: string; + conn_type: ConnType; } export interface RelayResponse { - socketAddr: Uint8Array; + socket_addr: Uint8Array; uuid: string; - relayServer: string; + relay_server: string; id: string | undefined; pk: Uint8Array | undefined; - refuseReason: string; + refuse_reason: string; version: string; } @@ -298,14 +298,14 @@ export interface SoftwareUpdate { * so we request local address to connect. */ export interface FetchLocalAddr { - socketAddr: Uint8Array; - relayServer: string; + socket_addr: Uint8Array; + relay_server: string; } export interface LocalAddr { - socketAddr: Uint8Array; - localAddr: Uint8Array; - relayServer: string; + socket_addr: Uint8Array; + local_addr: Uint8Array; + relay_server: string; id: string; version: string; } @@ -321,23 +321,23 @@ export interface PeerDiscovery { } export interface RendezvousMessage { - registerPeer: RegisterPeer | undefined; - registerPeerResponse: RegisterPeerResponse | undefined; - punchHoleRequest: PunchHoleRequest | undefined; - punchHole: PunchHole | undefined; - punchHoleSent: PunchHoleSent | undefined; - punchHoleResponse: PunchHoleResponse | undefined; - fetchLocalAddr: FetchLocalAddr | undefined; - localAddr: LocalAddr | undefined; - configureUpdate: ConfigUpdate | undefined; - registerPk: RegisterPk | undefined; - registerPkResponse: RegisterPkResponse | undefined; - softwareUpdate: SoftwareUpdate | undefined; - requestRelay: RequestRelay | undefined; - relayResponse: RelayResponse | undefined; - testNatRequest: TestNatRequest | undefined; - testNatResponse: TestNatResponse | undefined; - peerDiscovery: PeerDiscovery | undefined; + register_peer: RegisterPeer | undefined; + register_peer_response: RegisterPeerResponse | undefined; + punch_hole_request: PunchHoleRequest | undefined; + punch_hole: PunchHole | undefined; + punch_hole_sent: PunchHoleSent | undefined; + punch_hole_response: PunchHoleResponse | undefined; + fetch_local_addr: FetchLocalAddr | undefined; + local_addr: LocalAddr | undefined; + configure_update: ConfigUpdate | undefined; + register_pk: RegisterPk | undefined; + register_pk_response: RegisterPkResponse | undefined; + software_update: SoftwareUpdate | undefined; + request_relay: RequestRelay | undefined; + relay_response: RelayResponse | undefined; + test_nat_request: TestNatRequest | undefined; + test_nat_response: TestNatResponse | undefined; + peer_discovery: PeerDiscovery | undefined; } function createBaseRegisterPeer(): RegisterPeer { @@ -404,7 +404,7 @@ export const RegisterPeer = { }; function createBaseRegisterPeerResponse(): RegisterPeerResponse { - return { requestPk: false }; + return { request_pk: false }; } export const RegisterPeerResponse = { @@ -412,8 +412,8 @@ export const RegisterPeerResponse = { message: RegisterPeerResponse, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.requestPk === true) { - writer.uint32(16).bool(message.requestPk); + if (message.request_pk === true) { + writer.uint32(16).bool(message.request_pk); } return writer; }, @@ -429,7 +429,7 @@ export const RegisterPeerResponse = { const tag = reader.uint32(); switch (tag >>> 3) { case 2: - message.requestPk = reader.bool(); + message.request_pk = reader.bool(); break; default: reader.skipType(tag & 7); @@ -441,13 +441,13 @@ export const RegisterPeerResponse = { fromJSON(object: any): RegisterPeerResponse { return { - requestPk: isSet(object.requestPk) ? Boolean(object.requestPk) : false, + request_pk: isSet(object.request_pk) ? Boolean(object.request_pk) : false, }; }, toJSON(message: RegisterPeerResponse): unknown { const obj: any = {}; - message.requestPk !== undefined && (obj.requestPk = message.requestPk); + message.request_pk !== undefined && (obj.request_pk = message.request_pk); return obj; }, @@ -455,13 +455,13 @@ export const RegisterPeerResponse = { object: I ): RegisterPeerResponse { const message = createBaseRegisterPeerResponse(); - message.requestPk = object.requestPk ?? false; + message.request_pk = object.request_pk ?? false; return message; }, }; function createBasePunchHoleRequest(): PunchHoleRequest { - return { id: "", natType: 0, licenceKey: "", connType: 0 }; + return { id: "", nat_type: 0, licence_key: "", conn_type: 0 }; } export const PunchHoleRequest = { @@ -472,14 +472,14 @@ export const PunchHoleRequest = { if (message.id !== "") { writer.uint32(10).string(message.id); } - if (message.natType !== 0) { - writer.uint32(16).int32(message.natType); + if (message.nat_type !== 0) { + writer.uint32(16).int32(message.nat_type); } - if (message.licenceKey !== "") { - writer.uint32(26).string(message.licenceKey); + if (message.licence_key !== "") { + writer.uint32(26).string(message.licence_key); } - if (message.connType !== 0) { - writer.uint32(32).int32(message.connType); + if (message.conn_type !== 0) { + writer.uint32(32).int32(message.conn_type); } return writer; }, @@ -495,13 +495,13 @@ export const PunchHoleRequest = { message.id = reader.string(); break; case 2: - message.natType = reader.int32() as any; + message.nat_type = reader.int32() as any; break; case 3: - message.licenceKey = reader.string(); + message.licence_key = reader.string(); break; case 4: - message.connType = reader.int32() as any; + message.conn_type = reader.int32() as any; break; default: reader.skipType(tag & 7); @@ -514,20 +514,23 @@ export const PunchHoleRequest = { fromJSON(object: any): PunchHoleRequest { return { id: isSet(object.id) ? String(object.id) : "", - natType: isSet(object.natType) ? natTypeFromJSON(object.natType) : 0, - licenceKey: isSet(object.licenceKey) ? String(object.licenceKey) : "", - connType: isSet(object.connType) ? connTypeFromJSON(object.connType) : 0, + nat_type: isSet(object.nat_type) ? natTypeFromJSON(object.nat_type) : 0, + licence_key: isSet(object.licence_key) ? String(object.licence_key) : "", + conn_type: isSet(object.conn_type) + ? connTypeFromJSON(object.conn_type) + : 0, }; }, toJSON(message: PunchHoleRequest): unknown { const obj: any = {}; message.id !== undefined && (obj.id = message.id); - message.natType !== undefined && - (obj.natType = natTypeToJSON(message.natType)); - message.licenceKey !== undefined && (obj.licenceKey = message.licenceKey); - message.connType !== undefined && - (obj.connType = connTypeToJSON(message.connType)); + message.nat_type !== undefined && + (obj.nat_type = natTypeToJSON(message.nat_type)); + message.licence_key !== undefined && + (obj.licence_key = message.licence_key); + message.conn_type !== undefined && + (obj.conn_type = connTypeToJSON(message.conn_type)); return obj; }, @@ -536,15 +539,15 @@ export const PunchHoleRequest = { ): PunchHoleRequest { const message = createBasePunchHoleRequest(); message.id = object.id ?? ""; - message.natType = object.natType ?? 0; - message.licenceKey = object.licenceKey ?? ""; - message.connType = object.connType ?? 0; + message.nat_type = object.nat_type ?? 0; + message.licence_key = object.licence_key ?? ""; + message.conn_type = object.conn_type ?? 0; return message; }, }; function createBasePunchHole(): PunchHole { - return { socketAddr: new Uint8Array(), relayServer: "", natType: 0 }; + return { socket_addr: new Uint8Array(), relay_server: "", nat_type: 0 }; } export const PunchHole = { @@ -552,14 +555,14 @@ export const PunchHole = { message: PunchHole, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.socketAddr.length !== 0) { - writer.uint32(10).bytes(message.socketAddr); + if (message.socket_addr.length !== 0) { + writer.uint32(10).bytes(message.socket_addr); } - if (message.relayServer !== "") { - writer.uint32(18).string(message.relayServer); + if (message.relay_server !== "") { + writer.uint32(18).string(message.relay_server); } - if (message.natType !== 0) { - writer.uint32(24).int32(message.natType); + if (message.nat_type !== 0) { + writer.uint32(24).int32(message.nat_type); } return writer; }, @@ -572,13 +575,13 @@ export const PunchHole = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.socketAddr = reader.bytes(); + message.socket_addr = reader.bytes(); break; case 2: - message.relayServer = reader.string(); + message.relay_server = reader.string(); break; case 3: - message.natType = reader.int32() as any; + message.nat_type = reader.int32() as any; break; default: reader.skipType(tag & 7); @@ -590,24 +593,28 @@ export const PunchHole = { fromJSON(object: any): PunchHole { return { - socketAddr: isSet(object.socketAddr) - ? bytesFromBase64(object.socketAddr) + socket_addr: isSet(object.socket_addr) + ? bytesFromBase64(object.socket_addr) : new Uint8Array(), - relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", - natType: isSet(object.natType) ? natTypeFromJSON(object.natType) : 0, + relay_server: isSet(object.relay_server) + ? String(object.relay_server) + : "", + nat_type: isSet(object.nat_type) ? natTypeFromJSON(object.nat_type) : 0, }; }, toJSON(message: PunchHole): unknown { const obj: any = {}; - message.socketAddr !== undefined && - (obj.socketAddr = base64FromBytes( - message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + message.socket_addr !== undefined && + (obj.socket_addr = base64FromBytes( + message.socket_addr !== undefined + ? message.socket_addr + : new Uint8Array() )); - message.relayServer !== undefined && - (obj.relayServer = message.relayServer); - message.natType !== undefined && - (obj.natType = natTypeToJSON(message.natType)); + message.relay_server !== undefined && + (obj.relay_server = message.relay_server); + message.nat_type !== undefined && + (obj.nat_type = natTypeToJSON(message.nat_type)); return obj; }, @@ -615,9 +622,9 @@ export const PunchHole = { object: I ): PunchHole { const message = createBasePunchHole(); - message.socketAddr = object.socketAddr ?? new Uint8Array(); - message.relayServer = object.relayServer ?? ""; - message.natType = object.natType ?? 0; + message.socket_addr = object.socket_addr ?? new Uint8Array(); + message.relay_server = object.relay_server ?? ""; + message.nat_type = object.nat_type ?? 0; return message; }, }; @@ -745,10 +752,10 @@ export const TestNatResponse = { function createBasePunchHoleSent(): PunchHoleSent { return { - socketAddr: new Uint8Array(), + socket_addr: new Uint8Array(), id: "", - relayServer: "", - natType: 0, + relay_server: "", + nat_type: 0, version: "", }; } @@ -758,17 +765,17 @@ export const PunchHoleSent = { message: PunchHoleSent, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.socketAddr.length !== 0) { - writer.uint32(10).bytes(message.socketAddr); + if (message.socket_addr.length !== 0) { + writer.uint32(10).bytes(message.socket_addr); } if (message.id !== "") { writer.uint32(18).string(message.id); } - if (message.relayServer !== "") { - writer.uint32(26).string(message.relayServer); + if (message.relay_server !== "") { + writer.uint32(26).string(message.relay_server); } - if (message.natType !== 0) { - writer.uint32(32).int32(message.natType); + if (message.nat_type !== 0) { + writer.uint32(32).int32(message.nat_type); } if (message.version !== "") { writer.uint32(42).string(message.version); @@ -784,16 +791,16 @@ export const PunchHoleSent = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.socketAddr = reader.bytes(); + message.socket_addr = reader.bytes(); break; case 2: message.id = reader.string(); break; case 3: - message.relayServer = reader.string(); + message.relay_server = reader.string(); break; case 4: - message.natType = reader.int32() as any; + message.nat_type = reader.int32() as any; break; case 5: message.version = reader.string(); @@ -808,27 +815,31 @@ export const PunchHoleSent = { fromJSON(object: any): PunchHoleSent { return { - socketAddr: isSet(object.socketAddr) - ? bytesFromBase64(object.socketAddr) + socket_addr: isSet(object.socket_addr) + ? bytesFromBase64(object.socket_addr) : new Uint8Array(), id: isSet(object.id) ? String(object.id) : "", - relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", - natType: isSet(object.natType) ? natTypeFromJSON(object.natType) : 0, + relay_server: isSet(object.relay_server) + ? String(object.relay_server) + : "", + nat_type: isSet(object.nat_type) ? natTypeFromJSON(object.nat_type) : 0, version: isSet(object.version) ? String(object.version) : "", }; }, toJSON(message: PunchHoleSent): unknown { const obj: any = {}; - message.socketAddr !== undefined && - (obj.socketAddr = base64FromBytes( - message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + message.socket_addr !== undefined && + (obj.socket_addr = base64FromBytes( + message.socket_addr !== undefined + ? message.socket_addr + : new Uint8Array() )); message.id !== undefined && (obj.id = message.id); - message.relayServer !== undefined && - (obj.relayServer = message.relayServer); - message.natType !== undefined && - (obj.natType = natTypeToJSON(message.natType)); + message.relay_server !== undefined && + (obj.relay_server = message.relay_server); + message.nat_type !== undefined && + (obj.nat_type = natTypeToJSON(message.nat_type)); message.version !== undefined && (obj.version = message.version); return obj; }, @@ -837,17 +848,17 @@ export const PunchHoleSent = { object: I ): PunchHoleSent { const message = createBasePunchHoleSent(); - message.socketAddr = object.socketAddr ?? new Uint8Array(); + message.socket_addr = object.socket_addr ?? new Uint8Array(); message.id = object.id ?? ""; - message.relayServer = object.relayServer ?? ""; - message.natType = object.natType ?? 0; + message.relay_server = object.relay_server ?? ""; + message.nat_type = object.nat_type ?? 0; message.version = object.version ?? ""; return message; }, }; function createBaseRegisterPk(): RegisterPk { - return { id: "", uuid: new Uint8Array(), pk: new Uint8Array(), oldId: "" }; + return { id: "", uuid: new Uint8Array(), pk: new Uint8Array(), old_id: "" }; } export const RegisterPk = { @@ -864,8 +875,8 @@ export const RegisterPk = { if (message.pk.length !== 0) { writer.uint32(26).bytes(message.pk); } - if (message.oldId !== "") { - writer.uint32(34).string(message.oldId); + if (message.old_id !== "") { + writer.uint32(34).string(message.old_id); } return writer; }, @@ -887,7 +898,7 @@ export const RegisterPk = { message.pk = reader.bytes(); break; case 4: - message.oldId = reader.string(); + message.old_id = reader.string(); break; default: reader.skipType(tag & 7); @@ -904,7 +915,7 @@ export const RegisterPk = { ? bytesFromBase64(object.uuid) : new Uint8Array(), pk: isSet(object.pk) ? bytesFromBase64(object.pk) : new Uint8Array(), - oldId: isSet(object.oldId) ? String(object.oldId) : "", + old_id: isSet(object.old_id) ? String(object.old_id) : "", }; }, @@ -919,7 +930,7 @@ export const RegisterPk = { (obj.pk = base64FromBytes( message.pk !== undefined ? message.pk : new Uint8Array() )); - message.oldId !== undefined && (obj.oldId = message.oldId); + message.old_id !== undefined && (obj.old_id = message.old_id); return obj; }, @@ -930,7 +941,7 @@ export const RegisterPk = { message.id = object.id ?? ""; message.uuid = object.uuid ?? new Uint8Array(); message.pk = object.pk ?? new Uint8Array(); - message.oldId = object.oldId ?? ""; + message.old_id = object.old_id ?? ""; return message; }, }; @@ -994,13 +1005,13 @@ export const RegisterPkResponse = { function createBasePunchHoleResponse(): PunchHoleResponse { return { - socketAddr: new Uint8Array(), + socket_addr: new Uint8Array(), pk: new Uint8Array(), failure: 0, - relayServer: "", - natType: undefined, - isLocal: undefined, - otherFailure: "", + relay_server: "", + nat_type: undefined, + is_local: undefined, + other_failure: "", }; } @@ -1009,8 +1020,8 @@ export const PunchHoleResponse = { message: PunchHoleResponse, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.socketAddr.length !== 0) { - writer.uint32(10).bytes(message.socketAddr); + if (message.socket_addr.length !== 0) { + writer.uint32(10).bytes(message.socket_addr); } if (message.pk.length !== 0) { writer.uint32(18).bytes(message.pk); @@ -1018,17 +1029,17 @@ export const PunchHoleResponse = { if (message.failure !== 0) { writer.uint32(24).int32(message.failure); } - if (message.relayServer !== "") { - writer.uint32(34).string(message.relayServer); + if (message.relay_server !== "") { + writer.uint32(34).string(message.relay_server); } - if (message.natType !== undefined) { - writer.uint32(40).int32(message.natType); + if (message.nat_type !== undefined) { + writer.uint32(40).int32(message.nat_type); } - if (message.isLocal !== undefined) { - writer.uint32(48).bool(message.isLocal); + if (message.is_local !== undefined) { + writer.uint32(48).bool(message.is_local); } - if (message.otherFailure !== "") { - writer.uint32(58).string(message.otherFailure); + if (message.other_failure !== "") { + writer.uint32(58).string(message.other_failure); } return writer; }, @@ -1041,7 +1052,7 @@ export const PunchHoleResponse = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.socketAddr = reader.bytes(); + message.socket_addr = reader.bytes(); break; case 2: message.pk = reader.bytes(); @@ -1050,16 +1061,16 @@ export const PunchHoleResponse = { message.failure = reader.int32() as any; break; case 4: - message.relayServer = reader.string(); + message.relay_server = reader.string(); break; case 5: - message.natType = reader.int32() as any; + message.nat_type = reader.int32() as any; break; case 6: - message.isLocal = reader.bool(); + message.is_local = reader.bool(); break; case 7: - message.otherFailure = reader.string(); + message.other_failure = reader.string(); break; default: reader.skipType(tag & 7); @@ -1071,29 +1082,33 @@ export const PunchHoleResponse = { fromJSON(object: any): PunchHoleResponse { return { - socketAddr: isSet(object.socketAddr) - ? bytesFromBase64(object.socketAddr) + socket_addr: isSet(object.socket_addr) + ? bytesFromBase64(object.socket_addr) : new Uint8Array(), pk: isSet(object.pk) ? bytesFromBase64(object.pk) : new Uint8Array(), failure: isSet(object.failure) ? punchHoleResponse_FailureFromJSON(object.failure) : 0, - relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", - natType: isSet(object.natType) - ? natTypeFromJSON(object.natType) + relay_server: isSet(object.relay_server) + ? String(object.relay_server) + : "", + nat_type: isSet(object.nat_type) + ? natTypeFromJSON(object.nat_type) : undefined, - isLocal: isSet(object.isLocal) ? Boolean(object.isLocal) : undefined, - otherFailure: isSet(object.otherFailure) - ? String(object.otherFailure) + is_local: isSet(object.is_local) ? Boolean(object.is_local) : undefined, + other_failure: isSet(object.other_failure) + ? String(object.other_failure) : "", }; }, toJSON(message: PunchHoleResponse): unknown { const obj: any = {}; - message.socketAddr !== undefined && - (obj.socketAddr = base64FromBytes( - message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + message.socket_addr !== undefined && + (obj.socket_addr = base64FromBytes( + message.socket_addr !== undefined + ? message.socket_addr + : new Uint8Array() )); message.pk !== undefined && (obj.pk = base64FromBytes( @@ -1101,16 +1116,16 @@ export const PunchHoleResponse = { )); message.failure !== undefined && (obj.failure = punchHoleResponse_FailureToJSON(message.failure)); - message.relayServer !== undefined && - (obj.relayServer = message.relayServer); - message.natType !== undefined && - (obj.natType = - message.natType !== undefined - ? natTypeToJSON(message.natType) + message.relay_server !== undefined && + (obj.relay_server = message.relay_server); + message.nat_type !== undefined && + (obj.nat_type = + message.nat_type !== undefined + ? natTypeToJSON(message.nat_type) : undefined); - message.isLocal !== undefined && (obj.isLocal = message.isLocal); - message.otherFailure !== undefined && - (obj.otherFailure = message.otherFailure); + message.is_local !== undefined && (obj.is_local = message.is_local); + message.other_failure !== undefined && + (obj.other_failure = message.other_failure); return obj; }, @@ -1118,19 +1133,19 @@ export const PunchHoleResponse = { object: I ): PunchHoleResponse { const message = createBasePunchHoleResponse(); - message.socketAddr = object.socketAddr ?? new Uint8Array(); + message.socket_addr = object.socket_addr ?? new Uint8Array(); message.pk = object.pk ?? new Uint8Array(); message.failure = object.failure ?? 0; - message.relayServer = object.relayServer ?? ""; - message.natType = object.natType ?? undefined; - message.isLocal = object.isLocal ?? undefined; - message.otherFailure = object.otherFailure ?? ""; + message.relay_server = object.relay_server ?? ""; + message.nat_type = object.nat_type ?? undefined; + message.is_local = object.is_local ?? undefined; + message.other_failure = object.other_failure ?? ""; return message; }, }; function createBaseConfigUpdate(): ConfigUpdate { - return { serial: 0, rendezvousServers: [] }; + return { serial: 0, rendezvous_servers: [] }; } export const ConfigUpdate = { @@ -1141,7 +1156,7 @@ export const ConfigUpdate = { if (message.serial !== 0) { writer.uint32(8).int32(message.serial); } - for (const v of message.rendezvousServers) { + for (const v of message.rendezvous_servers) { writer.uint32(18).string(v!); } return writer; @@ -1158,7 +1173,7 @@ export const ConfigUpdate = { message.serial = reader.int32(); break; case 2: - message.rendezvousServers.push(reader.string()); + message.rendezvous_servers.push(reader.string()); break; default: reader.skipType(tag & 7); @@ -1171,8 +1186,8 @@ export const ConfigUpdate = { fromJSON(object: any): ConfigUpdate { return { serial: isSet(object.serial) ? Number(object.serial) : 0, - rendezvousServers: Array.isArray(object?.rendezvousServers) - ? object.rendezvousServers.map((e: any) => String(e)) + rendezvous_servers: Array.isArray(object?.rendezvous_servers) + ? object.rendezvous_servers.map((e: any) => String(e)) : [], }; }, @@ -1180,10 +1195,10 @@ export const ConfigUpdate = { toJSON(message: ConfigUpdate): unknown { const obj: any = {}; message.serial !== undefined && (obj.serial = Math.round(message.serial)); - if (message.rendezvousServers) { - obj.rendezvousServers = message.rendezvousServers.map((e) => e); + if (message.rendezvous_servers) { + obj.rendezvous_servers = message.rendezvous_servers.map((e) => e); } else { - obj.rendezvousServers = []; + obj.rendezvous_servers = []; } return obj; }, @@ -1193,7 +1208,7 @@ export const ConfigUpdate = { ): ConfigUpdate { const message = createBaseConfigUpdate(); message.serial = object.serial ?? 0; - message.rendezvousServers = object.rendezvousServers?.map((e) => e) || []; + message.rendezvous_servers = object.rendezvous_servers?.map((e) => e) || []; return message; }, }; @@ -1202,11 +1217,11 @@ function createBaseRequestRelay(): RequestRelay { return { id: "", uuid: "", - socketAddr: new Uint8Array(), - relayServer: "", + socket_addr: new Uint8Array(), + relay_server: "", secure: false, - licenceKey: "", - connType: 0, + licence_key: "", + conn_type: 0, }; } @@ -1221,20 +1236,20 @@ export const RequestRelay = { if (message.uuid !== "") { writer.uint32(18).string(message.uuid); } - if (message.socketAddr.length !== 0) { - writer.uint32(26).bytes(message.socketAddr); + if (message.socket_addr.length !== 0) { + writer.uint32(26).bytes(message.socket_addr); } - if (message.relayServer !== "") { - writer.uint32(34).string(message.relayServer); + if (message.relay_server !== "") { + writer.uint32(34).string(message.relay_server); } if (message.secure === true) { writer.uint32(40).bool(message.secure); } - if (message.licenceKey !== "") { - writer.uint32(50).string(message.licenceKey); + if (message.licence_key !== "") { + writer.uint32(50).string(message.licence_key); } - if (message.connType !== 0) { - writer.uint32(56).int32(message.connType); + if (message.conn_type !== 0) { + writer.uint32(56).int32(message.conn_type); } return writer; }, @@ -1253,19 +1268,19 @@ export const RequestRelay = { message.uuid = reader.string(); break; case 3: - message.socketAddr = reader.bytes(); + message.socket_addr = reader.bytes(); break; case 4: - message.relayServer = reader.string(); + message.relay_server = reader.string(); break; case 5: message.secure = reader.bool(); break; case 6: - message.licenceKey = reader.string(); + message.licence_key = reader.string(); break; case 7: - message.connType = reader.int32() as any; + message.conn_type = reader.int32() as any; break; default: reader.skipType(tag & 7); @@ -1279,13 +1294,17 @@ export const RequestRelay = { return { id: isSet(object.id) ? String(object.id) : "", uuid: isSet(object.uuid) ? String(object.uuid) : "", - socketAddr: isSet(object.socketAddr) - ? bytesFromBase64(object.socketAddr) + socket_addr: isSet(object.socket_addr) + ? bytesFromBase64(object.socket_addr) : new Uint8Array(), - relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + relay_server: isSet(object.relay_server) + ? String(object.relay_server) + : "", secure: isSet(object.secure) ? Boolean(object.secure) : false, - licenceKey: isSet(object.licenceKey) ? String(object.licenceKey) : "", - connType: isSet(object.connType) ? connTypeFromJSON(object.connType) : 0, + licence_key: isSet(object.licence_key) ? String(object.licence_key) : "", + conn_type: isSet(object.conn_type) + ? connTypeFromJSON(object.conn_type) + : 0, }; }, @@ -1293,16 +1312,19 @@ export const RequestRelay = { const obj: any = {}; message.id !== undefined && (obj.id = message.id); message.uuid !== undefined && (obj.uuid = message.uuid); - message.socketAddr !== undefined && - (obj.socketAddr = base64FromBytes( - message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + message.socket_addr !== undefined && + (obj.socket_addr = base64FromBytes( + message.socket_addr !== undefined + ? message.socket_addr + : new Uint8Array() )); - message.relayServer !== undefined && - (obj.relayServer = message.relayServer); + message.relay_server !== undefined && + (obj.relay_server = message.relay_server); message.secure !== undefined && (obj.secure = message.secure); - message.licenceKey !== undefined && (obj.licenceKey = message.licenceKey); - message.connType !== undefined && - (obj.connType = connTypeToJSON(message.connType)); + message.licence_key !== undefined && + (obj.licence_key = message.licence_key); + message.conn_type !== undefined && + (obj.conn_type = connTypeToJSON(message.conn_type)); return obj; }, @@ -1312,23 +1334,23 @@ export const RequestRelay = { const message = createBaseRequestRelay(); message.id = object.id ?? ""; message.uuid = object.uuid ?? ""; - message.socketAddr = object.socketAddr ?? new Uint8Array(); - message.relayServer = object.relayServer ?? ""; + message.socket_addr = object.socket_addr ?? new Uint8Array(); + message.relay_server = object.relay_server ?? ""; message.secure = object.secure ?? false; - message.licenceKey = object.licenceKey ?? ""; - message.connType = object.connType ?? 0; + message.licence_key = object.licence_key ?? ""; + message.conn_type = object.conn_type ?? 0; return message; }, }; function createBaseRelayResponse(): RelayResponse { return { - socketAddr: new Uint8Array(), + socket_addr: new Uint8Array(), uuid: "", - relayServer: "", + relay_server: "", id: undefined, pk: undefined, - refuseReason: "", + refuse_reason: "", version: "", }; } @@ -1338,14 +1360,14 @@ export const RelayResponse = { message: RelayResponse, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.socketAddr.length !== 0) { - writer.uint32(10).bytes(message.socketAddr); + if (message.socket_addr.length !== 0) { + writer.uint32(10).bytes(message.socket_addr); } if (message.uuid !== "") { writer.uint32(18).string(message.uuid); } - if (message.relayServer !== "") { - writer.uint32(26).string(message.relayServer); + if (message.relay_server !== "") { + writer.uint32(26).string(message.relay_server); } if (message.id !== undefined) { writer.uint32(34).string(message.id); @@ -1353,8 +1375,8 @@ export const RelayResponse = { if (message.pk !== undefined) { writer.uint32(42).bytes(message.pk); } - if (message.refuseReason !== "") { - writer.uint32(50).string(message.refuseReason); + if (message.refuse_reason !== "") { + writer.uint32(50).string(message.refuse_reason); } if (message.version !== "") { writer.uint32(58).string(message.version); @@ -1370,13 +1392,13 @@ export const RelayResponse = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.socketAddr = reader.bytes(); + message.socket_addr = reader.bytes(); break; case 2: message.uuid = reader.string(); break; case 3: - message.relayServer = reader.string(); + message.relay_server = reader.string(); break; case 4: message.id = reader.string(); @@ -1385,7 +1407,7 @@ export const RelayResponse = { message.pk = reader.bytes(); break; case 6: - message.refuseReason = reader.string(); + message.refuse_reason = reader.string(); break; case 7: message.version = reader.string(); @@ -1400,15 +1422,17 @@ export const RelayResponse = { fromJSON(object: any): RelayResponse { return { - socketAddr: isSet(object.socketAddr) - ? bytesFromBase64(object.socketAddr) + socket_addr: isSet(object.socket_addr) + ? bytesFromBase64(object.socket_addr) : new Uint8Array(), uuid: isSet(object.uuid) ? String(object.uuid) : "", - relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + relay_server: isSet(object.relay_server) + ? String(object.relay_server) + : "", id: isSet(object.id) ? String(object.id) : undefined, pk: isSet(object.pk) ? bytesFromBase64(object.pk) : undefined, - refuseReason: isSet(object.refuseReason) - ? String(object.refuseReason) + refuse_reason: isSet(object.refuse_reason) + ? String(object.refuse_reason) : "", version: isSet(object.version) ? String(object.version) : "", }; @@ -1416,19 +1440,21 @@ export const RelayResponse = { toJSON(message: RelayResponse): unknown { const obj: any = {}; - message.socketAddr !== undefined && - (obj.socketAddr = base64FromBytes( - message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + message.socket_addr !== undefined && + (obj.socket_addr = base64FromBytes( + message.socket_addr !== undefined + ? message.socket_addr + : new Uint8Array() )); message.uuid !== undefined && (obj.uuid = message.uuid); - message.relayServer !== undefined && - (obj.relayServer = message.relayServer); + message.relay_server !== undefined && + (obj.relay_server = message.relay_server); message.id !== undefined && (obj.id = message.id); message.pk !== undefined && (obj.pk = message.pk !== undefined ? base64FromBytes(message.pk) : undefined); - message.refuseReason !== undefined && - (obj.refuseReason = message.refuseReason); + message.refuse_reason !== undefined && + (obj.refuse_reason = message.refuse_reason); message.version !== undefined && (obj.version = message.version); return obj; }, @@ -1437,12 +1463,12 @@ export const RelayResponse = { object: I ): RelayResponse { const message = createBaseRelayResponse(); - message.socketAddr = object.socketAddr ?? new Uint8Array(); + message.socket_addr = object.socket_addr ?? new Uint8Array(); message.uuid = object.uuid ?? ""; - message.relayServer = object.relayServer ?? ""; + message.relay_server = object.relay_server ?? ""; message.id = object.id ?? undefined; message.pk = object.pk ?? undefined; - message.refuseReason = object.refuseReason ?? ""; + message.refuse_reason = object.refuse_reason ?? ""; message.version = object.version ?? ""; return message; }, @@ -1503,7 +1529,7 @@ export const SoftwareUpdate = { }; function createBaseFetchLocalAddr(): FetchLocalAddr { - return { socketAddr: new Uint8Array(), relayServer: "" }; + return { socket_addr: new Uint8Array(), relay_server: "" }; } export const FetchLocalAddr = { @@ -1511,11 +1537,11 @@ export const FetchLocalAddr = { message: FetchLocalAddr, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.socketAddr.length !== 0) { - writer.uint32(10).bytes(message.socketAddr); + if (message.socket_addr.length !== 0) { + writer.uint32(10).bytes(message.socket_addr); } - if (message.relayServer !== "") { - writer.uint32(18).string(message.relayServer); + if (message.relay_server !== "") { + writer.uint32(18).string(message.relay_server); } return writer; }, @@ -1528,10 +1554,10 @@ export const FetchLocalAddr = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.socketAddr = reader.bytes(); + message.socket_addr = reader.bytes(); break; case 2: - message.relayServer = reader.string(); + message.relay_server = reader.string(); break; default: reader.skipType(tag & 7); @@ -1543,21 +1569,25 @@ export const FetchLocalAddr = { fromJSON(object: any): FetchLocalAddr { return { - socketAddr: isSet(object.socketAddr) - ? bytesFromBase64(object.socketAddr) + socket_addr: isSet(object.socket_addr) + ? bytesFromBase64(object.socket_addr) : new Uint8Array(), - relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + relay_server: isSet(object.relay_server) + ? String(object.relay_server) + : "", }; }, toJSON(message: FetchLocalAddr): unknown { const obj: any = {}; - message.socketAddr !== undefined && - (obj.socketAddr = base64FromBytes( - message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + message.socket_addr !== undefined && + (obj.socket_addr = base64FromBytes( + message.socket_addr !== undefined + ? message.socket_addr + : new Uint8Array() )); - message.relayServer !== undefined && - (obj.relayServer = message.relayServer); + message.relay_server !== undefined && + (obj.relay_server = message.relay_server); return obj; }, @@ -1565,17 +1595,17 @@ export const FetchLocalAddr = { object: I ): FetchLocalAddr { const message = createBaseFetchLocalAddr(); - message.socketAddr = object.socketAddr ?? new Uint8Array(); - message.relayServer = object.relayServer ?? ""; + message.socket_addr = object.socket_addr ?? new Uint8Array(); + message.relay_server = object.relay_server ?? ""; return message; }, }; function createBaseLocalAddr(): LocalAddr { return { - socketAddr: new Uint8Array(), - localAddr: new Uint8Array(), - relayServer: "", + socket_addr: new Uint8Array(), + local_addr: new Uint8Array(), + relay_server: "", id: "", version: "", }; @@ -1586,14 +1616,14 @@ export const LocalAddr = { message: LocalAddr, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.socketAddr.length !== 0) { - writer.uint32(10).bytes(message.socketAddr); + if (message.socket_addr.length !== 0) { + writer.uint32(10).bytes(message.socket_addr); } - if (message.localAddr.length !== 0) { - writer.uint32(18).bytes(message.localAddr); + if (message.local_addr.length !== 0) { + writer.uint32(18).bytes(message.local_addr); } - if (message.relayServer !== "") { - writer.uint32(26).string(message.relayServer); + if (message.relay_server !== "") { + writer.uint32(26).string(message.relay_server); } if (message.id !== "") { writer.uint32(34).string(message.id); @@ -1612,13 +1642,13 @@ export const LocalAddr = { const tag = reader.uint32(); switch (tag >>> 3) { case 1: - message.socketAddr = reader.bytes(); + message.socket_addr = reader.bytes(); break; case 2: - message.localAddr = reader.bytes(); + message.local_addr = reader.bytes(); break; case 3: - message.relayServer = reader.string(); + message.relay_server = reader.string(); break; case 4: message.id = reader.string(); @@ -1636,13 +1666,15 @@ export const LocalAddr = { fromJSON(object: any): LocalAddr { return { - socketAddr: isSet(object.socketAddr) - ? bytesFromBase64(object.socketAddr) + socket_addr: isSet(object.socket_addr) + ? bytesFromBase64(object.socket_addr) : new Uint8Array(), - localAddr: isSet(object.localAddr) - ? bytesFromBase64(object.localAddr) + local_addr: isSet(object.local_addr) + ? bytesFromBase64(object.local_addr) : new Uint8Array(), - relayServer: isSet(object.relayServer) ? String(object.relayServer) : "", + relay_server: isSet(object.relay_server) + ? String(object.relay_server) + : "", id: isSet(object.id) ? String(object.id) : "", version: isSet(object.version) ? String(object.version) : "", }; @@ -1650,16 +1682,18 @@ export const LocalAddr = { toJSON(message: LocalAddr): unknown { const obj: any = {}; - message.socketAddr !== undefined && - (obj.socketAddr = base64FromBytes( - message.socketAddr !== undefined ? message.socketAddr : new Uint8Array() + message.socket_addr !== undefined && + (obj.socket_addr = base64FromBytes( + message.socket_addr !== undefined + ? message.socket_addr + : new Uint8Array() )); - message.localAddr !== undefined && - (obj.localAddr = base64FromBytes( - message.localAddr !== undefined ? message.localAddr : new Uint8Array() + message.local_addr !== undefined && + (obj.local_addr = base64FromBytes( + message.local_addr !== undefined ? message.local_addr : new Uint8Array() )); - message.relayServer !== undefined && - (obj.relayServer = message.relayServer); + message.relay_server !== undefined && + (obj.relay_server = message.relay_server); message.id !== undefined && (obj.id = message.id); message.version !== undefined && (obj.version = message.version); return obj; @@ -1669,9 +1703,9 @@ export const LocalAddr = { object: I ): LocalAddr { const message = createBaseLocalAddr(); - message.socketAddr = object.socketAddr ?? new Uint8Array(); - message.localAddr = object.localAddr ?? new Uint8Array(); - message.relayServer = object.relayServer ?? ""; + message.socket_addr = object.socket_addr ?? new Uint8Array(); + message.local_addr = object.local_addr ?? new Uint8Array(); + message.relay_server = object.relay_server ?? ""; message.id = object.id ?? ""; message.version = object.version ?? ""; return message; @@ -1796,23 +1830,23 @@ export const PeerDiscovery = { function createBaseRendezvousMessage(): RendezvousMessage { return { - registerPeer: undefined, - registerPeerResponse: undefined, - punchHoleRequest: undefined, - punchHole: undefined, - punchHoleSent: undefined, - punchHoleResponse: undefined, - fetchLocalAddr: undefined, - localAddr: undefined, - configureUpdate: undefined, - registerPk: undefined, - registerPkResponse: undefined, - softwareUpdate: undefined, - requestRelay: undefined, - relayResponse: undefined, - testNatRequest: undefined, - testNatResponse: undefined, - peerDiscovery: undefined, + register_peer: undefined, + register_peer_response: undefined, + punch_hole_request: undefined, + punch_hole: undefined, + punch_hole_sent: undefined, + punch_hole_response: undefined, + fetch_local_addr: undefined, + local_addr: undefined, + configure_update: undefined, + register_pk: undefined, + register_pk_response: undefined, + software_update: undefined, + request_relay: undefined, + relay_response: undefined, + test_nat_request: undefined, + test_nat_response: undefined, + peer_discovery: undefined, }; } @@ -1821,96 +1855,99 @@ export const RendezvousMessage = { message: RendezvousMessage, writer: _m0.Writer = _m0.Writer.create() ): _m0.Writer { - if (message.registerPeer !== undefined) { + if (message.register_peer !== undefined) { RegisterPeer.encode( - message.registerPeer, + message.register_peer, writer.uint32(50).fork() ).ldelim(); } - if (message.registerPeerResponse !== undefined) { + if (message.register_peer_response !== undefined) { RegisterPeerResponse.encode( - message.registerPeerResponse, + message.register_peer_response, writer.uint32(58).fork() ).ldelim(); } - if (message.punchHoleRequest !== undefined) { + if (message.punch_hole_request !== undefined) { PunchHoleRequest.encode( - message.punchHoleRequest, + message.punch_hole_request, writer.uint32(66).fork() ).ldelim(); } - if (message.punchHole !== undefined) { - PunchHole.encode(message.punchHole, writer.uint32(74).fork()).ldelim(); + if (message.punch_hole !== undefined) { + PunchHole.encode(message.punch_hole, writer.uint32(74).fork()).ldelim(); } - if (message.punchHoleSent !== undefined) { + if (message.punch_hole_sent !== undefined) { PunchHoleSent.encode( - message.punchHoleSent, + message.punch_hole_sent, writer.uint32(82).fork() ).ldelim(); } - if (message.punchHoleResponse !== undefined) { + if (message.punch_hole_response !== undefined) { PunchHoleResponse.encode( - message.punchHoleResponse, + message.punch_hole_response, writer.uint32(90).fork() ).ldelim(); } - if (message.fetchLocalAddr !== undefined) { + if (message.fetch_local_addr !== undefined) { FetchLocalAddr.encode( - message.fetchLocalAddr, + message.fetch_local_addr, writer.uint32(98).fork() ).ldelim(); } - if (message.localAddr !== undefined) { - LocalAddr.encode(message.localAddr, writer.uint32(106).fork()).ldelim(); + if (message.local_addr !== undefined) { + LocalAddr.encode(message.local_addr, writer.uint32(106).fork()).ldelim(); } - if (message.configureUpdate !== undefined) { + if (message.configure_update !== undefined) { ConfigUpdate.encode( - message.configureUpdate, + message.configure_update, writer.uint32(114).fork() ).ldelim(); } - if (message.registerPk !== undefined) { - RegisterPk.encode(message.registerPk, writer.uint32(122).fork()).ldelim(); + if (message.register_pk !== undefined) { + RegisterPk.encode( + message.register_pk, + writer.uint32(122).fork() + ).ldelim(); } - if (message.registerPkResponse !== undefined) { + if (message.register_pk_response !== undefined) { RegisterPkResponse.encode( - message.registerPkResponse, + message.register_pk_response, writer.uint32(130).fork() ).ldelim(); } - if (message.softwareUpdate !== undefined) { + if (message.software_update !== undefined) { SoftwareUpdate.encode( - message.softwareUpdate, + message.software_update, writer.uint32(138).fork() ).ldelim(); } - if (message.requestRelay !== undefined) { + if (message.request_relay !== undefined) { RequestRelay.encode( - message.requestRelay, + message.request_relay, writer.uint32(146).fork() ).ldelim(); } - if (message.relayResponse !== undefined) { + if (message.relay_response !== undefined) { RelayResponse.encode( - message.relayResponse, + message.relay_response, writer.uint32(154).fork() ).ldelim(); } - if (message.testNatRequest !== undefined) { + if (message.test_nat_request !== undefined) { TestNatRequest.encode( - message.testNatRequest, + message.test_nat_request, writer.uint32(162).fork() ).ldelim(); } - if (message.testNatResponse !== undefined) { + if (message.test_nat_response !== undefined) { TestNatResponse.encode( - message.testNatResponse, + message.test_nat_response, writer.uint32(170).fork() ).ldelim(); } - if (message.peerDiscovery !== undefined) { + if (message.peer_discovery !== undefined) { PeerDiscovery.encode( - message.peerDiscovery, + message.peer_discovery, writer.uint32(178).fork() ).ldelim(); } @@ -1925,82 +1962,91 @@ export const RendezvousMessage = { const tag = reader.uint32(); switch (tag >>> 3) { case 6: - message.registerPeer = RegisterPeer.decode(reader, reader.uint32()); + message.register_peer = RegisterPeer.decode(reader, reader.uint32()); break; case 7: - message.registerPeerResponse = RegisterPeerResponse.decode( + message.register_peer_response = RegisterPeerResponse.decode( reader, reader.uint32() ); break; case 8: - message.punchHoleRequest = PunchHoleRequest.decode( + message.punch_hole_request = PunchHoleRequest.decode( reader, reader.uint32() ); break; case 9: - message.punchHole = PunchHole.decode(reader, reader.uint32()); + message.punch_hole = PunchHole.decode(reader, reader.uint32()); break; case 10: - message.punchHoleSent = PunchHoleSent.decode(reader, reader.uint32()); + message.punch_hole_sent = PunchHoleSent.decode( + reader, + reader.uint32() + ); break; case 11: - message.punchHoleResponse = PunchHoleResponse.decode( + message.punch_hole_response = PunchHoleResponse.decode( reader, reader.uint32() ); break; case 12: - message.fetchLocalAddr = FetchLocalAddr.decode( + message.fetch_local_addr = FetchLocalAddr.decode( reader, reader.uint32() ); break; case 13: - message.localAddr = LocalAddr.decode(reader, reader.uint32()); + message.local_addr = LocalAddr.decode(reader, reader.uint32()); break; case 14: - message.configureUpdate = ConfigUpdate.decode( + message.configure_update = ConfigUpdate.decode( reader, reader.uint32() ); break; case 15: - message.registerPk = RegisterPk.decode(reader, reader.uint32()); + message.register_pk = RegisterPk.decode(reader, reader.uint32()); break; case 16: - message.registerPkResponse = RegisterPkResponse.decode( + message.register_pk_response = RegisterPkResponse.decode( reader, reader.uint32() ); break; case 17: - message.softwareUpdate = SoftwareUpdate.decode( + message.software_update = SoftwareUpdate.decode( reader, reader.uint32() ); break; case 18: - message.requestRelay = RequestRelay.decode(reader, reader.uint32()); + message.request_relay = RequestRelay.decode(reader, reader.uint32()); break; case 19: - message.relayResponse = RelayResponse.decode(reader, reader.uint32()); + message.relay_response = RelayResponse.decode( + reader, + reader.uint32() + ); break; case 20: - message.testNatRequest = TestNatRequest.decode( + message.test_nat_request = TestNatRequest.decode( reader, reader.uint32() ); break; case 21: - message.testNatResponse = TestNatResponse.decode( + message.test_nat_response = TestNatResponse.decode( reader, reader.uint32() ); break; case 22: - message.peerDiscovery = PeerDiscovery.decode(reader, reader.uint32()); + message.peer_discovery = PeerDiscovery.decode( + reader, + reader.uint32() + ); break; default: reader.skipType(tag & 7); @@ -2012,129 +2058,129 @@ export const RendezvousMessage = { fromJSON(object: any): RendezvousMessage { return { - registerPeer: isSet(object.registerPeer) - ? RegisterPeer.fromJSON(object.registerPeer) + register_peer: isSet(object.register_peer) + ? RegisterPeer.fromJSON(object.register_peer) : undefined, - registerPeerResponse: isSet(object.registerPeerResponse) - ? RegisterPeerResponse.fromJSON(object.registerPeerResponse) + register_peer_response: isSet(object.register_peer_response) + ? RegisterPeerResponse.fromJSON(object.register_peer_response) : undefined, - punchHoleRequest: isSet(object.punchHoleRequest) - ? PunchHoleRequest.fromJSON(object.punchHoleRequest) + punch_hole_request: isSet(object.punch_hole_request) + ? PunchHoleRequest.fromJSON(object.punch_hole_request) : undefined, - punchHole: isSet(object.punchHole) - ? PunchHole.fromJSON(object.punchHole) + punch_hole: isSet(object.punch_hole) + ? PunchHole.fromJSON(object.punch_hole) : undefined, - punchHoleSent: isSet(object.punchHoleSent) - ? PunchHoleSent.fromJSON(object.punchHoleSent) + punch_hole_sent: isSet(object.punch_hole_sent) + ? PunchHoleSent.fromJSON(object.punch_hole_sent) : undefined, - punchHoleResponse: isSet(object.punchHoleResponse) - ? PunchHoleResponse.fromJSON(object.punchHoleResponse) + punch_hole_response: isSet(object.punch_hole_response) + ? PunchHoleResponse.fromJSON(object.punch_hole_response) : undefined, - fetchLocalAddr: isSet(object.fetchLocalAddr) - ? FetchLocalAddr.fromJSON(object.fetchLocalAddr) + fetch_local_addr: isSet(object.fetch_local_addr) + ? FetchLocalAddr.fromJSON(object.fetch_local_addr) : undefined, - localAddr: isSet(object.localAddr) - ? LocalAddr.fromJSON(object.localAddr) + local_addr: isSet(object.local_addr) + ? LocalAddr.fromJSON(object.local_addr) : undefined, - configureUpdate: isSet(object.configureUpdate) - ? ConfigUpdate.fromJSON(object.configureUpdate) + configure_update: isSet(object.configure_update) + ? ConfigUpdate.fromJSON(object.configure_update) : undefined, - registerPk: isSet(object.registerPk) - ? RegisterPk.fromJSON(object.registerPk) + register_pk: isSet(object.register_pk) + ? RegisterPk.fromJSON(object.register_pk) : undefined, - registerPkResponse: isSet(object.registerPkResponse) - ? RegisterPkResponse.fromJSON(object.registerPkResponse) + register_pk_response: isSet(object.register_pk_response) + ? RegisterPkResponse.fromJSON(object.register_pk_response) : undefined, - softwareUpdate: isSet(object.softwareUpdate) - ? SoftwareUpdate.fromJSON(object.softwareUpdate) + software_update: isSet(object.software_update) + ? SoftwareUpdate.fromJSON(object.software_update) : undefined, - requestRelay: isSet(object.requestRelay) - ? RequestRelay.fromJSON(object.requestRelay) + request_relay: isSet(object.request_relay) + ? RequestRelay.fromJSON(object.request_relay) : undefined, - relayResponse: isSet(object.relayResponse) - ? RelayResponse.fromJSON(object.relayResponse) + relay_response: isSet(object.relay_response) + ? RelayResponse.fromJSON(object.relay_response) : undefined, - testNatRequest: isSet(object.testNatRequest) - ? TestNatRequest.fromJSON(object.testNatRequest) + test_nat_request: isSet(object.test_nat_request) + ? TestNatRequest.fromJSON(object.test_nat_request) : undefined, - testNatResponse: isSet(object.testNatResponse) - ? TestNatResponse.fromJSON(object.testNatResponse) + test_nat_response: isSet(object.test_nat_response) + ? TestNatResponse.fromJSON(object.test_nat_response) : undefined, - peerDiscovery: isSet(object.peerDiscovery) - ? PeerDiscovery.fromJSON(object.peerDiscovery) + peer_discovery: isSet(object.peer_discovery) + ? PeerDiscovery.fromJSON(object.peer_discovery) : undefined, }; }, toJSON(message: RendezvousMessage): unknown { const obj: any = {}; - message.registerPeer !== undefined && - (obj.registerPeer = message.registerPeer - ? RegisterPeer.toJSON(message.registerPeer) + message.register_peer !== undefined && + (obj.register_peer = message.register_peer + ? RegisterPeer.toJSON(message.register_peer) : undefined); - message.registerPeerResponse !== undefined && - (obj.registerPeerResponse = message.registerPeerResponse - ? RegisterPeerResponse.toJSON(message.registerPeerResponse) + message.register_peer_response !== undefined && + (obj.register_peer_response = message.register_peer_response + ? RegisterPeerResponse.toJSON(message.register_peer_response) : undefined); - message.punchHoleRequest !== undefined && - (obj.punchHoleRequest = message.punchHoleRequest - ? PunchHoleRequest.toJSON(message.punchHoleRequest) + message.punch_hole_request !== undefined && + (obj.punch_hole_request = message.punch_hole_request + ? PunchHoleRequest.toJSON(message.punch_hole_request) : undefined); - message.punchHole !== undefined && - (obj.punchHole = message.punchHole - ? PunchHole.toJSON(message.punchHole) + message.punch_hole !== undefined && + (obj.punch_hole = message.punch_hole + ? PunchHole.toJSON(message.punch_hole) : undefined); - message.punchHoleSent !== undefined && - (obj.punchHoleSent = message.punchHoleSent - ? PunchHoleSent.toJSON(message.punchHoleSent) + message.punch_hole_sent !== undefined && + (obj.punch_hole_sent = message.punch_hole_sent + ? PunchHoleSent.toJSON(message.punch_hole_sent) : undefined); - message.punchHoleResponse !== undefined && - (obj.punchHoleResponse = message.punchHoleResponse - ? PunchHoleResponse.toJSON(message.punchHoleResponse) + message.punch_hole_response !== undefined && + (obj.punch_hole_response = message.punch_hole_response + ? PunchHoleResponse.toJSON(message.punch_hole_response) : undefined); - message.fetchLocalAddr !== undefined && - (obj.fetchLocalAddr = message.fetchLocalAddr - ? FetchLocalAddr.toJSON(message.fetchLocalAddr) + message.fetch_local_addr !== undefined && + (obj.fetch_local_addr = message.fetch_local_addr + ? FetchLocalAddr.toJSON(message.fetch_local_addr) : undefined); - message.localAddr !== undefined && - (obj.localAddr = message.localAddr - ? LocalAddr.toJSON(message.localAddr) + message.local_addr !== undefined && + (obj.local_addr = message.local_addr + ? LocalAddr.toJSON(message.local_addr) : undefined); - message.configureUpdate !== undefined && - (obj.configureUpdate = message.configureUpdate - ? ConfigUpdate.toJSON(message.configureUpdate) + message.configure_update !== undefined && + (obj.configure_update = message.configure_update + ? ConfigUpdate.toJSON(message.configure_update) : undefined); - message.registerPk !== undefined && - (obj.registerPk = message.registerPk - ? RegisterPk.toJSON(message.registerPk) + message.register_pk !== undefined && + (obj.register_pk = message.register_pk + ? RegisterPk.toJSON(message.register_pk) : undefined); - message.registerPkResponse !== undefined && - (obj.registerPkResponse = message.registerPkResponse - ? RegisterPkResponse.toJSON(message.registerPkResponse) + message.register_pk_response !== undefined && + (obj.register_pk_response = message.register_pk_response + ? RegisterPkResponse.toJSON(message.register_pk_response) : undefined); - message.softwareUpdate !== undefined && - (obj.softwareUpdate = message.softwareUpdate - ? SoftwareUpdate.toJSON(message.softwareUpdate) + message.software_update !== undefined && + (obj.software_update = message.software_update + ? SoftwareUpdate.toJSON(message.software_update) : undefined); - message.requestRelay !== undefined && - (obj.requestRelay = message.requestRelay - ? RequestRelay.toJSON(message.requestRelay) + message.request_relay !== undefined && + (obj.request_relay = message.request_relay + ? RequestRelay.toJSON(message.request_relay) : undefined); - message.relayResponse !== undefined && - (obj.relayResponse = message.relayResponse - ? RelayResponse.toJSON(message.relayResponse) + message.relay_response !== undefined && + (obj.relay_response = message.relay_response + ? RelayResponse.toJSON(message.relay_response) : undefined); - message.testNatRequest !== undefined && - (obj.testNatRequest = message.testNatRequest - ? TestNatRequest.toJSON(message.testNatRequest) + message.test_nat_request !== undefined && + (obj.test_nat_request = message.test_nat_request + ? TestNatRequest.toJSON(message.test_nat_request) : undefined); - message.testNatResponse !== undefined && - (obj.testNatResponse = message.testNatResponse - ? TestNatResponse.toJSON(message.testNatResponse) + message.test_nat_response !== undefined && + (obj.test_nat_response = message.test_nat_response + ? TestNatResponse.toJSON(message.test_nat_response) : undefined); - message.peerDiscovery !== undefined && - (obj.peerDiscovery = message.peerDiscovery - ? PeerDiscovery.toJSON(message.peerDiscovery) + message.peer_discovery !== undefined && + (obj.peer_discovery = message.peer_discovery + ? PeerDiscovery.toJSON(message.peer_discovery) : undefined); return obj; }, @@ -2143,76 +2189,78 @@ export const RendezvousMessage = { object: I ): RendezvousMessage { const message = createBaseRendezvousMessage(); - message.registerPeer = - object.registerPeer !== undefined && object.registerPeer !== null - ? RegisterPeer.fromPartial(object.registerPeer) + message.register_peer = + object.register_peer !== undefined && object.register_peer !== null + ? RegisterPeer.fromPartial(object.register_peer) : undefined; - message.registerPeerResponse = - object.registerPeerResponse !== undefined && - object.registerPeerResponse !== null - ? RegisterPeerResponse.fromPartial(object.registerPeerResponse) + message.register_peer_response = + object.register_peer_response !== undefined && + object.register_peer_response !== null + ? RegisterPeerResponse.fromPartial(object.register_peer_response) : undefined; - message.punchHoleRequest = - object.punchHoleRequest !== undefined && object.punchHoleRequest !== null - ? PunchHoleRequest.fromPartial(object.punchHoleRequest) + message.punch_hole_request = + object.punch_hole_request !== undefined && + object.punch_hole_request !== null + ? PunchHoleRequest.fromPartial(object.punch_hole_request) : undefined; - message.punchHole = - object.punchHole !== undefined && object.punchHole !== null - ? PunchHole.fromPartial(object.punchHole) + message.punch_hole = + object.punch_hole !== undefined && object.punch_hole !== null + ? PunchHole.fromPartial(object.punch_hole) : undefined; - message.punchHoleSent = - object.punchHoleSent !== undefined && object.punchHoleSent !== null - ? PunchHoleSent.fromPartial(object.punchHoleSent) + message.punch_hole_sent = + object.punch_hole_sent !== undefined && object.punch_hole_sent !== null + ? PunchHoleSent.fromPartial(object.punch_hole_sent) : undefined; - message.punchHoleResponse = - object.punchHoleResponse !== undefined && - object.punchHoleResponse !== null - ? PunchHoleResponse.fromPartial(object.punchHoleResponse) + message.punch_hole_response = + object.punch_hole_response !== undefined && + object.punch_hole_response !== null + ? PunchHoleResponse.fromPartial(object.punch_hole_response) : undefined; - message.fetchLocalAddr = - object.fetchLocalAddr !== undefined && object.fetchLocalAddr !== null - ? FetchLocalAddr.fromPartial(object.fetchLocalAddr) + message.fetch_local_addr = + object.fetch_local_addr !== undefined && object.fetch_local_addr !== null + ? FetchLocalAddr.fromPartial(object.fetch_local_addr) : undefined; - message.localAddr = - object.localAddr !== undefined && object.localAddr !== null - ? LocalAddr.fromPartial(object.localAddr) + message.local_addr = + object.local_addr !== undefined && object.local_addr !== null + ? LocalAddr.fromPartial(object.local_addr) : undefined; - message.configureUpdate = - object.configureUpdate !== undefined && object.configureUpdate !== null - ? ConfigUpdate.fromPartial(object.configureUpdate) + message.configure_update = + object.configure_update !== undefined && object.configure_update !== null + ? ConfigUpdate.fromPartial(object.configure_update) : undefined; - message.registerPk = - object.registerPk !== undefined && object.registerPk !== null - ? RegisterPk.fromPartial(object.registerPk) + message.register_pk = + object.register_pk !== undefined && object.register_pk !== null + ? RegisterPk.fromPartial(object.register_pk) : undefined; - message.registerPkResponse = - object.registerPkResponse !== undefined && - object.registerPkResponse !== null - ? RegisterPkResponse.fromPartial(object.registerPkResponse) + message.register_pk_response = + object.register_pk_response !== undefined && + object.register_pk_response !== null + ? RegisterPkResponse.fromPartial(object.register_pk_response) : undefined; - message.softwareUpdate = - object.softwareUpdate !== undefined && object.softwareUpdate !== null - ? SoftwareUpdate.fromPartial(object.softwareUpdate) + message.software_update = + object.software_update !== undefined && object.software_update !== null + ? SoftwareUpdate.fromPartial(object.software_update) : undefined; - message.requestRelay = - object.requestRelay !== undefined && object.requestRelay !== null - ? RequestRelay.fromPartial(object.requestRelay) + message.request_relay = + object.request_relay !== undefined && object.request_relay !== null + ? RequestRelay.fromPartial(object.request_relay) : undefined; - message.relayResponse = - object.relayResponse !== undefined && object.relayResponse !== null - ? RelayResponse.fromPartial(object.relayResponse) + message.relay_response = + object.relay_response !== undefined && object.relay_response !== null + ? RelayResponse.fromPartial(object.relay_response) : undefined; - message.testNatRequest = - object.testNatRequest !== undefined && object.testNatRequest !== null - ? TestNatRequest.fromPartial(object.testNatRequest) + message.test_nat_request = + object.test_nat_request !== undefined && object.test_nat_request !== null + ? TestNatRequest.fromPartial(object.test_nat_request) : undefined; - message.testNatResponse = - object.testNatResponse !== undefined && object.testNatResponse !== null - ? TestNatResponse.fromPartial(object.testNatResponse) + message.test_nat_response = + object.test_nat_response !== undefined && + object.test_nat_response !== null + ? TestNatResponse.fromPartial(object.test_nat_response) : undefined; - message.peerDiscovery = - object.peerDiscovery !== undefined && object.peerDiscovery !== null - ? PeerDiscovery.fromPartial(object.peerDiscovery) + message.peer_discovery = + object.peer_discovery !== undefined && object.peer_discovery !== null + ? PeerDiscovery.fromPartial(object.peer_discovery) : undefined; return message; }, diff --git a/src/websock.ts b/src/websock.ts index 6fc66ee17..6b05827de 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -37,7 +37,7 @@ export default class Websock { this._secretKey = [key, 0, 0]; } - sendMessage(json: any) { + sendMessage(json: message.DeepPartial) { let data = message.Message.encode( message.Message.fromPartial(json) ).finish(); @@ -49,7 +49,7 @@ export default class Websock { this._websocket.send(data); } - sendRendezvous(data: any) { + sendRendezvous(data: rendezvous.DeepPartial) { this._websocket.send( rendezvous.RendezvousMessage.encode( rendezvous.RendezvousMessage.fromPartial(data) @@ -96,7 +96,7 @@ export default class Websock { resolve(this); }; this._websocket.onclose = (e) => { - if (this._status == 'open') { + if (this._status == "open") { reject(e); } this._status = e; @@ -105,7 +105,7 @@ export default class Websock { }; this._websocket.onerror = (e) => { if (!this._status) { - reject('Failed to connect to ' + this._uri); + reject("Failed to connect to " + this._uri); return; } this._status = e; @@ -143,7 +143,7 @@ export default class Websock { } close() { - this._status = ''; + this._status = ""; if (this._websocket) { if ( this._websocket.readyState === WebSocket.OPEN || diff --git a/ts_proto.py b/ts_proto.py old mode 100644 new mode 100755 index 5f8932731..f917c6b37 --- a/ts_proto.py +++ b/ts_proto.py @@ -5,16 +5,16 @@ import os path = os.path.abspath(os.path.join(os.getcwd(), '..', 'hbb', 'libs', 'hbb_common', 'protos')) if os.name == 'nt': - cmd = r'protoc --ts_proto_opt=esModuleInterop=true --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd -I "%s" --ts_proto_out=./src/ rendezvous.proto'%path + cmd = r'protoc --ts_proto_opt=esModuleInterop=true --ts_proto_opt=snakeToCamel=false --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd -I "%s" --ts_proto_out=./src/ rendezvous.proto'%path print(cmd) os.system(cmd) - cmd = r'protoc --ts_proto_opt=esModuleInterop=true --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd -I "%s" --ts_proto_out=./src/ message.proto'%path + cmd = r'protoc --ts_proto_opt=esModuleInterop=true --ts_proto_opt=snakeToCamel=false --plugin=protoc-gen-ts_proto=.\node_modules\.bin\protoc-gen-ts_proto.cmd -I "%s" --ts_proto_out=./src/ message.proto'%path print(cmd) os.system(cmd) else: - cmd = r'protoc --ts_proto_opt=esModuleInterop=true --plugin=./node_modules/.bin/protoc-gen-ts_proto -I "%s" --ts_proto_out=./src/ rendezvous.proto'%path + cmd = r'protoc --ts_proto_opt=esModuleInterop=true --ts_proto_opt=snakeToCamel=false --plugin=./node_modules/.bin/protoc-gen-ts_proto -I "%s" --ts_proto_out=./src/ rendezvous.proto'%path print(cmd) os.system(cmd) - cmd = r'protoc --ts_proto_opt=esModuleInterop=true --plugin=./node_modules/.bin/protoc-gen-ts_proto -I "%s" --ts_proto_out=./src/ message.proto'%path + cmd = r'protoc --ts_proto_opt=esModuleInterop=true --ts_proto_opt=snakeToCamel=false --plugin=./node_modules/.bin/protoc-gen-ts_proto -I "%s" --ts_proto_out=./src/ message.proto'%path print(cmd) os.system(cmd) From b750ec7ac50ba1f9069ba0f4ce380b41ca813df6 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sun, 30 Jan 2022 19:48:41 +0800 Subject: [PATCH 39/66] more api --- gen_js_from_hbb.py | 3 ++ src/connection.ts | 77 ++++++++++++++++++++++++++++++++++-------- src/gen_js_from_hbb.ts | 2 ++ src/globals.js | 33 +++++++++++++----- src/websock.ts | 4 +-- 5 files changed, 95 insertions(+), 24 deletions(-) diff --git a/gen_js_from_hbb.py b/gen_js_from_hbb.py index 73a1f8ebe..024cef387 100755 --- a/gen_js_from_hbb.py +++ b/gen_js_from_hbb.py @@ -51,6 +51,9 @@ def main(): print('export const KEY_MAP: any = {') print(KEY_MAP[0]) print('}') + for ln in open('../hbb/Cargo.toml'): + if ln.startswith('version ='): + print('export const ' + ln) diff --git a/src/connection.ts b/src/connection.ts index 27998bab5..11d1b39e1 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -25,7 +25,7 @@ export default class Connection { _firstFrame: Boolean | undefined; _videoDecoder: any; _audioDecoder: any; - _password: string | undefined; + _password: Uint8Array | undefined; _options: any; constructor() { @@ -36,11 +36,18 @@ export default class Connection { } async start(id: string) { - try { - this._options = - JSON.parse(localStorage.getItem("peers") || "{}")[id] || {}; - } catch (e) { - this._options = {}; + if (!this._options) { + this._options = globals.getPeers()[id] || {}; + } + if (!this._password) { + const p = this.getOption("password"); + if (p) { + try { + this._password = Uint8Array.from(JSON.parse("[" + p + "]")); + } catch (e) { + console.error(e); + } + } } this._interval = setInterval(() => { while (this._msgs.length) { @@ -203,9 +210,10 @@ export default class Connection { this._hash = msg?.hash; if (!this._password) this.msgbox("input-password", "Password Required", ""); - this.login(this._password); + this.login(); } else if (msg?.test_delay) { const test_delay = msg?.test_delay; + console.log(test_delay); if (!test_delay.from_client) { this._ws?.sendMessage({ test_delay }); } @@ -261,9 +269,7 @@ export default class Connection { } refresh() { - const misc = message.Misc.fromPartial({ - refresh_video: true, - }); + const misc = message.Misc.fromPartial({ refresh_video: true }); this._ws?.sendMessage({ misc }); } @@ -275,17 +281,22 @@ export default class Connection { this._draw = callback; } - login(password: string | undefined, _remember: Boolean = false) { - this._password = password; + login(password: string | undefined = undefined) { if (password) { const salt = this._hash?.salt; let p = hash([password, salt!]); + this._password = p; const challenge = this._hash?.challenge; p = hash([p, challenge!]); this.msgbox("connecting", "Connecting...", "Logging in..."); this._sendLoginMessage(p); } else { - this._sendLoginMessage(); + let p = this._password; + if (p) { + const challenge = this._hash?.challenge; + p = hash([p, challenge!]); + } + this._sendLoginMessage(p); } } @@ -363,6 +374,32 @@ export default class Connection { } this.msgbox("success", "Successful", "Connected, waiting for image..."); globals.pushEvent("peer_info", pi); + const p = this.shouldAutoLogin(); + if (p) this.inputOsPassword(p); + const username = this.getOption("info")?.username; + if (username && !pi.username) pi.username = username; + this.setOption("info", pi); + if (this.getRemember()) { + if (this._password?.length) { + const p = this._password.toString(); + if (p != this.getOption("password")) { + this.setOption("password", p); + console.log("remember password of " + this._id); + } + } + } else { + this.setOption("password", undefined); + } + } + + shouldAutoLogin(): string { + const l = this.getOption("lock-after-session-end"); + const a = !!this.getOption("auto-login"); + const p = this.getOption("os-password"); + if (p && l && a) { + return p; + } + return ""; } handleMisc(misc: message.Misc) { @@ -397,12 +434,24 @@ export default class Connection { return this._options["remember"]; } + setRemember(v: Boolean) { + this.setOption("remember", v); + } + getOption(name: string): any { return this._options[name]; } setOption(name: string, value: any) { - this._options[name] = value; + if (value == undefined) { + delete this._options[name]; + } else { + this._options[name] = value; + } + this._options["tm"] = new Date().getTime(); + const peers = globals.getPeers(); + peers[this._id] = this._options; + localStorage.setItem("peers", JSON.stringify(peers)); } inputKey( diff --git a/src/gen_js_from_hbb.ts b/src/gen_js_from_hbb.ts index e9af6cf20..2ad8407a9 100644 --- a/src/gen_js_from_hbb.ts +++ b/src/gen_js_from_hbb.ts @@ -741,3 +741,5 @@ export const KEY_MAP: any = { "LOCK_SCREEN": "LockScreen", } +export const version = "1.1.9" + diff --git a/src/globals.js b/src/globals.js index 3e30d9d5b..d7154043e 100644 --- a/src/globals.js +++ b/src/globals.js @@ -2,7 +2,7 @@ import Connection from "./connection"; import _sodium from "libsodium-wrappers"; import { CursorData } from "./message"; import { loadOpus, loadVp9 } from "./codec"; -import { checkIfRetry } from "./gen_js_from_hbb"; +import { checkIfRetry, version } from "./gen_js_from_hbb"; import { initZstd, translate } from "./common"; var currentFrame = undefined; @@ -62,6 +62,7 @@ export async function startConn(id) { try { currentFrame = undefined; events = []; + setByName('remote_id', id); await curConn.start(id); } catch (e) { console.log(e); @@ -136,16 +137,18 @@ export function decrypt(signed, nonce, key) { } window.setByName = (name, value) => { - try { - value = JSON.parse(value); - } catch (e) { } switch (name) { + case 'remote_id': + localStorage.setItem('remote-id', value); + break; case 'connect': newConn(); - startConn(String(value)); + startConn(value); break; case 'login': - curConn.login(value.password, value.remember || false); + value = JSON.parse(value); + curConn.setRemember(value.remember == 'true'); + curConn.login(value.password); break; case 'close': close(); @@ -172,11 +175,12 @@ window.setByName = (name, value) => { curConn.switchDisplay(value); break; case 'remove': - const peers = JSON.parse(localStorage.getItem('peers') || '{}'); + const peers = getPeers(); delete peers[value]; localStorage.setItem('peers', JSON.stringify(peers)); break; case 'input_key': + value = JSON.parse(value); curConn.inputKey(value.name, value.alt || false, value.ctrl || false, value.shift || false, value.command || false); break; case 'input_string': @@ -184,6 +188,7 @@ window.setByName = (name, value) => { break; case 'send_mouse': let mask = 0; + value = JSON.parse(value); switch (value.type) { case 'down': mask = 1; @@ -205,12 +210,14 @@ window.setByName = (name, value) => { case 'wheel': mask |= 4 << 3; } - curConn.inputMouse(mask, value.x || 0, value.y || 0, value.alt || false, value.ctrl || false, value.shift || false, value.command || false); + curConn.inputMouse(mask, parseInt(value.x || '0'), parseInt(value.y || '0'), value.alt || false, value.ctrl || false, value.shift || false, value.command || false); break; case 'option': + value = JSON.parse(value); localStorage.setItem(value.name, value.value); break; case 'peer_option': + value = JSON.parse(value); curConn.setOption(value.name, value.value); break; case 'input_os_password': @@ -251,6 +258,8 @@ window.getByName = (name, arg) => { return curConn.getOption(arg); case 'test_if_valid_server': break; + case 'version': + return version; } return ''; } @@ -259,4 +268,12 @@ window.init = async () => { loadOpus(() => { }); loadVp9(() => { }); await initZstd(); +} + +export function getPeers() { + try { + return JSON.parse(localStorage.getItem('peers')) || {}; + } catch (e) { + return {}; + } } \ No newline at end of file diff --git a/src/websock.ts b/src/websock.ts index 6b05827de..5eda025d6 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -78,7 +78,7 @@ export default class Websock { return new Promise((resolve, reject) => { setTimeout(() => { if (this._status != "open") { - reject(this._status || "timeout"); + reject(this._status || "Timeout"); } }, timeout); this._websocket.onopen = () => { @@ -131,7 +131,7 @@ export default class Websock { return; } if (new Date().getTime() > tm0 + timeout) { - reject("timeout"); + reject("Timeout"); } else { setTimeout(() => func(resolve, reject, tm0), 1); } From a75bef9791ae2b296be0af08e0a4a5e99150b355 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 31 Jan 2022 00:34:45 +0800 Subject: [PATCH 40/66] fix image quality --- src/connection.ts | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index 11d1b39e1..a25bcee68 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -55,15 +55,8 @@ export default class Connection { this._msgs.splice(0, 1); } }, 1); - loadVp9((decoder: any) => { - this._videoDecoder = decoder; - console.log("vp9 loaded"); - console.log(decoder); - }); - loadOpus((decoder: any) => { - this._audioDecoder = decoder; - console.log("opus loaded"); - }); + this.loadVideoDecoder(); + this.loadAudioDecoder(); const uri = getDefaultUri(); const ws = new Websock(uri); this._ws = ws; @@ -319,7 +312,7 @@ export default class Connection { getOptionMessage(): message.OptionMessage | undefined { let n = 0; const msg = message.OptionMessage.fromPartial({}); - const q = this.getImageQualityEnum(this._options["image-quality"], true); + const q = this.getImageQualityEnum(this.getImageQuality(), true); const yes = message.OptionMessage_BoolOption.Yes; if (q != undefined) { msg.image_quality = q; @@ -424,6 +417,7 @@ export default class Connection { } globals.pushEvent("permission", { [name]: p.enabled }); } else if (misc.switch_display) { + this.loadVideoDecoder(); globals.pushEvent("switch_display", misc.switch_display); } else if (misc.close_reason) { this.msgbox("error", "Connection Error", misc.close_reason); @@ -573,6 +567,10 @@ export default class Connection { this._ws?.sendMessage({ misc }); } + getImageQuality() { + return this.getOption("image-quality"); + } + getImageQualityEnum( value: string, ignoreDefault: Boolean @@ -597,6 +595,23 @@ export default class Connection { const misc = message.Misc.fromPartial({ option }); this._ws?.sendMessage({ misc }); } + + loadVideoDecoder() { + this._videoDecoder?.close(); + loadVp9((decoder: any) => { + this._videoDecoder = decoder; + console.log("vp9 loaded"); + console.log(decoder); + }); + } + + loadAudioDecoder() { + this._audioDecoder?.close(); + loadOpus((decoder: any) => { + this._audioDecoder = decoder; + console.log("opus loaded"); + }); + } } // @ts-ignore From 1e13484c26cff13523971a59c48ef5f1efa1cb9c Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 31 Jan 2022 00:48:04 +0800 Subject: [PATCH 41/66] fix on getByname --- src/connection.ts | 8 ++++---- src/globals.js | 14 +++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index a25bcee68..3337d3505 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -424,8 +424,8 @@ export default class Connection { } } - getRemember(): any { - return this._options["remember"]; + getRemember(): Boolean { + return this._options["remember"] || false; } setRemember(v: Boolean) { @@ -566,9 +566,9 @@ export default class Connection { const misc = message.Misc.fromPartial({ option }); this._ws?.sendMessage({ misc }); } - + getImageQuality() { - return this.getOption("image-quality"); + return this.getOption('image-quality'); } getImageQualityEnum( diff --git a/src/globals.js b/src/globals.js index d7154043e..ca3001d19 100644 --- a/src/globals.js +++ b/src/globals.js @@ -229,14 +229,18 @@ window.setByName = (name, value) => { } window.getByName = (name, arg) => { - try { - arg = JSON.parse(arg); - } catch (e) { } + let v = _getByName(name, arg); + if (typeof v == 'string' || v instanceof String) return v; + if (v == undefined || v == null) return ''; + return JSON.stringify(v); +} + +function _getByName(name, arg) { switch (name) { case 'peers': return localStorage.getItem('peers') || '[]'; case 'remote_id': - return localStorage.getItem('remote-id') || ''; + return localStorage.getItem('remote-id'); case 'remember': return curConn.getRemember(); case 'event': @@ -247,7 +251,7 @@ window.getByName = (name, arg) => { } break; case 'toggle_option': - return curConn.getOption(arg); + return curConn.getOption(arg) || false; case 'option': return localStorage.getItem(arg); case 'image_quality': From 60783c875ea2251435d097000c5eee734d6a01b8 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 31 Jan 2022 02:01:17 +0800 Subject: [PATCH 42/66] peers and more trans --- package.json | 2 +- src/common.ts | 2 +- src/gen_js_from_hbb.ts | 18 ++++++++++++++++++ src/globals.js | 15 ++++++++++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index bc2aa5fff..a69274015 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "scripts": { "dev": "vite", - "build": "tsc && vite build", + "build": "./gen_js_from_hbb.py > src/gen_js_from_hbb.ts && ./ts_proto.py && tsc && vite build", "preview": "vite preview" }, "devDependencies": { diff --git a/src/common.ts b/src/common.ts index 80125848b..2f1516042 100644 --- a/src/common.ts +++ b/src/common.ts @@ -33,7 +33,7 @@ export async function decompress(compressedArray: Uint8Array) { } export function translate(locale: string, text: string): string { - const lang = locale.substr(locale.length - 2).toLowerCase(); + const lang = locale.substring(locale.length - 2).toLowerCase(); let en = LANGS.en as any; let dict = (LANGS as any)[lang]; if (!dict) dict = en; diff --git a/src/gen_js_from_hbb.ts b/src/gen_js_from_hbb.ts index 2ad8407a9..1a53133bc 100644 --- a/src/gen_js_from_hbb.ts +++ b/src/gen_js_from_hbb.ts @@ -199,6 +199,12 @@ export const LANGS = { "Hostname": "主机名", "Discovered": "已发现", "install_daemon_tip": "为了开机启动,请安装系统服务。", + "Remote ID": "远程ID", + "Paste": "粘贴", + "Are you sure to close the connection?": "是否确认关闭连接?", + "Download new version": "下载新版本", + "Touch mode": "触屏模式", + "Reset canvas": "重置画布", }, it: { "Status": "Stato", @@ -393,6 +399,12 @@ export const LANGS = { "Invalid folder name": "Nome della cartella non valido", "Hostname": "Nome host", "Discovered": "Scoperto", + "Remote ID": "ID remoto", + "Paste": "Impasto", + "Are you sure to close the connection?": "Sei sicuro di chiudere la connessione?", + "Download new version": "Scarica nuova versione", + "Touch mode": "Modalità tocco", + "Reset canvas": "Ripristina tela", }, en: { "desk_tip": "Your desktop can be accessed with this ID and password.", @@ -605,6 +617,12 @@ export const LANGS = { "Invalid folder name": "Nom de dossier invalide", "Hostname": "nom d'hôte", "Discovered": "Découvert", + "Remote ID": "ID à distance", + "Paste": "Pâte", + "Are you sure to close the connection?": "Êtes-vous sûr de fermer la connexion?", + "Download new version": "Télécharger la nouvelle version", + "Touch mode": "Mode tactile", + "Reset canvas": "Réinitialiser le canevas", }, } diff --git a/src/globals.js b/src/globals.js index ca3001d19..9b06848b5 100644 --- a/src/globals.js +++ b/src/globals.js @@ -235,10 +235,22 @@ window.getByName = (name, arg) => { return JSON.stringify(v); } +function getPeersForDart() { + const peers = []; + for (const [key, value] of Object.entries(getPeers())) { + if (!key) continue; + const tm = value['tm']; + const info = values['info']; + if (!tm || !info) continue; + peers.push([tm, id, info]); + } + return peers.sort().reverse().map(x => x.slice(1)); +} + function _getByName(name, arg) { switch (name) { case 'peers': - return localStorage.getItem('peers') || '[]'; + return getPeersForDart(); case 'remote_id': return localStorage.getItem('remote-id'); case 'remember': @@ -257,6 +269,7 @@ function _getByName(name, arg) { case 'image_quality': return curConn.getImageQuality(); case 'translate': + const arg = JSON.parse(arg); return translate(arg.locale, arg.text); case 'peer_option': return curConn.getOption(arg); From c58659c7f9d46c3ffa3afa0fa2bbbd4f9b46f75a Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 31 Jan 2022 02:17:04 +0800 Subject: [PATCH 43/66] bug fix --- src/globals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals.js b/src/globals.js index 9b06848b5..3c3013a8f 100644 --- a/src/globals.js +++ b/src/globals.js @@ -269,7 +269,7 @@ function _getByName(name, arg) { case 'image_quality': return curConn.getImageQuality(); case 'translate': - const arg = JSON.parse(arg); + arg = JSON.parse(arg); return translate(arg.locale, arg.text); case 'peer_option': return curConn.getOption(arg); From 529b8dc895bc7f58cc37c55f1069a67639ed8158 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 31 Jan 2022 13:15:18 +0800 Subject: [PATCH 44/66] bug fix --- src/globals.js | 14 +++++++------- src/websock.ts | 7 ++++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/globals.js b/src/globals.js index 3c3013a8f..dd2204684 100644 --- a/src/globals.js +++ b/src/globals.js @@ -40,14 +40,10 @@ export function pushEvent(name, payload) { events.push(payload); } -const yuvWorker = new Worker("./yuv.js"); - -yuvWorker.onmessage = (e) => { - currentFrame = e.data; -} +let yuvWorker; export function draw(frame) { - yuvWorker.postMessage(frame); + if (yuvvWorker) yuvWorker.postMessage(frame); } export function setConn(conn) { @@ -240,7 +236,7 @@ function getPeersForDart() { for (const [key, value] of Object.entries(getPeers())) { if (!key) continue; const tm = value['tm']; - const info = values['info']; + const info = value['info']; if (!tm || !info) continue; peers.push([tm, id, info]); } @@ -282,6 +278,10 @@ function _getByName(name, arg) { } window.init = async () => { + yuvWorker = new Worker("./yuv.js"); + yuvWorker.onmessage = (e) => { + currentFrame = e.data; + } loadOpus(() => { }); loadVp9(() => { }); await initZstd(); diff --git a/src/websock.ts b/src/websock.ts index 5eda025d6..71b84fba4 100644 --- a/src/websock.ts +++ b/src/websock.ts @@ -97,13 +97,14 @@ export default class Websock { }; this._websocket.onclose = (e) => { if (this._status == "open") { - reject(e); + // e.code 1000 means that the connection was closed normally. + reject('Reset by the peer'); } this._status = e; console.error("WebSock.onclose: " + e); this._eventHandlers.close(e); }; - this._websocket.onerror = (e) => { + this._websocket.onerror = (e: any) => { if (!this._status) { reject("Failed to connect to " + this._uri); return; @@ -111,7 +112,7 @@ export default class Websock { this._status = e; console.error("WebSock.onerror: " + e); this._eventHandlers.error(e); - reject(e); + reject(e['data']); }; }); } From 66f5a86827ff80e52cf3ade3b20bf4ea14d474ba Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 31 Jan 2022 13:16:34 +0800 Subject: [PATCH 45/66] typo --- src/globals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals.js b/src/globals.js index dd2204684..f30d67a6d 100644 --- a/src/globals.js +++ b/src/globals.js @@ -43,7 +43,7 @@ export function pushEvent(name, payload) { let yuvWorker; export function draw(frame) { - if (yuvvWorker) yuvWorker.postMessage(frame); + if (yuvWorker) yuvWorker.postMessage(frame); } export function setConn(conn) { From 31076dae41b5c5b9bb895d5b113ed8b491ea0d07 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 31 Jan 2022 13:58:01 +0800 Subject: [PATCH 46/66] add isMobile --- src/globals.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/globals.js b/src/globals.js index f30d67a6d..b0721f18c 100644 --- a/src/globals.js +++ b/src/globals.js @@ -15,6 +15,10 @@ window.getRgba = () => { return tmp || null; } window.getLanguage = () => navigator.language; +window.isMobile = () => { + return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) + || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4)); +} export function msgbox(type, title, text) { if (!events) return; @@ -233,8 +237,8 @@ window.getByName = (name, arg) => { function getPeersForDart() { const peers = []; - for (const [key, value] of Object.entries(getPeers())) { - if (!key) continue; + for (const [id, value] of Object.entries(getPeers())) { + if (!id) continue; const tm = value['tm']; const info = value['info']; if (!tm || !info) continue; From 9ff3bd74c9c8f5c8cf6c14a0bebe6c0bcff1ec6f Mon Sep 17 00:00:00 2001 From: open-trade Date: Thu, 3 Feb 2022 21:26:35 +0800 Subject: [PATCH 47/66] modify input key --- src/connection.ts | 17 ++++++++++++++++- src/globals.js | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/connection.ts b/src/connection.ts index 3337d3505..c0e4138ba 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -450,6 +450,8 @@ export default class Connection { inputKey( name: string, + down: boolean, + press: boolean, alt: Boolean, ctrl: Boolean, shift: Boolean, @@ -457,7 +459,20 @@ export default class Connection { ) { const key_event = mapKey(name); if (!key_event) return; - key_event.press = true; + if (alt && name == 'VK_MENU') { + alt = false; + } + if (ctrl && name == 'VK_CONTROL') { + ctrl = false; + } + if (shift && name == 'VK_SHIFT') { + shift = false; + } + if (command && name == 'Meta') { + command = false; + } + key_event.down = down; + key_event.press = press; key_event.modifiers = this.getMod(alt, ctrl, shift, command); this._ws?.sendMessage({ key_event }); } diff --git a/src/globals.js b/src/globals.js index b0721f18c..f67703cd1 100644 --- a/src/globals.js +++ b/src/globals.js @@ -181,7 +181,7 @@ window.setByName = (name, value) => { break; case 'input_key': value = JSON.parse(value); - curConn.inputKey(value.name, value.alt || false, value.ctrl || false, value.shift || false, value.command || false); + curConn.inputKey(value.name, value.down || false, value.press || false, value.alt || false, value.ctrl || false, value.shift || false, value.command || false); break; case 'input_string': curConn.inputString(value); From b348b3fdc8da6b386273f914e3545f99a24d99b7 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 5 Feb 2022 01:55:23 +0800 Subject: [PATCH 48/66] video_ack_required --- gen_js_from_hbb.py | 5 + index.html | 2 +- ogvjs-1.8.6/COPYING | 21 + ogvjs-1.8.6/COPYING-dav1d.txt | 23 ++ ogvjs-1.8.6/COPYING-ogg.txt | 28 ++ ogvjs-1.8.6/COPYING-opus.txt | 44 ++ ogvjs-1.8.6/COPYING-theora.txt | 28 ++ ogvjs-1.8.6/COPYING-vorbis.txt | 28 ++ ogvjs-1.8.6/LICENSE-nestegg.txt | 13 + ogvjs-1.8.6/LICENSE-vpx.txt | 31 ++ ogvjs-1.8.6/PATENTS-vpx.txt | 23 ++ ogvjs-1.8.6/README.md | 391 ++++++++++++++++++ ogvjs-1.8.6/ogv-decoder-audio-opus-wasm.js | 39 ++ ogvjs-1.8.6/ogv-decoder-audio-opus-wasm.wasm | Bin 0 -> 143417 bytes ogvjs-1.8.6/ogv-decoder-audio-vorbis-wasm.js | 40 ++ .../ogv-decoder-audio-vorbis-wasm.wasm | Bin 0 -> 155787 bytes ogvjs-1.8.6/ogv-decoder-video-av1-mt-wasm.js | 21 + .../ogv-decoder-video-av1-mt-wasm.wasm | Bin 0 -> 418335 bytes .../ogv-decoder-video-av1-mt-wasm.worker.js | 1 + .../ogv-decoder-video-av1-simd-mt-wasm.js | 21 + .../ogv-decoder-video-av1-simd-mt-wasm.wasm | Bin 0 -> 495935 bytes ...v-decoder-video-av1-simd-mt-wasm.worker.js | 1 + .../ogv-decoder-video-av1-simd-wasm.js | 43 ++ .../ogv-decoder-video-av1-simd-wasm.wasm | Bin 0 -> 484008 bytes ogvjs-1.8.6/ogv-decoder-video-av1-wasm.js | 43 ++ ogvjs-1.8.6/ogv-decoder-video-av1-wasm.wasm | Bin 0 -> 406454 bytes ogvjs-1.8.6/ogv-decoder-video-theora-wasm.js | 42 ++ .../ogv-decoder-video-theora-wasm.wasm | Bin 0 -> 48923 bytes ogvjs-1.8.6/ogv-decoder-video-vp8-mt-wasm.js | 21 + .../ogv-decoder-video-vp8-mt-wasm.wasm | Bin 0 -> 139143 bytes .../ogv-decoder-video-vp8-mt-wasm.worker.js | 1 + ogvjs-1.8.6/ogv-decoder-video-vp8-wasm.js | 44 ++ ogvjs-1.8.6/ogv-decoder-video-vp8-wasm.wasm | Bin 0 -> 113790 bytes ogvjs-1.8.6/ogv-decoder-video-vp9-mt-wasm.js | 21 + .../ogv-decoder-video-vp9-mt-wasm.wasm | Bin 0 -> 259095 bytes .../ogv-decoder-video-vp9-mt-wasm.worker.js | 1 + .../ogv-decoder-video-vp9-simd-mt-wasm.js | 21 + .../ogv-decoder-video-vp9-simd-mt-wasm.wasm | Bin 0 -> 277701 bytes ...v-decoder-video-vp9-simd-mt-wasm.worker.js | 1 + .../ogv-decoder-video-vp9-simd-wasm.js | 45 ++ .../ogv-decoder-video-vp9-simd-wasm.wasm | Bin 0 -> 260523 bytes ogvjs-1.8.6/ogv-decoder-video-vp9-wasm.js | 45 ++ ogvjs-1.8.6/ogv-decoder-video-vp9-wasm.wasm | Bin 0 -> 241857 bytes ogvjs-1.8.6/ogv-demuxer-ogg-wasm.js | 43 ++ ogvjs-1.8.6/ogv-demuxer-ogg-wasm.wasm | Bin 0 -> 39042 bytes ogvjs-1.8.6/ogv-demuxer-webm-wasm.js | 46 +++ ogvjs-1.8.6/ogv-demuxer-webm-wasm.wasm | Bin 0 -> 43838 bytes ogvjs-1.8.6/ogv-es2017.js | 2 + ogvjs-1.8.6/ogv-support.js | 1 + ogvjs-1.8.6/ogv-version.js | 1 + ogvjs-1.8.6/ogv-worker-audio.js | 1 + ogvjs-1.8.6/ogv-worker-video.js | 1 + ogvjs-1.8.6/ogv.js | 2 + package.json | 1 - src/codec.js | 9 +- src/common.ts | 5 +- src/connection.ts | 58 ++- src/gen_js_from_hbb.ts | 12 +- src/globals.js | 7 +- src/message.ts | 28 ++ src/ui.js | 1 + src/websock.ts | 33 +- yarn.lock | 19 - yuv.js | 4 +- yuv_rgb.c | 3 + 65 files changed, 1307 insertions(+), 58 deletions(-) create mode 100644 ogvjs-1.8.6/COPYING create mode 100644 ogvjs-1.8.6/COPYING-dav1d.txt create mode 100644 ogvjs-1.8.6/COPYING-ogg.txt create mode 100644 ogvjs-1.8.6/COPYING-opus.txt create mode 100644 ogvjs-1.8.6/COPYING-theora.txt create mode 100644 ogvjs-1.8.6/COPYING-vorbis.txt create mode 100644 ogvjs-1.8.6/LICENSE-nestegg.txt create mode 100644 ogvjs-1.8.6/LICENSE-vpx.txt create mode 100644 ogvjs-1.8.6/PATENTS-vpx.txt create mode 100644 ogvjs-1.8.6/README.md create mode 100644 ogvjs-1.8.6/ogv-decoder-audio-opus-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-audio-opus-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-audio-vorbis-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-audio-vorbis-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-av1-mt-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-av1-mt-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-av1-mt-wasm.worker.js create mode 100644 ogvjs-1.8.6/ogv-decoder-video-av1-simd-mt-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-av1-simd-mt-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-av1-simd-mt-wasm.worker.js create mode 100644 ogvjs-1.8.6/ogv-decoder-video-av1-simd-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-av1-simd-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-av1-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-av1-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-theora-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-theora-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-vp8-mt-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-vp8-mt-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-vp8-mt-wasm.worker.js create mode 100644 ogvjs-1.8.6/ogv-decoder-video-vp8-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-vp8-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-vp9-mt-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-vp9-mt-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-vp9-mt-wasm.worker.js create mode 100644 ogvjs-1.8.6/ogv-decoder-video-vp9-simd-mt-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-vp9-simd-mt-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-vp9-simd-mt-wasm.worker.js create mode 100644 ogvjs-1.8.6/ogv-decoder-video-vp9-simd-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-vp9-simd-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-decoder-video-vp9-wasm.js create mode 100755 ogvjs-1.8.6/ogv-decoder-video-vp9-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-demuxer-ogg-wasm.js create mode 100755 ogvjs-1.8.6/ogv-demuxer-ogg-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-demuxer-webm-wasm.js create mode 100755 ogvjs-1.8.6/ogv-demuxer-webm-wasm.wasm create mode 100644 ogvjs-1.8.6/ogv-es2017.js create mode 100644 ogvjs-1.8.6/ogv-support.js create mode 100644 ogvjs-1.8.6/ogv-version.js create mode 100644 ogvjs-1.8.6/ogv-worker-audio.js create mode 100644 ogvjs-1.8.6/ogv-worker-video.js create mode 100644 ogvjs-1.8.6/ogv.js diff --git a/gen_js_from_hbb.py b/gen_js_from_hbb.py index 024cef387..0ee6e40c4 100755 --- a/gen_js_from_hbb.py +++ b/gen_js_from_hbb.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +import re import os import glob from tabnanny import check @@ -30,6 +31,7 @@ def main(): check_if_retry[1] = False continue if check_if_retry[1]: + ln = removeComment(ln) check_if_retry[0] += ln + '\n' if 'KEY_MAP' in ln: KEY_MAP[1] = True @@ -38,6 +40,7 @@ def main(): KEY_MAP[1] = False continue if KEY_MAP[1] and ln.startswith('('): + ln = removeComment(ln) toks = ln.split('", Key::') assert(len(toks) == 2) a = toks[0][2:] @@ -56,5 +59,7 @@ def main(): print('export const ' + ln) +def removeComment(ln): + return re.sub('\s+\/\/.*$', '', ln) main() \ No newline at end of file diff --git a/index.html b/index.html index aef6abe0f..93d956b74 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - + Vite App diff --git a/ogvjs-1.8.6/COPYING b/ogvjs-1.8.6/COPYING new file mode 100644 index 000000000..56c4368fa --- /dev/null +++ b/ogvjs-1.8.6/COPYING @@ -0,0 +1,21 @@ +ogv.js wrapper and player code + +Copyright (c) 2013-2019 Brion Vibber and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/ogvjs-1.8.6/COPYING-dav1d.txt b/ogvjs-1.8.6/COPYING-dav1d.txt new file mode 100644 index 000000000..875b138ec --- /dev/null +++ b/ogvjs-1.8.6/COPYING-dav1d.txt @@ -0,0 +1,23 @@ +Copyright © 2018-2019, VideoLAN and dav1d authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ogvjs-1.8.6/COPYING-ogg.txt b/ogvjs-1.8.6/COPYING-ogg.txt new file mode 100644 index 000000000..6111c6c5a --- /dev/null +++ b/ogvjs-1.8.6/COPYING-ogg.txt @@ -0,0 +1,28 @@ +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ogvjs-1.8.6/COPYING-opus.txt b/ogvjs-1.8.6/COPYING-opus.txt new file mode 100644 index 000000000..9c739c34a --- /dev/null +++ b/ogvjs-1.8.6/COPYING-opus.txt @@ -0,0 +1,44 @@ +Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic, + Jean-Marc Valin, Timothy B. Terriberry, + CSIRO, Gregory Maxwell, Mark Borgerding, + Erik de Castro Lopo + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Opus is subject to the royalty-free patent licenses which are +specified at: + +Xiph.Org Foundation: +https://datatracker.ietf.org/ipr/1524/ + +Microsoft Corporation: +https://datatracker.ietf.org/ipr/1914/ + +Broadcom Corporation: +https://datatracker.ietf.org/ipr/1526/ diff --git a/ogvjs-1.8.6/COPYING-theora.txt b/ogvjs-1.8.6/COPYING-theora.txt new file mode 100644 index 000000000..c8ccce4ff --- /dev/null +++ b/ogvjs-1.8.6/COPYING-theora.txt @@ -0,0 +1,28 @@ +Copyright (C) 2002-2009 Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ogvjs-1.8.6/COPYING-vorbis.txt b/ogvjs-1.8.6/COPYING-vorbis.txt new file mode 100644 index 000000000..153b926a1 --- /dev/null +++ b/ogvjs-1.8.6/COPYING-vorbis.txt @@ -0,0 +1,28 @@ +Copyright (c) 2002-2018 Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ogvjs-1.8.6/LICENSE-nestegg.txt b/ogvjs-1.8.6/LICENSE-nestegg.txt new file mode 100644 index 000000000..a67984a61 --- /dev/null +++ b/ogvjs-1.8.6/LICENSE-nestegg.txt @@ -0,0 +1,13 @@ +Copyright © 2010 Mozilla Foundation + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/ogvjs-1.8.6/LICENSE-vpx.txt b/ogvjs-1.8.6/LICENSE-vpx.txt new file mode 100644 index 000000000..1ce44343c --- /dev/null +++ b/ogvjs-1.8.6/LICENSE-vpx.txt @@ -0,0 +1,31 @@ +Copyright (c) 2010, The WebM Project authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Google, nor the WebM Project, nor the names + of its contributors may be used to endorse or promote products + derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/ogvjs-1.8.6/PATENTS-vpx.txt b/ogvjs-1.8.6/PATENTS-vpx.txt new file mode 100644 index 000000000..caedf607e --- /dev/null +++ b/ogvjs-1.8.6/PATENTS-vpx.txt @@ -0,0 +1,23 @@ +Additional IP Rights Grant (Patents) +------------------------------------ + +"These implementations" means the copyrightable works that implement the WebM +codecs distributed by Google as part of the WebM Project. + +Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, +royalty-free, irrevocable (except as stated in this section) patent license to +make, have made, use, offer to sell, sell, import, transfer, and otherwise +run, modify and propagate the contents of these implementations of WebM, where +such license applies only to those patent claims, both currently owned by +Google and acquired in the future, licensable by Google that are necessarily +infringed by these implementations of WebM. This grant does not include claims +that would be infringed only as a consequence of further modification of these +implementations. If you or your agent or exclusive licensee institute or order +or agree to the institution of patent litigation or any other patent +enforcement activity against any entity (including a cross-claim or +counterclaim in a lawsuit) alleging that any of these implementations of WebM +or any code incorporated within any of these implementations of WebM +constitute direct or contributory patent infringement, or inducement of +patent infringement, then any patent rights granted to you under this License +for these implementations of WebM shall terminate as of the date such +litigation is filed. diff --git a/ogvjs-1.8.6/README.md b/ogvjs-1.8.6/README.md new file mode 100644 index 000000000..cb7e249d5 --- /dev/null +++ b/ogvjs-1.8.6/README.md @@ -0,0 +1,391 @@ +ogv.js +====== + +Media decoder and player for Ogg Vorbis/Opus/Theora and WebM VP8/VP9/AV1 video. + +Based around libogg, libvorbis, libtheora, libopus, libvpx, libnestegg and dav1d compiled to JavaScript and WebAssembly with Emscripten. + +## Updates + +1.8.6 - 2022-01-12 +* Bump to yuv-canvas +* Fix demo for removal of video-canvas mode + +1.8.5 - 2022-01-11 +* Remove unnecessary user-agent checks +* Remove flaky, obsolete support for faking CSS `object-fit` +* Remove experimental support for streaming `` into `